svn changeset:2831/svn branch:trunktags/6.7.0.beta1
@@ -6,61 +6,60 @@ import com.google.gwt.user.client.DOM; | |||
import com.google.gwt.user.client.Element; | |||
import com.google.gwt.user.client.ui.FlowPanel; | |||
import com.google.gwt.user.client.ui.HTML; | |||
import com.google.gwt.user.client.ui.PopupPanel; | |||
import com.itmill.toolkit.terminal.gwt.client.ui.ToolkitOverlay; | |||
public class ErrorMessage extends FlowPanel { | |||
public static final String CLASSNAME = "i-error"; | |||
public static final String CLASSNAME = "i-error"; | |||
public ErrorMessage() { | |||
super(); | |||
setStyleName(CLASSNAME); | |||
} | |||
public ErrorMessage() { | |||
super(); | |||
setStyleName(CLASSNAME); | |||
} | |||
public void updateFromUIDL(UIDL uidl) { | |||
clear(); | |||
for (Iterator it = uidl.getChildIterator(); it.hasNext();) { | |||
Object child = it.next(); | |||
if (child instanceof String) { | |||
String errorMessage = (String) child; | |||
add(new HTML(errorMessage)); | |||
} else if (child instanceof UIDL.XML) { | |||
UIDL.XML xml = (UIDL.XML) child; | |||
add(new HTML(xml.getXMLAsString())); | |||
} else { | |||
ErrorMessage childError = new ErrorMessage(); | |||
add(childError); | |||
childError.updateFromUIDL((UIDL) child); | |||
} | |||
} | |||
} | |||
/** | |||
* Shows this error message next to given element. | |||
* | |||
* @param indicatorElement | |||
*/ | |||
public void showAt(Element indicatorElement) { | |||
PopupPanel errorContainer = (PopupPanel) this.getParent(); | |||
if (errorContainer == null) { | |||
errorContainer = new PopupPanel(); | |||
errorContainer.setWidget(this); | |||
} | |||
errorContainer.setPopupPosition(DOM | |||
.getAbsoluteLeft(indicatorElement) | |||
+ 2 | |||
* DOM.getElementPropertyInt(indicatorElement, | |||
"offsetHeight"), DOM | |||
.getAbsoluteTop(indicatorElement) | |||
+ 2 | |||
* DOM.getElementPropertyInt(indicatorElement, | |||
"offsetHeight")); | |||
errorContainer.show(); | |||
} | |||
public void updateFromUIDL(UIDL uidl) { | |||
clear(); | |||
for (Iterator it = uidl.getChildIterator(); it.hasNext();) { | |||
Object child = it.next(); | |||
if (child instanceof String) { | |||
String errorMessage = (String) child; | |||
add(new HTML(errorMessage)); | |||
} else if (child instanceof UIDL.XML) { | |||
UIDL.XML xml = (UIDL.XML) child; | |||
add(new HTML(xml.getXMLAsString())); | |||
} else { | |||
ErrorMessage childError = new ErrorMessage(); | |||
add(childError); | |||
childError.updateFromUIDL((UIDL) child); | |||
} | |||
} | |||
} | |||
public void hide() { | |||
PopupPanel errorContainer = (PopupPanel) this.getParent(); | |||
if(errorContainer != null) | |||
errorContainer.hide(); | |||
} | |||
/** | |||
* Shows this error message next to given element. | |||
* | |||
* @param indicatorElement | |||
*/ | |||
public void showAt(Element indicatorElement) { | |||
ToolkitOverlay errorContainer = (ToolkitOverlay) getParent(); | |||
if (errorContainer == null) { | |||
errorContainer = new ToolkitOverlay(); | |||
errorContainer.setWidget(this); | |||
} | |||
errorContainer.setPopupPosition(DOM.getAbsoluteLeft(indicatorElement) | |||
+ 2 | |||
* DOM.getElementPropertyInt(indicatorElement, "offsetHeight"), | |||
DOM.getAbsoluteTop(indicatorElement) | |||
+ 2 | |||
* DOM.getElementPropertyInt(indicatorElement, | |||
"offsetHeight")); | |||
errorContainer.show(); | |||
} | |||
public void hide() { | |||
ToolkitOverlay errorContainer = (ToolkitOverlay) getParent(); | |||
if (errorContainer != null) { | |||
errorContainer.hide(); | |||
} | |||
} | |||
} |
@@ -5,93 +5,95 @@ import com.google.gwt.user.client.ui.MenuBar; | |||
import com.google.gwt.user.client.ui.MenuItem; | |||
import com.google.gwt.user.client.ui.PopupPanel; | |||
public class ContextMenu extends PopupPanel { | |||
public class ContextMenu extends ToolkitOverlay { | |||
private ActionOwner actionOwner; | |||
private ActionOwner actionOwner; | |||
private CMenuBar menu = new CMenuBar(); | |||
private CMenuBar menu = new CMenuBar(); | |||
private int left; | |||
private int left; | |||
private int top; | |||
private int top; | |||
/** | |||
* This method should be used only by Client object as only one per client | |||
* should exists. Request an instance via client.getContextMenu(); | |||
* | |||
* @param cli | |||
* to be set as an owner of menu | |||
*/ | |||
public ContextMenu() { | |||
super(true); | |||
setWidget(menu); | |||
setStyleName("i-contextmenu"); | |||
} | |||
/** | |||
* This method should be used only by Client object as only one per client | |||
* should exists. Request an instance via client.getContextMenu(); | |||
* | |||
* @param cli | |||
* to be set as an owner of menu | |||
*/ | |||
public ContextMenu() { | |||
super(true); | |||
setWidget(menu); | |||
setStyleName("i-contextmenu"); | |||
} | |||
/** | |||
* Sets the element from which to build menu | |||
* | |||
* @param ao | |||
*/ | |||
public void setActionOwner(ActionOwner ao) { | |||
this.actionOwner = ao; | |||
} | |||
/** | |||
* Sets the element from which to build menu | |||
* | |||
* @param ao | |||
*/ | |||
public void setActionOwner(ActionOwner ao) { | |||
actionOwner = ao; | |||
} | |||
/** | |||
* Shows context menu at given location. | |||
* | |||
* @param left | |||
* @param top | |||
*/ | |||
public void showAt(int left, int top) { | |||
this.left = left; | |||
this.top = top; | |||
menu.clearItems(); | |||
Action[] actions = actionOwner.getActions(); | |||
for (int i = 0; i < actions.length; i++) { | |||
Action a = actions[i]; | |||
menu.addItem(new MenuItem(a.getHTML(), true, a)); | |||
} | |||
/** | |||
* Shows context menu at given location. | |||
* | |||
* @param left | |||
* @param top | |||
*/ | |||
public void showAt(int left, int top) { | |||
this.left = left; | |||
this.top = top; | |||
menu.clearItems(); | |||
Action[] actions = actionOwner.getActions(); | |||
for (int i = 0; i < actions.length; i++) { | |||
Action a = actions[i]; | |||
menu.addItem(new MenuItem(a.getHTML(), true, a)); | |||
} | |||
this.setPopupPositionAndShow(new PositionCallback() { | |||
public void setPosition(int offsetWidth, int offsetHeight) { | |||
// mac FF gets bad width due GWT popups overflow hacks, | |||
// re-determine width | |||
offsetWidth = menu.getOffsetWidth(); | |||
int left = ContextMenu.this.left; | |||
int top = ContextMenu.this.top; | |||
if (offsetWidth + left > Window.getClientWidth()) { | |||
left = left - offsetWidth; | |||
if (left < 0) | |||
left = 0; | |||
} | |||
if (offsetHeight + top > Window.getClientHeight()) { | |||
top = top - offsetHeight; | |||
if (top < 0) | |||
top = 0; | |||
} | |||
setPopupPosition(left, top); | |||
} | |||
}); | |||
} | |||
setPopupPositionAndShow(new PositionCallback() { | |||
public void setPosition(int offsetWidth, int offsetHeight) { | |||
// mac FF gets bad width due GWT popups overflow hacks, | |||
// re-determine width | |||
offsetWidth = menu.getOffsetWidth(); | |||
int left = ContextMenu.this.left; | |||
int top = ContextMenu.this.top; | |||
if (offsetWidth + left > Window.getClientWidth()) { | |||
left = left - offsetWidth; | |||
if (left < 0) { | |||
left = 0; | |||
} | |||
} | |||
if (offsetHeight + top > Window.getClientHeight()) { | |||
top = top - offsetHeight; | |||
if (top < 0) { | |||
top = 0; | |||
} | |||
} | |||
setPopupPosition(left, top); | |||
} | |||
}); | |||
} | |||
public void showAt(ActionOwner ao, int left, int top) { | |||
setActionOwner(ao); | |||
showAt(left, top); | |||
} | |||
public void showAt(ActionOwner ao, int left, int top) { | |||
setActionOwner(ao); | |||
showAt(left, top); | |||
} | |||
/** | |||
* Extend standard Gwt MenuBar to set proper settings and to override | |||
* onPopupClosed method so that PopupPanel gets closed. | |||
*/ | |||
class CMenuBar extends MenuBar { | |||
public CMenuBar() { | |||
super(true); | |||
} | |||
/** | |||
* Extend standard Gwt MenuBar to set proper settings and to override | |||
* onPopupClosed method so that PopupPanel gets closed. | |||
*/ | |||
class CMenuBar extends MenuBar { | |||
public CMenuBar() { | |||
super(true); | |||
} | |||
public void onPopupClosed(PopupPanel sender, boolean autoClosed) { | |||
super.onPopupClosed(sender, autoClosed); | |||
ContextMenu.this.hide(); | |||
} | |||
} | |||
public void onPopupClosed(PopupPanel sender, boolean autoClosed) { | |||
super.onPopupClosed(sender, autoClosed); | |||
ContextMenu.this.hide(); | |||
} | |||
} | |||
} |
@@ -3,10 +3,9 @@ package com.itmill.toolkit.terminal.gwt.client.ui; | |||
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.ui.Button; | |||
import com.google.gwt.user.client.ui.ClickListener; | |||
import com.google.gwt.user.client.ui.PopupPanel; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.google.gwt.user.client.ui.Button; | |||
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; | |||
import com.itmill.toolkit.terminal.gwt.client.ErrorMessage; | |||
import com.itmill.toolkit.terminal.gwt.client.Paintable; | |||
@@ -14,116 +13,119 @@ import com.itmill.toolkit.terminal.gwt.client.UIDL; | |||
public class IButton extends Button implements Paintable { | |||
public static final String CLASSNAME = "i-button"; | |||
String id; | |||
ApplicationConnection client; | |||
private Element errorIndicatorElement; | |||
private ErrorMessage errorMessage; | |||
private PopupPanel errorContainer; | |||
public IButton() { | |||
setStyleName(CLASSNAME); | |||
addClickListener(new ClickListener() { | |||
public void onClick(Widget sender) { | |||
if (id == null || client == null) | |||
return; | |||
/* | |||
* TODO isolata workaround. Safari don't always seem to fire | |||
* onblur previously focused component before button is clicked. | |||
*/ | |||
IButton.this.setFocus(true); | |||
client.updateVariable(id, "state", true, true); | |||
} | |||
}); | |||
} | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
// Ensure correct implementation, | |||
// but don't let container manage caption etc. | |||
if (client.updateComponent(this, uidl, false)) | |||
return; | |||
// Save details | |||
this.client = client; | |||
id = uidl.getId(); | |||
// Set text | |||
setText(uidl.getStringAttribute("caption")); | |||
if (uidl.hasAttribute("error")) { | |||
UIDL errorUidl = uidl.getErrors(); | |||
if (errorIndicatorElement == null) { | |||
errorIndicatorElement = DOM.createDiv(); | |||
DOM.setElementProperty(errorIndicatorElement, "className", | |||
"i-errorindicator"); | |||
DOM.sinkEvents(errorIndicatorElement, Event.MOUSEEVENTS); | |||
} | |||
DOM.insertChild(getElement(), errorIndicatorElement, 0); | |||
if (errorMessage == null) | |||
errorMessage = new ErrorMessage(); | |||
errorMessage.updateFromUIDL(errorUidl); | |||
} else if (errorIndicatorElement != null) { | |||
DOM.setStyleAttribute(errorIndicatorElement, "display", "none"); | |||
} | |||
if (uidl.hasAttribute("description")) { | |||
setTitle(uidl.getStringAttribute("description")); | |||
} | |||
} | |||
public void onBrowserEvent(Event event) { | |||
Element target = DOM.eventGetTarget(event); | |||
if (errorIndicatorElement != null | |||
&& DOM.compare(target, errorIndicatorElement)) { | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONMOUSEOVER: | |||
showErrorMessage(); | |||
break; | |||
case Event.ONMOUSEOUT: | |||
hideErrorMessage(); | |||
break; | |||
case Event.ONCLICK: | |||
ApplicationConnection.getConsole().log( | |||
DOM.getInnerHTML(errorMessage.getElement())); | |||
return; | |||
default: | |||
break; | |||
} | |||
} | |||
super.onBrowserEvent(event); | |||
} | |||
private void hideErrorMessage() { | |||
if (errorContainer != null) { | |||
errorContainer.hide(); | |||
} | |||
} | |||
private void showErrorMessage() { | |||
if (errorMessage != null) { | |||
if (errorContainer == null) { | |||
errorContainer = new PopupPanel(); | |||
errorContainer.setWidget(errorMessage); | |||
} | |||
errorContainer.setPopupPosition(DOM | |||
.getAbsoluteLeft(errorIndicatorElement) | |||
+ 2 | |||
* DOM.getElementPropertyInt(errorIndicatorElement, | |||
"offsetHeight"), DOM | |||
.getAbsoluteTop(errorIndicatorElement) | |||
+ 2 | |||
* DOM.getElementPropertyInt(errorIndicatorElement, | |||
"offsetHeight")); | |||
errorContainer.show(); | |||
} | |||
} | |||
public static final String CLASSNAME = "i-button"; | |||
String id; | |||
ApplicationConnection client; | |||
private Element errorIndicatorElement; | |||
private ErrorMessage errorMessage; | |||
private ToolkitOverlay errorContainer; | |||
public IButton() { | |||
setStyleName(CLASSNAME); | |||
addClickListener(new ClickListener() { | |||
public void onClick(Widget sender) { | |||
if (id == null || client == null) { | |||
return; | |||
} | |||
/* | |||
* TODO isolata workaround. Safari don't always seem to fire | |||
* onblur previously focused component before button is clicked. | |||
*/ | |||
IButton.this.setFocus(true); | |||
client.updateVariable(id, "state", true, true); | |||
} | |||
}); | |||
} | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
// Ensure correct implementation, | |||
// but don't let container manage caption etc. | |||
if (client.updateComponent(this, uidl, false)) { | |||
return; | |||
} | |||
// Save details | |||
this.client = client; | |||
id = uidl.getId(); | |||
// Set text | |||
setText(uidl.getStringAttribute("caption")); | |||
if (uidl.hasAttribute("error")) { | |||
UIDL errorUidl = uidl.getErrors(); | |||
if (errorIndicatorElement == null) { | |||
errorIndicatorElement = DOM.createDiv(); | |||
DOM.setElementProperty(errorIndicatorElement, "className", | |||
"i-errorindicator"); | |||
DOM.sinkEvents(errorIndicatorElement, Event.MOUSEEVENTS); | |||
} | |||
DOM.insertChild(getElement(), errorIndicatorElement, 0); | |||
if (errorMessage == null) { | |||
errorMessage = new ErrorMessage(); | |||
} | |||
errorMessage.updateFromUIDL(errorUidl); | |||
} else if (errorIndicatorElement != null) { | |||
DOM.setStyleAttribute(errorIndicatorElement, "display", "none"); | |||
} | |||
if (uidl.hasAttribute("description")) { | |||
setTitle(uidl.getStringAttribute("description")); | |||
} | |||
} | |||
public void onBrowserEvent(Event event) { | |||
Element target = DOM.eventGetTarget(event); | |||
if (errorIndicatorElement != null | |||
&& DOM.compare(target, errorIndicatorElement)) { | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONMOUSEOVER: | |||
showErrorMessage(); | |||
break; | |||
case Event.ONMOUSEOUT: | |||
hideErrorMessage(); | |||
break; | |||
case Event.ONCLICK: | |||
ApplicationConnection.getConsole().log( | |||
DOM.getInnerHTML(errorMessage.getElement())); | |||
return; | |||
default: | |||
break; | |||
} | |||
} | |||
super.onBrowserEvent(event); | |||
} | |||
private void hideErrorMessage() { | |||
if (errorContainer != null) { | |||
errorContainer.hide(); | |||
} | |||
} | |||
private void showErrorMessage() { | |||
if (errorMessage != null) { | |||
if (errorContainer == null) { | |||
errorContainer = new ToolkitOverlay(); | |||
errorContainer.setWidget(errorMessage); | |||
} | |||
errorContainer.setPopupPosition(DOM | |||
.getAbsoluteLeft(errorIndicatorElement) | |||
+ 2 | |||
* DOM.getElementPropertyInt(errorIndicatorElement, | |||
"offsetHeight"), DOM | |||
.getAbsoluteTop(errorIndicatorElement) | |||
+ 2 | |||
* DOM.getElementPropertyInt(errorIndicatorElement, | |||
"offsetHeight")); | |||
errorContainer.show(); | |||
} | |||
} | |||
} |
@@ -81,7 +81,7 @@ public class IFilterSelect extends Composite implements Paintable, | |||
* @author mattitahvonen | |||
* | |||
*/ | |||
public class SuggestionPopup extends PopupPanel implements | |||
public class SuggestionPopup extends ToolkitOverlay implements | |||
PositionCallback, PopupListener { | |||
private static final int EXTRASPACE = 8; | |||
@@ -654,25 +654,25 @@ public class IFilterSelect extends Composite implements Paintable, | |||
* Calculate minumum width for FilterSelect textarea | |||
*/ | |||
private native int minWidth(String captions) /*-{ | |||
if(!captions || captions.length <= 0) | |||
return 0; | |||
captions = captions.split("|"); | |||
var d = $wnd.document.createElement("div"); | |||
var html = ""; | |||
for(var i=0; i < captions.length; i++) { | |||
html += "<div>" + captions[i] + "</div>"; | |||
// TODO apply same CSS classname as in suggestionmenu | |||
} | |||
d.style.position = "absolute"; | |||
d.style.top = "0"; | |||
d.style.left = "0"; | |||
d.style.visibility = "hidden"; | |||
d.innerHTML = html; | |||
$wnd.document.body.appendChild(d); | |||
var w = d.offsetWidth; | |||
$wnd.document.body.removeChild(d); | |||
return w; | |||
}-*/; | |||
if(!captions || captions.length <= 0) | |||
return 0; | |||
captions = captions.split("|"); | |||
var d = $wnd.document.createElement("div"); | |||
var html = ""; | |||
for(var i=0; i < captions.length; i++) { | |||
html += "<div>" + captions[i] + "</div>"; | |||
// TODO apply same CSS classname as in suggestionmenu | |||
} | |||
d.style.position = "absolute"; | |||
d.style.top = "0"; | |||
d.style.left = "0"; | |||
d.style.visibility = "hidden"; | |||
d.innerHTML = html; | |||
$wnd.document.body.appendChild(d); | |||
var w = d.offsetWidth; | |||
$wnd.document.body.removeChild(d); | |||
return w; | |||
}-*/; | |||
public void onFocus(Widget sender) { | |||
// NOP |
@@ -10,61 +10,65 @@ import com.itmill.toolkit.terminal.gwt.client.Paintable; | |||
import com.itmill.toolkit.terminal.gwt.client.UIDL; | |||
public class IPopupCalendar extends ITextualDate implements Paintable, | |||
ClickListener, PopupListener { | |||
ClickListener, PopupListener { | |||
private IButton calendarToggle; | |||
private IButton calendarToggle; | |||
private CalendarPanel calendar; | |||
private CalendarPanel calendar; | |||
private PopupPanel popup; | |||
private ToolkitOverlay popup; | |||
public IPopupCalendar() { | |||
super(); | |||
public IPopupCalendar() { | |||
super(); | |||
calendarToggle = new IButton(); | |||
calendarToggle.setText("..."); | |||
calendarToggle.addClickListener(this); | |||
add(calendarToggle); | |||
calendarToggle = new IButton(); | |||
calendarToggle.setText("..."); | |||
calendarToggle.addClickListener(this); | |||
add(calendarToggle); | |||
calendar = new CalendarPanel(this); | |||
popup = new PopupPanel(true); | |||
popup.setStyleName(IDateField.CLASSNAME + "-popup"); | |||
popup.setWidget(calendar); | |||
popup.addPopupListener(this); | |||
} | |||
calendar = new CalendarPanel(this); | |||
popup = new ToolkitOverlay(true); | |||
popup.setStyleName(IDateField.CLASSNAME + "-popup"); | |||
popup.setWidget(calendar); | |||
popup.addPopupListener(this); | |||
} | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
super.updateFromUIDL(uidl, client); | |||
if (date != null) | |||
calendar.updateCalendar(); | |||
calendarToggle.setEnabled(enabled); | |||
} | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
super.updateFromUIDL(uidl, client); | |||
if (date != null) { | |||
calendar.updateCalendar(); | |||
} | |||
calendarToggle.setEnabled(enabled); | |||
} | |||
public void onClick(Widget sender) { | |||
if (sender == calendarToggle) { | |||
calendar.updateCalendar(); | |||
popup.show(); | |||
// clear previous values | |||
popup.setWidth(""); | |||
popup.setHeight(""); | |||
int w = calendar.getOffsetWidth(); | |||
int h = calendar.getOffsetHeight(); | |||
int t = calendarToggle.getAbsoluteTop(); | |||
int l = calendarToggle.getAbsoluteLeft(); | |||
if (l + w > Window.getClientWidth()) | |||
l = Window.getClientWidth() - w; | |||
if (t + h > Window.getClientHeight()) | |||
t = Window.getClientHeight() - h | |||
- calendarToggle.getOffsetHeight() - 2; | |||
popup.setPopupPosition(l, t + calendarToggle.getOffsetHeight() + 2); | |||
popup.setWidth(w + "px"); | |||
popup.setHeight(h + "px"); | |||
} | |||
} | |||
public void onClick(Widget sender) { | |||
if (sender == calendarToggle) { | |||
calendar.updateCalendar(); | |||
popup.show(); | |||
// clear previous values | |||
popup.setWidth(""); | |||
popup.setHeight(""); | |||
int w = calendar.getOffsetWidth(); | |||
int h = calendar.getOffsetHeight(); | |||
int t = calendarToggle.getAbsoluteTop(); | |||
int l = calendarToggle.getAbsoluteLeft(); | |||
if (l + w > Window.getClientWidth()) { | |||
l = Window.getClientWidth() - w; | |||
} | |||
if (t + h > Window.getClientHeight()) { | |||
t = Window.getClientHeight() - h | |||
- calendarToggle.getOffsetHeight() - 2; | |||
} | |||
popup.setPopupPosition(l, t + calendarToggle.getOffsetHeight() + 2); | |||
popup.setWidth(w + "px"); | |||
popup.setHeight(h + "px"); | |||
} | |||
} | |||
public void onPopupClosed(PopupPanel sender, boolean autoClosed) { | |||
if (sender == popup) | |||
buildDate(); | |||
} | |||
public void onPopupClosed(PopupPanel sender, boolean autoClosed) { | |||
if (sender == popup) { | |||
buildDate(); | |||
} | |||
} | |||
} |
@@ -921,8 +921,6 @@ public class IScrollTable extends Composite implements Table, ScrollListener, | |||
DOM.setInnerHTML(floatingCopyOfHeaderCell, DOM.getInnerHTML(td)); | |||
floatingCopyOfHeaderCell = DOM | |||
.getChild(floatingCopyOfHeaderCell, 1); | |||
// TODO isolate non-standard css attribute (filter) | |||
// TODO move styles to css file | |||
DOM.setElementProperty(floatingCopyOfHeaderCell, "className", | |||
CLASSNAME + "-header-drag"); | |||
updateFloatingCopysPosition(DOM.getAbsoluteLeft(td), DOM |
@@ -17,6 +17,9 @@ package com.itmill.toolkit.terminal.gwt.client.ui; | |||
*/ | |||
//COPIED HERE DUE package privates in GWT | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import com.google.gwt.user.client.Command; | |||
import com.google.gwt.user.client.DOM; | |||
import com.google.gwt.user.client.DeferredCommand; | |||
@@ -26,9 +29,6 @@ import com.google.gwt.user.client.ui.PopupListener; | |||
import com.google.gwt.user.client.ui.PopupPanel; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
/** | |||
* A standard menu bar widget. A menu bar can contain any number of menu items, | |||
* each of which can either fire a {@link com.google.gwt.user.client.Command} or | |||
@@ -52,455 +52,455 @@ import java.util.List; | |||
*/ | |||
public class MenuBar extends Widget implements PopupListener { | |||
private Element body; | |||
private ArrayList items = new ArrayList(); | |||
private MenuBar parentMenu; | |||
private PopupPanel popup; | |||
private MenuItem selectedItem; | |||
private MenuBar shownChildMenu; | |||
private boolean vertical, autoOpen; | |||
/** | |||
* Creates an empty horizontal menu bar. | |||
*/ | |||
public MenuBar() { | |||
this(false); | |||
} | |||
/** | |||
* Creates an empty menu bar. | |||
* | |||
* @param vertical | |||
* <code>true</code> to orient the menu bar vertically | |||
*/ | |||
public MenuBar(boolean vertical) { | |||
super(); | |||
Element table = DOM.createTable(); | |||
body = DOM.createTBody(); | |||
DOM.appendChild(table, body); | |||
if (!vertical) { | |||
Element tr = DOM.createTR(); | |||
DOM.appendChild(body, tr); | |||
} | |||
this.vertical = vertical; | |||
Element outer = DOM.createDiv(); | |||
DOM.appendChild(outer, table); | |||
setElement(outer); | |||
sinkEvents(Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT); | |||
setStyleName("gwt-MenuBar"); | |||
} | |||
/** | |||
* Adds a menu item to the bar. | |||
* | |||
* @param item | |||
* the item to be added | |||
*/ | |||
public void addItem(MenuItem item) { | |||
Element tr; | |||
if (vertical) { | |||
tr = DOM.createTR(); | |||
DOM.appendChild(body, tr); | |||
} else { | |||
tr = DOM.getChild(body, 0); | |||
} | |||
DOM.appendChild(tr, item.getElement()); | |||
item.setParentMenu(this); | |||
item.setSelectionStyle(false); | |||
items.add(item); | |||
} | |||
/** | |||
* Adds a menu item to the bar, that will fire the given command when it is | |||
* selected. | |||
* | |||
* @param text | |||
* the item's text | |||
* @param asHTML | |||
* <code>true</code> to treat the specified text as html | |||
* @param cmd | |||
* the command to be fired | |||
* @return the {@link MenuItem} object created | |||
*/ | |||
public MenuItem addItem(String text, boolean asHTML, Command cmd) { | |||
MenuItem item = new MenuItem(text, asHTML, cmd); | |||
addItem(item); | |||
return item; | |||
} | |||
/** | |||
* Adds a menu item to the bar, that will open the specified menu when it is | |||
* selected. | |||
* | |||
* @param text | |||
* the item's text | |||
* @param asHTML | |||
* <code>true</code> to treat the specified text as html | |||
* @param popup | |||
* the menu to be cascaded from it | |||
* @return the {@link MenuItem} object created | |||
*/ | |||
public MenuItem addItem(String text, boolean asHTML, MenuBar popup) { | |||
MenuItem item = new MenuItem(text, asHTML, popup); | |||
addItem(item); | |||
return item; | |||
} | |||
/** | |||
* Adds a menu item to the bar, that will fire the given command when it is | |||
* selected. | |||
* | |||
* @param text | |||
* the item's text | |||
* @param cmd | |||
* the command to be fired | |||
* @return the {@link MenuItem} object created | |||
*/ | |||
public MenuItem addItem(String text, Command cmd) { | |||
MenuItem item = new MenuItem(text, cmd); | |||
addItem(item); | |||
return item; | |||
} | |||
/** | |||
* Adds a menu item to the bar, that will open the specified menu when it is | |||
* selected. | |||
* | |||
* @param text | |||
* the item's text | |||
* @param popup | |||
* the menu to be cascaded from it | |||
* @return the {@link MenuItem} object created | |||
*/ | |||
public MenuItem addItem(String text, MenuBar popup) { | |||
MenuItem item = new MenuItem(text, popup); | |||
addItem(item); | |||
return item; | |||
} | |||
/** | |||
* Removes all menu items from this menu bar. | |||
*/ | |||
public void clearItems() { | |||
Element container = getItemContainerElement(); | |||
while (DOM.getChildCount(container) > 0) { | |||
DOM.removeChild(container, DOM.getChild(container, 0)); | |||
} | |||
items.clear(); | |||
} | |||
/** | |||
* Gets whether this menu bar's child menus will open when the mouse is | |||
* moved over it. | |||
* | |||
* @return <code>true</code> if child menus will auto-open | |||
*/ | |||
public boolean getAutoOpen() { | |||
return autoOpen; | |||
} | |||
public void onBrowserEvent(Event event) { | |||
super.onBrowserEvent(event); | |||
MenuItem item = findItem(DOM.eventGetTarget(event)); | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONCLICK: { | |||
// Fire an item's command when the user clicks on it. | |||
if (item != null) { | |||
doItemAction(item, true); | |||
} | |||
break; | |||
} | |||
case Event.ONMOUSEOVER: { | |||
if (item != null) { | |||
itemOver(item); | |||
} | |||
break; | |||
} | |||
case Event.ONMOUSEOUT: { | |||
if (item != null) { | |||
itemOver(null); | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
public void onPopupClosed(PopupPanel sender, boolean autoClosed) { | |||
// If the menu popup was auto-closed, close all of its parents as well. | |||
if (autoClosed) { | |||
closeAllParents(); | |||
} | |||
// When the menu popup closes, remember that no item is | |||
// currently showing a popup menu. | |||
onHide(); | |||
shownChildMenu = null; | |||
popup = null; | |||
} | |||
/** | |||
* Removes the specified menu item from the bar. | |||
* | |||
* @param item | |||
* the item to be removed | |||
*/ | |||
public void removeItem(MenuItem item) { | |||
int idx = items.indexOf(item); | |||
if (idx == -1) { | |||
return; | |||
} | |||
Element container = getItemContainerElement(); | |||
DOM.removeChild(container, DOM.getChild(container, idx)); | |||
items.remove(idx); | |||
} | |||
/** | |||
* Sets whether this menu bar's child menus will open when the mouse is | |||
* moved over it. | |||
* | |||
* @param autoOpen | |||
* <code>true</code> to cause child menus to auto-open | |||
*/ | |||
public void setAutoOpen(boolean autoOpen) { | |||
this.autoOpen = autoOpen; | |||
} | |||
/** | |||
* Returns a list containing the <code>MenuItem</code> objects in the menu | |||
* bar. If there are no items in the menu bar, then an empty | |||
* <code>List</code> object will be returned. | |||
* | |||
* @return a list containing the <code>MenuItem</code> objects in the menu | |||
* bar | |||
*/ | |||
protected List getItems() { | |||
return this.items; | |||
} | |||
/** | |||
* Returns the <code>MenuItem</code> that is currently selected | |||
* (highlighted) by the user. If none of the items in the menu are currently | |||
* selected, then <code>null</code> will be returned. | |||
* | |||
* @return the <code>MenuItem</code> that is currently selected, or | |||
* <code>null</code> if no items are currently selected | |||
*/ | |||
protected MenuItem getSelectedItem() { | |||
return this.selectedItem; | |||
} | |||
protected void onDetach() { | |||
// When the menu is detached, make sure to close all of its children. | |||
if (popup != null) { | |||
popup.hide(); | |||
} | |||
super.onDetach(); | |||
} | |||
/* | |||
* Closes all parent menu popups. | |||
*/ | |||
void closeAllParents() { | |||
MenuBar curMenu = this; | |||
while (curMenu != null) { | |||
curMenu.close(); | |||
if ((curMenu.parentMenu == null) && (curMenu.selectedItem != null)) { | |||
curMenu.selectedItem.setSelectionStyle(false); | |||
curMenu.selectedItem = null; | |||
} | |||
curMenu = curMenu.parentMenu; | |||
} | |||
} | |||
/* | |||
* Performs the action associated with the given menu item. If the item has | |||
* a popup associated with it, the popup will be shown. If it has a command | |||
* associated with it, and 'fireCommand' is true, then the command will be | |||
* fired. Popups associated with other items will be hidden. | |||
* | |||
* @param item the item whose popup is to be shown. @param fireCommand | |||
* <code>true</code> if the item's command should be fired, <code>false</code> | |||
* otherwise. | |||
*/ | |||
void doItemAction(final MenuItem item, boolean fireCommand) { | |||
// If the given item is already showing its menu, we're done. | |||
if ((shownChildMenu != null) && (item.getSubMenu() == shownChildMenu)) { | |||
return; | |||
} | |||
// If another item is showing its menu, then hide it. | |||
if (shownChildMenu != null) { | |||
shownChildMenu.onHide(); | |||
popup.hide(); | |||
} | |||
// If the item has no popup, optionally fire its command. | |||
if (item.getSubMenu() == null) { | |||
if (fireCommand) { | |||
// Close this menu and all of its parents. | |||
closeAllParents(); | |||
// Fire the item's command. | |||
Command cmd = item.getCommand(); | |||
if (cmd != null) { | |||
DeferredCommand.addCommand(cmd); | |||
} | |||
} | |||
return; | |||
} | |||
// Ensure that the item is selected. | |||
selectItem(item); | |||
// Create a new popup for this item, and position it next to | |||
// the item (below if this is a horizontal menu bar, to the | |||
// right if it's a vertical bar). | |||
popup = new PopupPanel(true) { | |||
{ | |||
setWidget(item.getSubMenu()); | |||
item.getSubMenu().onShow(); | |||
} | |||
public boolean onEventPreview(Event event) { | |||
// Hook the popup panel's event preview. We use this to keep it | |||
// from | |||
// auto-hiding when the parent menu is clicked. | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONCLICK: | |||
// If the event target is part of the parent menu, suppress | |||
// the | |||
// event altogether. | |||
Element target = DOM.eventGetTarget(event); | |||
Element parentMenuElement = item.getParentMenu() | |||
.getElement(); | |||
if (DOM.isOrHasChild(parentMenuElement, target)) { | |||
return false; | |||
} | |||
break; | |||
} | |||
return super.onEventPreview(event); | |||
} | |||
}; | |||
popup.addPopupListener(this); | |||
if (vertical) { | |||
popup.setPopupPosition(item.getAbsoluteLeft() | |||
+ item.getOffsetWidth(), item.getAbsoluteTop()); | |||
} else { | |||
popup.setPopupPosition(item.getAbsoluteLeft(), item | |||
.getAbsoluteTop() | |||
+ item.getOffsetHeight()); | |||
} | |||
shownChildMenu = item.getSubMenu(); | |||
item.getSubMenu().parentMenu = this; | |||
// Show the popup, ensuring that the menubar's event preview remains on | |||
// top | |||
// of the popup's. | |||
popup.show(); | |||
} | |||
void itemOver(MenuItem item) { | |||
if (item == null) { | |||
// Don't clear selection if the currently selected item's menu is | |||
// showing. | |||
if ((selectedItem != null) | |||
&& (shownChildMenu == selectedItem.getSubMenu())) { | |||
return; | |||
} | |||
} | |||
// Style the item selected when the mouse enters. | |||
selectItem(item); | |||
// If child menus are being shown, or this menu is itself | |||
// a child menu, automatically show an item's child menu | |||
// when the mouse enters. | |||
if (item != null) { | |||
if ((shownChildMenu != null) || (parentMenu != null) || autoOpen) { | |||
doItemAction(item, false); | |||
} | |||
} | |||
} | |||
void selectItem(MenuItem item) { | |||
if (item == selectedItem) { | |||
return; | |||
} | |||
if (selectedItem != null) { | |||
selectedItem.setSelectionStyle(false); | |||
} | |||
if (item != null) { | |||
item.setSelectionStyle(true); | |||
} | |||
selectedItem = item; | |||
} | |||
/** | |||
* Closes this menu (if it is a popup). | |||
*/ | |||
private void close() { | |||
if (parentMenu != null) { | |||
parentMenu.popup.hide(); | |||
} | |||
} | |||
private MenuItem findItem(Element hItem) { | |||
for (int i = 0; i < items.size(); ++i) { | |||
MenuItem item = (MenuItem) items.get(i); | |||
if (DOM.isOrHasChild(item.getElement(), hItem)) { | |||
return item; | |||
} | |||
} | |||
return null; | |||
} | |||
private Element getItemContainerElement() { | |||
if (vertical) { | |||
return body; | |||
} else { | |||
return DOM.getChild(body, 0); | |||
} | |||
} | |||
/* | |||
* This method is called when a menu bar is hidden, so that it can hide any | |||
* child popups that are currently being shown. | |||
*/ | |||
private void onHide() { | |||
if (shownChildMenu != null) { | |||
shownChildMenu.onHide(); | |||
popup.hide(); | |||
} | |||
} | |||
/* | |||
* This method is called when a menu bar is shown. | |||
*/ | |||
private void onShow() { | |||
// Select the first item when a menu is shown. | |||
if (items.size() > 0) { | |||
selectItem((MenuItem) items.get(0)); | |||
} | |||
} | |||
private Element body; | |||
private ArrayList items = new ArrayList(); | |||
private MenuBar parentMenu; | |||
private PopupPanel popup; | |||
private MenuItem selectedItem; | |||
private MenuBar shownChildMenu; | |||
private boolean vertical, autoOpen; | |||
/** | |||
* Creates an empty horizontal menu bar. | |||
*/ | |||
public MenuBar() { | |||
this(false); | |||
} | |||
/** | |||
* Creates an empty menu bar. | |||
* | |||
* @param vertical | |||
* <code>true</code> to orient the menu bar vertically | |||
*/ | |||
public MenuBar(boolean vertical) { | |||
super(); | |||
Element table = DOM.createTable(); | |||
body = DOM.createTBody(); | |||
DOM.appendChild(table, body); | |||
if (!vertical) { | |||
Element tr = DOM.createTR(); | |||
DOM.appendChild(body, tr); | |||
} | |||
this.vertical = vertical; | |||
Element outer = DOM.createDiv(); | |||
DOM.appendChild(outer, table); | |||
setElement(outer); | |||
sinkEvents(Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT); | |||
setStyleName("gwt-MenuBar"); | |||
} | |||
/** | |||
* Adds a menu item to the bar. | |||
* | |||
* @param item | |||
* the item to be added | |||
*/ | |||
public void addItem(MenuItem item) { | |||
Element tr; | |||
if (vertical) { | |||
tr = DOM.createTR(); | |||
DOM.appendChild(body, tr); | |||
} else { | |||
tr = DOM.getChild(body, 0); | |||
} | |||
DOM.appendChild(tr, item.getElement()); | |||
item.setParentMenu(this); | |||
item.setSelectionStyle(false); | |||
items.add(item); | |||
} | |||
/** | |||
* Adds a menu item to the bar, that will fire the given command when it is | |||
* selected. | |||
* | |||
* @param text | |||
* the item's text | |||
* @param asHTML | |||
* <code>true</code> to treat the specified text as html | |||
* @param cmd | |||
* the command to be fired | |||
* @return the {@link MenuItem} object created | |||
*/ | |||
public MenuItem addItem(String text, boolean asHTML, Command cmd) { | |||
MenuItem item = new MenuItem(text, asHTML, cmd); | |||
addItem(item); | |||
return item; | |||
} | |||
/** | |||
* Adds a menu item to the bar, that will open the specified menu when it is | |||
* selected. | |||
* | |||
* @param text | |||
* the item's text | |||
* @param asHTML | |||
* <code>true</code> to treat the specified text as html | |||
* @param popup | |||
* the menu to be cascaded from it | |||
* @return the {@link MenuItem} object created | |||
*/ | |||
public MenuItem addItem(String text, boolean asHTML, MenuBar popup) { | |||
MenuItem item = new MenuItem(text, asHTML, popup); | |||
addItem(item); | |||
return item; | |||
} | |||
/** | |||
* Adds a menu item to the bar, that will fire the given command when it is | |||
* selected. | |||
* | |||
* @param text | |||
* the item's text | |||
* @param cmd | |||
* the command to be fired | |||
* @return the {@link MenuItem} object created | |||
*/ | |||
public MenuItem addItem(String text, Command cmd) { | |||
MenuItem item = new MenuItem(text, cmd); | |||
addItem(item); | |||
return item; | |||
} | |||
/** | |||
* Adds a menu item to the bar, that will open the specified menu when it is | |||
* selected. | |||
* | |||
* @param text | |||
* the item's text | |||
* @param popup | |||
* the menu to be cascaded from it | |||
* @return the {@link MenuItem} object created | |||
*/ | |||
public MenuItem addItem(String text, MenuBar popup) { | |||
MenuItem item = new MenuItem(text, popup); | |||
addItem(item); | |||
return item; | |||
} | |||
/** | |||
* Removes all menu items from this menu bar. | |||
*/ | |||
public void clearItems() { | |||
Element container = getItemContainerElement(); | |||
while (DOM.getChildCount(container) > 0) { | |||
DOM.removeChild(container, DOM.getChild(container, 0)); | |||
} | |||
items.clear(); | |||
} | |||
/** | |||
* Gets whether this menu bar's child menus will open when the mouse is | |||
* moved over it. | |||
* | |||
* @return <code>true</code> if child menus will auto-open | |||
*/ | |||
public boolean getAutoOpen() { | |||
return autoOpen; | |||
} | |||
public void onBrowserEvent(Event event) { | |||
super.onBrowserEvent(event); | |||
MenuItem item = findItem(DOM.eventGetTarget(event)); | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONCLICK: { | |||
// Fire an item's command when the user clicks on it. | |||
if (item != null) { | |||
doItemAction(item, true); | |||
} | |||
break; | |||
} | |||
case Event.ONMOUSEOVER: { | |||
if (item != null) { | |||
itemOver(item); | |||
} | |||
break; | |||
} | |||
case Event.ONMOUSEOUT: { | |||
if (item != null) { | |||
itemOver(null); | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
public void onPopupClosed(PopupPanel sender, boolean autoClosed) { | |||
// If the menu popup was auto-closed, close all of its parents as well. | |||
if (autoClosed) { | |||
closeAllParents(); | |||
} | |||
// When the menu popup closes, remember that no item is | |||
// currently showing a popup menu. | |||
onHide(); | |||
shownChildMenu = null; | |||
popup = null; | |||
} | |||
/** | |||
* Removes the specified menu item from the bar. | |||
* | |||
* @param item | |||
* the item to be removed | |||
*/ | |||
public void removeItem(MenuItem item) { | |||
int idx = items.indexOf(item); | |||
if (idx == -1) { | |||
return; | |||
} | |||
Element container = getItemContainerElement(); | |||
DOM.removeChild(container, DOM.getChild(container, idx)); | |||
items.remove(idx); | |||
} | |||
/** | |||
* Sets whether this menu bar's child menus will open when the mouse is | |||
* moved over it. | |||
* | |||
* @param autoOpen | |||
* <code>true</code> to cause child menus to auto-open | |||
*/ | |||
public void setAutoOpen(boolean autoOpen) { | |||
this.autoOpen = autoOpen; | |||
} | |||
/** | |||
* Returns a list containing the <code>MenuItem</code> objects in the menu | |||
* bar. If there are no items in the menu bar, then an empty | |||
* <code>List</code> object will be returned. | |||
* | |||
* @return a list containing the <code>MenuItem</code> objects in the menu | |||
* bar | |||
*/ | |||
protected List getItems() { | |||
return items; | |||
} | |||
/** | |||
* Returns the <code>MenuItem</code> that is currently selected | |||
* (highlighted) by the user. If none of the items in the menu are currently | |||
* selected, then <code>null</code> will be returned. | |||
* | |||
* @return the <code>MenuItem</code> that is currently selected, or | |||
* <code>null</code> if no items are currently selected | |||
*/ | |||
protected MenuItem getSelectedItem() { | |||
return selectedItem; | |||
} | |||
protected void onDetach() { | |||
// When the menu is detached, make sure to close all of its children. | |||
if (popup != null) { | |||
popup.hide(); | |||
} | |||
super.onDetach(); | |||
} | |||
/* | |||
* Closes all parent menu popups. | |||
*/ | |||
void closeAllParents() { | |||
MenuBar curMenu = this; | |||
while (curMenu != null) { | |||
curMenu.close(); | |||
if ((curMenu.parentMenu == null) && (curMenu.selectedItem != null)) { | |||
curMenu.selectedItem.setSelectionStyle(false); | |||
curMenu.selectedItem = null; | |||
} | |||
curMenu = curMenu.parentMenu; | |||
} | |||
} | |||
/* | |||
* Performs the action associated with the given menu item. If the item has | |||
* a popup associated with it, the popup will be shown. If it has a command | |||
* associated with it, and 'fireCommand' is true, then the command will be | |||
* fired. Popups associated with other items will be hidden. | |||
* | |||
* @param item the item whose popup is to be shown. @param fireCommand | |||
* <code>true</code> if the item's command should be fired, <code>false</code> | |||
* otherwise. | |||
*/ | |||
void doItemAction(final MenuItem item, boolean fireCommand) { | |||
// If the given item is already showing its menu, we're done. | |||
if ((shownChildMenu != null) && (item.getSubMenu() == shownChildMenu)) { | |||
return; | |||
} | |||
// If another item is showing its menu, then hide it. | |||
if (shownChildMenu != null) { | |||
shownChildMenu.onHide(); | |||
popup.hide(); | |||
} | |||
// If the item has no popup, optionally fire its command. | |||
if (item.getSubMenu() == null) { | |||
if (fireCommand) { | |||
// Close this menu and all of its parents. | |||
closeAllParents(); | |||
// Fire the item's command. | |||
Command cmd = item.getCommand(); | |||
if (cmd != null) { | |||
DeferredCommand.addCommand(cmd); | |||
} | |||
} | |||
return; | |||
} | |||
// Ensure that the item is selected. | |||
selectItem(item); | |||
// Create a new popup for this item, and position it next to | |||
// the item (below if this is a horizontal menu bar, to the | |||
// right if it's a vertical bar). | |||
popup = new ToolkitOverlay(true) { | |||
{ | |||
setWidget(item.getSubMenu()); | |||
item.getSubMenu().onShow(); | |||
} | |||
public boolean onEventPreview(Event event) { | |||
// Hook the popup panel's event preview. We use this to keep it | |||
// from | |||
// auto-hiding when the parent menu is clicked. | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONCLICK: | |||
// If the event target is part of the parent menu, suppress | |||
// the | |||
// event altogether. | |||
Element target = DOM.eventGetTarget(event); | |||
Element parentMenuElement = item.getParentMenu() | |||
.getElement(); | |||
if (DOM.isOrHasChild(parentMenuElement, target)) { | |||
return false; | |||
} | |||
break; | |||
} | |||
return super.onEventPreview(event); | |||
} | |||
}; | |||
popup.addPopupListener(this); | |||
if (vertical) { | |||
popup.setPopupPosition(item.getAbsoluteLeft() | |||
+ item.getOffsetWidth(), item.getAbsoluteTop()); | |||
} else { | |||
popup.setPopupPosition(item.getAbsoluteLeft(), item | |||
.getAbsoluteTop() | |||
+ item.getOffsetHeight()); | |||
} | |||
shownChildMenu = item.getSubMenu(); | |||
item.getSubMenu().parentMenu = this; | |||
// Show the popup, ensuring that the menubar's event preview remains on | |||
// top | |||
// of the popup's. | |||
popup.show(); | |||
} | |||
void itemOver(MenuItem item) { | |||
if (item == null) { | |||
// Don't clear selection if the currently selected item's menu is | |||
// showing. | |||
if ((selectedItem != null) | |||
&& (shownChildMenu == selectedItem.getSubMenu())) { | |||
return; | |||
} | |||
} | |||
// Style the item selected when the mouse enters. | |||
selectItem(item); | |||
// If child menus are being shown, or this menu is itself | |||
// a child menu, automatically show an item's child menu | |||
// when the mouse enters. | |||
if (item != null) { | |||
if ((shownChildMenu != null) || (parentMenu != null) || autoOpen) { | |||
doItemAction(item, false); | |||
} | |||
} | |||
} | |||
void selectItem(MenuItem item) { | |||
if (item == selectedItem) { | |||
return; | |||
} | |||
if (selectedItem != null) { | |||
selectedItem.setSelectionStyle(false); | |||
} | |||
if (item != null) { | |||
item.setSelectionStyle(true); | |||
} | |||
selectedItem = item; | |||
} | |||
/** | |||
* Closes this menu (if it is a popup). | |||
*/ | |||
private void close() { | |||
if (parentMenu != null) { | |||
parentMenu.popup.hide(); | |||
} | |||
} | |||
private MenuItem findItem(Element hItem) { | |||
for (int i = 0; i < items.size(); ++i) { | |||
MenuItem item = (MenuItem) items.get(i); | |||
if (DOM.isOrHasChild(item.getElement(), hItem)) { | |||
return item; | |||
} | |||
} | |||
return null; | |||
} | |||
private Element getItemContainerElement() { | |||
if (vertical) { | |||
return body; | |||
} else { | |||
return DOM.getChild(body, 0); | |||
} | |||
} | |||
/* | |||
* This method is called when a menu bar is hidden, so that it can hide any | |||
* child popups that are currently being shown. | |||
*/ | |||
private void onHide() { | |||
if (shownChildMenu != null) { | |||
shownChildMenu.onHide(); | |||
popup.hide(); | |||
} | |||
} | |||
/* | |||
* This method is called when a menu bar is shown. | |||
*/ | |||
private void onShow() { | |||
// Select the first item when a menu is shown. | |||
if (items.size() > 0) { | |||
selectItem((MenuItem) items.get(0)); | |||
} | |||
} | |||
} |
@@ -6,224 +6,223 @@ import com.google.gwt.user.client.Event; | |||
import com.google.gwt.user.client.EventPreview; | |||
import com.google.gwt.user.client.Timer; | |||
import com.google.gwt.user.client.ui.HTML; | |||
import com.google.gwt.user.client.ui.PopupPanel; | |||
import com.google.gwt.user.client.ui.Widget; | |||
public class Notification extends PopupPanel { | |||
public static final int CENTERED = 1; | |||
public static final int CENTERED_TOP = 2; | |||
public static final int CENTERED_BOTTOM = 3; | |||
public static final int TOP_LEFT = 4; | |||
public static final int TOP_RIGHT = 5; | |||
public static final int BOTTOM_LEFT = 6; | |||
public static final int BOTTOM_RIGHT = 7; | |||
public static final int DELAY_FOREVER = -1; | |||
public static final int DELAY_NONE = 0; | |||
private static final String STYLENAME = "i-Notification"; | |||
private static final int mouseMoveThreshold = 7; | |||
private static final int Z_INDEX_BASE = 20000; | |||
private int startOpacity = 90; | |||
private int fadeMsec = 400; | |||
private int delayMsec = 1000; | |||
private Timer fader; | |||
private Timer delay; | |||
private EventPreview eventPreview; | |||
private String temporaryStyle; | |||
public Notification() { | |||
setStylePrimaryName(STYLENAME); | |||
sinkEvents(Event.ONCLICK); | |||
DOM.setStyleAttribute(getElement(), "zIndex", "" + Z_INDEX_BASE); | |||
} | |||
public Notification(int delayMsec) { | |||
this(); | |||
this.delayMsec = delayMsec; | |||
} | |||
public Notification(int delayMsec, int fadeMsec, int startOpacity) { | |||
this(delayMsec); | |||
this.fadeMsec = fadeMsec; | |||
this.startOpacity = startOpacity; | |||
} | |||
public void startDelay() { | |||
DOM.removeEventPreview(eventPreview); | |||
if (delayMsec > 0) { | |||
delay = new Timer() { | |||
public void run() { | |||
fade(); | |||
} | |||
}; | |||
delay.scheduleRepeating(delayMsec); | |||
} else if (delayMsec == 0) { | |||
fade(); | |||
} | |||
} | |||
public void show() { | |||
show(CENTERED); | |||
} | |||
public void show(String style) { | |||
show(CENTERED, style); | |||
} | |||
public void show(int position) { | |||
show(position, null); | |||
} | |||
public void show(Widget widget, int position, String style) { | |||
setWidget(widget); | |||
show(position, style); | |||
} | |||
public void show(String html, int position, String style) { | |||
setWidget(new HTML(html)); | |||
show(position, style); | |||
} | |||
public void show(int position, String style) { | |||
hide(); | |||
setOpacity(getElement(), startOpacity); | |||
if (style != null) { | |||
this.temporaryStyle = style; | |||
addStyleName(style); | |||
} | |||
super.show(); | |||
setPosition(position); | |||
if (eventPreview == null) { | |||
eventPreview = new EventPreview() { | |||
int x = -1; | |||
int y = -1; | |||
public boolean onEventPreview(Event event) { | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONMOUSEMOVE: | |||
if (x < 0) { | |||
x = DOM.eventGetClientX(event); | |||
y = DOM.eventGetClientY(event); | |||
} else if (Math.abs(DOM.eventGetClientX(event) - x) > mouseMoveThreshold | |||
|| Math.abs(DOM.eventGetClientY(event) - y) > mouseMoveThreshold) { | |||
startDelay(); | |||
} | |||
break; | |||
case Event.KEYEVENTS: | |||
case Event.ONCLICK: | |||
case Event.ONDBLCLICK: | |||
case Event.ONSCROLL: | |||
default: | |||
startDelay(); | |||
} | |||
return true; | |||
} | |||
}; | |||
} | |||
DOM.addEventPreview(eventPreview); | |||
} | |||
public void hide() { | |||
DOM.removeEventPreview(eventPreview); | |||
cancelDelay(); | |||
cancelFade(); | |||
if (this.temporaryStyle != null) { | |||
removeStyleName(this.temporaryStyle); | |||
this.temporaryStyle = null; | |||
} | |||
super.hide(); | |||
} | |||
public void fade() { | |||
cancelDelay(); | |||
fader = new Timer() { | |||
int opacity = startOpacity; | |||
public void run() { | |||
opacity -= 5; | |||
setOpacity(getElement(), opacity); | |||
if (opacity <= 0) { | |||
cancel(); | |||
hide(); | |||
} | |||
} | |||
}; | |||
int msec = fadeMsec / (startOpacity / 5); | |||
fader.scheduleRepeating(msec); | |||
} | |||
public void setPosition(int position) { | |||
Element el = getElement(); | |||
DOM.setStyleAttribute(el, "top", null); | |||
DOM.setStyleAttribute(el, "left", null); | |||
DOM.setStyleAttribute(el, "bottom", null); | |||
DOM.setStyleAttribute(el, "right", null); | |||
switch (position) { | |||
case TOP_LEFT: | |||
DOM.setStyleAttribute(el, "top", "0px"); | |||
DOM.setStyleAttribute(el, "left", "0px"); | |||
break; | |||
case TOP_RIGHT: | |||
DOM.setStyleAttribute(el, "top", "0px"); | |||
DOM.setStyleAttribute(el, "right", "0px"); | |||
break; | |||
case BOTTOM_RIGHT: | |||
DOM.setStyleAttribute(el, "position", "absolute"); | |||
DOM.setStyleAttribute(el, "bottom", "0px"); | |||
DOM.setStyleAttribute(el, "right", "0px"); | |||
break; | |||
case BOTTOM_LEFT: | |||
DOM.setStyleAttribute(el, "bottom", "0px"); | |||
DOM.setStyleAttribute(el, "left", "0px"); | |||
break; | |||
case CENTERED_TOP: | |||
center(); | |||
DOM.setStyleAttribute(el, "top", "0px"); | |||
break; | |||
case CENTERED_BOTTOM: | |||
center(); | |||
DOM.setStyleAttribute(el, "top", null); | |||
DOM.setStyleAttribute(el, "bottom", "0px"); | |||
break; | |||
default: | |||
case CENTERED: | |||
center(); | |||
break; | |||
} | |||
} | |||
private void cancelFade() { | |||
if (fader != null) { | |||
fader.cancel(); | |||
fader = null; | |||
} | |||
} | |||
private void cancelDelay() { | |||
if (delay != null) { | |||
delay.cancel(); | |||
delay = null; | |||
} | |||
} | |||
private void setOpacity(Element el, int opacity) { | |||
DOM.setStyleAttribute(el, "opacity", "" + (opacity / 100.0)); | |||
DOM.setStyleAttribute(el, "filter", "Alpha(opacity=" + opacity + ")"); | |||
} | |||
public void onBrowserEvent(Event event) { | |||
DOM.removeEventPreview(eventPreview); | |||
if (fader == null) { | |||
fade(); | |||
} | |||
} | |||
public class Notification extends ToolkitOverlay { | |||
public static final int CENTERED = 1; | |||
public static final int CENTERED_TOP = 2; | |||
public static final int CENTERED_BOTTOM = 3; | |||
public static final int TOP_LEFT = 4; | |||
public static final int TOP_RIGHT = 5; | |||
public static final int BOTTOM_LEFT = 6; | |||
public static final int BOTTOM_RIGHT = 7; | |||
public static final int DELAY_FOREVER = -1; | |||
public static final int DELAY_NONE = 0; | |||
private static final String STYLENAME = "i-Notification"; | |||
private static final int mouseMoveThreshold = 7; | |||
private static final int Z_INDEX_BASE = 20000; | |||
private int startOpacity = 90; | |||
private int fadeMsec = 400; | |||
private int delayMsec = 1000; | |||
private Timer fader; | |||
private Timer delay; | |||
private EventPreview eventPreview; | |||
private String temporaryStyle; | |||
public Notification() { | |||
setStylePrimaryName(STYLENAME); | |||
sinkEvents(Event.ONCLICK); | |||
DOM.setStyleAttribute(getElement(), "zIndex", "" + Z_INDEX_BASE); | |||
} | |||
public Notification(int delayMsec) { | |||
this(); | |||
this.delayMsec = delayMsec; | |||
} | |||
public Notification(int delayMsec, int fadeMsec, int startOpacity) { | |||
this(delayMsec); | |||
this.fadeMsec = fadeMsec; | |||
this.startOpacity = startOpacity; | |||
} | |||
public void startDelay() { | |||
DOM.removeEventPreview(eventPreview); | |||
if (delayMsec > 0) { | |||
delay = new Timer() { | |||
public void run() { | |||
fade(); | |||
} | |||
}; | |||
delay.scheduleRepeating(delayMsec); | |||
} else if (delayMsec == 0) { | |||
fade(); | |||
} | |||
} | |||
public void show() { | |||
show(CENTERED); | |||
} | |||
public void show(String style) { | |||
show(CENTERED, style); | |||
} | |||
public void show(int position) { | |||
show(position, null); | |||
} | |||
public void show(Widget widget, int position, String style) { | |||
setWidget(widget); | |||
show(position, style); | |||
} | |||
public void show(String html, int position, String style) { | |||
setWidget(new HTML(html)); | |||
show(position, style); | |||
} | |||
public void show(int position, String style) { | |||
hide(); | |||
setOpacity(getElement(), startOpacity); | |||
if (style != null) { | |||
temporaryStyle = style; | |||
addStyleName(style); | |||
} | |||
super.show(); | |||
setPosition(position); | |||
if (eventPreview == null) { | |||
eventPreview = new EventPreview() { | |||
int x = -1; | |||
int y = -1; | |||
public boolean onEventPreview(Event event) { | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONMOUSEMOVE: | |||
if (x < 0) { | |||
x = DOM.eventGetClientX(event); | |||
y = DOM.eventGetClientY(event); | |||
} else if (Math.abs(DOM.eventGetClientX(event) - x) > mouseMoveThreshold | |||
|| Math.abs(DOM.eventGetClientY(event) - y) > mouseMoveThreshold) { | |||
startDelay(); | |||
} | |||
break; | |||
case Event.KEYEVENTS: | |||
case Event.ONCLICK: | |||
case Event.ONDBLCLICK: | |||
case Event.ONSCROLL: | |||
default: | |||
startDelay(); | |||
} | |||
return true; | |||
} | |||
}; | |||
} | |||
DOM.addEventPreview(eventPreview); | |||
} | |||
public void hide() { | |||
DOM.removeEventPreview(eventPreview); | |||
cancelDelay(); | |||
cancelFade(); | |||
if (temporaryStyle != null) { | |||
removeStyleName(temporaryStyle); | |||
temporaryStyle = null; | |||
} | |||
super.hide(); | |||
} | |||
public void fade() { | |||
cancelDelay(); | |||
fader = new Timer() { | |||
int opacity = startOpacity; | |||
public void run() { | |||
opacity -= 5; | |||
setOpacity(getElement(), opacity); | |||
if (opacity <= 0) { | |||
cancel(); | |||
hide(); | |||
} | |||
} | |||
}; | |||
int msec = fadeMsec / (startOpacity / 5); | |||
fader.scheduleRepeating(msec); | |||
} | |||
public void setPosition(int position) { | |||
Element el = getElement(); | |||
DOM.setStyleAttribute(el, "top", null); | |||
DOM.setStyleAttribute(el, "left", null); | |||
DOM.setStyleAttribute(el, "bottom", null); | |||
DOM.setStyleAttribute(el, "right", null); | |||
switch (position) { | |||
case TOP_LEFT: | |||
DOM.setStyleAttribute(el, "top", "0px"); | |||
DOM.setStyleAttribute(el, "left", "0px"); | |||
break; | |||
case TOP_RIGHT: | |||
DOM.setStyleAttribute(el, "top", "0px"); | |||
DOM.setStyleAttribute(el, "right", "0px"); | |||
break; | |||
case BOTTOM_RIGHT: | |||
DOM.setStyleAttribute(el, "position", "absolute"); | |||
DOM.setStyleAttribute(el, "bottom", "0px"); | |||
DOM.setStyleAttribute(el, "right", "0px"); | |||
break; | |||
case BOTTOM_LEFT: | |||
DOM.setStyleAttribute(el, "bottom", "0px"); | |||
DOM.setStyleAttribute(el, "left", "0px"); | |||
break; | |||
case CENTERED_TOP: | |||
center(); | |||
DOM.setStyleAttribute(el, "top", "0px"); | |||
break; | |||
case CENTERED_BOTTOM: | |||
center(); | |||
DOM.setStyleAttribute(el, "top", null); | |||
DOM.setStyleAttribute(el, "bottom", "0px"); | |||
break; | |||
default: | |||
case CENTERED: | |||
center(); | |||
break; | |||
} | |||
} | |||
private void cancelFade() { | |||
if (fader != null) { | |||
fader.cancel(); | |||
fader = null; | |||
} | |||
} | |||
private void cancelDelay() { | |||
if (delay != null) { | |||
delay.cancel(); | |||
delay = null; | |||
} | |||
} | |||
private void setOpacity(Element el, int opacity) { | |||
DOM.setStyleAttribute(el, "opacity", "" + (opacity / 100.0)); | |||
DOM.setStyleAttribute(el, "filter", "Alpha(opacity=" + opacity + ")"); | |||
} | |||
public void onBrowserEvent(Event event) { | |||
DOM.removeEventPreview(eventPreview); | |||
if (fader == null) { | |||
fade(); | |||
} | |||
} | |||
} |
@@ -139,6 +139,7 @@ | |||
opacity: 0.5; | |||
filter: alpha(opacity=50); | |||
margin-top: 20px; | |||
z-index: 20000; | |||
} | |||
.i-table-scrollposition { |