com.chinarewards.gwt.license.client.ui.DialogBox.java Source code

Java tutorial

Introduction

Here is the source code for com.chinarewards.gwt.license.client.ui.DialogBox.java

Source

package com.chinarewards.gwt.license.client.ui;

import com.chinarewards.gwt.license.client.core.Platform;
import com.chinarewards.gwt.license.client.core.ui.Dialog;
import com.chinarewards.gwt.license.client.widget.Span;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasAllMouseHandlers;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
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.Event.NativePreviewEvent;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.DecoratedPopupPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;

/**
 * A form of popup that has a caption area at the top and can be dragged by the
 * user. Unlike a PopupPanel, calls to {@link #setWidth(String)} and
 * {@link #setHeight(String)} will set the width and height of the dialog box
 * itself, even if a widget has not been added as yet.
 * <p>
 * <img class='gallery' src='doc-files/DialogBox.png'/>
 * </p>
 * <h3>CSS Style Rules</h3>
 * 
 * <ul>
 * <li>.gwt-DialogBox { the outside of the dialog }</li>
 * <li>.gwt-DialogBox .Caption { the caption }</li>
 * <li>.gwt-DialogBox .dialogContent { the wrapper around the content }</li>
 * <li>.gwt-DialogBox .dialogTopLeft { the top left cell }</li>
 * <li>.gwt-DialogBox .dialogTopLeftInner { the inner element of the cell }</li>
 * <li>.gwt-DialogBox .dialogTopCenter { the top center cell, where the caption
 * is located }</li>
 * <li>.gwt-DialogBox .dialogTopCenterInner { the inner element of the cell }</li>
 * <li>.gwt-DialogBox .dialogTopRight { the top right cell }</li>
 * <li>.gwt-DialogBox .dialogTopRightInner { the inner element of the cell }</li>
 * <li>.gwt-DialogBox .dialogMiddleLeft { the middle left cell }</li>
 * <li>.gwt-DialogBox .dialogMiddleLeftInner { the inner element of the cell }</li>
 * <li>.gwt-DialogBox .dialogMiddleCenter { the middle center cell, where the
 * content is located }</li>
 * <li>.gwt-DialogBox .dialogMiddleCenterInner { the inner element of the cell }
 * </li>
 * <li>.gwt-DialogBox .dialogMiddleRight { the middle right cell }</li>
 * <li>.gwt-DialogBox .dialogMiddleRightInner { the inner element of the cell }</li>
 * <li>.gwt-DialogBox .dialogBottomLeft { the bottom left cell }</li>
 * <li>.gwt-DialogBox .dialogBottomLeftInner { the inner element of the cell }</li>
 * <li>.gwt-DialogBox .dialogBottomCenter { the bottom center cell }</li>
 * <li>.gwt-DialogBox .dialogBottomCenterInner { the inner element of the cell }
 * </li>
 * <li>.gwt-DialogBox .dialogBottomRight { the bottom right cell }</li>
 * <li>.gwt-DialogBox .dialogBottomRightInner { the inner element of the cell }</li>
 * </ul>
 * <p>
 * <h3>Example</h3>
 * {@example com.google.gwt.examples.DialogBoxExample}
 * </p>
 * 
 * <h3>Use in UiBinder Templates</h3>
 * <p>
 * DialogBox elements in {@link com.google.gwt.uibinder.client.UiBinder
 * UiBinder} templates can have one widget child and one &lt;g:caption> child.
 * (Note the lower case "c", meant to signal that the caption is not a runtime
 * object, and so cannot have a <code>ui:field</code> attribute.) The body of
 * the caption can be html.
 * <p>
 * For example:
 * 
 * <pre>
 * &lt;g:DialogBox autoHide="true" modal="true">
 *   &lt;g:caption>&lt;b>Caption text&lt;/b>&lt;/g:caption>
 *   &lt;g:HTMLPanel>
 *     Body text
 *     &lt;g:Button ui:field='cancelButton'>Cancel&lt;/g:Button>
 *     &lt;g:Button ui:field='okButton'>Okay&lt;/g:Button>
 *   &lt;/g:HTMLPanel>
 * &lt;/g:DialogBox>
 * </pre>
 */
@SuppressWarnings("deprecation")
public class DialogBox extends DecoratedPopupPanel implements MouseListener {
    /**
     * Set of characteristic interfaces supported by the {@link DialogBox}
     * caption
     * 
     * Note that this set might expand over time, so implement this interface at
     * your own risk.
     */
    public interface Caption extends HasAllMouseHandlers {
    }

    private static class CaptionImpl extends FocusPanel implements Caption {

        @Override
        protected void onDetach() {
            super.onDetach();
        }

        @Override
        protected void onAttach() {
            super.onAttach();
        }
    }

    private class MouseHandler
            implements MouseDownHandler, MouseUpHandler, MouseOutHandler, MouseOverHandler, MouseMoveHandler {

        public void onMouseDown(MouseDownEvent event) {
            beginDragging(event);
        }

        public void onMouseMove(MouseMoveEvent event) {
            continueDragging(event);
        }

        public void onMouseOut(MouseOutEvent event) {
            DialogBox.this.onMouseLeave(caption);
        }

        public void onMouseOver(MouseOverEvent event) {
            DialogBox.this.onMouseEnter(caption);
        }

        public void onMouseUp(MouseUpEvent event) {
            endDragging(event);
        }
    }

    /**
     * The default style name.
     */
    private static final String DEFAULT_STYLENAME = "gwt-DialogBox";

    private CaptionImpl caption = new CaptionImpl();
    private HTML captionHtml = new HTML(); // The caption aka title
    private Span cross;

    private boolean dragging;
    private int dragStartX, dragStartY;
    private int windowWidth;
    private int clientLeft;
    private int clientTop;

    private Dialog dialog;

    private HandlerRegistration resizeHandlerRegistration;

    /**
     * Creates an empty dialog box. It should not be shown until its child
     * widget has been added using {@link #add(Widget)}.
     */
    public DialogBox() {
        this(false);
    }

    /**
     * Creates an empty dialog box specifying its "auto-hide" property. It
     * should not be shown until its child widget has been added using
     * {@link #add(Widget)}.
     * 
     * @param autoHide
     *            <code>true</code> if the dialog should be automatically hidden
     *            when the user clicks outside of it
     */
    public DialogBox(boolean autoHide) {
        this(autoHide, true);
    }

    /**
     * Creates an empty dialog box specifying its "auto-hide" property. It
     * should not be shown until its child widget has been added using
     * {@link #add(Widget)}.
     * 
     * @param autoHide
     *            <code>true</code> if the dialog should be automatically hidden
     *            when the user clicks outside of it
     * @param modal
     *            <code>true</code> if keyboard and mouse events for widgets not
     *            contained by the dialog should be ignored
     */
    public DialogBox(boolean autoHide, boolean modal) {
        super(autoHide, modal);

        // Add the caption to the top row of the decorator panel. We need to
        // logically adopt the caption so we can catch mouse events.
        Element td = getCellElement(0, 1);
        HorizontalPanel panel = new HorizontalPanel();
        /**
         * About the icon to close the window.
         */

        //   <div class="close-wrap"><span class="box-title-sep"></span><span class="box-close" onclick="this.parentNode.parentNode.parentNode.style.display='none'"></span></div>

        cross = new Span();
        cross.setStyleName("box-close");
        CrossHandler crossHandler = new CrossHandler();
        cross.addClickHandler(crossHandler);
        cross.addMouseDownHandler(crossHandler);
        cross.addMouseOverHandler(crossHandler);
        cross.addMouseOutHandler(crossHandler);

        //      Label left = new Label("");
        //      left.setStyleName("left");
        //      Label right = new Label("");
        //      right.setStyleName("right");

        //      panel.add(left);
        panel.add(captionHtml);
        panel.add(cross);
        //      panel.add(right);
        //      panel.setCellWidth(left, "10px");
        //      panel.setCellHorizontalAlignment(left, HorizontalPanel.ALIGN_LEFT);
        panel.setCellHorizontalAlignment(captionHtml, HorizontalPanel.ALIGN_LEFT);
        panel.setCellHorizontalAlignment(cross, HorizontalPanel.ALIGN_RIGHT);
        //      panel.setCellHorizontalAlignment(right, HorizontalPanel.ALIGN_RIGHT);
        panel.setWidth("100%");

        caption.add(panel);
        DOM.appendChild(td, caption.getElement());
        adopt(caption);
        caption.setStyleName("Caption");

        // Set the style name
        setStyleName(DEFAULT_STYLENAME);

        windowWidth = Window.getClientWidth();
        clientLeft = Document.get().getBodyOffsetLeft();
        clientTop = Document.get().getBodyOffsetTop();

        MouseHandler mouseHandler = new MouseHandler();
        addDomHandler(mouseHandler, MouseDownEvent.getType());
        addDomHandler(mouseHandler, MouseUpEvent.getType());
        addDomHandler(mouseHandler, MouseMoveEvent.getType());
        addDomHandler(mouseHandler, MouseOverEvent.getType());
        addDomHandler(mouseHandler, MouseOutEvent.getType());
    }

    /**
     * Provides access to the dialog's caption.
     * 
     * This method is final because the Caption interface will expand. Therefore
     * it is highly likely that subclasses which implemented this method would
     * end up breaking.
     * 
     * @return the logical caption for this dialog box
     */
    public final Caption getCaption() {
        return caption;
    }

    public String getHTML() {
        return captionHtml.getHTML();
    }

    public String getText() {
        return captionHtml.getText();
    }

    @Override
    public void hide() {
        if (resizeHandlerRegistration != null) {
            resizeHandlerRegistration.removeHandler();
            resizeHandlerRegistration = null;
        }
        super.hide();
    }

    @Override
    public void onBrowserEvent(Event event) {
        // If we're not yet dragging, only trigger mouse events if the event
        // occurs
        // in the caption wrapper
        switch (event.getTypeInt()) {
        case Event.ONMOUSEDOWN:
        case Event.ONMOUSEUP:
        case Event.ONMOUSEMOVE:
        case Event.ONMOUSEOVER:
        case Event.ONMOUSEOUT:
            if (!dragging && !isCaptionEvent(event)) {
                return;
            }
        }

        super.onBrowserEvent(event);
    }

    /**
     * @deprecated Use {@link #beginDragging} and {@link #getCaption} instead
     */
    @Deprecated
    public void onMouseDown(Widget sender, int x, int y) {
        dragging = true;
        DOM.setCapture(getElement());
        dragStartX = x;
        dragStartY = y;
    }

    /**
     * @deprecated Use {@link Caption#addMouseOverHandler} instead
     */
    @Deprecated
    public void onMouseEnter(Widget sender) {
    }

    /**
     * @deprecated Use {@link Caption#addMouseOutHandler} instead
     */
    @Deprecated
    public void onMouseLeave(Widget sender) {
    }

    /**
     * @deprecated Use {@link #continueDragging} and {@link #getCaption} instead
     */
    @Deprecated
    public void onMouseMove(Widget sender, int x, int y) {
        if (dragging) {
            int absX = x + getAbsoluteLeft();
            int absY = y + getAbsoluteTop();

            // if the mouse is off the screen to the left, right, or top, don't
            // move the dialog box. This would let users lose dialog boxes,
            // which
            // would be bad for modal popups.
            if (absX < clientLeft || absX >= windowWidth || absY < clientTop) {
                return;
            }

            setPopupPosition(absX - dragStartX, absY - dragStartY);
        }
    }

    /**
     * @deprecated Use {@link #endDragging} and {@link #getCaption} instead
     */
    @Deprecated
    public void onMouseUp(Widget sender, int x, int y) {
        dragging = false;
        DOM.releaseCapture(getElement());
    }

    /**
     * Sets the html string inside the caption.
     * 
     * Use {@link #setWidget(Widget)} to set the contents inside the
     * {@link DialogBox}.
     * 
     * @param html
     *            the object's new HTML
     */
    public void setHTML(String html) {
        captionHtml.setHTML(html);
    }

    /**
     * Sets the text inside the caption.
     * 
     * Use {@link #setWidget(Widget)} to set the contents inside the
     * {@link DialogBox}.
     * 
     * @param text
     *            the object's new text
     */
    public void setText(String text) {
        captionHtml.setText(text);
    }

    @Override
    public void show() {
        if (resizeHandlerRegistration == null) {
            resizeHandlerRegistration = Window.addResizeHandler(new ResizeHandler() {
                public void onResize(ResizeEvent event) {
                    windowWidth = event.getWidth();
                }
            });
        }
        super.show();
    }

    /**
     * Called on mouse down in the caption area, begins the dragging loop by
     * turning on event capture.
     * 
     * @see DOM#setCapture
     * @see #continueDragging
     * @param event
     *            the mouse down event that triggered dragging
     */
    protected void beginDragging(MouseDownEvent event) {
        onMouseDown(caption, event.getX(), event.getY());
    }

    /**
     * Called on mouse move in the caption area, continues dragging if it was
     * started by {@link #beginDragging}.
     * 
     * @see #beginDragging
     * @see #endDragging
     * @param event
     *            the mouse move event that continues dragging
     */
    protected void continueDragging(MouseMoveEvent event) {
        onMouseMove(caption, event.getX(), event.getY());
    }

    @Override
    protected void doAttachChildren() {
        try {
            super.doAttachChildren();
        } finally {
            // See comment in doDetachChildren for an explanation of this call
            caption.onAttach();
        }
    }

    @Override
    protected void doDetachChildren() {
        try {
            super.doDetachChildren();
        } finally {
            // We need to detach the caption specifically because it is not part
            // of the
            // iterator of Widgets that the {@link SimplePanel} super class
            // returns.
            // This is similar to a {@link ComplexPanel}, but we do not want to
            // expose
            // the caption widget, as its just an internal implementation.
            caption.onDetach();
        }
    }

    /**
     * Called on mouse up in the caption area, ends dragging by ending event
     * capture.
     * 
     * @param event
     *            the mouse up event that ended dragging
     * 
     * @see DOM#releaseCapture
     * @see #beginDragging
     * @see #endDragging
     */
    protected void endDragging(MouseUpEvent event) {
        onMouseUp(caption, event.getX(), event.getY());
    }

    /**
     * <b>Affected Elements:</b>
     * <ul>
     * <li>-caption = text at the top of the {@link DialogBox}.</li>
     * <li>-content = the container around the content.</li>
     * </ul>
     * 
     * @see UIObject#onEnsureDebugId(String)
     */
    @Override
    protected void onEnsureDebugId(String baseID) {
        super.onEnsureDebugId(baseID);
        caption.ensureDebugId(baseID + "-caption");
        ensureDebugId(getCellElement(1, 1), baseID, "content");
    }

    @Override
    protected void onPreviewNativeEvent(NativePreviewEvent event) {
        // We need to preventDefault() on mouseDown events (outside of the
        // DialogBox content) to keep text from being selected when it
        // is dragged.
        NativeEvent nativeEvent = event.getNativeEvent();

        if (!event.isCanceled() && (event.getTypeInt() == Event.ONMOUSEDOWN) && isCaptionEvent(nativeEvent)) {
            nativeEvent.preventDefault();
        }

        super.onPreviewNativeEvent(event);
    }

    private boolean isCaptionEvent(NativeEvent event) {
        EventTarget target = event.getEventTarget();
        if (Element.is(target)) {
            return getCellElement(0, 1).getParentElement().isOrHasChild(Element.as(target));
        }
        return false;
    }

    public void setDialog(Dialog dialog) {
        this.dialog = dialog;
    }

    private class CrossHandler implements ClickHandler, MouseOverHandler, MouseOutHandler, MouseDownHandler {

        @Override
        public void onClick(ClickEvent event) {
            if (dialog == null) {
                clear();
                hide();
            } else {
                Platform.getInstance().getSiteManager().closeDialog(dialog);
            }
        }

        @Override
        public void onMouseOver(MouseOverEvent event) {
            //   cross.setStyleName("closeover");

        }

        @Override
        public void onMouseOut(MouseOutEvent event) {
            //   cross.setStyleName("close");

        }

        @Override
        public void onMouseDown(MouseDownEvent event) {
            //   cross.setStyleName("closedown");
        }
    }
}