package org.geogebra.web.web.gui.util; import org.geogebra.web.html5.awt.GDimensionW; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.HasChangeHandlers; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; 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.user.client.ui.FocusWidget; import com.google.gwt.user.client.ui.HasValue; /** * Slider widget that allows Double values * * parts of the code copied from {@link org.geogebra.web.html5.gui.util.Slider} (which * can only be used for Integers) * */ public class SliderW extends FocusWidget implements HasChangeHandlers, HasValue<Double>, MouseDownHandler, MouseUpHandler, MouseMoveHandler { private Element range; private boolean valueChangeHandlerInitialized; protected Double valueOnDragStart; public SliderW(double min, double max) { range = Document.get().createElement("input"); range.setAttribute("type", "range"); range.setAttribute("min", String.valueOf(min)); range.setAttribute("max", String.valueOf(max)); setRangeValue(range, String.valueOf(min)); setElement(range); addMouseDownHandler(this); addMouseMoveHandler(this); addMouseUpHandler(this); } private native void setRangeValue(Element range, String value) /*-{ range.value = value; }-*/; @Override public Double getValue() { return Double.valueOf(getRangeValue(range)); } private native String getRangeValue(Element range1) /*-{ return range1.value; }-*/; public void setMinimum(double min) { range.setAttribute("min", String.valueOf(min)); } public void setMaximum(double max) { range.setAttribute("max", String.valueOf(max)); } public void setMajorTickSpacing(double step) { range.setAttribute("step", String.valueOf(step)); } public void setMinorTickSpacing(double step) { range.setAttribute("step", String.valueOf(step)); } public GDimensionW getPreferredSize() { return new GDimensionW(100, 10); } @Override public HandlerRegistration addValueChangeHandler( ValueChangeHandler<Double> handler) { if (!valueChangeHandlerInitialized) { valueChangeHandlerInitialized = true; addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { ValueChangeEvent.fire(SliderW.this, getValue()); } }); } return addHandler(handler, ValueChangeEvent.getType()); } @Override public void setValue(Double value) { setValue(value, false); } @Override public void setValue(Double value, boolean fireEvents) { setSliderValue(String.valueOf(value)); } private void setSliderValue(String value) { setRangeValue(range, value); } @Override public HandlerRegistration addChangeHandler(ChangeHandler handler) { return addDomHandler(handler, ChangeEvent.getType()); } @Override public void onMouseUp(MouseUpEvent event) { ValueChangeEvent.fireIfNotEqual(this, valueOnDragStart, getValue()); valueOnDragStart = null; } @Override public void onMouseDown(MouseDownEvent event) { event.stopPropagation(); valueOnDragStart = getValue(); } @Override public void onMouseMove(MouseMoveEvent event) { // the event is only fired when the slider is dragged to a new value if (valueOnDragStart != null) { ValueChangeEvent.fireIfNotEqual(this, valueOnDragStart, getValue()); } event.stopPropagation(); } }