1 /***********************************************************************
2 	created:	25/4/2004
3 	author:		Paul D Turner
4 
5 	purpose:	Implements common parts of the Thumb base class widget
6 *************************************************************************/
7 /***************************************************************************
8  *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
9  *
10  *   Permission is hereby granted, free of charge, to any person obtaining
11  *   a copy of this software and associated documentation files (the
12  *   "Software"), to deal in the Software without restriction, including
13  *   without limitation the rights to use, copy, modify, merge, publish,
14  *   distribute, sublicense, and/or sell copies of the Software, and to
15  *   permit persons to whom the Software is furnished to do so, subject to
16  *   the following conditions:
17  *
18  *   The above copyright notice and this permission notice shall be
19  *   included in all copies or substantial portions of the Software.
20  *
21  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  *   OTHER DEALINGS IN THE SOFTWARE.
28  ***************************************************************************/
29 #include "CEGUI/widgets/Thumb.h"
30 #include "CEGUI/CoordConverter.h"
31 
32 // Start of CEGUI namespace section
33 namespace CEGUI
34 {
35 const String Thumb::EventNamespace("Thumb");
36 const String Thumb::WidgetTypeName("CEGUI/Thumb");
37 
38 /*************************************************************************
39 	Event name constants
40 *************************************************************************/
41 // generated internally by Window
42 const String Thumb::EventThumbPositionChanged( "ThumbPositionChanged" );
43 const String Thumb::EventThumbTrackStarted( "ThumbTrackStarted" );
44 const String Thumb::EventThumbTrackEnded( "ThumbTrackEnded" );
45 
46 
47 /*************************************************************************
48 	Constructor for Thumb objects
49 *************************************************************************/
Thumb(const String & type,const String & name)50 Thumb::Thumb(const String& type, const String& name) :
51 	PushButton(type, name),
52 	d_hotTrack(true),
53 	d_vertFree(false),
54 	d_horzFree(false),
55 	d_vertMin(0.0f),
56 	d_vertMax(1.0f),
57     d_horzMin(0.0f),
58 	d_horzMax(1.0f),
59     d_beingDragged(false)
60 {
61 	addThumbProperties();
62 }
63 
64 
65 /*************************************************************************
66 	Destructor for Thumb objects
67 *************************************************************************/
~Thumb(void)68 Thumb::~Thumb(void)
69 {
70 }
71 
72 
73 /*************************************************************************
74 	set the movement range of the thumb for the vertical axis.
75 *************************************************************************/
setVertRange(float min,float max)76 void Thumb::setVertRange(float min, float max)
77 {
78 	// ensure min <= max, swap if not.
79 	if (min > max)
80 	{
81 		float tmp = min;
82 		max = min;
83 		min = tmp;
84 	}
85 
86 	d_vertMax = max;
87 	d_vertMin = min;
88 
89 	// validate current position.
90 	const float cp = CoordConverter::asRelative(getYPosition(), getParentPixelSize().d_height);
91 
92 	if (cp < min)
93 	{
94 		setYPosition(cegui_reldim(min));
95 	}
96 	else if (cp > max)
97 	{
98 		setYPosition(cegui_reldim(max));
99 	}
100 
101 }
102 
103 /*************************************************************************
104 	set the movement range of the thumb for the vertical axis.
105 *************************************************************************/
setVertRange(const std::pair<float,float> & range)106 void Thumb::setVertRange(const std::pair<float, float> &range)
107 {
108 	setVertRange(range.first,range.second);
109 }
110 /*************************************************************************
111 	set the movement range of the thumb for the horizontal axis.
112 *************************************************************************/
setHorzRange(float min,float max)113 void Thumb::setHorzRange(float min, float max)
114 {
115     Sizef parentSize(getParentPixelSize());
116 
117 	// ensure min <= max, swap if not.
118 	if (min > max)
119 	{
120 		float tmp = min;
121 		max = min;
122 		min = tmp;
123 	}
124 
125 	d_horzMax = max;
126 	d_horzMin = min;
127 
128 	// validate current position.
129 	const float cp = CoordConverter::asAbsolute(getXPosition(), parentSize.d_width);
130 
131 	if (cp < min)
132 	{
133 		setXPosition(cegui_absdim(min));
134 	}
135 	else if (cp > max)
136 	{
137 		setXPosition(cegui_absdim(max));
138 	}
139 
140 }
141 /*************************************************************************
142 	set the movement range of the thumb for the horizontal axis.
143 *************************************************************************/
setHorzRange(const std::pair<float,float> & range)144 void Thumb::setHorzRange(const std::pair<float, float> &range)
145 {
146 	setHorzRange(range.first,range.second);
147 }
148 
149 
150 /*************************************************************************
151 	event triggered internally when the position of the thumb
152 *************************************************************************/
onThumbPositionChanged(WindowEventArgs & e)153 void Thumb::onThumbPositionChanged(WindowEventArgs& e)
154 {
155 	fireEvent(EventThumbPositionChanged, e, EventNamespace);
156 }
157 
158 
159 /*************************************************************************
160 	Handler triggered when the user begins to drag the thumb.
161 *************************************************************************/
onThumbTrackStarted(WindowEventArgs & e)162 void Thumb::onThumbTrackStarted(WindowEventArgs& e)
163 {
164 	fireEvent(EventThumbTrackStarted, e, EventNamespace);
165 }
166 
167 
168 /*************************************************************************
169 	Handler triggered when the thumb is released
170 *************************************************************************/
onThumbTrackEnded(WindowEventArgs & e)171 void Thumb::onThumbTrackEnded(WindowEventArgs& e)
172 {
173 	fireEvent(EventThumbTrackEnded, e, EventNamespace);
174 }
175 
176 
177 /*************************************************************************
178 	Handler for mouse movement events
179 *************************************************************************/
onMouseMove(MouseEventArgs & e)180 void Thumb::onMouseMove(MouseEventArgs& e)
181 {
182 	// default processing
183 	PushButton::onMouseMove(e);
184 
185 	// only react if we are being dragged
186 	if (d_beingDragged)
187 	{
188         Sizef parentSize(getParentPixelSize());
189 
190 		Vector2f delta;
191 		float hmin, hmax, vmin, vmax;
192 
193         delta = CoordConverter::screenToWindow(*this, e.position);
194 
195         hmin = d_horzMin;
196         hmax = d_horzMax;
197         vmin = d_vertMin;
198         vmax = d_vertMax;
199 
200 		// calculate amount of movement
201 		delta -= d_dragPoint;
202         delta.d_x /= parentSize.d_width;
203         delta.d_y /= parentSize.d_height;
204 
205 		//
206 		// Calculate new (pixel) position for thumb
207 		//
208 		UVector2 newPos(getPosition());
209 
210 		if (d_horzFree)
211 		{
212 			newPos.d_x.d_scale += delta.d_x;
213 
214 			// limit value to within currently set range
215 			newPos.d_x.d_scale = (newPos.d_x.d_scale < hmin) ? hmin : (newPos.d_x.d_scale > hmax) ? hmax : newPos.d_x.d_scale;
216 		}
217 
218 		if (d_vertFree)
219 		{
220 			newPos.d_y.d_scale += delta.d_y;
221 
222 			// limit new position to within currently set range
223 			newPos.d_y.d_scale = (newPos.d_y.d_scale < vmin) ? vmin : (newPos.d_y.d_scale > vmax) ? vmax : newPos.d_y.d_scale;
224 		}
225 
226 		// update thumb position if needed
227 		if (newPos != getPosition())
228 		{
229 			setPosition(newPos);
230 
231 			// send notification as required
232 			if (d_hotTrack)
233 			{
234 				WindowEventArgs args(this);
235 				onThumbPositionChanged(args);
236 			}
237 
238 		}
239 
240 	}
241 
242 	++e.handled;
243 }
244 
245 
246 /*************************************************************************
247 	Handler for mouse button down events
248 *************************************************************************/
onMouseButtonDown(MouseEventArgs & e)249 void Thumb::onMouseButtonDown(MouseEventArgs& e)
250 {
251 	// default processing
252 	PushButton::onMouseButtonDown(e);
253 
254 	if (e.button == LeftButton)
255 	{
256 		// initialise the dragging state
257 		d_beingDragged = true;
258 		d_dragPoint = CoordConverter::screenToWindow(*this, e.position);
259 
260 		// trigger tracking started event
261 		WindowEventArgs args(this);
262 		onThumbTrackStarted(args);
263 
264 		++e.handled;
265 	}
266 
267 }
268 
269 
270 /*************************************************************************
271 	Handler for event triggered when we lose capture of mouse input
272 *************************************************************************/
onCaptureLost(WindowEventArgs & e)273 void Thumb::onCaptureLost(WindowEventArgs& e)
274 {
275 	// default handling
276 	PushButton::onCaptureLost(e);
277 
278 	d_beingDragged = false;
279 
280 	// trigger tracking ended event
281 	WindowEventArgs args(this);
282 	onThumbTrackEnded(args);
283 
284 	// send notification whenever thumb is released
285 	onThumbPositionChanged(args);
286 }
287 
288 
289 /*************************************************************************
290 	Return a std::pair that describes the current range set for the
291 	vertical movement.
292 *************************************************************************/
getVertRange(void) const293 std::pair<float, float>	Thumb::getVertRange(void) const
294 {
295 	return std::make_pair(d_vertMin, d_vertMax);
296 }
297 
298 
299 /*************************************************************************
300 	Return a std::pair that describes the current range set for the
301 	horizontal movement.
302 *************************************************************************/
getHorzRange(void) const303 std::pair<float, float>	Thumb::getHorzRange(void) const
304 {
305 	return std::make_pair(d_horzMin, d_horzMax);
306 }
307 
308 
309 /*************************************************************************
310 	Add thumb specifiec properties
311 *************************************************************************/
addThumbProperties(void)312 void Thumb::addThumbProperties(void)
313 {
314     const String& propertyOrigin = WidgetTypeName;
315 
316     CEGUI_DEFINE_PROPERTY(Thumb, bool,
317         "HotTracked", "Property to get/set the state of the state of the 'hot-tracked' setting for the thumb."
318         "  Value is either \"true\" or \"false\".",
319         &Thumb::setHotTracked, &Thumb::isHotTracked, true
320     );
321 
322     typedef std::pair<float,float> range;
323 
324     CEGUI_DEFINE_PROPERTY(Thumb, range,
325         "VertRange", "Property to get/set the vertical movement range for the thumb.  Value is \"min:[float] max:[float]\".",
326         &Thumb::setVertRange, &Thumb::getVertRange, range(0.0f, 1.0f)
327     );
328 
329     CEGUI_DEFINE_PROPERTY(Thumb, range,
330         "HorzRange", "Property to get/set the horizontal movement range for the thumb.  Value is \"min:[float] max:[float]\".",
331         &Thumb::setHorzRange, &Thumb::getHorzRange, range(0.0f, 1.0f)
332     );
333 
334     CEGUI_DEFINE_PROPERTY(Thumb, bool,
335         "VertFree", "Property to get/set the state the setting to free the thumb vertically.  Value is either \"true\" or \"false\".",
336         &Thumb::setVertFree, &Thumb::isVertFree, false
337     );
338 
339     CEGUI_DEFINE_PROPERTY(Thumb, bool,
340         "HorzFree", "Property to get/set the state the setting to free the thumb horizontally.  Value is either \"true\" or \"false\".",
341         &Thumb::setHorzFree, &Thumb::isHorzFree, false
342     );
343 }
344 
345 //----------------------------------------------------------------------------//
banPropertiesForAutoWindow()346 void Thumb::banPropertiesForAutoWindow()
347 {
348     PushButton::banPropertiesForAutoWindow();
349 
350     banPropertyFromXML("VertRange");
351     banPropertyFromXML("HorzRange");
352     banPropertyFromXML("VertFree");
353     banPropertyFromXML("HorzFree");
354 }
355 
356 //----------------------------------------------------------------------------//
357 
358 } // End of  CEGUI namespace section
359