handler) {
return super.addHandler(handler, ValueChangeEvent.getType());
}
/**
* @see com.alkacon.geranium.client.ui.input.I_FormWidget#getFieldType()
*/
public FieldType getFieldType() {
return FieldType.STRING;
}
/**
* @see com.alkacon.geranium.client.ui.input.I_FormWidget#getFormValue()
*/
public Object getFormValue() {
if (m_selectedValue.equals("")) {
return null;
}
return m_selectedValue;
}
/**
* @see com.alkacon.geranium.client.ui.input.I_FormWidget#getFormValueAsString()
*/
public String getFormValueAsString() {
return (String)getFormValue();
}
/**
* @see com.alkacon.geranium.client.ui.input.I_FormWidget#isEnabled()
*/
public boolean isEnabled() {
return m_enabled;
}
/**
* @see com.google.gwt.user.client.ui.Composite#onBrowserEvent(com.google.gwt.user.client.Event)
*/
@Override
public void onBrowserEvent(Event event) {
// Should not act on button if disabled.
if (!isEnabled()) {
return;
}
super.onBrowserEvent(event);
}
/**
* @see com.alkacon.geranium.client.ui.input.I_FormWidget#reset()
*/
public void reset() {
close();
onValueSelect(m_firstValue);
}
/**
* Helper method to set the current selected option.
*
* This method does not trigger the "value changed" event.
*
* @param value the new value
*/
public void selectValue(String value) {
if (m_selectCells.get(value) == null) {
return;
}
updateOpener(value);
if (m_textMetricsPrefix != null) {
truncate(m_textMetricsPrefix, m_widgetWidth);
}
m_selectedValue = value;
close();
}
/**
* @see com.alkacon.geranium.client.ui.input.I_FormWidget#setEnabled(boolean)
*/
public void setEnabled(boolean enabled) {
close();
m_enabled = enabled;
DOM.setElementPropertyBoolean(getElement(), "disabled", !enabled);
m_openClose.setEnabled(enabled);
if (enabled) {
removeStyleName(CSS.selectBoxDisabled());
} else {
addStyleName(CSS.selectBoxDisabled());
}
}
/**
* @see com.alkacon.geranium.client.ui.input.I_FormWidget#setErrorMessage(java.lang.String)
*/
public void setErrorMessage(String errorMessage) {
m_error.setText(errorMessage);
}
/**
* Sets the form value of this select box.
*
* @param value the new value
*/
public void setFormValue(Object value) {
if (value == null) {
value = "";
}
if (!"".equals(value) && !m_selectCells.containsKey(value)) {
OPTION option = createUnknownOption((String)value);
if (option != null) {
addOption(option);
}
}
if (value instanceof String) {
String strValue = (String)value;
this.onValueSelect(strValue);
}
}
/**
* @see com.alkacon.geranium.client.ui.input.I_FormWidget#setFormValueAsString(java.lang.String)
*/
public void setFormValueAsString(String formValue) {
setFormValue(formValue);
}
/**
* @see com.alkacon.geranium.client.ui.I_Truncable#truncate(java.lang.String, int)
*/
public void truncate(String textMetricsPrefix, int widgetWidth) {
m_textMetricsPrefix = textMetricsPrefix;
m_widgetWidth = widgetWidth;
truncateOpener(textMetricsPrefix, widgetWidth);
}
/**
* Internal helper method for clearing the select options.
*/
protected void clearItems() {
m_selectCells.clear();
m_selector.clear();
m_selectedValue = null;
}
/**
* Internal method which is called when the selector is closed.
*/
protected void close() {
if (!m_enabled) {
return;
}
m_openClose.setDown(false);
m_popup.hide();
m_selectBoxState.setValue(I_LayoutBundle.INSTANCE.generalCss().cornerAll());
}
/**
* Internal method to create a select option for an unknown value.
*
* @param value the value for which to create the option
*
* @return the new option
*/
protected abstract OPTION createUnknownOption(String value);
/**
* Handle clicks on the opener.
*
* @param e the click event
*/
@UiHandler("m_opener")
protected void doClickOpener(ClickEvent e) {
toggleOpen();
}
/**
* Initializes the selector width.
*/
protected void initMaxCellWidth() {
m_maxCellWidth = m_opener.getOffsetWidth() - 2 /*border*/;
for (Widget widget : m_selector) {
if (widget instanceof A_SelectCell) {
int cellWidth = ((A_SelectCell)widget).getRequiredWidth();
DebugLog.getInstance().printLine(
"Measure for " + ((A_SelectCell)widget).getElement().getInnerText() + ": " + cellWidth);
if (cellWidth > m_maxCellWidth) {
m_maxCellWidth = cellWidth;
}
}
}
}
/**
* The implementation of this method should initialize the opener of the select box.
*/
protected abstract void initOpener();
/**
* Internal handler method which is called when a new value is selected.
*
* @param value the new value
*/
protected void onValueSelect(String value) {
String oldValue = m_selectedValue;
selectValue(value);
if ((oldValue == null) || !oldValue.equals(value)) {
// fire value change only if the the value really changed
ValueChangeEvent. fire(this, value);
}
}
/**
* Internal method which is called when the selector is opened.
*/
protected void open() {
if (!m_enabled) {
return;
}
m_openClose.setDown(true);
if (m_maxCellWidth == 0) {
initMaxCellWidth();
}
int selectorWidth = m_maxCellWidth;
// should not be any wider than the actual window
int windowWidth = Window.getClientWidth();
if (m_maxCellWidth > windowWidth) {
selectorWidth = windowWidth - 10;
}
m_popup.setWidth(selectorWidth + "px");
m_popup.show();
int panelTop = m_panel.getElement().getAbsoluteTop();
int openerHeight = DomUtil.getCurrentStyleInt(m_opener.getElement(), DomUtil.Style.height);
int popupHeight = m_popup.getOffsetHeight();
int dx = 0;
if (selectorWidth > (m_opener.getOffsetWidth() - 2)) {
int spaceOnTheRight = (Window.getClientWidth() + Window.getScrollLeft())
- m_opener.getAbsoluteLeft()
- selectorWidth
- 2;
dx = spaceOnTheRight < 0 ? spaceOnTheRight : 0;
}
if (((Window.getClientHeight() - (panelTop + openerHeight)) < popupHeight) && (panelTop > popupHeight)) {
DomUtil.positionElement(m_popup.getElement(), m_panel.getElement(), dx, -(popupHeight - 2));
m_selectBoxState.setValue(I_LayoutBundle.INSTANCE.generalCss().cornerBottom());
m_selectorState.setValue(I_LayoutBundle.INSTANCE.generalCss().cornerTop());
} else {
DomUtil.positionElement(m_popup.getElement(), m_panel.getElement(), dx, openerHeight);
m_selectBoxState.setValue(I_LayoutBundle.INSTANCE.generalCss().cornerTop());
m_selectorState.setValue(I_LayoutBundle.INSTANCE.generalCss().cornerBottom());
}
// m_selectBoxState.setValue(CSS.selectBoxOpen());
}
/**
* Abstract method whose implementation should truncate the opener widget(s).
*
* @param prefix the text metrics prefix
* @param width the widget width
*/
protected abstract void truncateOpener(String prefix, int width);
/**
* The implementation of this method should update the opener when a new value is selected by the user.
*
* @param newValue the value selected by the user
*/
protected abstract void updateOpener(String newValue);
/**
* Helper method for adding event handlers for a 'hover' effect to the opener.
*
* @param panel the opener
*/
private void addHoverHandlers(FocusPanel panel) {
final StyleVariable hoverVar = new StyleVariable(panel);
hoverVar.setValue(CSS.openerNoHover());
panel.addMouseOverHandler(new MouseOverHandler() {
/**
* @see com.google.gwt.event.dom.client.MouseOverHandler#onMouseOver(com.google.gwt.event.dom.client.MouseOverEvent)
*/
public void onMouseOver(MouseOverEvent event) {
hoverVar.setValue(CSS.openerHover());
}
});
panel.addMouseOutHandler(new MouseOutHandler() {
/**
* @see com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google.gwt.event.dom.client.MouseOutEvent)
*/
public void onMouseOut(MouseOutEvent event) {
hoverVar.setValue(CSS.openerNoHover());
}
});
}
/**
* Initializes the event handlers of a select cell.
*
* @param cell the select cell whose event handlers should be initialized
*/
private void initSelectCell(final A_SelectCell cell) {
cell.registerDomHandler(new ClickHandler() {
/**
* @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
*/
public void onClick(ClickEvent e) {
onValueSelect(cell.getValue());
cell.removeStyleName(CSS.selectHover());
}
}, ClickEvent.getType());
cell.registerDomHandler(new MouseOverHandler() {
/**
* @see com.google.gwt.event.dom.client.MouseOverHandler#onMouseOver(com.google.gwt.event.dom.client.MouseOverEvent)
*/
public void onMouseOver(MouseOverEvent e) {
cell.addStyleName(CSS.selectHover());
}
}, MouseOverEvent.getType());
cell.registerDomHandler(new MouseOutHandler() {
/**
* @see com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google.gwt.event.dom.client.MouseOutEvent)
*/
public void onMouseOut(MouseOutEvent e) {
cell.removeStyleName(CSS.selectHover());
}
}, MouseOutEvent.getType());
}
/**
* Toggles the state of the selector popup between 'open' and 'closed'.
*/
private void toggleOpen() {
if (!m_enabled) {
return;
}
if (m_popup.isShowing()) {
close();
} else {
open();
}
}
}