浏览代码

fix stuck (press) slider w. clicking on empty area

Laserlicht 8 月之前
父节点
当前提交
eeef7efac5
共有 4 个文件被更改,包括 54 次插入25 次删除
  1. 5 0
      client/widgets/Buttons.cpp
  2. 1 0
      client/widgets/Buttons.h
  3. 45 25
      client/widgets/Slider.cpp
  4. 3 0
      client/widgets/Slider.h

+ 5 - 0
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;

+ 1 - 0
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<std::string, std::string> & help,

+ 45 - 25
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());
 }
 
-void CSlider::clickPressed(const Point & cursorPosition)
+double CSlider::getClickPos(const Point & cursorPosition)
 {
-	if(!slider->isBlocked())
+	double pw = 0;
+	double rw = 0;
+	if(getOrientation() == Orientation::HORIZONTAL)
 	{
-		double pw = 0;
-		double rw = 0;
-		if(getOrientation() == Orientation::HORIZONTAL)
-		{
-			pw = cursorPosition.x-pos.x-25;
-			rw = pw / static_cast<double>(pos.w - 48);
-		}
-		else
-		{
-			pw = cursorPosition.y-pos.y-24;
-			rw = pw / (pos.h-48);
-		}
+		pw = cursorPosition.x-pos.x-25;
+		rw = pw / static_cast<double>(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;
+	return rw;
+}
 
-		slider->clickPressed(cursorPosition);
-		scrollTo((int)(rw * positions  +  0.5));
+void CSlider::clickPressed(const Point & cursorPosition)
+{
+	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;

+ 3 - 0
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;