com.extjs.gxt.ui.client.widget.Popup Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gxt Show documentation
Show all versions of gxt Show documentation
Rich Internet Application Framework for GWT
/*
* Sencha GXT 2.3.1 - Sencha for GWT
* Copyright(c) 2007-2013, Sencha, Inc.
* [email protected]
*
* http://www.sencha.com/products/gxt/license/
*/
package com.extjs.gxt.ui.client.widget;
import com.extjs.gxt.ui.client.core.CompositeElement;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.core.XDOM;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.FxEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.PreviewEvent;
import com.extjs.gxt.ui.client.fx.FxConfig;
import com.extjs.gxt.ui.client.util.BaseEventPreview;
import com.extjs.gxt.ui.client.util.Point;
import com.extjs.gxt.ui.client.util.Rectangle;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
/**
* A panel that can be displayed over other widgets.
*
*
* - Events:
*
* - BeforeShow : ComponentEvent(component)
* Fires before the popup is displayed. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.
*
* - component : this
*
*
*
* - Show : ComponentEvent(component)
* Fires after a popup is displayed.
*
* - component : this
*
*
*
* - BeforeHide : ComponentEvent(component)
* Fires before the popup is hidden. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.
*
* - component : this
*
*
*
* - Hide : ComponentEvent(component)
* Fires after a popup is hidden.
*
* - component : this
*
*
*
*
*
* - Inherited Events:
* - LayoutContainer AfterLayout
* - ScrollContainer Scroll
* - Container BeforeAdd
* - Container Add
* - Container BeforeRemove
* - Container Remove
* - BoxComponent Move
* - BoxComponent Resize
* - Component Enable
* - Component Disable
* - Component BeforeHide
* - Component Hide
* - Component BeforeShow
* - Component Show
* - Component Attach
* - Component Detach
* - Component BeforeRender
* - Component Render
* - Component BrowserEvent
* - Component BeforeStateRestore
* - Component StateRestore
* - Component BeforeStateSave
* - Component SaveState
*
*
*
* - CSS:
* - .x-popup (the popup itself)
*
*/
public class Popup extends LayoutContainer {
protected BaseEventPreview preview = new BaseEventPreview() {
@Override
protected boolean onAutoHide(PreviewEvent ce) {
if (Popup.this.onAutoHide(ce.getEvent())) {
hide();
return true;
}
return false;
}
};
private Element alignElem;
private int[] alignOffsets;
private Point alignPoint;
private String alignPos;
private boolean animate;
private boolean autoFocus = true;
private boolean autoHide = true;
private boolean constrainViewport = true;
private String defaultAlign = "tl-bl?";
private int xOffset = 10;
private int yOffset = 15;
/**
* Creates a new popup panel.
*/
public Popup() {
baseStyle = "x-popup";
shim = true;
enableLayout = true;
}
/**
* Centers the panel within the viewport.
*/
public void center() {
if (rendered) {
el().center();
}
}
/**
* Returns the default alignment.
*
* @return the default align
*/
public String getDefaultAlign() {
return defaultAlign;
}
/**
* Any elements added to this list will be ignored when auto close is enabled.
*
* @return the list of ignored elements
*/
public CompositeElement getIgnoreList() {
return preview.getIgnoreList();
}
/**
* Returns the x offset.
*
* @return the offset
*/
public int getXOffset() {
return xOffset;
}
/**
* Returns the y offsets.
*
* @return the offset
*/
public int getYOffset() {
return yOffset;
}
/**
* Hides the popup.
*/
public void hide() {
if (!fireEvent(Events.BeforeHide, new ComponentEvent(this))) {
return;
}
if (autoHide) {
preview.remove();
}
if (isAnimate()) {
el().fadeOut(new FxConfig(new Listener() {
public void handleEvent(FxEvent fe) {
afterHide();
}
}));
} else {
afterHide();
}
}
/**
* Returns true if animations are enabled.
*
* @return the animation state
*/
public boolean isAnimate() {
return animate;
}
/**
* Returns true if auto focus is enabled.
*
* @return the auto focus state
*/
public boolean isAutoFocus() {
return autoFocus;
}
/**
* Returns true if auto hide is enabled.
*
* @return the auto hide state
*/
public boolean isAutoHide() {
return autoHide;
}
/**
* Returns true if contrain to viewport is enabled.
*
* @return the constrain viewport state
*/
public boolean isConstrainViewport() {
return constrainViewport;
}
/**
* True to enable animations when showing and hiding (defaults to false).
*
* @param animate true to enable animations
*/
public void setAnimate(boolean animate) {
this.animate = animate;
}
/**
* True to move focus to the popup when being opened (defaults to true).
*
* @param autoFocus true for auto focus
*/
public void setAutoFocus(boolean autoFocus) {
this.autoFocus = autoFocus;
}
/**
* True to close the popup when the user clicks outside of the menu (default
* to true).
*
* @param autoHide true for auto hide
*/
public void setAutoHide(boolean autoHide) {
this.autoHide = autoHide;
}
/**
* True to ensure popup is dislayed within the browser's viewport.
*
* @param constrainViewport true to constrain
*/
public void setConstrainViewport(boolean constrainViewport) {
this.constrainViewport = constrainViewport;
}
/**
* The default {@link El#alignTo} anchor position value for this menu relative
* to its element of origin (defaults to "tl-bl?").
*
* @param defaultAlign the default alignment
*/
public void setDefaultAlign(String defaultAlign) {
this.defaultAlign = defaultAlign;
}
/**
* Sets the xOffset when constrainViewport == true (defaults to 10).
*
* @param xOffset the x offset
*/
public void setXOffset(int xOffset) {
this.xOffset = xOffset;
}
/**
* Sets the yOffset when constrainViewport == true (defaults to 15).
*
* @param yOffset the offset
*/
public void setYOffset(int yOffset) {
this.yOffset = yOffset;
}
/**
* Displays the popup.
*/
public void show() {
Point p = new Point((int) Window.getClientWidth() / 2, (int) Window.getClientHeight() / 2);
showAt(p.x, p.y);
}
/**
* Displays the popup aligned to the bottom left of the widget. For exact
* control of popup position see {@link #show(Element, String, int[])}.
*
* @param widget the widget to use for alignment
*/
public void show(Component widget) {
if (!fireEvent(Events.BeforeShow, new ComponentEvent(this))) {
return;
}
alignElem = widget.getElement();
onShowPopup();
}
/**
* Displays the popup.
*
* @param elem the element to align to
* @param pos the position
*/
public void show(Element elem, String pos) {
if (!fireEvent(Events.BeforeShow, new ComponentEvent(this))) return;
alignElem = elem;
alignPos = pos;
onShowPopup();
}
/**
* Displays the popup.
*
* @param elem the element to align to
* @param pos the postion
* @param offsets the offsets
*/
public void show(Element elem, String pos, int[] offsets) {
if (!fireEvent(Events.BeforeShow, new ComponentEvent(this))) {
return;
}
alignElem = elem;
alignPos = pos;
alignOffsets = offsets;
onShowPopup();
}
/**
* Shows the popup at the specified location.
*
* @param x the x coordinate
* @param y the y coordinate
*/
public void showAt(int x, int y) {
if (!fireEvent(Events.BeforeShow, new ComponentEvent(this))) {
return;
}
alignPoint = new Point(x, y);
onShowPopup();
}
protected void afterHide() {
RootPanel.get().remove(this);
hidden = true;
hideShadow();
fireEvent(Events.Hide, new ComponentEvent(this));
}
protected void afterShow() {
if (layer != null) {
layer.sync(true);
}
if (isAutoFocus()) {
focus();
}
setZIndex(XDOM.getTopZIndex());
fireEvent(Events.Open, new ComponentEvent(this));
}
protected void handleKeyUp(ComponentEvent ce) {
int code = ce.getKeyCode();
ce.setComponent(this);
onKeyPress(ce);
switch (code) {
case KeyCodes.KEY_ESCAPE:
onAutoHide(ce.getEvent());
}
}
/**
* Subclasses may override to cancel the hide from an auto hide.
*
* @param event the current event
* @return true to close, false to cancel
*/
protected boolean onAutoHide(Event event) {
return true;
}
@Override
protected void onDetach() {
super.onDetach();
if (preview != null) {
preview.remove();
}
}
protected void onKeyPress(BaseEvent be) {
}
@Override
protected void onRender(Element target, int index) {
super.onRender(target, index);
el().makePositionable(true);
preview.getIgnoreList().add(getElement());
}
protected Popup onShowPopup() {
RootPanel.get().add(this);
hidden = false;
Point p = null;
if (alignElem != null) {
alignPos = alignPos != null ? alignPos : getDefaultAlign();
alignOffsets = alignOffsets != null ? alignOffsets : new int[] {0, 2};
p = el().getAlignToXY(alignElem, alignPos, alignOffsets);
} else if (alignPoint != null) {
p = alignPoint;
}
el().makePositionable(true).setVisibility(false);
el().setLeftTop(p.x, p.y);
alignElem = null;
alignPos = null;
alignOffsets = null;
alignPoint = null;
if (constrainViewport) {
int clientHeight = Window.getClientHeight() + XDOM.getBodyScrollTop();
int clientWidth = Window.getClientWidth() + XDOM.getBodyScrollLeft();
Rectangle r = el().getBounds();
int x = r.x;
int y = r.y;
if (y + r.height > clientHeight) {
y = clientHeight - r.height - getYOffset();
el().setTop(y);
}
if (x + r.width > clientWidth) {
x = clientWidth - r.width - getXOffset();
el().setLeft(x);
}
}
el().setVisibility(true);
if (autoHide) {
preview.add();
}
if (animate) {
el().fadeIn(new FxConfig(new Listener() {
public void handleEvent(FxEvent fe) {
afterShow();
}
}));
} else {
afterShow();
}
return this;
}
}