|
|
@@ -29,6 +29,7 @@
|
|
|
#include "WidgetScroll.h"
|
|
|
#include "../../Include/RmlUi/Core/ComputedValues.h"
|
|
|
#include "../../Include/RmlUi/Core/Element.h"
|
|
|
+#include "../../Include/RmlUi/Core/ElementUtilities.h"
|
|
|
#include "../../Include/RmlUi/Core/Event.h"
|
|
|
#include "../../Include/RmlUi/Core/Factory.h"
|
|
|
#include "../../Include/RmlUi/Core/Property.h"
|
|
|
@@ -37,8 +38,11 @@
|
|
|
|
|
|
namespace Rml {
|
|
|
|
|
|
-static const float DEFAULT_REPEAT_DELAY = 0.5f;
|
|
|
-static const float DEFAULT_REPEAT_PERIOD = 0.1f;
|
|
|
+static constexpr float DEFAULT_REPEAT_DELAY = 0.5f;
|
|
|
+static constexpr float DEFAULT_REPEAT_PERIOD = 0.1f;
|
|
|
+
|
|
|
+static constexpr float SCROLL_LINE_LENGTH = 30.f; // [dp]
|
|
|
+static constexpr float SCROLL_PAGE_FACTOR = 0.8f;
|
|
|
|
|
|
WidgetScroll::WidgetScroll(Element* _parent)
|
|
|
{
|
|
|
@@ -60,7 +64,6 @@ WidgetScroll::WidgetScroll(Element* _parent)
|
|
|
|
|
|
track_length = 0;
|
|
|
bar_length = 0;
|
|
|
- line_height = 12;
|
|
|
}
|
|
|
|
|
|
WidgetScroll::~WidgetScroll()
|
|
|
@@ -161,7 +164,10 @@ void WidgetScroll::Update()
|
|
|
while (arrow_timers[i] <= 0)
|
|
|
{
|
|
|
arrow_timers[i] += DEFAULT_REPEAT_PERIOD;
|
|
|
- SetBarPosition(i == 0 ? OnLineDecrement() : OnLineIncrement());
|
|
|
+ if (i == 0)
|
|
|
+ ScrollLineUp();
|
|
|
+ else
|
|
|
+ ScrollLineDown();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -172,19 +178,6 @@ void WidgetScroll::SetBarPosition(float _bar_position)
|
|
|
{
|
|
|
bar_position = Math::Clamp(_bar_position, 0.0f, 1.0f);
|
|
|
PositionBar();
|
|
|
-
|
|
|
- // 'parent' is the scrollbar element, its parent again is the actual element we want to scroll
|
|
|
- Element* element_scroll = parent->GetParentNode();
|
|
|
- if (!element_scroll)
|
|
|
- {
|
|
|
- RMLUI_ERROR;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (orientation == VERTICAL)
|
|
|
- element_scroll->SetScrollTop(bar_position * (element_scroll->GetScrollHeight() - element_scroll->GetClientHeight()));
|
|
|
- else if (orientation == HORIZONTAL)
|
|
|
- element_scroll->SetScrollLeft(bar_position * (element_scroll->GetScrollWidth() - element_scroll->GetClientWidth()));
|
|
|
}
|
|
|
|
|
|
// Returns the current position of the bar.
|
|
|
@@ -372,57 +365,57 @@ void WidgetScroll::ProcessEvent(Event& event)
|
|
|
{
|
|
|
if (event == EventId::Drag)
|
|
|
{
|
|
|
+ float new_bar_position = 0.f;
|
|
|
if (orientation == HORIZONTAL)
|
|
|
{
|
|
|
- float traversable_track_length = track->GetBox().GetSize(Box::CONTENT).x - bar->GetBox().GetSize(Box::CONTENT).x;
|
|
|
+ float traversable_track_length = track->GetBox().GetSize().x - bar->GetBox().GetSize().x;
|
|
|
if (traversable_track_length > 0)
|
|
|
{
|
|
|
float traversable_track_origin = track->GetAbsoluteOffset().x + bar_drag_anchor;
|
|
|
- float new_bar_position = (event.GetParameter< float >("mouse_x", 0) - traversable_track_origin) / traversable_track_length;
|
|
|
- new_bar_position = Math::Clamp(new_bar_position, 0.0f, 1.0f);
|
|
|
-
|
|
|
- SetBarPosition(new_bar_position);
|
|
|
+ new_bar_position = (event.GetParameter("mouse_x", 0.f) - traversable_track_origin) / traversable_track_length;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- float traversable_track_length = track->GetBox().GetSize(Box::CONTENT).y - bar->GetBox().GetSize(Box::CONTENT).y;
|
|
|
+ float traversable_track_length = track->GetBox().GetSize().y - bar->GetBox().GetSize().y;
|
|
|
if (traversable_track_length > 0)
|
|
|
{
|
|
|
float traversable_track_origin = track->GetAbsoluteOffset().y + bar_drag_anchor;
|
|
|
- float new_bar_position = (event.GetParameter< float >("mouse_y", 0) - traversable_track_origin) / traversable_track_length;
|
|
|
- new_bar_position = Math::Clamp(new_bar_position, 0.0f, 1.0f);
|
|
|
-
|
|
|
- SetBarPosition(new_bar_position);
|
|
|
+ new_bar_position = (event.GetParameter("mouse_y", 0.f) - traversable_track_origin) / traversable_track_length;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ SetBarPosition(new_bar_position);
|
|
|
+ Scroll(0.f, ScrollBehavior::Instant);
|
|
|
}
|
|
|
else if (event == EventId::Dragstart)
|
|
|
{
|
|
|
if (orientation == HORIZONTAL)
|
|
|
- bar_drag_anchor = event.GetParameter< int >("mouse_x", 0) - Math::RealToInteger(bar->GetAbsoluteOffset().x);
|
|
|
+ bar_drag_anchor = event.GetParameter("mouse_x", 0.f) - bar->GetAbsoluteOffset().x;
|
|
|
else
|
|
|
- bar_drag_anchor = event.GetParameter< int >("mouse_y", 0) - Math::RealToInteger(bar->GetAbsoluteOffset().y);
|
|
|
+ bar_drag_anchor = event.GetParameter("mouse_y", 0.f) - bar->GetAbsoluteOffset().y;
|
|
|
}
|
|
|
}
|
|
|
else if (event.GetTargetElement() == track)
|
|
|
{
|
|
|
if (event == EventId::Click)
|
|
|
{
|
|
|
+ float click_position = 0.f;
|
|
|
if (orientation == HORIZONTAL)
|
|
|
{
|
|
|
- float mouse_position = event.GetParameter< float >("mouse_x", 0);
|
|
|
- float click_position = (mouse_position - track->GetAbsoluteOffset().x) / track->GetBox().GetSize().x;
|
|
|
-
|
|
|
- SetBarPosition(click_position <= bar_position ? OnPageDecrement() : OnPageIncrement());
|
|
|
+ float mouse_position = event.GetParameter("mouse_x", 0.f);
|
|
|
+ click_position = (mouse_position - track->GetAbsoluteOffset().x) / track->GetBox().GetSize().x;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- float mouse_position = event.GetParameter< float >("mouse_y", 0);
|
|
|
- float click_position = (mouse_position - track->GetAbsoluteOffset().y) / track->GetBox().GetSize().y;
|
|
|
-
|
|
|
- SetBarPosition(click_position <= bar_position ? OnPageDecrement() : OnPageIncrement());
|
|
|
+ float mouse_position = event.GetParameter<float>("mouse_y", 0);
|
|
|
+ click_position = (mouse_position - track->GetAbsoluteOffset().y) / track->GetBox().GetSize().y;
|
|
|
}
|
|
|
+
|
|
|
+ if (click_position <= bar_position)
|
|
|
+ ScrollPageUp();
|
|
|
+ else
|
|
|
+ ScrollPageDown();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -432,13 +425,13 @@ void WidgetScroll::ProcessEvent(Event& event)
|
|
|
{
|
|
|
arrow_timers[0] = DEFAULT_REPEAT_DELAY;
|
|
|
last_update_time = Clock::GetElapsedTime();
|
|
|
- SetBarPosition(OnLineDecrement());
|
|
|
+ ScrollLineUp();
|
|
|
}
|
|
|
else if (event.GetTargetElement() == arrows[1])
|
|
|
{
|
|
|
arrow_timers[1] = DEFAULT_REPEAT_DELAY;
|
|
|
last_update_time = Clock::GetElapsedTime();
|
|
|
- SetBarPosition(OnLineIncrement());
|
|
|
+ ScrollLineDown();
|
|
|
}
|
|
|
}
|
|
|
else if (event == EventId::Mouseup ||
|
|
|
@@ -468,36 +461,16 @@ void WidgetScroll::PositionBar()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
// Sets the length of the entire track in some arbitrary unit.
|
|
|
-void WidgetScroll::SetTrackLength(float _track_length, bool RMLUI_UNUSED_PARAMETER(force_resize))
|
|
|
+void WidgetScroll::SetTrackLength(float _track_length)
|
|
|
{
|
|
|
- RMLUI_UNUSED(force_resize);
|
|
|
-
|
|
|
- if (track_length != _track_length)
|
|
|
- {
|
|
|
- track_length = _track_length;
|
|
|
- // GenerateBar();
|
|
|
- }
|
|
|
+ track_length = _track_length;
|
|
|
}
|
|
|
|
|
|
// Sets the length the bar represents in some arbitrary unit, relative to the track length.
|
|
|
-void WidgetScroll::SetBarLength(float _bar_length, bool RMLUI_UNUSED_PARAMETER(force_resize))
|
|
|
-{
|
|
|
- RMLUI_UNUSED(force_resize);
|
|
|
-
|
|
|
- if (bar_length != _bar_length)
|
|
|
- {
|
|
|
- bar_length = _bar_length;
|
|
|
- // GenerateBar();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Sets the line height of the parent element; this is used for scrolling speeds.
|
|
|
-void WidgetScroll::SetLineHeight(float _line_height)
|
|
|
+void WidgetScroll::SetBarLength(float _bar_length)
|
|
|
{
|
|
|
- line_height = _line_height;
|
|
|
+ bar_length = _bar_length;
|
|
|
}
|
|
|
|
|
|
// Lays out and resizes the internal elements.
|
|
|
@@ -515,42 +488,49 @@ void WidgetScroll::FormatElements(const Vector2f containing_block, float slider_
|
|
|
WidgetScroll::FormatElements(containing_block, true, slider_length, relative_bar_length);
|
|
|
}
|
|
|
|
|
|
-// Called when the slider is incremented by one 'line', either by the down / right key or a mouse-click on the
|
|
|
-// increment arrow.
|
|
|
-float WidgetScroll::OnLineIncrement()
|
|
|
+void WidgetScroll::ScrollLineDown()
|
|
|
{
|
|
|
- return Scroll(line_height);
|
|
|
+ Scroll(SCROLL_LINE_LENGTH * ElementUtilities::GetDensityIndependentPixelRatio(parent), ScrollBehavior::Smooth);
|
|
|
}
|
|
|
|
|
|
-// Called when the slider is decremented by one 'line', either by the up / left key or a mouse-click on the decrement
|
|
|
-// arrow.
|
|
|
-float WidgetScroll::OnLineDecrement()
|
|
|
+void WidgetScroll::ScrollLineUp()
|
|
|
{
|
|
|
- return Scroll(-line_height);
|
|
|
+ Scroll(-SCROLL_LINE_LENGTH * ElementUtilities::GetDensityIndependentPixelRatio(parent), ScrollBehavior::Smooth);
|
|
|
}
|
|
|
|
|
|
-// Called when the slider is incremented by one 'page', either by the page-up key or a mouse-click on the track
|
|
|
-// below / right of the bar.
|
|
|
-float WidgetScroll::OnPageIncrement()
|
|
|
+void WidgetScroll::ScrollPageDown()
|
|
|
{
|
|
|
- return Scroll(bar_length);
|
|
|
+ Scroll(SCROLL_PAGE_FACTOR * bar_length, ScrollBehavior::Smooth);
|
|
|
}
|
|
|
|
|
|
-// Called when the slider is incremented by one 'page', either by the page-down key or a mouse-click on the track
|
|
|
-// above / left of the bar.
|
|
|
-float WidgetScroll::OnPageDecrement()
|
|
|
+void WidgetScroll::ScrollPageUp()
|
|
|
{
|
|
|
- return Scroll(-bar_length);
|
|
|
+ Scroll(-SCROLL_PAGE_FACTOR * bar_length, ScrollBehavior::Smooth);
|
|
|
}
|
|
|
|
|
|
-// Returns the bar position after scrolling for a number of pixels.
|
|
|
-float WidgetScroll::Scroll(float distance)
|
|
|
+void WidgetScroll::Scroll(float distance, ScrollBehavior behavior)
|
|
|
{
|
|
|
float traversable_track_length = (track_length - bar_length);
|
|
|
- if (traversable_track_length <= 0)
|
|
|
- return bar_position;
|
|
|
|
|
|
- return (bar_position * traversable_track_length + distance) / traversable_track_length;
|
|
|
+ float new_bar_position = bar_position;
|
|
|
+ if (traversable_track_length > 0.f)
|
|
|
+ new_bar_position = Math::Clamp((bar_position * traversable_track_length + distance) / traversable_track_length, 0.f, 1.f);
|
|
|
+
|
|
|
+ // 'parent' is the scrollbar element, its parent again is the actual element we want to scroll
|
|
|
+ Element* element_scroll = parent->GetParentNode();
|
|
|
+ if (!element_scroll)
|
|
|
+ {
|
|
|
+ RMLUI_ERROR;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Vector2f scroll_offset = {element_scroll->GetScrollLeft(), element_scroll->GetScrollTop()};
|
|
|
+ if (orientation == HORIZONTAL)
|
|
|
+ scroll_offset.x = new_bar_position * (element_scroll->GetScrollWidth() - element_scroll->GetClientWidth());
|
|
|
+ else
|
|
|
+ scroll_offset.y = new_bar_position * (element_scroll->GetScrollHeight() - element_scroll->GetClientHeight());
|
|
|
+
|
|
|
+ element_scroll->ScrollTo(scroll_offset, behavior);
|
|
|
}
|
|
|
|
|
|
} // namespace Rml
|