Harmonic Flow Framework (libhffwk)
Cross platform C++ 2D Game Engine Framework
SliderWidget.cpp
1 /*
2  Harmonic Flow Framework
3  Copyright (C) 2011-2018 Andreas Widen <andreas@harmonicflow.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SliderWidget.h"
22 #include "SliderListener.h"
23 #include "WidgetManager.h"
24 #include "platform/Graphics.h"
25 #include "platform/Image.h"
26 #include <assert.h>
27 
28 using namespace HFCore;
29 
30 #include "debug/CrtDbgNew.h"
31 
32 SliderWidget::SliderWidget(int32_hf id, SliderListener *listener, bool horizontal,
33  Image *sliderRailImage, int32_hf knobOffset, Image *sliderKnobImage,
34  Image *sliderKnobOverImage, Image *sliderKnobDownImage) :
35  mListener(listener),
36  mVal(0.0f),
37  mId(id),
38  mSliderRailImage(sliderRailImage),
39  mSliderKnobImage(sliderKnobImage),
40  mSliderKnobOverImage(sliderKnobOverImage),
41  mSliderKnobDownImage(sliderKnobDownImage),
42  mAtlasImage(NULL),
43  mSliderRailRect(Rect::ZERO()),
44  mSliderKnobRect(Rect::ZERO()),
45  mSliderKnobOverRect(Rect::ZERO()),
46  mSliderKnobDownRect(Rect::ZERO()),
47  mKnobOffset(knobOffset),
48  mHorizontal(horizontal)
49 {
50  assert(listener != NULL);
51  assert(sliderRailImage != NULL);
52  assert(sliderKnobImage != NULL);
53 
54  mDragging = false;
55  mMouseOverKnob = false;
56 
57  mSliderKnobPosX = 0;
58  mSliderKnobPosY = 0;
59  mSliderKnobWidth = mSliderKnobImage->getWidth();
60  mSliderKnobHeight = mSliderKnobImage->getHeight();
61 
62  mSliderRailWidth = mSliderRailImage->getWidth();
63  mSliderRailHeight = mSliderRailImage->getHeight();
64 
65  mUsingAtlas = false;
66 }
67 
68 SliderWidget::SliderWidget(int32_hf id, SliderListener *listener, bool horizontal,
69  int32_hf knobOffset, Image *sliderKnobImage, Image *sliderKnobOverImage,
70  Image *sliderKnobDownImage) :
71  mListener(listener),
72  mVal(0.0f),
73  mId(id),
75  mSliderKnobImage(sliderKnobImage),
76  mSliderKnobOverImage(sliderKnobOverImage),
77  mSliderKnobDownImage(sliderKnobDownImage),
79  mSliderRailRect(Rect::ZERO()),
80  mSliderKnobRect(Rect::ZERO()),
81  mSliderKnobOverRect(Rect::ZERO()),
82  mSliderKnobDownRect(Rect::ZERO()),
83  mKnobOffset(knobOffset),
84  mHorizontal(horizontal)
85 {
86  assert(listener != NULL);
87  assert(sliderKnobImage != NULL);
88 
89  mDragging = false;
90  mMouseOverKnob = false;
91 
92  mSliderKnobPosX = 0;
93  mSliderKnobPosY = 0;
94  mSliderKnobWidth = mSliderKnobImage->getWidth();
95  mSliderKnobHeight = mSliderKnobImage->getHeight();
96 
97  mSliderRailWidth = 0;
98  mSliderRailHeight = 0;
99  if (mSliderRailImage != NULL)
100  {
101  mSliderRailWidth = mSliderRailImage->getWidth();
102  mSliderRailHeight = mSliderRailImage->getHeight();
103  }
104 
105  mUsingAtlas = false;
106 }
107 
108 SliderWidget::SliderWidget(int32_hf id, SliderListener *listener, bool horizontal,
109  Image *atlasImage,
110  int32_hf knobOffset, const Rect &sliderRailRect, const
111  Rect &sliderKnobRect, const Rect &sliderKnobOverRect,
112  const Rect &sliderKnobDownRect) :
113  mListener(listener),
114  mVal(0.0f),
115  mId(id),
120  mAtlasImage(atlasImage),
121  mSliderRailRect(sliderRailRect),
122  mSliderKnobRect(sliderKnobRect),
123  mSliderKnobOverRect(sliderKnobOverRect),
124  mSliderKnobDownRect(sliderKnobDownRect),
125  mKnobOffset(knobOffset),
126  mHorizontal(horizontal)
127 {
128  assert(listener != NULL);
129  assert(atlasImage != NULL);
130  assert(sliderKnobRect != Rect::ZERO());
131 
132  mDragging = false;
133  mMouseOverKnob = false;
134 
135  mSliderKnobPosX = 0;
136  mSliderKnobPosY = 0;
137  mSliderKnobWidth = (int32_hf)mSliderKnobRect.getWidth();
138  mSliderKnobHeight = (int32_hf)mSliderKnobRect.getHeight();
139 
140  mSliderRailWidth = 0;
141  mSliderRailHeight = 0;
142  if (mSliderRailRect != Rect::ZERO())
143  {
144  mSliderRailWidth = (int32_hf)sliderRailRect.getWidth();
145  mSliderRailHeight = (int32_hf)sliderRailRect.getHeight();
146  }
147 
148  mUsingAtlas = true;
149 }
150 
152 {
153  mVal = val;
154  if (mVal < 0.0)
155  {
156  mVal = 0.0;
157  }
158  else if (mVal > 1.0)
159  {
160  mVal = 1.0;
161  }
162 }
163 
165 {
166  return true;
167 }
168 
170 {
171  // draw rail:
172  drawRail(g);
173 
174  // draw knob:
175  drawKnob(g);
176 }
177 
178 void SliderWidget::drawRail(Graphics *g)
179 {
180  if (mUsingAtlas)
181  {
182  if (mSliderRailRect != Rect::ZERO())
183  {
184  fp32_hf x = (mSliderRailWidth / 2) + mX;
185  fp32_hf y = (mSliderRailHeight / 2) + mY;
186  mRenderHelper.drawImage(g, mAtlasImage, mSliderRailRect, x, y, 1.0f,
189  }
190  }
191  else
192  {
193  if (mSliderRailImage != NULL)
194  {
195  fp32_hf x = (mSliderRailWidth / 2) + mX;
196  fp32_hf y = (mSliderRailHeight / 2) + mY;
197  mRenderHelper.drawImage(g, mSliderRailImage, x, y, 1.0f,
200  }
201  }
202 }
203 
204 void SliderWidget::drawKnob(Graphics *g)
205 {
206  // Start pos for knob concerning rendering.
207  mSliderKnobPosX = (mSliderKnobWidth / 2) + mX;
208  mSliderKnobPosY = (mSliderKnobHeight / 2) + mY;
209 
210  fp32_hf x, y = 0;
211  if (mHorizontal)
212  {
213  fp32_hf pos = (mWidth - mSliderKnobWidth) * mVal;
214  x = mSliderKnobPosX + pos;
215  y = mSliderKnobPosY;
216  }
217  else
218  {
219  fp32_hf pos = (mHeight - mSliderKnobHeight) * mVal;
220  x = mSliderKnobPosX;
221  y = mSliderKnobPosY + pos;
222  }
223 
224  if (mUsingAtlas)
225  {
226  Rect destRect;
227  Rect srcRect;
229  {
230  srcRect = mSliderKnobDownRect;
231  }
232  else if (mMouseOverKnob && mSliderKnobOverRect != Rect::ZERO())
233  {
234  srcRect = mSliderKnobOverRect;
235  }
236  else
237  {
238  srcRect = mSliderKnobRect;
239  }
240  mRenderHelper.drawImage(g, mAtlasImage, srcRect, x, y, 1.0f,
243  }
244  else
245  {
246  // Now draw knob
247  Rect destRect;
249  {
250  mRenderHelper.drawImage(g, mSliderKnobDownImage, x, y, 1.0f,
253  }
254  else if (mMouseOverKnob && mSliderKnobOverImage != NULL)
255  {
256  mRenderHelper.drawImage(g, mSliderKnobOverImage, x, y, 1.0f,
259  }
260  else
261  {
262  mRenderHelper.drawImage(g, mSliderKnobImage, x, y, 1.0f,
265  }
266  }
267 }
268 
269 bool SliderWidget::isOverKnob(fp32_hf x, fp32_hf y)
270 {
271  bool overKnob = false;
272  if (mHorizontal)
273  {
274  fp32_hf offsetX = (mSliderKnobPosX - mX) - mKnobOffset;
275  fp32_hf thumbX = (mWidth - mSliderKnobWidth) * mVal;
276  if ((x >= (thumbX - offsetX)) && (x < thumbX + offsetX))
277  {
278  overKnob = true;
279  }
280  else
281  {
282  overKnob = false;
283  }
284  }
285  else
286  {
287  fp32_hf offsetY = (mSliderKnobPosY - mY) - mKnobOffset;
288  fp32_hf thumbY = (mHeight - mSliderKnobHeight) * mVal;
289  if ((y >= (thumbY - offsetY)) && (y < thumbY + offsetY))
290  {
291  overKnob = true;
292  }
293  else
294  {
295  overKnob = false;
296  }
297  }
298  return overKnob;
299 }
300 
302 {
303  fp32_hf x = touch.x - mSliderKnobPosX;
304  fp32_hf y = touch.y - mSliderKnobPosY;
305 
306  if (isOverKnob(x, y))
307  {
308  mDragging = true;
309  }
310  else
311  {
312  if (mHorizontal)
313  {
314  // clicked on the bar, set position to mouse click
315  fp32_hf pos = x / (mWidth - mSliderKnobWidth);
316  setValue(pos);
318  }
319  else
320  {
321  // clicked on the bar, set position to mouse click
322  fp32_hf pos = y / (mHeight - mSliderKnobHeight);
323  setValue(pos);
325  }
326  }
327 }
328 
330 {
331  mDragging = false;
332 
333  fp32_hf x = touch.x - mSliderKnobPosX;
334  fp32_hf y = touch.y - mSliderKnobPosY;
335 
336  if (mHorizontal)
337  {
338  // clicked on the bar, set position to mouse click
339  mVal = x / (mWidth - mSliderKnobWidth);
340  }
341  else
342  {
343  // clicked on the bar, set position to mouse click
344  mVal = y / (mHeight - mSliderKnobHeight);
345  }
346 
347  // clamp
348  if (mVal > 1.0f)
349  {
350  mVal = 1.0f;
351  }
352  else if (mVal < 0.0f)
353  {
354  mVal = 0.0f;
355  }
356 
357  if (mListener)
358  {
361  }
362 }
363 
365 {
366  fp32_hf x = touch.x - mSliderKnobPosX;
367  fp32_hf y = touch.y - mSliderKnobPosY;
368 
369  if (mDragging)
370  {
371  fp32_hf oldVal = mVal;
372 
373  if (mHorizontal)
374  {
375  mVal = x / (mWidth - mSliderKnobWidth);
376  }
377  else
378  {
379  mVal = y / (mHeight - mSliderKnobHeight);
380  }
381 
382  if (mVal < 0.0)
383  {
384  mVal = 0.0;
385  }
386  if (mVal > 1.0)
387  {
388  mVal = 1.0;
389  }
390 
391  if (mVal != oldVal)
392  {
393  if (mListener)
394  {
397  }
398  }
399  }
400 }
401 
403 {
404  fp32_hf x = mouse.x - mSliderKnobPosX;
405  fp32_hf y = mouse.y - mSliderKnobPosY;
406 
407  if (mHorizontal)
408  {
409  fp32_hf offsetX = (mSliderKnobPosX - mX) - mKnobOffset;
410  fp32_hf thumbX = (mWidth - mSliderKnobWidth) * mVal;
411  if ((x >= (thumbX - offsetX)) && (x < thumbX + offsetX) && mIsOver)
412  {
413  mMouseOverKnob = true;
414  }
415  else
416  {
417  mMouseOverKnob = false;
418  }
419  }
420  else
421  {
422  fp32_hf offsetY = (mSliderKnobPosY - mY) - mKnobOffset;
423  fp32_hf thumbY = (mHeight - mSliderKnobHeight) * mVal;
424  if ((y >= (thumbY - offsetY)) && (y < thumbY + offsetY) && mIsOver)
425  {
426  mMouseOverKnob = true;
427  }
428  else
429  {
430  mMouseOverKnob = false;
431  }
432  }
433 
434  if (mDragging)
435  {
436  fp32_hf oldVal = mVal;
437 
438  if (mHorizontal)
439  {
440  mVal = x / (mWidth - mSliderKnobWidth);
441  }
442  else
443  {
444  mVal = y / (mHeight - mSliderKnobHeight);
445  }
446 
447  if (mVal < 0.0)
448  {
449  mVal = 0.0;
450  }
451  if (mVal > 1.0)
452  {
453  mVal = 1.0;
454  }
455 
456  if (mVal != oldVal)
457  {
458  if (mListener)
459  {
462  }
463  }
464  }
465 }
466 
468 {
469  fp32_hf x = mouse.x - mSliderKnobPosX;
470  fp32_hf y = mouse.y - mSliderKnobPosY;
471 
472  if (mMouseOverKnob)
473  {
474  mDragging = true;
475  }
476  else
477  {
478  if (mHorizontal)
479  {
480  // clicked on the bar, set position to mouse click
481  fp32_hf pos = x / (mWidth - mSliderKnobWidth);
482  setValue(pos);
484  }
485  else
486  {
487  // clicked on the bar, set position to mouse click
488  fp32_hf pos = y / (mHeight - mSliderKnobHeight);
489  setValue(pos);
491  }
492  }
493 }
494 
496 {
497  mDragging = false;
498 
499  fp32_hf x = mouse.x - mSliderKnobPosX;
500  fp32_hf y = mouse.y - mSliderKnobPosY;
501 
502  if (mHorizontal)
503  {
504  // clicked on the bar, set position to mouse click
505  mVal = x / (mWidth - mSliderKnobWidth);
506  }
507  else
508  {
509  // clicked on the bar, set position to mouse click
510  mVal = y / (mHeight - mSliderKnobHeight);
511  }
512 
513  // clamp
514  if (mVal > 1.0f)
515  {
516  mVal = 1.0f;
517  }
518  else if (mVal < 0.0f)
519  {
520  mVal = 0.0f;
521  }
522 
523  if (mListener)
524  {
527  }
528 }
529 
531 {
532  if (mListener)
533  {
536  }
537 }
538 
540 {
541  mMouseOverKnob = false;
542 
543  if (!mDragging)
544  {
545  if (mListener)
546  {
549  }
550  }
551 }
Interface for all rendering related things.
fp32_hf x
X coordinate, relative to window.
Definition: Touch.h:55
virtual void mouseButtonUp(Mouse::MouseInfo mouse)
Called automatically when Mouse button up event occurs.
virtual void setBatchUIUpdateNeeded(bool update)
Set BatchUI update needed flag.
Definition: Widget.cpp:503
virtual void touchUp(Touch::TouchInfo touch)
Called automatically when Touch up event occurs.
fp32_hf y
Y coordinate, relative to window.
Definition: Mouse.h:69
Interface for UI SliderWidget.
fp32_hf getWidth() const
Get Rect Width (or maxX).
Definition: Rect.h:168
Rect mSliderKnobRect
Holds Rect for slider knob Image region within mAtlasImage.
Definition: SliderWidget.h:284
int int32_hf
A type definition for int.
Definition: HFDataTypes.h:349
Image * mSliderRailImage
Holds pointer to slider rail Image.
Definition: SliderWidget.h:251
static Rect ZERO()
Initialize Rect with 0 for all members.
Definition: Rect.h:141
fp32_hf mX
Holds Widget X position.
fp32_hf mVal
Holds slider value.
Definition: SliderWidget.h:240
virtual void mouseButtonDown(Mouse::MouseInfo mouse)
Called automatically when Mouse button down event occurs.
bool mIsOver
Flag indicating if over or not.
Definition: Widget.h:1070
fp32_hf x
X coordinate, relative to window.
Definition: Mouse.h:68
Rect mSliderRailRect
Holds Rect for slider rail Image region within mAtlasImage.
Definition: SliderWidget.h:278
Image * mAtlasImage
Holds pointer to atlas Image.
Definition: SliderWidget.h:272
Rect mSliderKnobOverRect
Holds Rect for slider knob over Image region within mAtlasImage.
Definition: SliderWidget.h:290
virtual void sliderMouseLeave(int32_hf id)
Called automatically when Mouse leave SliderWidget.
virtual void sliderValChanged(int32_hf id, fp32_hf val, bool mouseUp)
Called automatically when slider value changes.
A structure that contains Touch event information.
Definition: Touch.h:50
virtual void touchDown(Touch::TouchInfo touch)
Called automatically when Touch down event occurs.
Interface for Resource type Image.
#define NULL
Convenient define for 0.
Definition: HFDataTypes.h:42
virtual Graphics::MinFilter getMinRenderFilter()
Get Graphics::MinFilter currently set.
Definition: Widget.cpp:488
Image * mSliderKnobOverImage
Holds pointer to slider knob over Image.
Definition: SliderWidget.h:261
virtual void sliderMouseEnter(int32_hf id)
Called automatically when Mouse enter SliderWidget.
A structure that contains Mouse event information.
Definition: Mouse.h:63
virtual void mouseEnter(Mouse::MouseInfo mouse)
Called automatically when Mouse enter event occurs.
virtual Graphics::MagFilter getMagRenderFilter()
Get Graphics::MagFilter currently set.
Definition: Widget.cpp:483
fp32_hf y
Y coordinate, relative to window.
Definition: Touch.h:56
Interface for SliderWidget listener callback methods.
virtual void draw(Graphics *g)
Called by the framework once for every iteration of the main loop.
Rect mSliderKnobDownRect
Holds Rect for slider knob down Image region within mAtlasImage.
Definition: SliderWidget.h:296
virtual void mouseLeave(Mouse::MouseInfo mouse)
Called automatically when Mouse leave event occurs.
fp32_hf mY
Holds Widget Y position.
virtual void setValue(fp32_hf val)
Set value in the range 0.0f - 1.0f.
SliderWidget(int32_hf id, SliderListener *listener, bool horizontal, Image *sliderRailImage, int32_hf knobOffset, Image *sliderKnobImage, Image *sliderKnobOverImage=NULL, Image *sliderKnobDownImage=NULL)
Constructor.
Image * mSliderKnobImage
Holds pointer to slider knob Image.
Definition: SliderWidget.h:256
Definition: Actor.h:34
Interface for Resource type Image.
Definition: Image.h:63
SliderListener * mListener
Holds pointer to SliderListener class.
Definition: SliderWidget.h:235
Draw mode default / normal.
Definition: Graphics.h:143
Interface for SliderWidget listener callback methods.
void drawImage(Graphics *g, Image *img, fp32_hf x, fp32_hf y, fp32_hf alpha=1.0f, Graphics::DrawMode drawMode=Graphics::DRAWMODE_NORMAL, Graphics::MagFilter magFilter=Graphics::MAGFILTER_LINEAR, Graphics::MinFilter minFilter=Graphics::MINFILTER_LINEAR)
Draw a Image.
Definition: RenderHelper.h:530
Specialized Boundary representing a Rect.
Definition: Rect.h:34
virtual bool hasTransparencies()
Determine whether slider has transparencies.
Interface for all rendering related things.
Definition: Graphics.h:120
int32_hf mId
Holds SliderWidget ID.
Definition: SliderWidget.h:245
WidgetManager manages Widget&#39;s and interacts with Game interface.
Image * mSliderKnobDownImage
Holds pointer to slider knob down Image.
Definition: SliderWidget.h:266
bool mIsDown
Flag indicating if down or not.
Definition: Widget.h:1065
virtual void touchMove(Touch::TouchInfo touch)
Called automatically when Touch move/drag event occurs.
virtual int32_hf getHeight()=0
Get the Image original height.
fp32_hf getHeight() const
Get Rect Height (or maxY).
Definition: Rect.h:177
virtual void mouseMove(Mouse::MouseInfo mouse)
Called automatically when Mouse motion event occurs.
virtual int32_hf getWidth()=0
Get the Image original width.
fp32_hf mWidth
Holds Widget width.
float fp32_hf
A type definition for float.
Definition: HFDataTypes.h:359
fp32_hf mHeight
Holds Widget height.