org.uberfire.client.workbench.widgets.dnd.CompassWidget.java Source code

Java tutorial

Introduction

Here is the source code for org.uberfire.client.workbench.widgets.dnd.CompassWidget.java

Source

/*
 * Copyright 2012 JBoss Inc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.uberfire.client.workbench.widgets.dnd;

import com.allen_sauer.gwt.dnd.client.DragContext;
import com.allen_sauer.gwt.dnd.client.VetoDragException;
import com.allen_sauer.gwt.dnd.client.drop.DropController;
import com.allen_sauer.gwt.dnd.client.util.CoordinateArea;
import com.allen_sauer.gwt.dnd.client.util.CoordinateLocation;
import com.allen_sauer.gwt.dnd.client.util.Location;
import com.allen_sauer.gwt.dnd.client.util.WidgetArea;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
import org.uberfire.client.resources.WorkbenchResources;
import org.uberfire.workbench.model.Position;

/**
 * A pop-up "compass" widget that appears centralised on it's parent Drop Target
 * and permits drop events on the compass points.
 */
public class CompassWidget extends PopupPanel implements DropController {

    private static CompassWidget instance;

    private static Element dropTargetHighlight;

    private final Image northWidget = new Image(WorkbenchResources.INSTANCE.images().compassNorth());
    private final Image southWidget = new Image(WorkbenchResources.INSTANCE.images().compassSouth());
    private final Image eastWidget = new Image(WorkbenchResources.INSTANCE.images().compassEast());
    private final Image westWidget = new Image(WorkbenchResources.INSTANCE.images().compassWest());
    private final Image centreWidget = new Image(WorkbenchResources.INSTANCE.images().compassCentre());

    private final FlexTable container = new FlexTable();

    private Position dropTargetPosition = Position.NONE;

    public static CompassWidget getInstance() {
        if (instance == null) {
            instance = new CompassWidget();
        }
        return instance;
    }

    private CompassWidget() {
        super();
        this.setStyleName(WorkbenchResources.INSTANCE.CSS().dropTargetCompass());
        this.container.setCellPadding(0);
        this.container.setCellSpacing(0);

        //Setup drop indicator
        if (dropTargetHighlight == null) {
            dropTargetHighlight = Document.get().createDivElement();
            dropTargetHighlight.getStyle().setPosition(Style.Position.ABSOLUTE);
            dropTargetHighlight.getStyle().setVisibility(Visibility.HIDDEN);
            dropTargetHighlight.setClassName(WorkbenchResources.INSTANCE.CSS().dropTargetHighlight());
            dropTargetHighlight.getStyle().setMargin(0, Unit.PX);
            dropTargetHighlight.getStyle().setPadding(0, Unit.PX);
            dropTargetHighlight.getStyle().setBorderWidth(0, Unit.PX);
            Document.get().getBody().appendChild(dropTargetHighlight);
        }

        //Setup Compass images
        northWidget.getElement().getStyle().setOpacity(0.75);
        southWidget.getElement().getStyle().setOpacity(0.75);
        eastWidget.getElement().getStyle().setOpacity(0.75);
        westWidget.getElement().getStyle().setOpacity(0.75);
        container.setWidget(0, 1, northWidget);
        container.setWidget(1, 0, westWidget);
        container.setWidget(1, 1, centreWidget);
        container.setWidget(1, 2, eastWidget);
        container.setWidget(2, 1, southWidget);

        setWidget(container);
    }

    @Override
    public void onEnter(DragContext context) {
        show(context);
    }

    @Override
    public void onLeave(DragContext context) {
        hide();
    }

    @Override
    public void onMove(DragContext context) {
        final Location l = new CoordinateLocation(context.mouseX, context.mouseY);
        final WidgetArea northWidgetArea = new WidgetArea(northWidget, null);
        final WidgetArea southWidgetArea = new WidgetArea(southWidget, null);
        final WidgetArea eastWidgetArea = new WidgetArea(eastWidget, null);
        final WidgetArea westWidgetArea = new WidgetArea(westWidget, null);
        final WidgetArea centreWidgetArea = new WidgetArea(centreWidget, null);
        Position p = Position.NONE;
        if (northWidgetArea.intersects(l)) {
            p = Position.NORTH;
        } else if (southWidgetArea.intersects(l)) {
            p = Position.SOUTH;
        } else if (eastWidgetArea.intersects(l)) {
            p = Position.EAST;
        } else if (westWidgetArea.intersects(l)) {
            p = Position.WEST;
        } else if (centreWidgetArea.intersects(l)) {
            p = Position.SELF;
        }
        if (p != dropTargetPosition) {
            dropTargetPosition = p;
            showDropTarget(context, p);
        }
    }

    public Position getDropPosition() {
        return this.dropTargetPosition;
    }

    @Override
    public Widget getDropTarget() {
        throw new UnsupportedOperationException();
    }

    @Override
    public void onDrop(DragContext context) {
        this.dropTargetPosition = Position.NONE;
        hideDropTarget();
    }

    @Override
    public void onPreviewDrop(DragContext context) throws VetoDragException {
        throw new UnsupportedOperationException();
    }

    private void show(final DragContext context) {

        //Get centre of DropTarget
        final Widget dropTargetParent = context.dropController.getDropTarget();
        int cxmin = dropTargetParent.getElement().getAbsoluteLeft();
        int cymin = dropTargetParent.getElement().getAbsoluteTop();
        int cxmax = dropTargetParent.getElement().getAbsoluteRight();
        int cymax = dropTargetParent.getElement().getAbsoluteBottom();

        final CoordinateArea ca = new CoordinateArea(cxmin, cymin, cxmax, cymax);

        //Display Compass if not already visible
        if (!isAttached()) {
            setPopupPositionAndShow(new PositionCallback() {

                @Override
                public void setPosition(int offsetWidth, int offsetHeight) {
                    setPopupPosition(ca.getCenter().getLeft() - (offsetWidth / 2),
                            ca.getCenter().getTop() - (offsetHeight / 2));
                }

            });

        } else {
            setPopupPosition(ca.getCenter().getLeft() - (getOffsetWidth() / 2),
                    ca.getCenter().getTop() - (getOffsetHeight() / 2));
        }

    }

    private void showDropTarget(final DragContext context, final Position p) {
        int x = 0;
        int y = 0;
        int width = 0;
        int height = 0;
        final Widget dropTargetParent = context.dropController.getDropTarget();
        switch (p) {
        case SELF:
            x = dropTargetParent.getAbsoluteLeft();
            y = dropTargetParent.getAbsoluteTop();
            width = dropTargetParent.getOffsetWidth();
            height = dropTargetParent.getOffsetHeight();
            showDropTarget(x, y, width, height);
            break;
        case NORTH:
            x = dropTargetParent.getAbsoluteLeft();
            y = dropTargetParent.getAbsoluteTop();
            width = dropTargetParent.getOffsetWidth();
            height = (int) (dropTargetParent.getOffsetHeight() * 0.50);
            showDropTarget(x, y, width, height);
            break;
        case SOUTH:
            x = dropTargetParent.getAbsoluteLeft();
            height = (int) (dropTargetParent.getOffsetHeight() * 0.50);
            y = dropTargetParent.getOffsetHeight() + dropTargetParent.getAbsoluteTop() - height;
            width = dropTargetParent.getOffsetWidth();
            showDropTarget(x, y, width, height);
            break;
        case EAST:
            width = (int) (dropTargetParent.getOffsetWidth() * 0.50);
            x = dropTargetParent.getOffsetWidth() + dropTargetParent.getAbsoluteLeft() - width;
            y = dropTargetParent.getAbsoluteTop();
            height = dropTargetParent.getOffsetHeight();
            showDropTarget(x, y, width, height);
            break;
        case WEST:
            x = dropTargetParent.getAbsoluteLeft();
            y = dropTargetParent.getAbsoluteTop();
            width = (int) (dropTargetParent.getOffsetWidth() * 0.50);
            height = dropTargetParent.getOffsetHeight();
            showDropTarget(x, y, width, height);
            break;
        default:
            hideDropTarget();
        }
    }

    private void showDropTarget(int x, int y, int width, int height) {
        dropTargetHighlight.getStyle().setLeft(x, Unit.PX);
        dropTargetHighlight.getStyle().setWidth(width, Unit.PX);
        dropTargetHighlight.getStyle().setTop(y, Unit.PX);
        dropTargetHighlight.getStyle().setHeight(height, Unit.PX);
        dropTargetHighlight.getStyle().setVisibility(Visibility.VISIBLE);
        dropTargetHighlight.getStyle().setDisplay(Display.BLOCK);
    }

    private void hideDropTarget() {
        dropTargetHighlight.getStyle().setVisibility(Visibility.HIDDEN);
        dropTargetHighlight.getStyle().setDisplay(Display.NONE);
        dropTargetPosition = Position.NONE;
    }

}