View Javadoc

1   /**********************************************
2    * Copyright (C) 2011 Lukas Laag
3    * This file is part of svgreal.
4    * 
5    * svgreal is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * svgreal is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with svgreal.  If not, see http://www.gnu.org/licenses/
17   **********************************************/
18  package org.vectomatic.svg.edit.client.gxt.form;
19  
20  import com.extjs.gxt.ui.client.GXT;
21  import com.extjs.gxt.ui.client.core.El;
22  import com.extjs.gxt.ui.client.event.ComponentEvent;
23  import com.extjs.gxt.ui.client.event.DragEvent;
24  import com.extjs.gxt.ui.client.event.Events;
25  import com.extjs.gxt.ui.client.event.Listener;
26  import com.extjs.gxt.ui.client.event.SliderEvent;
27  import com.extjs.gxt.ui.client.widget.ComponentHelper;
28  import com.extjs.gxt.ui.client.widget.Slider;
29  import com.extjs.gxt.ui.client.widget.form.Field;
30  import com.google.gwt.dom.client.Document;
31  import com.google.gwt.user.client.DOM;
32  import com.google.gwt.user.client.Element;
33  
34  /**
35   * Float slider field
36   * @author laaglu
37   */
38  public class FloatSliderField extends Field<Float> {
39  	/**
40  	 * Custom slider class. It fires extra event which the binding catches so
41  	 * that the binding will not create a command until the thumb is released
42  	 * or the slider is clicked.
43  	 * @author laaglu
44  	 */
45  	private static class FloatSlider extends Slider {
46  		@Override
47  		protected void onClick(ComponentEvent ce) {
48  			fireEvent(Events.OnClick, ce);
49  			super.onClick(ce);
50  		}
51  		
52  		@Override
53  		protected void onDragEnd(DragEvent de) {
54  			fireEvent(Events.DragEnd, de);
55  			super.onDragEnd(de);
56  		}
57  	}
58  
59  	private float floatMin;
60  	private float floatMax;
61  	private FloatSlider slider;
62  	protected El hidden;
63  	protected Listener<SliderEvent> listener;
64  
65  	/**
66  	 * Creates a new slider field.
67  	 * @param slider
68  	 * the slider to be wrapped.
69  	 */
70  	public FloatSliderField(float floatMin, float floatMax) {
71  		super();
72  		setFireChangeEventOnSetValue(true);
73  		this.floatMin = floatMin;
74  		this.floatMax = floatMax;
75  		FloatSlider slider = new FloatSlider();
76  		slider.setMinValue(0);
77  		slider.setMaxValue(100);
78  		slider.setIncrement(1);
79  		slider.setClickToChange(true);
80  		setSlider(slider);
81  	}
82  
83  	/**
84  	 * Returns the slider component.
85  	 * @return the slider.
86  	 */
87  	public Slider getSlider() {
88  		return slider;
89  	}
90  
91  	@Override
92  	public void setReadOnly(boolean readOnly) {
93  		super.setReadOnly(readOnly);
94  		if (readOnly) {
95  			slider.disable();
96  		} else if (!readOnly && isEnabled()) {
97  			slider.enable();
98  		}
99  	}
100 
101 	/**
102 	 * Sets the slider component.
103 	 * @param slider
104 	 * the slider
105 	 */
106 	public void setSlider(FloatSlider slider) {
107 		assertPreRender();
108 		if (listener == null) {
109 			listener = new Listener<SliderEvent>() {
110 				public void handleEvent(SliderEvent be) {
111 					if (rendered) {
112 						updateHiddenField();
113 					}
114 					int intValue = FloatSliderField.this.slider.getValue();
115 					float modelValue = floatMin + (intValue / (float)((FloatSliderField.this.slider.getMaxValue() - FloatSliderField.this.slider.getMinValue()))) * (floatMax - floatMin);
116 					FloatSliderField.super.setValue(modelValue);
117 				}
118 			};
119 		}
120 		if (this.slider != slider) {
121 			if (this.slider != null) {
122 				ComponentHelper.removeFromParent(this.slider);
123 				this.slider.removeListener(Events.Change, listener);
124 			}
125 			this.slider = slider;
126 			slider.getFocusSupport().setIgnore(true);
127 			ComponentHelper.setParent(this, slider);
128 			slider.addListener(Events.Change, listener);
129 		}
130 	}
131 	
132 	@Override
133 	public Float getValue() {
134 		return value;
135 	}
136 	
137 	@Override
138 	public void setValue(Float value) {
139 		if (value == null) {
140 			int min = slider.getMinValue();
141 			slider.setValue(min);
142 			super.setValue((float)min);
143 		} else {
144 			int sliderValue = slider.getMinValue() + (int)((slider.getMaxValue() - slider.getMinValue()) * (value - floatMin) / (floatMax - floatMin));
145 			slider.setValue(sliderValue);
146 			super.setValue(value);
147 		}
148 	}
149 
150 	@Override
151 	protected void afterRender() {
152 		super.afterRender();
153 		updateHiddenField();
154 
155 		El elem = findLabelElement();
156 		if (elem != null) {
157 			elem.dom.setAttribute("for", slider.getId());
158 		}
159 	}
160 
161 	@Override
162 	protected void doAttachChildren() {
163 		super.doAttachChildren();
164 		ComponentHelper.doAttach(slider);
165 	}
166 
167 	@Override
168 	protected void doDetachChildren() {
169 		super.doDetachChildren();
170 		ComponentHelper.doDetach(slider);
171 	}
172 
173 	@Override
174 	protected El getFocusEl() {
175 		return slider.getFocusEl();
176 	}
177 
178 	@Override
179 	protected El getInputEl() {
180 		return hidden;
181 	}
182 
183 	@Override
184 	protected void onDisable() {
185 		super.onDisable();
186 		slider.disable();
187 	}
188 
189 	@Override
190 	protected void onEnable() {
191 		super.onEnable();
192 		if (!readOnly) {
193 			slider.enable();
194 		}
195 	}
196 
197 	@Override
198 	protected void onRender(Element parent, int index) {
199 		setElement(DOM.createDiv(), parent, index);
200 
201 		slider.render(getElement());
202 		hidden = new El((Element) Document.get().createHiddenInputElement().cast());
203 		getElement().appendChild(hidden.dom);
204 
205 		if (GXT.isIE) {
206 			el().makePositionable();
207 		}
208 
209 		super.onRender(parent, index);
210 	}
211 
212 	@Override
213 	protected void onResize(int width, int height) {
214 		if (rendered) {
215 			if (slider.isVertical()) {
216 				slider.setHeight(height);
217 			} else {
218 				slider.setWidth(width);
219 			}
220 		}
221 		super.onResize(width, height);
222 	}
223 
224 	protected void updateHiddenField() {
225 		if (rendered) {
226 			hidden.setValue(slider.getValue() + "");
227 		}
228 	}
229 }