2 * DISTRHO Plugin Framework (DPF)
3 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with
6 * or without fee is hereby granted, provided that the above copyright notice and this
7 * permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "../ImageBaseWidgets.hpp"
18 #include "../Color.hpp"
22 // --------------------------------------------------------------------------------------------------------------------
24 template <class ImageType
>
25 ImageBaseAboutWindow
<ImageType
>::ImageBaseAboutWindow(Window
& transientParentWindow
, const ImageType
& image
)
26 : StandaloneWindow(transientParentWindow
.getApp(), transientParentWindow
),
34 setSize(image
.getSize());
35 setGeometryConstraints(image
.getWidth(), image
.getHeight(), true, true);
41 template <class ImageType
>
42 ImageBaseAboutWindow
<ImageType
>::ImageBaseAboutWindow(TopLevelWidget
* const topLevelWidget
, const ImageType
& image
)
43 : StandaloneWindow(topLevelWidget
->getApp(), topLevelWidget
->getWindow()),
51 setSize(image
.getSize());
52 setGeometryConstraints(image
.getWidth(), image
.getHeight(), true, true);
58 template <class ImageType
>
59 void ImageBaseAboutWindow
<ImageType
>::setImage(const ImageType
& image
)
66 if (image
.isInvalid())
69 setSize(image
.getSize());
70 setGeometryConstraints(image
.getWidth(), image
.getHeight(), true, true);
73 template <class ImageType
>
74 void ImageBaseAboutWindow
<ImageType
>::onDisplay()
76 img
.draw(getGraphicsContext());
79 template <class ImageType
>
80 bool ImageBaseAboutWindow
<ImageType
>::onKeyboard(const KeyboardEvent
& ev
)
82 if (ev
.press
&& ev
.key
== kKeyEscape
)
91 template <class ImageType
>
92 bool ImageBaseAboutWindow
<ImageType
>::onMouse(const MouseEvent
& ev
)
103 // --------------------------------------------------------------------------------------------------------------------
105 template <class ImageType
>
106 struct ImageBaseButton
<ImageType
>::PrivateData
: public ButtonEventHandler::Callback
{
107 ImageBaseButton
<ImageType
>::Callback
* callback
;
108 ImageType imageNormal
;
109 ImageType imageHover
;
112 PrivateData(const ImageType
& normal
, const ImageType
& hover
, const ImageType
& down
)
118 void buttonClicked(SubWidget
* widget
, int button
) override
120 if (callback
!= nullptr)
121 if (ImageBaseButton
* const imageButton
= dynamic_cast<ImageBaseButton
*>(widget
))
122 callback
->imageButtonClicked(imageButton
, button
);
125 DISTRHO_DECLARE_NON_COPYABLE(PrivateData
)
128 // --------------------------------------------------------------------------------------------------------------------
130 template <class ImageType
>
131 ImageBaseButton
<ImageType
>::ImageBaseButton(Widget
* const parentWidget
, const ImageType
& image
)
132 : SubWidget(parentWidget
),
133 ButtonEventHandler(this),
134 pData(new PrivateData(image
, image
, image
))
136 ButtonEventHandler::setCallback(pData
);
137 setSize(image
.getSize());
140 template <class ImageType
>
141 ImageBaseButton
<ImageType
>::ImageBaseButton(Widget
* const parentWidget
, const ImageType
& imageNormal
, const ImageType
& imageDown
)
142 : SubWidget(parentWidget
),
143 ButtonEventHandler(this),
144 pData(new PrivateData(imageNormal
, imageNormal
, imageDown
))
146 DISTRHO_SAFE_ASSERT(imageNormal
.getSize() == imageDown
.getSize());
148 ButtonEventHandler::setCallback(pData
);
149 setSize(imageNormal
.getSize());
152 template <class ImageType
>
153 ImageBaseButton
<ImageType
>::ImageBaseButton(Widget
* const parentWidget
, const ImageType
& imageNormal
, const ImageType
& imageHover
, const ImageType
& imageDown
)
154 : SubWidget(parentWidget
),
155 ButtonEventHandler(this),
156 pData(new PrivateData(imageNormal
, imageHover
, imageDown
))
158 DISTRHO_SAFE_ASSERT(imageNormal
.getSize() == imageHover
.getSize() && imageHover
.getSize() == imageDown
.getSize());
160 ButtonEventHandler::setCallback(pData
);
161 setSize(imageNormal
.getSize());
164 template <class ImageType
>
165 ImageBaseButton
<ImageType
>::~ImageBaseButton()
170 template <class ImageType
>
171 void ImageBaseButton
<ImageType
>::setCallback(Callback
* callback
) noexcept
173 pData
->callback
= callback
;
176 template <class ImageType
>
177 void ImageBaseButton
<ImageType
>::onDisplay()
179 const GraphicsContext
& context(getGraphicsContext());
181 const State state
= ButtonEventHandler::getState();
183 if (state
& kButtonStateActive
)
184 pData
->imageDown
.draw(context
);
185 else if (state
& kButtonStateHover
)
186 pData
->imageHover
.draw(context
);
188 pData
->imageNormal
.draw(context
);
191 template <class ImageType
>
192 bool ImageBaseButton
<ImageType
>::onMouse(const MouseEvent
& ev
)
194 if (SubWidget::onMouse(ev
))
196 return ButtonEventHandler::mouseEvent(ev
);
199 template <class ImageType
>
200 bool ImageBaseButton
<ImageType
>::onMotion(const MotionEvent
& ev
)
202 if (SubWidget::onMotion(ev
))
204 return ButtonEventHandler::motionEvent(ev
);
207 // --------------------------------------------------------------------------------------------------------------------
209 template <class ImageType
>
210 struct ImageBaseKnob
<ImageType
>::PrivateData
: public KnobEventHandler::Callback
{
211 ImageBaseKnob
<ImageType
>::Callback
* callback
;
228 explicit PrivateData(const ImageType
& img
)
232 alwaysRepaint(false),
233 isImgVertical(img
.getHeight() > img
.getWidth()),
234 imgLayerWidth(isImgVertical
? img
.getWidth() : img
.getHeight()),
235 imgLayerHeight(imgLayerWidth
),
236 imgLayerCount(isImgVertical
? img
.getHeight()/imgLayerHeight
: img
.getWidth()/imgLayerWidth
),
242 explicit PrivateData(PrivateData
* const other
)
243 : callback(other
->callback
),
245 rotationAngle(other
->rotationAngle
),
246 alwaysRepaint(other
->alwaysRepaint
),
247 isImgVertical(other
->isImgVertical
),
248 imgLayerWidth(other
->imgLayerWidth
),
249 imgLayerHeight(other
->imgLayerHeight
),
250 imgLayerCount(other
->imgLayerCount
),
256 void assignFrom(PrivateData
* const other
)
259 image
= other
->image
;
260 rotationAngle
= other
->rotationAngle
;
261 callback
= other
->callback
;
262 alwaysRepaint
= other
->alwaysRepaint
;
263 isImgVertical
= other
->isImgVertical
;
264 imgLayerWidth
= other
->imgLayerWidth
;
265 imgLayerHeight
= other
->imgLayerHeight
;
266 imgLayerCount
= other
->imgLayerCount
;
276 void knobDragStarted(SubWidget
* const widget
) override
278 if (callback
!= nullptr)
279 if (ImageBaseKnob
* const imageKnob
= dynamic_cast<ImageBaseKnob
*>(widget
))
280 callback
->imageKnobDragStarted(imageKnob
);
283 void knobDragFinished(SubWidget
* const widget
) override
285 if (callback
!= nullptr)
286 if (ImageBaseKnob
* const imageKnob
= dynamic_cast<ImageBaseKnob
*>(widget
))
287 callback
->imageKnobDragFinished(imageKnob
);
290 void knobValueChanged(SubWidget
* const widget
, const float value
) override
292 if (rotationAngle
== 0 || alwaysRepaint
)
295 if (callback
!= nullptr)
296 if (ImageBaseKnob
* const imageKnob
= dynamic_cast<ImageBaseKnob
*>(widget
))
297 callback
->imageKnobValueChanged(imageKnob
, value
);
300 // implemented independently per graphics backend
304 DISTRHO_DECLARE_NON_COPYABLE(PrivateData
)
307 // --------------------------------------------------------------------------------------------------------------------
309 template <class ImageType
>
310 ImageBaseKnob
<ImageType
>::ImageBaseKnob(Widget
* const parentWidget
,
311 const ImageType
& image
,
312 const Orientation orientation
) noexcept
313 : SubWidget(parentWidget
),
314 KnobEventHandler(this),
315 pData(new PrivateData(image
))
317 KnobEventHandler::setCallback(pData
);
318 setOrientation(orientation
);
319 setSize(pData
->imgLayerWidth
, pData
->imgLayerHeight
);
322 template <class ImageType
>
323 ImageBaseKnob
<ImageType
>::ImageBaseKnob(const ImageBaseKnob
<ImageType
>& imageKnob
)
324 : SubWidget(imageKnob
.getParentWidget()),
325 KnobEventHandler(this, imageKnob
),
326 pData(new PrivateData(imageKnob
.pData
))
328 KnobEventHandler::setCallback(pData
);
329 setOrientation(imageKnob
.getOrientation());
330 setSize(pData
->imgLayerWidth
, pData
->imgLayerHeight
);
333 template <class ImageType
>
334 ImageBaseKnob
<ImageType
>& ImageBaseKnob
<ImageType
>::operator=(const ImageBaseKnob
<ImageType
>& imageKnob
)
336 KnobEventHandler::operator=(imageKnob
);
337 pData
->assignFrom(imageKnob
.pData
);
338 setSize(pData
->imgLayerWidth
, pData
->imgLayerHeight
);
342 template <class ImageType
>
343 ImageBaseKnob
<ImageType
>::~ImageBaseKnob()
348 template <class ImageType
>
349 void ImageBaseKnob
<ImageType
>::setCallback(Callback
* callback
) noexcept
351 pData
->callback
= callback
;
354 template <class ImageType
>
355 void ImageBaseKnob
<ImageType
>::setImageLayerCount(uint count
) noexcept
357 DISTRHO_SAFE_ASSERT_RETURN(count
> 1,);
359 pData
->imgLayerCount
= count
;
361 if (pData
->isImgVertical
)
362 pData
->imgLayerHeight
= pData
->image
.getHeight()/count
;
364 pData
->imgLayerWidth
= pData
->image
.getWidth()/count
;
366 setSize(pData
->imgLayerWidth
, pData
->imgLayerHeight
);
369 template <class ImageType
>
370 void ImageBaseKnob
<ImageType
>::setRotationAngle(int angle
)
372 if (pData
->rotationAngle
== angle
)
375 pData
->rotationAngle
= angle
;
376 pData
->isReady
= false;
379 template <class ImageType
>
380 bool ImageBaseKnob
<ImageType
>::setValue(float value
, bool sendCallback
) noexcept
382 if (KnobEventHandler::setValue(value
, sendCallback
))
384 if (pData
->rotationAngle
== 0 || pData
->alwaysRepaint
)
385 pData
->isReady
= false;
393 template <class ImageType
>
394 bool ImageBaseKnob
<ImageType
>::onMouse(const MouseEvent
& ev
)
396 if (SubWidget::onMouse(ev
))
398 return KnobEventHandler::mouseEvent(ev
);
401 template <class ImageType
>
402 bool ImageBaseKnob
<ImageType
>::onMotion(const MotionEvent
& ev
)
404 if (SubWidget::onMotion(ev
))
406 return KnobEventHandler::motionEvent(ev
);
409 template <class ImageType
>
410 bool ImageBaseKnob
<ImageType
>::onScroll(const ScrollEvent
& ev
)
412 if (SubWidget::onScroll(ev
))
414 return KnobEventHandler::scrollEvent(ev
);
417 // --------------------------------------------------------------------------------------------------------------------
419 template <class ImageType
>
420 struct ImageBaseSlider
<ImageType
>::PrivateData
{
440 Rectangle
<double> sliderArea
;
442 PrivateData(const ImageType
& img
)
461 void recheckArea() noexcept
463 if (startPos
.getY() == endPos
.getY())
466 sliderArea
= Rectangle
<double>(startPos
.getX(),
468 endPos
.getX() + static_cast<int>(image
.getWidth()) - startPos
.getX(),
469 static_cast<int>(image
.getHeight()));
474 sliderArea
= Rectangle
<double>(startPos
.getX(),
476 static_cast<int>(image
.getWidth()),
477 endPos
.getY() + static_cast<int>(image
.getHeight()) - startPos
.getY());
481 DISTRHO_DECLARE_NON_COPYABLE(PrivateData
)
484 // --------------------------------------------------------------------------------------------------------------------
486 template <class ImageType
>
487 ImageBaseSlider
<ImageType
>::ImageBaseSlider(Widget
* const parentWidget
, const ImageType
& image
) noexcept
488 : SubWidget(parentWidget
),
489 pData(new PrivateData(image
))
491 setNeedsFullViewportDrawing();
494 template <class ImageType
>
495 ImageBaseSlider
<ImageType
>::~ImageBaseSlider()
500 template <class ImageType
>
501 float ImageBaseSlider
<ImageType
>::getValue() const noexcept
506 template <class ImageType
>
507 void ImageBaseSlider
<ImageType
>::setValue(float value
, bool sendCallback
) noexcept
509 if (! pData
->valueIsSet
)
510 pData
->valueIsSet
= true;
512 if (d_isEqual(pData
->value
, value
))
515 pData
->value
= value
;
517 if (d_isZero(pData
->step
))
518 pData
->valueTmp
= value
;
522 if (sendCallback
&& pData
->callback
!= nullptr)
525 pData
->callback
->imageSliderValueChanged(this, pData
->value
);
526 } DISTRHO_SAFE_EXCEPTION("ImageBaseSlider::setValue");
530 template <class ImageType
>
531 void ImageBaseSlider
<ImageType
>::setStartPos(const Point
<int>& startPos
) noexcept
533 pData
->startPos
= startPos
;
534 pData
->recheckArea();
537 template <class ImageType
>
538 void ImageBaseSlider
<ImageType
>::setStartPos(int x
, int y
) noexcept
540 setStartPos(Point
<int>(x
, y
));
543 template <class ImageType
>
544 void ImageBaseSlider
<ImageType
>::setEndPos(const Point
<int>& endPos
) noexcept
546 pData
->endPos
= endPos
;
547 pData
->recheckArea();
550 template <class ImageType
>
551 void ImageBaseSlider
<ImageType
>::setEndPos(int x
, int y
) noexcept
553 setEndPos(Point
<int>(x
, y
));
556 template <class ImageType
>
557 void ImageBaseSlider
<ImageType
>::setInverted(bool inverted
) noexcept
559 if (pData
->inverted
== inverted
)
562 pData
->inverted
= inverted
;
566 template <class ImageType
>
567 void ImageBaseSlider
<ImageType
>::setDefault(float value
) noexcept
569 pData
->valueDef
= value
;
570 pData
->usingDefault
= true;
573 template <class ImageType
>
574 void ImageBaseSlider
<ImageType
>::setRange(float min
, float max
) noexcept
576 pData
->minimum
= min
;
577 pData
->maximum
= max
;
579 if (pData
->value
< min
)
584 if (pData
->callback
!= nullptr && pData
->valueIsSet
)
587 pData
->callback
->imageSliderValueChanged(this, pData
->value
);
588 } DISTRHO_SAFE_EXCEPTION("ImageBaseSlider::setRange < min");
591 else if (pData
->value
> max
)
596 if (pData
->callback
!= nullptr && pData
->valueIsSet
)
599 pData
->callback
->imageSliderValueChanged(this, pData
->value
);
600 } DISTRHO_SAFE_EXCEPTION("ImageBaseSlider::setRange > max");
605 template <class ImageType
>
606 void ImageBaseSlider
<ImageType
>::setStep(float step
) noexcept
611 template <class ImageType
>
612 void ImageBaseSlider
<ImageType
>::setCallback(Callback
* callback
) noexcept
614 pData
->callback
= callback
;
617 template <class ImageType
>
618 void ImageBaseSlider
<ImageType
>::onDisplay()
620 const GraphicsContext
& context(getGraphicsContext());
622 #if 0 // DEBUG, paints slider area
623 Color(1.0f
, 1.0f
, 1.0f
, 0.5f
).setFor(context
, true);
624 Rectangle
<int>(pData
->sliderArea
.getX(),
625 pData
->sliderArea
.getY(),
626 pData
->sliderArea
.getX()+pData
->sliderArea
.getWidth(),
627 pData
->sliderArea
.getY()+pData
->sliderArea
.getHeight()).draw(context
);
628 Color(1.0f
, 1.0f
, 1.0f
, 1.0f
).setFor(context
, true);
631 const float normValue
= (pData
->value
- pData
->minimum
) / (pData
->maximum
- pData
->minimum
);
635 if (pData
->startPos
.getY() == pData
->endPos
.getY())
639 x
= pData
->endPos
.getX() - static_cast<int>(normValue
*static_cast<float>(pData
->endPos
.getX()-pData
->startPos
.getX()));
641 x
= pData
->startPos
.getX() + static_cast<int>(normValue
*static_cast<float>(pData
->endPos
.getX()-pData
->startPos
.getX()));
643 y
= pData
->startPos
.getY();
648 x
= pData
->startPos
.getX();
651 y
= pData
->endPos
.getY() - static_cast<int>(normValue
*static_cast<float>(pData
->endPos
.getY()-pData
->startPos
.getY()));
653 y
= pData
->startPos
.getY() + static_cast<int>(normValue
*static_cast<float>(pData
->endPos
.getY()-pData
->startPos
.getY()));
656 pData
->image
.drawAt(context
, x
, y
);
659 template <class ImageType
>
660 bool ImageBaseSlider
<ImageType
>::onMouse(const MouseEvent
& ev
)
667 if (! pData
->sliderArea
.contains(ev
.pos
))
670 if ((ev
.mod
& kModifierShift
) != 0 && pData
->usingDefault
)
672 setValue(pData
->valueDef
, true);
673 pData
->valueTmp
= pData
->value
;
678 const double x
= ev
.pos
.getX();
679 const double y
= ev
.pos
.getY();
681 if (pData
->startPos
.getY() == pData
->endPos
.getY())
684 vper
= float(x
- pData
->sliderArea
.getX()) / float(pData
->sliderArea
.getWidth());
689 vper
= float(y
- pData
->sliderArea
.getY()) / float(pData
->sliderArea
.getHeight());
695 value
= pData
->maximum
- vper
* (pData
->maximum
- pData
->minimum
);
697 value
= pData
->minimum
+ vper
* (pData
->maximum
- pData
->minimum
);
699 if (value
< pData
->minimum
)
701 pData
->valueTmp
= value
= pData
->minimum
;
703 else if (value
> pData
->maximum
)
705 pData
->valueTmp
= value
= pData
->maximum
;
707 else if (d_isNotZero(pData
->step
))
709 pData
->valueTmp
= value
;
710 const float rest
= std::fmod(value
, pData
->step
);
711 value
= value
- rest
+ (rest
> pData
->step
/2.0f
? pData
->step
: 0.0f
);
714 pData
->dragging
= true;
718 if (pData
->callback
!= nullptr)
719 pData
->callback
->imageSliderDragStarted(this);
721 setValue(value
, true);
725 else if (pData
->dragging
)
727 if (pData
->callback
!= nullptr)
728 pData
->callback
->imageSliderDragFinished(this);
730 pData
->dragging
= false;
737 template <class ImageType
>
738 bool ImageBaseSlider
<ImageType
>::onMotion(const MotionEvent
& ev
)
740 if (! pData
->dragging
)
743 const bool horizontal
= pData
->startPos
.getY() == pData
->endPos
.getY();
744 const double x
= ev
.pos
.getX();
745 const double y
= ev
.pos
.getY();
747 if ((horizontal
&& pData
->sliderArea
.containsX(x
)) || (pData
->sliderArea
.containsY(y
) && ! horizontal
))
754 vper
= float(x
- pData
->sliderArea
.getX()) / float(pData
->sliderArea
.getWidth());
759 vper
= float(y
- pData
->sliderArea
.getY()) / float(pData
->sliderArea
.getHeight());
765 value
= pData
->maximum
- vper
* (pData
->maximum
- pData
->minimum
);
767 value
= pData
->minimum
+ vper
* (pData
->maximum
- pData
->minimum
);
769 if (value
< pData
->minimum
)
771 pData
->valueTmp
= value
= pData
->minimum
;
773 else if (value
> pData
->maximum
)
775 pData
->valueTmp
= value
= pData
->maximum
;
777 else if (d_isNotZero(pData
->step
))
779 pData
->valueTmp
= value
;
780 const float rest
= std::fmod(value
, pData
->step
);
781 value
= value
- rest
+ (rest
> pData
->step
/2.0f
? pData
->step
: 0.0f
);
784 setValue(value
, true);
788 if (x
< pData
->sliderArea
.getX())
789 setValue(pData
->inverted
? pData
->maximum
: pData
->minimum
, true);
791 setValue(pData
->inverted
? pData
->minimum
: pData
->maximum
, true);
795 if (y
< pData
->sliderArea
.getY())
796 setValue(pData
->inverted
? pData
->maximum
: pData
->minimum
, true);
798 setValue(pData
->inverted
? pData
->minimum
: pData
->maximum
, true);
804 // --------------------------------------------------------------------------------------------------------------------
806 template <class ImageType
>
807 struct ImageBaseSwitch
<ImageType
>::PrivateData
{
808 ImageType imageNormal
;
813 PrivateData(const ImageType
& normal
, const ImageType
& down
)
814 : imageNormal(normal
),
819 DISTRHO_SAFE_ASSERT(imageNormal
.getSize() == imageDown
.getSize());
822 PrivateData(PrivateData
* const other
)
823 : imageNormal(other
->imageNormal
),
824 imageDown(other
->imageDown
),
825 isDown(other
->isDown
),
826 callback(other
->callback
)
828 DISTRHO_SAFE_ASSERT(imageNormal
.getSize() == imageDown
.getSize());
831 void assignFrom(PrivateData
* const other
)
833 imageNormal
= other
->imageNormal
;
834 imageDown
= other
->imageDown
;
835 isDown
= other
->isDown
;
836 callback
= other
->callback
;
837 DISTRHO_SAFE_ASSERT(imageNormal
.getSize() == imageDown
.getSize());
840 DISTRHO_DECLARE_NON_COPYABLE(PrivateData
)
843 // --------------------------------------------------------------------------------------------------------------------
845 template <class ImageType
>
846 ImageBaseSwitch
<ImageType
>::ImageBaseSwitch(Widget
* const parentWidget
, const ImageType
& imageNormal
, const ImageType
& imageDown
) noexcept
847 : SubWidget(parentWidget
),
848 pData(new PrivateData(imageNormal
, imageDown
))
850 setSize(imageNormal
.getSize());
853 template <class ImageType
>
854 ImageBaseSwitch
<ImageType
>::ImageBaseSwitch(const ImageBaseSwitch
<ImageType
>& imageSwitch
) noexcept
855 : SubWidget(imageSwitch
.getParentWidget()),
856 pData(new PrivateData(imageSwitch
.pData
))
858 setSize(pData
->imageNormal
.getSize());
861 template <class ImageType
>
862 ImageBaseSwitch
<ImageType
>& ImageBaseSwitch
<ImageType
>::operator=(const ImageBaseSwitch
<ImageType
>& imageSwitch
) noexcept
864 pData
->assignFrom(imageSwitch
.pData
);
865 setSize(pData
->imageNormal
.getSize());
869 template <class ImageType
>
870 ImageBaseSwitch
<ImageType
>::~ImageBaseSwitch()
875 template <class ImageType
>
876 bool ImageBaseSwitch
<ImageType
>::isDown() const noexcept
878 return pData
->isDown
;
881 template <class ImageType
>
882 void ImageBaseSwitch
<ImageType
>::setDown(const bool down
) noexcept
884 if (pData
->isDown
== down
)
887 pData
->isDown
= down
;
891 template <class ImageType
>
892 void ImageBaseSwitch
<ImageType
>::setCallback(Callback
* const callback
) noexcept
894 pData
->callback
= callback
;
897 template <class ImageType
>
898 void ImageBaseSwitch
<ImageType
>::onDisplay()
900 const GraphicsContext
& context(getGraphicsContext());
903 pData
->imageDown
.draw(context
);
905 pData
->imageNormal
.draw(context
);
908 template <class ImageType
>
909 bool ImageBaseSwitch
<ImageType
>::onMouse(const MouseEvent
& ev
)
911 if (ev
.press
&& contains(ev
.pos
))
913 pData
->isDown
= !pData
->isDown
;
917 if (pData
->callback
!= nullptr)
918 pData
->callback
->imageSwitchClicked(this, pData
->isDown
);
926 // --------------------------------------------------------------------------------------------------------------------