diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index 9725b628b..71cba9efb 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -206,6 +206,11 @@ bool CButton::isHighlighted() return getState() == EButtonState::HIGHLIGHTED; } +bool CButton::isPressed() +{ + return getState() == EButtonState::PRESSED; +} + void CButton::setHoverable(bool on) { hoverable = on; diff --git a/client/widgets/Buttons.h b/client/widgets/Buttons.h index f369473f8..79cc7fe20 100644 --- a/client/widgets/Buttons.h +++ b/client/widgets/Buttons.h @@ -105,6 +105,7 @@ public: /// State modifiers bool isBlocked(); bool isHighlighted(); + bool isPressed(); /// Constructor CButton(Point position, const AnimationPath & defName, const std::pair & help, diff --git a/client/widgets/Slider.cpp b/client/widgets/Slider.cpp index d5c19ebac..5ba3ad703 100644 --- a/client/widgets/Slider.cpp +++ b/client/widgets/Slider.cpp @@ -21,6 +21,13 @@ void CSlider::mouseDragged(const Point & cursorPosition, const Point & lastUpdateDistance) { + bool onControl = pos.isInside(cursorPosition) && !left->pos.isInside(cursorPosition) && !right->pos.isInside(cursorPosition); + if(!onControl && !slider->isPressed()) + return; + + if(onControl && !slider->isPressed()) + slider->clickPressed(cursorPosition); + double newPosition = 0; if(getOrientation() == Orientation::HORIZONTAL) { @@ -129,44 +136,57 @@ void CSlider::scrollTo(int to, bool callCallbacks) moved(getValue()); } +double CSlider::getClickPos(const Point & cursorPosition) +{ + double pw = 0; + double rw = 0; + if(getOrientation() == Orientation::HORIZONTAL) + { + pw = cursorPosition.x-pos.x-25; + rw = pw / static_cast(pos.w - 48); + } + else + { + pw = cursorPosition.y-pos.y-24; + rw = pw / (pos.h-48); + } + + return rw; +} + void CSlider::clickPressed(const Point & cursorPosition) { - if(!slider->isBlocked()) - { - double pw = 0; - double rw = 0; - if(getOrientation() == Orientation::HORIZONTAL) - { - pw = cursorPosition.x-pos.x-25; - rw = pw / static_cast(pos.w - 48); - } - else - { - pw = cursorPosition.y-pos.y-24; - rw = pw / (pos.h-48); - } - - // click on area covered by buttons -> ignore, will be handled by left/right buttons - if (!vstd::iswithin(rw, 0, 1)) - return; - - slider->clickPressed(cursorPosition); - scrollTo((int)(rw * positions + 0.5)); + bool onControl = pos.isInside(cursorPosition) && !left->pos.isInside(cursorPosition) && !right->pos.isInside(cursorPosition); + if(!onControl) return; - } + + if(slider->isBlocked()) + return; + + // click on area covered by buttons -> ignore, will be handled by left/right buttons + auto rw = getClickPos(cursorPosition); + if (!vstd::iswithin(rw, 0, 1)) + return; + + slider->clickPressed(cursorPosition); + scrollTo((int)(rw * positions + 0.5)); +} + +void CSlider::clickReleased(const Point & cursorPosition) +{ + if(slider->isBlocked()) + return; + + slider->clickReleased(cursorPosition); } bool CSlider::receiveEvent(const Point &position, int eventType) const { if (eventType == LCLICK) - { - return pos.isInside(position) && !left->pos.isInside(position) && !right->pos.isInside(position); - } + return true; //capture "clickReleased" also outside of control if(eventType != WHEEL && eventType != GESTURE) - { return CIntObject::receiveEvent(position, eventType); - } if (!scrollBounds) return true; diff --git a/client/widgets/Slider.h b/client/widgets/Slider.h index 6cbba6823..4114c60de 100644 --- a/client/widgets/Slider.h +++ b/client/widgets/Slider.h @@ -38,6 +38,8 @@ class CSlider : public Scrollable void updateSliderPos(); + double getClickPos(const Point & cursorPosition); + public: enum EStyle { @@ -71,6 +73,7 @@ public: bool receiveEvent(const Point & position, int eventType) const override; void keyPressed(EShortcut key) override; void clickPressed(const Point & cursorPosition) override; + void clickReleased(const Point & cursorPosition) override; void mouseDragged(const Point & cursorPosition, const Point & lastUpdateDistance) override; void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; void showAll(Canvas & to) override;