Skip to content

Commit 51e17e6

Browse files
author
Swagtoy
committed
Elastic overflow scroll
1 parent 12fc0d3 commit 51e17e6

File tree

2 files changed

+30
-39
lines changed

2 files changed

+30
-39
lines changed

src/gui/guiScrollBar.cpp

+28-38
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ GUIScrollBar::GUIScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s3
2626
dragged_by_slider(false), tray_clicked(false), scroll_pos(0),
2727
draw_center(0), thumb_size(0), min_pos(0), max_pos(100), small_step(10),
2828
large_step(50), drag_offset(0), page_size(100), border_size(0),
29-
m_tsrc(tsrc)
29+
m_tsrc(tsrc), target_pos(0.0f), variable_step(0.0f)
3030
{
3131
refreshControls();
3232
setNotClipped(false);
@@ -90,7 +90,10 @@ bool GUIScrollBar::OnEvent(const SEvent &event)
9090
if (Environment->hasFocus(this)) {
9191
s8 d = event.MouseInput.Wheel < 0 ? -1 : 1;
9292
s8 h = is_horizontal ? 1 : -1;
93-
setPosInterpolated(getTargetPos() + (d * small_step * h));
93+
94+
// NOTE: Is this noticable at all?
95+
variable_step += d;
96+
setPosInterpolated(getTargetPos() + ((event.MouseInput.Wheel + variable_step) * small_step * h));
9497
return true;
9598
}
9699
break;
@@ -192,30 +195,25 @@ void GUIScrollBar::draw()
192195
static inline f32 interpolate_scroll(f32 from, f32 to, f32 amount)
193196
{
194197
f32 step = /*core::round32*/((to - from) * amount);
195-
std::cout << "step: " << step << " ";
196198
if (step == 0)
197199
return to;
198200
return from + step;
199201
}
200202

201203
void GUIScrollBar::interpolatePos()
202204
{
203-
if (target_pos.has_value()) {
204-
// Adjust to match 60 FPS. This also means that interpolation is
205-
// effectively disabled at <= 30 FPS.
206-
f32 amount = 0.1f * (last_delta_ms / 16.667f);
207-
setPosRaw(interpolate_scroll(scroll_pos, *target_pos, amount));
208-
std::cout << "Amount: " << amount << " | at:" << scroll_pos << ", want:" << *target_pos << std::endl;
209-
// if (scroll_pos == target_pos)
210-
// target_pos = std::nullopt;
211-
212-
SEvent e;
213-
e.EventType = EET_GUI_EVENT;
214-
e.GUIEvent.Caller = this;
215-
e.GUIEvent.Element = nullptr;
216-
e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
217-
Parent->OnEvent(e);
218-
}
205+
// Adjust to match 60 FPS. This also means that interpolation is
206+
// effectively disabled at <= 30 FPS.
207+
f32 amount = 0.2f * (last_delta_ms / 16.667f);
208+
setPosRaw(interpolate_scroll(scroll_pos, target_pos, amount));
209+
variable_step *= 0.9f;
210+
211+
SEvent e;
212+
e.EventType = EET_GUI_EVENT;
213+
e.GUIEvent.Caller = this;
214+
e.GUIEvent.Element = nullptr;
215+
e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
216+
Parent->OnEvent(e);
219217
}
220218

221219
void GUIScrollBar::OnPostRender(u32 time_ms)
@@ -275,12 +273,13 @@ void GUIScrollBar::setPosRaw(const s32 &pos)
275273

276274
if (!is_dragging)
277275
{
278-
if (scroll_pos < 0) {
279-
*target_pos = (*target_pos * 0.9);
280-
}
281-
else if (scroll_pos > max_pos) {
282-
*target_pos += ((*target_pos) - max_pos) * -0.3;
283-
}
276+
// TODO support deltatime
277+
if (scroll_pos < 0) {
278+
target_pos = (target_pos * 0.9);
279+
}
280+
else if (scroll_pos > max_pos) {
281+
target_pos += (target_pos - max_pos) * -0.3;
282+
}
284283
}
285284

286285
f32 f = core::isnotzero(range()) ? (f32(thumb_area) - f32(thumb_size)) / range()
@@ -293,7 +292,6 @@ void GUIScrollBar::setPos(const s32 &pos)
293292
{
294293
setPosRaw(pos);
295294
target_pos = pos;
296-
//target_pos = std::nullopt;
297295
}
298296

299297
void GUIScrollBar::setPosAndSend(const s32 &pos)
@@ -316,14 +314,9 @@ void GUIScrollBar::setPosInterpolated(const s32 &pos)
316314
setPosAndSend(pos);
317315
return;
318316
}
319-
320-
s32 clamped = pos;//core::s32_clamp(pos, min_pos, max_pos);
321-
if (scroll_pos != clamped) {
322-
target_pos = clamped;
323-
interpolatePos();
324-
} else {
325-
//target_pos = std::nullopt;
326-
}
317+
318+
target_pos = pos;
319+
interpolatePos();
327320
}
328321

329322
void GUIScrollBar::setSmallStep(const s32 &step)
@@ -379,10 +372,7 @@ s32 GUIScrollBar::getPos() const
379372

380373
s32 GUIScrollBar::getTargetPos() const
381374
{
382-
if (target_pos.has_value()) {
383-
return *target_pos;
384-
}
385-
return scroll_pos;
375+
return target_pos;
386376
}
387377

388378
void GUIScrollBar::refreshControls()

src/gui/guiScrollBar.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ class GUIScrollBar : public IGUIElement
9494

9595
void setPosRaw(const s32 &pos);
9696
void updatePos();
97-
std::optional<f32> target_pos;
97+
f32 target_pos;
98+
f32 variable_step;
9899
u32 last_time_ms = 0;
99100
u32 last_delta_ms = 17; // assume 60 FPS
100101
void interpolatePos();

0 commit comments

Comments
 (0)