package com.eas.widgets.boxes; import java.util.Date; import com.google.gwt.core.shared.GWT; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Display; import com.google.gwt.dom.client.Style.Overflow; import com.google.gwt.dom.client.Style.Position; import com.google.gwt.dom.client.Style.TextAlign; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.Style.VerticalAlign; import com.google.gwt.dom.client.Style.Visibility; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.logical.shared.HasValueChangeHandlers; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HasValue; import com.google.gwt.user.client.ui.IntegerBox; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; public class TimePicker extends Composite implements HasValue<Date>, HasValueChangeHandlers<Date> { protected FlowPanel timePickerContainer = new FlowPanel(); FlowPanel dateBlock = new FlowPanel(); protected FlowPanel widgetContainer = new FlowPanel(); protected FlowPanel verticalAlign = new FlowPanel(); protected SimplePanel btnUpHour = new SimplePanel(); protected SimplePanel btnDownHour = new SimplePanel(); protected IntegerBox txtHour = new IntegerBox(); protected SimplePanel btnUpMinute = new SimplePanel(); protected SimplePanel btnDownMinute = new SimplePanel(); protected IntegerBox txtMinute = new IntegerBox(); protected SimplePanel btnUpSecond = new SimplePanel(); protected SimplePanel btnDownSecond = new SimplePanel(); protected IntegerBox txtSecond = new IntegerBox(); FlowPanel hCenter = new FlowPanel(); SimplePanel separatorUp1 = new SimplePanel(); SimplePanel separatorUp2 = new SimplePanel(); SimplePanel separatorTime1 = new SimplePanel(); SimplePanel separatorTime2 = new SimplePanel(); SimplePanel separatorDown1 = new SimplePanel(); SimplePanel separatorDown2 = new SimplePanel(); private int hour; private int minute; private int second; private int maxHourVal = 23; private int maxMinuteVal = 59; private int maxSecondVal = maxMinuteVal; private int componentWidth = 25; private int componentWidthRelative = 25; private int separatorWidthRelative = 5; private int separatorWidth = 10; private int componentHeight = 20; private int relativeWidth = 90; private boolean showing; private int marginLeft = 2; private int marginRight = 2; private Date currentDate; protected static TimePickerConstants constants = GWT.create(TimePickerConstants.class); public TimePicker() { super(); dateBlock.getElement().setInnerText(constants.date()); dateBlock.getElement().setClassName("time-picker-date"); widgetContainer.add(dateBlock); FlowPanel upperBtnBlock = new FlowPanel(); upperBtnBlock.add(btnUpHour); upperBtnBlock.add(separatorUp1); upperBtnBlock.add(btnUpMinute); upperBtnBlock.add(separatorUp2); upperBtnBlock.add(btnUpSecond); widgetContainer.add(upperBtnBlock); FlowPanel textBlock = new FlowPanel(); textBlock.add(txtHour); textBlock.add(separatorTime1); textBlock.add(txtMinute); textBlock.add(separatorTime2); textBlock.add(txtSecond); textBlock.getElement().getStyle().setDisplay(Style.Display.BLOCK); widgetContainer.add(textBlock); FlowPanel lowerBtnBlock = new FlowPanel(); lowerBtnBlock.add(btnDownHour); lowerBtnBlock.add(separatorDown1); lowerBtnBlock.add(btnDownMinute); lowerBtnBlock.add(separatorDown2); lowerBtnBlock.add(btnDownSecond); widgetContainer.add(lowerBtnBlock); hCenter.add(widgetContainer); hCenter.add(verticalAlign); timePickerContainer.add(hCenter); initWidget(timePickerContainer); setAbsolute(); btnUpHour.addDomHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { hour = updateUpValue(txtHour, hour, maxHourVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }, ClickEvent.getType()); btnUpMinute.addDomHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { minute = updateUpValue(txtMinute, minute, maxMinuteVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }, ClickEvent.getType()); btnUpSecond.addDomHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { second = updateUpValue(txtSecond, second, maxSecondVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }, ClickEvent.getType()); btnDownHour.addDomHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { hour = updateDownValue(txtHour, hour, maxHourVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }, ClickEvent.getType()); btnDownMinute.addDomHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { minute = updateDownValue(txtMinute, minute, maxMinuteVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }, ClickEvent.getType()); btnDownSecond.addDomHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { second = updateDownValue(txtSecond, second, maxSecondVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }, ClickEvent.getType()); txtHour.addValueChangeHandler(new ValueChangeHandler<Integer>() { @Override public void onValueChange(ValueChangeEvent<Integer> event) { hour = updateValue(txtHour, hour, maxHourVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }); txtMinute.addValueChangeHandler(new ValueChangeHandler<Integer>() { @Override public void onValueChange(ValueChangeEvent<Integer> event) { minute = updateValue(txtMinute, minute, maxMinuteVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }); txtSecond.addValueChangeHandler(new ValueChangeHandler<Integer>() { @Override public void onValueChange(ValueChangeEvent<Integer> event) { second = updateValue(txtSecond, second, maxSecondVal); ValueChangeEvent.fire(TimePicker.this, getValue()); } }); txtHour.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if (event.isUpArrow()) { hour = updateUpValue(txtHour, hour, maxHourVal); ValueChangeEvent.fire(TimePicker.this, getValue()); return; } if (event.isDownArrow()) { hour = updateDownValue(txtHour, hour, maxHourVal); ValueChangeEvent.fire(TimePicker.this, getValue()); return; } } }); txtMinute.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if (event.isUpArrow()) { minute = updateUpValue(txtMinute, minute, maxMinuteVal); ValueChangeEvent.fire(TimePicker.this, getValue()); return; } if (event.isDownArrow()) { minute = updateDownValue(txtMinute, minute, maxMinuteVal); ValueChangeEvent.fire(TimePicker.this, getValue()); return; } } }); txtSecond.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if (event.isUpArrow()) { second = updateUpValue(txtSecond, second, maxSecondVal); ValueChangeEvent.fire(TimePicker.this, getValue()); return; } if (event.isDownArrow()) { second = updateDownValue(txtSecond, second, maxSecondVal); ValueChangeEvent.fire(TimePicker.this, getValue()); return; } } }); } public void setAbsolute() { timePickerContainer.getElement().getStyle().setPosition(Position.ABSOLUTE); timePickerContainer.getElement().getStyle().setHeight(0, Style.Unit.PX); timePickerContainer.getElement().getStyle().setProperty("width", "auto"); timePickerContainer.getElement().getStyle().setBottom(0, Style.Unit.PCT); timePickerContainer.getElement().getStyle().setOverflow(Overflow.HIDDEN); setStyleName(timePickerContainer.getElement(), "time-picker"); verticalAlign.getElement().getStyle().setHeight(100, Style.Unit.PCT); verticalAlign.getElement().getStyle().setWidth(0, Style.Unit.PCT); widgetContainer.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); verticalAlign.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); dateBlock.getElement().getStyle().setDisplay(Display.BLOCK); dateBlock.getElement().getStyle().setTextAlign(TextAlign.CENTER); dateBlock.getElement().getStyle().setMarginBottom(10, Style.Unit.PCT); txtHour.getElement().getStyle().setWidth(componentWidth, Style.Unit.PCT); txtHour.getElement().getStyle().setMarginLeft(marginLeft, Style.Unit.PX); txtHour.getElement().getStyle().setTextAlign(TextAlign.CENTER); txtHour.setStyleName("time-picker-text"); txtMinute.getElement().getStyle().setWidth(componentWidth, Style.Unit.PCT); txtMinute.getElement().getStyle().setTextAlign(TextAlign.CENTER); txtMinute.setStyleName("time-picker-text"); txtSecond.getElement().getStyle().setTextAlign(TextAlign.CENTER); txtSecond.getElement().getStyle().setWidth(componentWidth, Style.Unit.PCT); txtSecond.setStyleName("time-picker-text"); txtSecond.getElement().getStyle().setMarginRight(marginRight, Style.Unit.PX); widgetContainer.getElement().getStyle().setVerticalAlign(VerticalAlign.MIDDLE); verticalAlign.getElement().getStyle().setVerticalAlign(VerticalAlign.MIDDLE); hCenter.getElement().getStyle().setHeight(100, Style.Unit.PCT); hCenter.getElement().getStyle().setDisplay(Display.BLOCK); hCenter.getElement().getStyle().setProperty("marginLeft", "auto"); hCenter.getElement().getStyle().setProperty("marginRight", "auto"); setButtonStyleAbsolute(btnUpHour, "time-picker-up"); btnUpHour.getElement().getStyle().setMarginLeft(marginLeft, Style.Unit.PX); setButtonStyleAbsolute(btnUpMinute, "time-picker-up"); setButtonStyleAbsolute(btnUpSecond, "time-picker-up"); btnUpSecond.getElement().getStyle().setMarginRight(marginRight, Style.Unit.PX); setButtonStyleAbsolute(btnDownHour, "time-picker-down"); btnDownHour.getElement().getStyle().setMarginLeft(marginLeft, Style.Unit.PX); setButtonStyleAbsolute(btnDownMinute, "time-picker-down"); setButtonStyleAbsolute(btnDownSecond, "time-picker-down"); btnDownSecond.getElement().getStyle().setMarginRight(marginRight, Style.Unit.PX); setSeparatorStyle(separatorUp1, true); setSeparatorStyle(separatorUp2, true); setSeparatorStyle(separatorTime1, false); setSeparatorStyle(separatorTime2, false); setSeparatorStyle(separatorDown1, true); setSeparatorStyle(separatorDown2, true); } public void setRelative() { timePickerContainer.getElement().getStyle().setPosition(Position.RELATIVE); timePickerContainer.getElement().getStyle().setHeight(0, Style.Unit.PX); timePickerContainer.getElement().getStyle().setBottom(0, Style.Unit.PCT); timePickerContainer.getElement().getStyle().setOverflow(Overflow.HIDDEN); setStyleName(timePickerContainer.getElement(), "time-picker"); timePickerContainer.getElement().getStyle().setWidth(relativeWidth, Style.Unit.PX); verticalAlign.getElement().getStyle().setHeight(100, Style.Unit.PCT); verticalAlign.getElement().getStyle().setWidth(0, Style.Unit.PCT); widgetContainer.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); verticalAlign.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); dateBlock.getElement().getStyle().setDisplay(Display.NONE); txtHour.getElement().getStyle().setWidth(componentWidthRelative, Style.Unit.PX); txtHour.getElement().getStyle().setMarginLeft(marginLeft, Style.Unit.PX); txtHour.getElement().getStyle().setTextAlign(TextAlign.CENTER); txtHour.setStyleName("time-picker-text"); txtMinute.getElement().getStyle().setWidth(componentWidthRelative, Style.Unit.PX); txtMinute.getElement().getStyle().setTextAlign(TextAlign.CENTER); txtMinute.setStyleName("time-picker-text"); txtSecond.getElement().getStyle().setTextAlign(TextAlign.CENTER); txtSecond.getElement().getStyle().setWidth(componentWidthRelative, Style.Unit.PX); txtSecond.setStyleName("time-picker-text"); txtSecond.getElement().getStyle().setMarginRight(marginRight, Style.Unit.PX); widgetContainer.getElement().getStyle().setVerticalAlign(VerticalAlign.MIDDLE); verticalAlign.getElement().getStyle().setVerticalAlign(VerticalAlign.MIDDLE); hCenter.getElement().getStyle().setHeight(100, Style.Unit.PCT); hCenter.getElement().getStyle().setDisplay(Display.BLOCK); hCenter.getElement().getStyle().setProperty("marginLeft", "auto"); hCenter.getElement().getStyle().setProperty("marginRight", "auto"); setButtonStyleRelative(btnUpHour, "time-picker-up"); btnUpHour.getElement().getStyle().setMarginLeft(marginLeft, Style.Unit.PX); setButtonStyleRelative(btnUpMinute, "time-picker-up"); setButtonStyleRelative(btnUpSecond, "time-picker-up"); btnUpSecond.getElement().getStyle().setMarginRight(marginRight, Style.Unit.PX); setButtonStyleRelative(btnDownHour, "time-picker-down"); btnDownHour.getElement().getStyle().setMarginLeft(marginLeft, Style.Unit.PX); setButtonStyleRelative(btnDownMinute, "time-picker-down"); setButtonStyleRelative(btnDownSecond, "time-picker-down"); btnDownSecond.getElement().getStyle().setMarginRight(marginRight, Style.Unit.PX); setSeparatorStyleRelative(separatorUp1, true); setSeparatorStyleRelative(separatorUp2, true); setSeparatorStyleRelative(separatorTime1, false); setSeparatorStyleRelative(separatorTime2, false); setSeparatorStyleRelative(separatorDown1, true); setSeparatorStyleRelative(separatorDown2, true); setHeight(100, Style.Unit.PCT); } private void setHeight(int aHeight, Unit aUnit) { timePickerContainer.getElement().getStyle().setHeight(aHeight, aUnit); } public void show() { DateTimeFormat fmt = DateTimeFormat.getFormat("dd:MM:yyyy"); if (currentDate == null) { dateBlock.getElement().setInnerText(constants.date()); } else { dateBlock.getElement().setInnerText(constants.date() + fmt.format(currentDate)); } setHeight(100, Style.Unit.PCT); showing = true; } public void hide() { setHeight(0, Style.Unit.PCT); showing = false; } public boolean isShowing() { return showing; } public Date getValue() { return new Date(hour * 60 * 60 * 1000 + minute * 60 * 1000 + second * 1000); } private int updateValue(IntegerBox aInput, int aVal, int maxVal) { if (aInput.getValue() != null) { int val = aInput.getValue(); if (val > maxVal) { val = maxVal; aInput.setValue(val); } if (val < 0) { val = 0; aInput.setValue(val); } aVal = val; } return aVal; } private int updateUpValue(IntegerBox aInput, int aVal, int maxVal) { aVal += 1; if (aVal > maxVal) { aVal = 0; } aInput.setValue(aVal); return aVal; } private int updateDownValue(IntegerBox aInput, int aVal, int maxVal) { aVal -= 1; if (aVal < 0) { aVal = maxVal; } aInput.setValue(aVal); return aVal; } private void setButtonStyleAbsolute(Widget aWidget, String divStyleName) { aWidget.getElement().getStyle().setWidth(componentWidth, Style.Unit.PCT); aWidget.getElement().getStyle().setHeight(componentHeight, Style.Unit.PX); aWidget.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); aWidget.getElement().addClassName(divStyleName); } private void setButtonStyleRelative(Widget aWidget, String divStyleName) { aWidget.getElement().getStyle().setWidth(componentWidthRelative, Style.Unit.PX); aWidget.getElement().getStyle().setHeight(componentHeight, Style.Unit.PX); aWidget.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); aWidget.getElement().addClassName(divStyleName); } private void setSeparatorStyle(Widget separator, boolean invisible) { separator.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); separator.getElement().getStyle().setWidth(separatorWidth, Style.Unit.PCT); separator.getElement().getStyle().setTextAlign(TextAlign.CENTER); separator.getElement().setInnerText(":"); separator.setStyleName("time-picker-separator"); if (invisible) { separator.getElement().getStyle().setVisibility(Visibility.HIDDEN); } } private void setSeparatorStyleRelative(Widget separator, boolean invisible) { separator.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); separator.getElement().getStyle().setWidth(separatorWidthRelative, Style.Unit.PX); separator.getElement().getStyle().setTextAlign(TextAlign.CENTER); separator.getElement().setInnerText(":"); separator.setStyleName("time-picker-separator"); if (invisible) { separator.getElement().getStyle().setVisibility(Visibility.HIDDEN); } } @Override public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Date> handler) { return addHandler(handler, ValueChangeEvent.getType()); } public void setValue(Date aDate) { setValue(aDate, false); } @Override public void setValue(Date value, boolean fireEvents) { currentDate = value; if (value == null) { hour = 0; minute = 0; second = 0; } else { hour = value.getHours(); minute = value.getMinutes(); second = value.getSeconds(); } txtHour.setValue(hour); txtMinute.setValue(minute); txtSecond.setValue(second); if (fireEvents) { ValueChangeEvent.fire(TimePicker.this, getValue()); } } }