Ver código fonte

Add Element::ScrollTo, with support for smooth scrolling behavior

Michael Ragazzon 2 anos atrás
pai
commit
e206617ef0

+ 4 - 1
Include/RmlUi/Core/Context.h

@@ -318,7 +318,7 @@ private:
 	Vector2i mouse_position;
 	bool mouse_active;
 
-	// Autoscroll state (scrolling with middle mouse button). Autoscroll enabled when target is non-null.
+	// Controller for various scroll behavior modes.
 	UniquePtr<ScrollController> scroll_controller; // [not-null]
 
 	// Enables cursor handling.
@@ -370,6 +370,9 @@ private:
 	// Releases the drag clone, if one exists.
 	void ReleaseDragClone();
 
+	// Scroll the target by the given amount, using smooth scrolling.
+	void PerformSmoothscrollOnTarget(Element* target, Vector2f delta_offset);
+
 	// Returns the data model with the provided name, or nullptr if it does not exist.
 	DataModel* GetDataModelPtr(const String& name) const;
 

+ 10 - 0
Include/RmlUi/Core/Element.h

@@ -66,6 +66,11 @@ class TransformState;
 struct ElementMeta;
 struct StackingOrderedChild;
 
+enum class ScrollBehavior {
+	Auto,    // Same as Instant.
+	Smooth,  // Scroll to the destination using a smooth animation.
+	Instant, // Scroll to the destination instantly.
+};
 enum class ScrollAlignment {
 	Start,   // Align to the top or left edge of the parent element.
 	Center,  // Align to the center of the parent element.
@@ -522,6 +527,11 @@ public:
 	/// Scrolls the parent element's contents so that this element is visible.
 	/// @param[in] align_with_top If true, the element will align itself to the top of the parent element's window. If false, the element will be aligned to the bottom of the parent element's window.
 	void ScrollIntoView(bool align_with_top = true);
+	/// Sets the scroll offset of this element to the given coordinates.
+	/// @param[in] position The scroll destination coordinates.
+	/// @param[in] behavior Smooth scrolling behavior.
+	/// @note Smooth scrolling can only be applied to a single element at a time, any active smooth scrolls will be cancelled.
+	void ScrollTo(Vector2f offset, ScrollBehavior behavior = ScrollBehavior::Auto);
 
 	/// Append a child to this element.
 	/// @param[in] element The element to append as a child.

+ 6 - 0
Source/Core/Context.cpp

@@ -1326,6 +1326,12 @@ void Context::ReleaseDragClone()
 	}
 }
 
+void Context::PerformSmoothscrollOnTarget(Element* target, Vector2f delta_offset)
+{
+	scroll_controller->ActivateSmoothscroll(target);
+	scroll_controller->IncrementSmoothscrollTarget(delta_offset);
+}
+
 DataModel* Context::GetDataModelPtr(const String& name) const
 {
 	auto it = data_models.find(name);

+ 15 - 0
Source/Core/Element.cpp

@@ -1324,6 +1324,21 @@ void Element::ScrollIntoView(bool align_with_top)
 	ScrollIntoView(options);
 }
 
+void Element::ScrollTo(Vector2f offset, ScrollBehavior behavior)
+{
+	if (behavior == ScrollBehavior::Smooth)
+	{
+		if (Context* context = GetContext())
+		{
+			context->PerformSmoothscrollOnTarget(this, offset - scroll_offset);
+			return;
+		}
+	}
+
+	SetScrollLeft(offset.x);
+	SetScrollTop(offset.y);
+}
+
 // Appends a child to this element
 Element* Element::AppendChild(ElementPtr child, bool dom_element)
 {