Package net.mygwt.ui.client.widget

Source Code of net.mygwt.ui.client.widget.Popup

/*
* Copyright 2007 Google 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.
*
* Contributers:
*      Darell Meyer <darrell@mygwt.net> - Derived implementation
  */
package net.mygwt.ui.client.widget;

import net.mygwt.ui.client.Events;
import net.mygwt.ui.client.MyDOM;
import net.mygwt.ui.client.event.BaseEvent;
import net.mygwt.ui.client.event.Listener;
import net.mygwt.ui.client.fx.FXStyle;
import net.mygwt.ui.client.util.Point;
import net.mygwt.ui.client.util.Rectangle;

import com.google.gwt.core.client.GWT;
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.EventPreview;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.WidgetHelper;
import com.google.gwt.user.client.ui.impl.PopupImpl;

/**
* A shadow panel that can "pop up" over other widgets. It overlays the
* browser's client area (and any previously-created popups).
*
* <dl>
* <dt><b>Events:</b></dt>
*
* <dd><b>BeforeShow</b> : (widget)<br>
* <div>Fires before the popup is displayed. Listeners can set the
* <code>doit</code> field to <code>false</code> to cancel the action.</div>
* <ul>
* <li>widget : this</li>
* </ul>
* </dd>
*
* <dd><b>Show</b> : (widget)<br>
* <div>Fires after a shell is shown.</div>
* <ul>
* <li>widget : this</li>
* </ul>
* </dd>
*
* <dd><b>BeforeHide</b> : (widget)<br>
* <div>Fires before the popup is hidden. Listeners can set the
* <code>doit</code> field to <code>false</code> to cancel the action.</div>
* <ul>
* <li>widget : this</li>
* </ul>
* </dd>
*
* <dd><b>Hide</b> : (widget)<br>
* <div>Fires after a shell is hidden.</div>
* <ul>
* <li>widget : this</li>
* </ul>
* </dd>
*
* <dt><b>CSS:</b></dt>
* <dd>.my-popup (the popup itself)</dd>
* </dl>
*/
public class Popup extends Component implements EventPreview {

  private static PopupImpl impl = (PopupImpl) GWT.create(PopupImpl.class);

  /**
   * animate specifies if the hiding and showing of the panel should be
   * animated. Default value is <code>true</code>.
   */
  public boolean animate = true;

  /**
   * eventPreview specifies if event preview should be activated when the popup
   * is displayed. Default value is <code>true</code>
   */
  public boolean eventPreview = true;

  /**
   * autoFocus specifies if focus should be set on the popup when displayed.
   * Default value is <code>true</code>
   */
  public boolean autoFocus = true;

  /**
   * Specifies the vertical offset. Only applies when constrainViewerport is
   * <code>true</code>. Default value is 15.
   */
  public int topOffset = 15;

  /**
   * leftOffset specifies the horizontal offset. Only applies when
   * constrainViewerport is <code>true</code>. Default value is 10.
   */
  public int leftOffset = 10;

  /**
   * constrainViewport specifies if the popup location should be forced to the
   * viewport area. Default value is <code>true</code>
   */
  public boolean constrainViewport = true;

  /**
   * duration specifies the length of the fade effect in milliseconds. Default
   * value is 200.
   */
  public int duration = 200;

  private boolean showing, autoHide;
  private Widget widget;

  /**
   * Creates a new popup panel.
   */
  public Popup() {

  }

  /**
   * Creates an new popup panel.
   *
   * @param autoHide <code>true</code> to hide if "click" occurs outside of
   *            the popup
   */
  public Popup(boolean autoHide) {
    this();
    this.autoHide = autoHide;
  }

  /**
   * Centers the panel within the viewport.
   */
  public void center() {
    MyDOM.center(getElement());
  }

  /**
   * Hides the popup. This has no effect if it is not currently visible.
   */
  public void hide() {
    if (!showing) return;
    showing = false;
    if (eventPreview) {
      DOM.removeEventPreview(this);
    }

    if (animate) {
      FXStyle fx = new FXStyle(getElement());
      fx.duration = duration;
      fx.addListener(Events.EffectComplete, new Listener() {
        public void handleEvent(BaseEvent be) {
          afterHide();
        }
      });
      fx.fadeOut();
    } else {
      afterHide();
    }
  }

  public boolean isVisible() {
    return showing;
  }

  public boolean onEventPreview(Event event) {
    int type = DOM.eventGetType(event);
    Element target = DOM.eventGetTarget(event);
    switch (type) {
      case Event.ONMOUSEDOWN:
      case Event.ONMOUSEUP:
      case Event.ONMOUSEMOVE:
      case Event.ONCLICK:
      case Event.ONDBLCLICK: {
        // Don't eat events if event capture is enabled, as this can interfere
        // with dialog dragging, for example.
        if (DOM.getCaptureElement() == null) {
          // Disallow mouse events outside of the popup.
          if (!DOM.isOrHasChild(getElement(), target)) {
            // If it's a click event, and auto-hide is enabled: hide the popup
            // and _don't_ eat the event.
            if (autoHide && (type == Event.ONCLICK)) {
              if (onAutoHide(event)) {
                hide();
                return true;
              }
              return false;
            }
            return false;
          }
        }
        break;
      }
      case Event.ONKEYUP:
        int code = DOM.eventGetKeyCode(event);
        switch (code) {
          case KeyboardListener.KEY_ESCAPE:
            hide();
        }
        break;
    }
    return true;
  }

  /**
   * Sets the popup's content.
   *
   * @param widget the content widget
   */
  public void setWidget(Widget widget) {
    this.widget = widget;
  }

  /**
   * Displays the popup. It must have a child widget before this method is
   * called.
   */
  public void show() {
    if (showing) {
      return;
    }
    showing = true;

    DOM.appendChild(getElement(), widget.getElement());

    if (constrainViewport) {
      int clientHeight = Window.getClientHeight() + MyDOM.getBodyScrollTop();
      int clientWidth = Window.getClientWidth() + MyDOM.getBodyScrollLeft();

      Rectangle r = MyDOM.getBounds(getElement());

      int x = r.x;
      int y = r.y;

      if (y + r.height > clientHeight) {
        y = y - topOffset - r.height;
        MyDOM.setTop(getElement(), y);
      }
      if (x + r.width > clientWidth) {
        x = x - leftOffset - r.width;
        MyDOM.setLeft(getElement(), x);
      }
    }

    MyDOM.setVisibility(getElement(), false);
    setStyleAttribute("position", "absolute");

    RootPanel.get().add(this);
    impl.onShow(getElement());

    WidgetHelper.doAttach(widget);

    MyDOM.setVisibility(getElement(), true);

    if (eventPreview) {
      DOM.addEventPreview(this);
    }

    if (animate) {
      FXStyle fx = new FXStyle(getElement());
      fx.duration = duration;
      fx.addListener(Events.EffectComplete, new Listener() {
        public void handleEvent(BaseEvent be) {
          afterShow();
        }
      });
      fx.fadeIn();
    } else {
      afterShow();
    }

  }

  /**
   * Shows the popup at the specified location.
   *
   * @param x the x coordinate
   * @param y the y coordinate
   */
  public void show(int x, int y) {
    DOM.appendChild(getElement(), widget.getElement());
    MyDOM.setLeftTop(getElement(), x, y);
    show();
  }

  /**
   * @param elem
   * @param pos
   */
  public void show(Element elem, String pos) {
    DOM.appendChild(getElement(), widget.getElement());
    Point p = MyDOM.getAlignToXY(getElement(), elem, pos, null);
    MyDOM.setLeftTop(getElement(), p.x, p.y);
    show();
  }

  public void show(Element elem, String pos, int[] offsets) {
    DOM.appendChild(getElement(), widget.getElement());
    Point p = MyDOM.getAlignToXY(getElement(), elem, pos, offsets);
    MyDOM.setLeftTop(getElement(), p.x, p.y);
    show();
  }

  /**
   * Displays the popup aligned to the bottom left of the widget. For exact
   * control of popup position see {@link MyDOM#alignTo}.
   *
   * @param widget the widget to use for alignment
   */
  public void show(Widget widget) {
    int[] offset = new int[] {0, 2};
    Point p = MyDOM.getAlignToXY(getElement(), widget.getElement(), null, offset);
    MyDOM.setLeftTop(getElement(), p.x, p.y);
    show();
  }

  protected void afterHide() {
    impl.onHide(getElement());
    RootPanel.get().remove(this);
    showing = false;

    WidgetHelper.doDetach(widget);

    fireEvent(Events.Hide);
  }

  protected void afterShow() {
    if (autoFocus) {
      MyDOM.setFocus(getElement(), true);
    }
    fireEvent(Events.Show);
  }

  protected boolean onAutoHide(Event event) {
    return true;
  }

  protected void onRender() {
    setElement(DOM.createDiv());
    setStyleName("my-popup");
    setStyleAttribute("position", "absolute");
    setStyleAttribute("zIndex", "100");
  }

}
TOP

Related Classes of net.mygwt.ui.client.widget.Popup

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.