Added smooth scrolling + horizontal scrolling support
This commit is contained in:
parent
d618de0981
commit
d8475ecb48
7 changed files with 46 additions and 37 deletions
1
.clangd
1
.clangd
|
|
@ -1,5 +1,4 @@
|
|||
CompileFlags:
|
||||
CompilationDatabase: bin
|
||||
Add: ["--target=x86_64-w64-mingw32"]
|
||||
Diagnostics:
|
||||
MissingIncludes: None
|
||||
|
|
@ -30,7 +30,8 @@ window.backgroundColor = rgba(160, 160, 160, 255)
|
|||
titlebarHeight = 18
|
||||
titlebarFontSize = 18
|
||||
titlebarTextAlign = text_left
|
||||
scrollSpeed = 15.0
|
||||
scrollSpeed = 1.2
|
||||
scrollSmoothFactor = 0.7
|
||||
padding = rect(15, 15, 15, 15)
|
||||
margin = rect(0, 0, 0, 0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2067
|
||||
2069
|
||||
|
|
|
|||
|
|
@ -39,15 +39,20 @@ namespace ogfx
|
|||
m_scrollbar.setMargin({ 0, getTitlebarHeight(), 0, 0 });
|
||||
m_scrollbar.enableManualDraw(true);
|
||||
addWidget(m_scrollbar);
|
||||
m_smoothScrollTimer.create(30.0f, [&](f64 dt) -> void {
|
||||
f32 scrollStep = m_scrollTarget / 60.0f;
|
||||
m_currentScroll += scrollStep;
|
||||
addScrollOffset({ 0, scrollStep });
|
||||
if (m_currentScroll > m_scrollTarget)
|
||||
m_currentScroll = m_scrollTarget;
|
||||
}, [&](void) -> bool {
|
||||
return m_currentScroll == m_scrollTarget;
|
||||
m_smoothScrollTimer.create(60.0f, [&](f64 dt) -> void {
|
||||
f32 stepX = m_scrollVelocity.x * (1.0f - m_scrollSmoothFactor);
|
||||
f32 stepY = m_scrollVelocity.y * (1.0f - m_scrollSmoothFactor);
|
||||
|
||||
addScrollOffset({ stepX, stepY });
|
||||
m_scrollVelocity -= { stepX, stepY };
|
||||
|
||||
if (std::abs(m_scrollVelocity.x) < 0.5f) m_scrollVelocity.x = 0;
|
||||
if (std::abs(m_scrollVelocity.y) < 0.5f) m_scrollVelocity.y = 0;
|
||||
}, true);
|
||||
|
||||
m_smoothScrollTimer.setStopCondition([&](void) -> bool {
|
||||
return m_scrollVelocity.x == 0 && m_scrollVelocity.y == 0;
|
||||
});
|
||||
validate();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -63,6 +68,7 @@ namespace ogfx
|
|||
setPadding(getThemeValue<Rectangle>(theme, "panel.padding", { 15, 15, 15, 15 }));
|
||||
setMargin(getThemeValue<Rectangle>(theme, "panel.margin", { 0, 0, 0, 0 }));
|
||||
m_scrollSpeed = getThemeValue<f32>(theme, "panel.scrollSpeed", 0.8f);
|
||||
m_scrollSmoothFactor = std::clamp(getThemeValue<f32>(theme, "panel.scrollSmoothFactor", 0.7f), 0.0f, 1.0f);
|
||||
m_basePadding = getPadding();
|
||||
m_titleColor = getThemeValue<Color>(theme, "panel.titleColor", Colors::Black);
|
||||
m_titlebarColor = getThemeValue<Color>(theme, "panel.titlebarColor", Colors::Transparent);
|
||||
|
|
@ -95,19 +101,15 @@ namespace ogfx
|
|||
{
|
||||
if (!isScrollAllowed())
|
||||
return;
|
||||
|
||||
if (std::abs(event.mouse->scrollAmount.y) > 0)
|
||||
m_scrollVelocity.y += m_scrollSpeed * event.mouse->scrollAmount.y * 15.0f;
|
||||
if (std::abs(event.mouse->scrollAmount.x) > 0)
|
||||
m_scrollVelocity.x += m_scrollSpeed * event.mouse->scrollAmount.x * 15.0f;
|
||||
|
||||
if (m_smoothScrollTimer.isStopped())
|
||||
m_smoothScrollTimer.restart();
|
||||
f32 offset_y = 0;
|
||||
if (event.mouse->scroll == MouseEventData::eScrollDirection::Down)
|
||||
{
|
||||
|
||||
m_scrollTarget += (m_scrollSpeed * event.mouse->scrollAmount.y);
|
||||
}
|
||||
else if (event.mouse->scroll == MouseEventData::eScrollDirection::Up)
|
||||
{
|
||||
|
||||
m_scrollTarget += (m_scrollSpeed * event.mouse->scrollAmount.y);
|
||||
}
|
||||
event.handle();
|
||||
}
|
||||
|
||||
|
|
@ -146,24 +148,30 @@ namespace ogfx
|
|||
{
|
||||
auto ext = getContentExtents();
|
||||
auto cont = getContentBounds();
|
||||
f32 maxScroll = -(ext.h - cont.h);
|
||||
f32 maxScrollY = -(ext.h - cont.h);
|
||||
f32 maxScrollX = -(ext.w - cont.w);
|
||||
|
||||
m_scrollOffset = offset;
|
||||
if (m_scrollOffset.y < maxScroll)
|
||||
m_scrollOffset.y = maxScroll;
|
||||
if (m_scrollOffset.y > 0)
|
||||
m_scrollOffset.y = 0;
|
||||
|
||||
if (m_scrollOffset.y < maxScrollY) m_scrollOffset.y = maxScrollY;
|
||||
if (m_scrollOffset.y > 0) m_scrollOffset.y = 0;
|
||||
if (m_scrollOffset.x < maxScrollX) m_scrollOffset.x = maxScrollX;
|
||||
if (m_scrollOffset.x > 0) m_scrollOffset.x = 0;
|
||||
}
|
||||
|
||||
void Panel::addScrollOffset(const Vec2& offset)
|
||||
{
|
||||
auto ext = getContentExtents();
|
||||
auto cont = getContentBounds();
|
||||
f32 maxScroll = -(ext.h - cont.h);
|
||||
f32 maxScrollY = -(ext.h - cont.h);
|
||||
f32 maxScrollX = -(ext.w - cont.w);
|
||||
|
||||
m_scrollOffset += offset;
|
||||
if (m_scrollOffset.y < maxScroll)
|
||||
m_scrollOffset.y = maxScroll;
|
||||
if (m_scrollOffset.y > 0)
|
||||
m_scrollOffset.y = 0;
|
||||
|
||||
if (m_scrollOffset.y < maxScrollY) m_scrollOffset.y = maxScrollY;
|
||||
if (m_scrollOffset.y > 0) m_scrollOffset.y = 0;
|
||||
if (m_scrollOffset.x < maxScrollX) m_scrollOffset.x = maxScrollX;
|
||||
if (m_scrollOffset.x > 0) m_scrollOffset.x = 0;
|
||||
}
|
||||
|
||||
bool Panel::needsScroll(void) const
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ namespace ogfx
|
|||
i32 m_titleTextAlign { 0 };
|
||||
f32 m_scrollSpeed { 0.8f };
|
||||
|
||||
f32 m_scrollTarget { 0.0f };
|
||||
f32 m_currentScroll { 0.0f };
|
||||
Vec2 m_scrollVelocity { 0.0f, 0.0f };
|
||||
f32 m_scrollSmoothFactor { 0.7f };
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -597,11 +597,10 @@ namespace ostd
|
|||
|
||||
|
||||
|
||||
StepTimer& StepTimer::create(f64 updatesPerSecond, StepTimer::Callback callback, StopConditionCallback stopCondition, bool stopped)
|
||||
StepTimer& StepTimer::create(f64 updatesPerSecond, StepTimer::Callback callback, bool stopped)
|
||||
{
|
||||
m_targetDt = 1.0 / updatesPerSecond;
|
||||
m_callback = std::move(callback);
|
||||
m_stopCondition = std::move(stopCondition);
|
||||
m_prevTime = Clock::now();
|
||||
m_accumulator = 0.0;
|
||||
m_stopped = stopped;
|
||||
|
|
@ -615,6 +614,8 @@ namespace ostd
|
|||
if (m_stopCondition && m_stopCondition())
|
||||
{
|
||||
m_stopped = true;
|
||||
if (m_stopCallback)
|
||||
m_stopCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,8 +131,8 @@ namespace ostd
|
|||
StepTimer& create(f64 updatesPerSecond, Callback callback, bool stopped = false);
|
||||
void update(void);
|
||||
void reset(void);
|
||||
inline void setStopCondition(StopConditionCallback stopCondition) { m_stopCondition = stopCondition; }
|
||||
inline void setStopCallback(StopCallback callback) { m_stopCallback = callback; }
|
||||
inline void setStopCondition(StopConditionCallback stopCondition) { m_stopCondition = std::move(stopCondition); }
|
||||
inline void setStopCallback(StopCallback callback) { m_stopCallback = std::move(callback); }
|
||||
inline void restart(void) { reset(); }
|
||||
inline void stop(void) { m_stopped = true; }
|
||||
inline f64 getInterpolationAlpha(void) const { return m_valid && m_targetDt > 0.0 ? m_accumulator / m_targetDt : 0.0; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue