Package com.totsp.gwittir.client.fx

Source Code of com.totsp.gwittir.client.fx.DragAndDropContext$DraggablePopupPanel

package com.totsp.gwittir.client.fx;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.SourcesMouseEvents;
import com.google.gwt.user.client.ui.Widget;

import com.totsp.gwittir.client.fx.DragListener.DragPoint;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


public class DragAndDropContext {
    private static final DraggedPlaceholderStrategy DEFAULT_DPS = new DraggedPlaceholderStrategy() {
            public void setupPlaceholderElement(Widget dragged, Element element) {
                DOM.setInnerHTML(element, dragged.toString());
                DOM.setStyleAttribute(element, "width",
                    dragged.getOffsetWidth() + "px");
                DOM.setStyleAttribute(element, "height",
                    dragged.getOffsetHeight() + "px");
                DOM.setStyleAttribute(element, "background", "#CCCCCC");
                DOM.setStyleAttribute(element, "opacity", ".5");
            }
        };

    private Draggable dragging;
    private Element placeholder;
    private HashMap<Widget, Draggable> draggables = new HashMap<Widget, Draggable>();
    private HashMap<Widget, List<DropListener>> dropListeners = new HashMap<Widget, List<DropListener>>();
    private List<Widget> dropTargets;

    public DragAndDropContext() {
    }

    public void setDraggedPlaceholderStrategy(Widget draggable,
        DraggedPlaceholderStrategy strat) {
        Draggable d = this.draggables.get(draggable);
        d.strat = strat;
    }

    public void addDragListener(SourcesMouseEvents w, DragListener l) {
        Draggable d = this.draggables.get((Widget) w);
        d.listeners.add(l);
    }

    public void addDropListener(Widget w, DropListener dl) {
        List<DropListener> listeners = (dropListeners.get(w) != null)
            ? dropListeners.get(w) : new ArrayList<DropListener>();
        listeners.add(dl);
        dropListeners.put(w, listeners);
    }

    public void makeDraggable(SourcesMouseEvents w, boolean revert) {
        Draggable d = new Draggable();
        d.widget = (Widget) w;
        d.listener = new DragSupportListener((Widget) w, revert);
        w.addMouseListener(d.listener);
        draggables.put(d.widget, d);
    }

    public void makeDroppable(Widget w) {
        dropTargets = (dropTargets == null) ? new ArrayList<Widget>()
                                            : dropTargets;
        dropTargets.add(w);
    }

    public void removeDragListener(SourcesMouseEvents w, DragListener l) {
        Draggable d = this.draggables.get((Widget) w);
        d.listeners.remove(l);
    }

    public void removeDraggable(SourcesMouseEvents w) {
        Draggable d = this.draggables.get((Widget) w);
        w.removeMouseListener(d.listener);
        this.draggables.remove(d.widget);
    }

    public void removeDropListeners(SourcesMouseEvents w, DropListener dl) {
        List<DropListener> listeners = (dropListeners.get((Widget) w) != null)
            ? dropListeners.get((Widget) w) : new ArrayList<DropListener>();
        listeners.remove(dl);
    }

    public void removeDroppable(Widget w) {
        this.dropListeners.remove(w);
        this.dropTargets.remove(w);
    }

    class DragSupportListener extends MouseListenerAdapter {
        DraggablePopupPanel p;
        boolean cancelled;
        private boolean revert;

        public DragSupportListener(Widget w, boolean revert) {
            this.revert = revert;
        }

        @Override
        public void onMouseDown(final Widget sender, final int x, final int y) {
            super.onMouseDown(sender, x, y);

            if (dragging != null) {
                dragging.listener.onMouseUp(dragging.widget, 0, 0);
            }

            cancelled = false;

            Timer t = new Timer() {
                    @Override
                    public void run() {
                        if (cancelled) {
                            return;
                        }

                        dragging = (Draggable) draggables.get(sender);

                        int ix = dragging.widget.getAbsoluteLeft();
                        int iy = dragging.widget.getAbsoluteTop();

                        placeholder = DOM.createDiv();

                        if (revert) {
                            if (dragging.strat == null) {
                                DEFAULT_DPS.setupPlaceholderElement(dragging.widget,
                                    placeholder);
                            } else {
                                dragging.strat.setupPlaceholderElement(dragging.widget,
                                    placeholder);
                            }
                        }

                        int index = DOM.getChildIndex(DOM.getParent(
                                    dragging.widget.getElement()),
                                dragging.widget.getElement());
                        DOM.insertChild(DOM.getParent(
                                dragging.widget.getElement()), placeholder,
                            index);
                        p = new DraggablePopupPanel(dragging);
                        p.setWidth(dragging.widget.getOffsetWidth() + "px");
                        p.setHeight(dragging.widget.getOffsetHeight() + "px");
                        p.p.setWidget(revert
                            ? new HTML(dragging.widget.toString())
                            : dragging.widget);

                        if (revert) {
                            dragging.display = dragging.widget.getElement()
                                                              .getStyle()
                                                              .getProperty("display");
                            dragging.widget.getElement().getStyle()
                                           .setProperty("display", "none");
                        }

                        p.revert = revert;
                        p.setPopupPosition(ix, iy);
                        p.show();
                        p.onMouseDown(p.p, x, y);
                    }
                };

            t.schedule(150);
        }

        @Override
        public void onMouseMove(Widget sender, int x, int y) {
        }

        @Override
        public void onMouseUp(Widget sender, int x, int y) {
            cancelled = true;
            if(p != null){
                p.onMouseUp(p.p, x, y);
            }
           
        }
    }

    private class Draggable {
        public ArrayList<DragListener> listeners = new ArrayList<DragListener>();
        public DragSupportListener listener;
        public DraggedPlaceholderStrategy strat;
        public String display;
        public Widget widget;
        public int lowerX;
        public int lowerY;
        public int upperX;
        public int upperY;
    }

    private class DraggablePopupPanel extends PopupPanel
        implements MouseListener {
        FocusPanel p = new FocusPanel();
        boolean isDragging = true;
        boolean revert;
        int dragStartX;
        int dragStartY;
        private Draggable d;
        private Widget lastHover = null;

        DraggablePopupPanel(Draggable d) {
            this.setWidget(p);
            this.d = d;
            p.addMouseListener(this);
            this.setStyleName("gwittir-Draggable");

            DOM.sinkEvents(getElement(),
                DOM.getEventsSunk(getElement()) | Event.MOUSEEVENTS);
            DOM.addEventPreview(this);
        }

        @Override
        public boolean onEventPreview(Event event) {
            if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
                if (DOM.isOrHasChild(p.getElement(), DOM.eventGetTarget(event))) {
                    DOM.eventPreventDefault(event);
                }
            }

            return true;
        }

        public void onMouseDown(Widget sender, int x, int y) {
            isDragging = true;
            DOM.setCapture(p.getElement());
            dragStartX = x;
            dragStartY = y;
        }

        public void onMouseEnter(Widget sender) {
        }

        public void onMouseLeave(Widget sender) {
        }

        public void onMouseMove(Widget sender, int x, int y) {
            if (isDragging) {
                int absX = x + getAbsoluteLeft();
                int absY = y + getAbsoluteTop();
                DragPoint pt = new DragPoint(absX - dragStartX,
                        absY - dragStartY);

                for (DragListener l : d.listeners) {
                    pt = l.onDrag(pt);
                }

                setPopupPosition(pt.getX(), pt.getY());

                Widget newHover = calc(sender, x, y, false);

                if ((lastHover != null) && (lastHover != newHover) &&
                        dropListeners.containsKey(lastHover)) {
                    for (DropListener l : dropListeners.get(lastHover)) {
                        l.onEndHover(sender);
                    }
                }

                lastHover = newHover;
            }
        }

        public void onMouseUp(Widget sender, int x, int y) {
            if (isDragging) {
                calc(sender, x, y, true);
            }
        }

        private Widget calc(Widget sender, int x, int y, boolean drop) {
            if (drop) {
                isDragging = false;
                dragStartX = (x + getAbsoluteLeft()) - dragStartX;
                dragStartY = (y + getAbsoluteTop()) - dragStartY;

                DOM.releaseCapture(p.getElement());
            }

            int top = this.getAbsoluteTop();
            int left = this.getAbsoluteLeft();
            int centerY = top +
                (int) ((float) this.getOffsetHeight() / (float) 2);
            int centerX = left +
                (int) ((float) this.getOffsetWidth() / (float) 2);

            Widget hit = null;
            for (int i = dropTargets == null ? -1 : dropTargets.size() -1 ; i > -1; i-- ) {
                Widget w = dropTargets.get(i);

                if ((centerY >= w.getAbsoluteTop()) &&
                        (centerY <= (w.getAbsoluteTop() + w.getOffsetHeight())) &&
                        (centerX >= w.getAbsoluteLeft()) &&
                        (centerX <= (w.getAbsoluteLeft() + w.getOffsetWidth()))) {
                    List<DropListener> listeners = dropListeners.get(w);

                    for (int j = 0;
                            (listeners != null) && (j < listeners.size());
                            j++) {
                        DropListener l = (DropListener) listeners.get(j);

                        if ((drop && l.canDrop(dragging.widget)) ||
                                (!drop && l.onHover(sender))) {
                            if (drop) {
                                //Make sure we revert the widget before the drop event in case the user
                                // wants to do something with it.
                                if (revert) {
                                    DOM.removeChild(DOM.getParent(
                                            dragging.widget.getElement()),
                                        placeholder);
                                    dragging.widget.getElement().getStyle()
                                                   .setProperty("display",
                                        dragging.display);
                                    hide();
                                    placeholder = null;
                                }

                                l.onDrop(dragging.widget);
                            }

                            hit = w;

                            break;
                        }
                    }
                }
            }

            if (drop && revert && (hit == null)) {
                DOM.removeChild(DOM.getParent(dragging.widget.getElement()),
                    placeholder);
                dragging.widget.getElement().getStyle()
                               .setProperty("display", dragging.display);
                hide();
                placeholder = null;
            }

            return hit;
        }
    }
}
TOP

Related Classes of com.totsp.gwittir.client.fx.DragAndDropContext$DraggablePopupPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.