Added ScrollableWidget class
This commit is contained in:
parent
510ce50684
commit
63d00adf96
5 changed files with 192 additions and 159 deletions
|
|
@ -43,7 +43,7 @@ window.backgroundColor = rgba(160, 160, 160, 255)
|
||||||
(scrollbar) {
|
(scrollbar) {
|
||||||
(thumb) {
|
(thumb) {
|
||||||
color = rgb(140, 140, 140)
|
color = rgb(140, 140, 140)
|
||||||
borderRadius = 0.0
|
borderRadius = 16.0
|
||||||
borderColor = rgb(150, 150, 150)
|
borderColor = rgb(150, 150, 150)
|
||||||
showBorder = true
|
showBorder = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,28 +35,6 @@ namespace ogfx
|
||||||
disableDrawBox();
|
disableDrawBox();
|
||||||
disableFocus();
|
disableFocus();
|
||||||
enableStopEvents();
|
enableStopEvents();
|
||||||
allowVScroll(true);
|
|
||||||
allowHScroll(true);
|
|
||||||
m_vScrollbar.setMargin({ 0, getTitlebarHeight(), 0, 0 });
|
|
||||||
m_vScrollbar.enableManualDraw(true);
|
|
||||||
addWidget(m_vScrollbar);
|
|
||||||
m_hScrollbar.setMargin({ 0, 0, 0, 0 });
|
|
||||||
m_hScrollbar.enableManualDraw(true);
|
|
||||||
addWidget(m_hScrollbar);
|
|
||||||
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();
|
validate();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -71,8 +49,8 @@ namespace ogfx
|
||||||
setBorderColor(getThemeValue<Color>(theme, "panel.borderColor", Colors::Black));
|
setBorderColor(getThemeValue<Color>(theme, "panel.borderColor", Colors::Black));
|
||||||
setPadding(getThemeValue<Rectangle>(theme, "panel.padding", { 15, 15, 15, 15 }));
|
setPadding(getThemeValue<Rectangle>(theme, "panel.padding", { 15, 15, 15, 15 }));
|
||||||
setMargin(getThemeValue<Rectangle>(theme, "panel.margin", { 0, 0, 0, 0 }));
|
setMargin(getThemeValue<Rectangle>(theme, "panel.margin", { 0, 0, 0, 0 }));
|
||||||
m_scrollSpeed = getThemeValue<f32>(theme, "panel.scrollSpeed", 0.8f);
|
setScrollSpeed(getThemeValue<f32>(theme, "panel.scrollSpeed", 0.8f));
|
||||||
m_scrollSmoothFactor = std::clamp(getThemeValue<f32>(theme, "panel.scrollSmoothFactor", 0.7f), 0.0f, 1.0f);
|
setScrollSmoothFactor(getThemeValue<f32>(theme, "panel.scrollSmoothFactor", 0.7f));
|
||||||
m_titleColor = getThemeValue<Color>(theme, "panel.titleColor", Colors::Black);
|
m_titleColor = getThemeValue<Color>(theme, "panel.titleColor", Colors::Black);
|
||||||
m_titlebarColor = getThemeValue<Color>(theme, "panel.titlebarColor", Colors::Transparent);
|
m_titlebarColor = getThemeValue<Color>(theme, "panel.titlebarColor", Colors::Transparent);
|
||||||
m_titlebarBorderColor = getThemeValue<Color>(theme, "panel.titlebarBorderColor", Colors::Black);
|
m_titlebarBorderColor = getThemeValue<Color>(theme, "panel.titlebarBorderColor", Colors::Black);
|
||||||
|
|
@ -83,54 +61,10 @@ namespace ogfx
|
||||||
setTitlebarType(getThemeValue<String>(theme, "panel.titlebarType", TitleBarTypes::None));
|
setTitlebarType(getThemeValue<String>(theme, "panel.titlebarType", TitleBarTypes::None));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::onDraw(ogfx::BasicRenderer2D& gfx)
|
|
||||||
{
|
|
||||||
// if (isScrollAllowed())
|
|
||||||
// gfx.fillRect(getContentExtents() + Rectangle { getGlobalPosition(), 0, 0 }, { 80, 0, 0, 30 });
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::onUpdate(void)
|
|
||||||
{
|
|
||||||
m_smoothScrollTimer.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::afterDraw(ogfx::BasicRenderer2D& gfx)
|
void Panel::afterDraw(ogfx::BasicRenderer2D& gfx)
|
||||||
{
|
{
|
||||||
draw_titlebar(gfx);
|
draw_titlebar(gfx);
|
||||||
m_vScrollbar.__draw(gfx);
|
drawScrollbars(gfx);
|
||||||
m_hScrollbar.__draw(gfx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::onMouseScrolled(const Event& event)
|
|
||||||
{
|
|
||||||
if (isVScrollAllowed())
|
|
||||||
{
|
|
||||||
bool mouseInsideHScrollbar = m_hScrollbar.isMouseInsideThumb({ event.mouse->position_x, event.mouse->position_y });
|
|
||||||
if (std::abs(event.mouse->scrollAmount.y) > 0 && !mouseInsideHScrollbar)
|
|
||||||
{
|
|
||||||
m_scrollVelocity.y += m_scrollSpeed * event.mouse->scrollAmount.y * m_scrollSpeedMultiplier;
|
|
||||||
if (m_smoothScrollTimer.isStopped())
|
|
||||||
m_smoothScrollTimer.restart();
|
|
||||||
event.handle();
|
|
||||||
}
|
|
||||||
else if (std::abs(event.mouse->scrollAmount.y) > 0)
|
|
||||||
{
|
|
||||||
m_scrollVelocity.x += m_scrollSpeed * event.mouse->scrollAmount.y * m_scrollSpeedMultiplier;
|
|
||||||
if (m_smoothScrollTimer.isStopped())
|
|
||||||
m_smoothScrollTimer.restart();
|
|
||||||
event.handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isHScrollAllowed())
|
|
||||||
{
|
|
||||||
if (std::abs(event.mouse->scrollAmount.x) > 0)
|
|
||||||
{
|
|
||||||
m_scrollVelocity.x += m_scrollSpeed * event.mouse->scrollAmount.x * m_scrollSpeedMultiplier;
|
|
||||||
if (m_smoothScrollTimer.isStopped())
|
|
||||||
m_smoothScrollTimer.restart();
|
|
||||||
event.handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::setTitlebarType(const String& type)
|
void Panel::setTitlebarType(const String& type)
|
||||||
|
|
@ -139,16 +73,19 @@ namespace ogfx
|
||||||
if (t == TitleBarTypes::None)
|
if (t == TitleBarTypes::None)
|
||||||
{
|
{
|
||||||
setContentOffset({ 0, 0 });
|
setContentOffset({ 0, 0 });
|
||||||
|
updateScrollbarsSize();
|
||||||
m_titlebarType = TitleBarTypes::NoneValue;
|
m_titlebarType = TitleBarTypes::NoneValue;
|
||||||
}
|
}
|
||||||
else if (t == TitleBarTypes::Minimal)
|
else if (t == TitleBarTypes::Minimal)
|
||||||
{
|
{
|
||||||
setContentOffset({ 0, m_titlebarHeight });
|
setContentOffset({ 0, m_titlebarHeight });
|
||||||
|
updateScrollbarsSize();
|
||||||
m_titlebarType = TitleBarTypes::MinimalValue;
|
m_titlebarType = TitleBarTypes::MinimalValue;
|
||||||
}
|
}
|
||||||
else if (t == TitleBarTypes::Full)
|
else if (t == TitleBarTypes::Full)
|
||||||
{
|
{
|
||||||
setContentOffset({ 0, m_titlebarHeight });
|
setContentOffset({ 0, m_titlebarHeight });
|
||||||
|
updateScrollbarsSize();
|
||||||
m_titlebarType = TitleBarTypes::FullValue;
|
m_titlebarType = TitleBarTypes::FullValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -164,72 +101,6 @@ namespace ogfx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::setScrollOffset(const Vec2& offset)
|
|
||||||
{
|
|
||||||
auto ext = getContentExtents();
|
|
||||||
auto cont = getContentBounds();
|
|
||||||
f32 maxScrollY = -(ext.h - cont.h);
|
|
||||||
f32 maxScrollX = -(ext.w - cont.w);
|
|
||||||
|
|
||||||
m_scrollOffset = offset;
|
|
||||||
|
|
||||||
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 maxScrollY = -(ext.h - cont.h);
|
|
||||||
f32 maxScrollX = -(ext.w - cont.w);
|
|
||||||
|
|
||||||
m_scrollOffset += offset;
|
|
||||||
|
|
||||||
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::needsVScroll(void) const
|
|
||||||
{
|
|
||||||
return isVScrollAllowed() && getContentExtents().h > getContentBounds().h;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Panel::needsHScroll(void) const
|
|
||||||
{
|
|
||||||
return isHScrollAllowed() && getContentExtents().w > getContentBounds().w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::onWidgetAdded(Widget& child)
|
|
||||||
{
|
|
||||||
removeWidget(m_vScrollbar);
|
|
||||||
removeWidget(m_hScrollbar);
|
|
||||||
addWidget(m_vScrollbar, { 0, 0 }, true);
|
|
||||||
addWidget(m_hScrollbar, { 0, 0 }, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 Panel::getVScrollbarSize(void) const
|
|
||||||
{
|
|
||||||
if (!isVScrollAllowed())
|
|
||||||
return 0;
|
|
||||||
if (!needsVScroll())
|
|
||||||
return 0;
|
|
||||||
return m_vScrollbar.getw();
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 Panel::getHScrollbarSize(void) const
|
|
||||||
{
|
|
||||||
if (!isHScrollAllowed())
|
|
||||||
return 0;
|
|
||||||
if (!needsHScroll())
|
|
||||||
return 0;
|
|
||||||
return m_hScrollbar.geth();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::draw_titlebar(BasicRenderer2D& gfx)
|
void Panel::draw_titlebar(BasicRenderer2D& gfx)
|
||||||
{
|
{
|
||||||
f32 br = cast<f32>(getBorderWidth());
|
f32 br = cast<f32>(getBorderWidth());
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace ogfx
|
||||||
{
|
{
|
||||||
namespace widgets
|
namespace widgets
|
||||||
{
|
{
|
||||||
class Panel : public Widget
|
class Panel : public ScrollableWidget
|
||||||
{
|
{
|
||||||
public: struct TitleBarTypes
|
public: struct TitleBarTypes
|
||||||
{
|
{
|
||||||
|
|
@ -43,27 +43,16 @@ namespace ogfx
|
||||||
inline static constexpr i32 MinimalValue = 2;
|
inline static constexpr i32 MinimalValue = 2;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
inline Panel(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(); }
|
inline Panel(WindowCore& window) : ScrollableWidget(window) { create(); }
|
||||||
Panel& create(void);
|
Panel& create(void);
|
||||||
void applyTheme(const ostd::Stylesheet& theme) override;
|
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||||
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
|
||||||
void onUpdate(void) override;
|
|
||||||
void afterDraw(ogfx::BasicRenderer2D& gfx) override;
|
void afterDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||||
void onMouseScrolled(const Event& event) override;
|
|
||||||
void setTitlebarType(const String& type);
|
void setTitlebarType(const String& type);
|
||||||
String getTitlebarType(void) const;
|
String getTitlebarType(void) const;
|
||||||
void setScrollOffset(const Vec2& offset) override;
|
|
||||||
void addScrollOffset(const Vec2& offset) override;
|
|
||||||
bool needsVScroll(void) const override;
|
|
||||||
bool needsHScroll(void) const override;
|
|
||||||
void onWidgetAdded(Widget& child) override;
|
|
||||||
f32 getVScrollbarSize(void) const override;
|
|
||||||
f32 getHScrollbarSize(void) const override;
|
|
||||||
inline void setBackGroundColor(const Color& color) { m_backgroundColor = color; }
|
inline void setBackGroundColor(const Color& color) { m_backgroundColor = color; }
|
||||||
inline Color getBackgroundColor(void) { return m_backgroundColor; }
|
inline Color getBackgroundColor(void) { return m_backgroundColor; }
|
||||||
inline String getTitle(void) const { return m_title; }
|
inline String getTitle(void) const { return m_title; }
|
||||||
inline void setTitle(const String& title) { m_title = title; }
|
inline void setTitle(const String& title) { m_title = title; }
|
||||||
inline Vec2 getScrollOffset(void) const override { return m_scrollOffset; }
|
|
||||||
inline f32 getTitlebarHeight(void) const { return m_titlebarHeight; }
|
inline f32 getTitlebarHeight(void) const { return m_titlebarHeight; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -71,10 +60,6 @@ namespace ogfx
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_title { "Panel" };
|
String m_title { "Panel" };
|
||||||
Vec2 m_scrollOffset { 0, 0 };
|
|
||||||
VerticalScrollBar m_vScrollbar { getWindow() };
|
|
||||||
HorizontalScrollbar m_hScrollbar { getWindow() };
|
|
||||||
ostd::StepTimer m_smoothScrollTimer;
|
|
||||||
|
|
||||||
Color m_titleColor { Colors::Black };
|
Color m_titleColor { Colors::Black };
|
||||||
i32 m_titlebarType = TitleBarTypes::NoneValue;
|
i32 m_titlebarType = TitleBarTypes::NoneValue;
|
||||||
|
|
@ -84,11 +69,6 @@ namespace ogfx
|
||||||
Color m_titlebarColor { Colors::Transparent };
|
Color m_titlebarColor { Colors::Transparent };
|
||||||
Color m_titlebarBorderColor { Colors::Black };
|
Color m_titlebarBorderColor { Colors::Black };
|
||||||
i32 m_titleTextAlign { 0 };
|
i32 m_titleTextAlign { 0 };
|
||||||
f32 m_scrollSpeed { 0.8f };
|
|
||||||
|
|
||||||
Vec2 m_scrollVelocity { 0.0f, 0.0f };
|
|
||||||
f32 m_scrollSmoothFactor { 0.7f };
|
|
||||||
f32 m_scrollSpeedMultiplier { 15.0f };
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ namespace ogfx
|
||||||
m_thumbBorderColor = getThemeValue<Color>(theme, "scrollbar.thumb.borderColor", { 150, 150, 150 });
|
m_thumbBorderColor = getThemeValue<Color>(theme, "scrollbar.thumb.borderColor", { 150, 150, 150 });
|
||||||
m_thumbShowBorder = getThemeValue<bool>(theme, "scrollbar.thumb.showBorder", true);
|
m_thumbShowBorder = getThemeValue<bool>(theme, "scrollbar.thumb.showBorder", true);
|
||||||
m_trackColor = getThemeValue<Color>(theme, "scrollbar.track.color", { 70, 70, 70 });
|
m_trackColor = getThemeValue<Color>(theme, "scrollbar.track.color", { 70, 70, 70 });
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizontalScrollbar::afterDraw(ogfx::BasicRenderer2D& gfx)
|
void HorizontalScrollbar::afterDraw(ogfx::BasicRenderer2D& gfx)
|
||||||
{
|
{
|
||||||
|
|
@ -268,6 +268,154 @@ namespace ogfx
|
||||||
parentScrollOffset.x = maxScroll * scrollProgress;
|
parentScrollOffset.x = maxScroll * scrollProgress;
|
||||||
getParent()->setScrollOffset(parentScrollOffset);
|
getParent()->setScrollOffset(parentScrollOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ScrollableWidget& ScrollableWidget::create(void)
|
||||||
|
{
|
||||||
|
setTypeName("ogfx::gui::widgets::ScrollableWidget");
|
||||||
|
allowVScroll(true);
|
||||||
|
allowHScroll(true);
|
||||||
|
m_vScrollbar.enableManualDraw(true);
|
||||||
|
addWidget(m_vScrollbar);
|
||||||
|
m_hScrollbar.setMargin({ 0, 0, 0, 0 });
|
||||||
|
m_hScrollbar.enableManualDraw(true);
|
||||||
|
addWidget(m_hScrollbar);
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
updateScrollbarsSize();
|
||||||
|
validate();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollableWidget::onUpdate(void)
|
||||||
|
{
|
||||||
|
m_smoothScrollTimer.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollableWidget::drawScrollbars(ogfx::BasicRenderer2D& gfx)
|
||||||
|
{
|
||||||
|
m_vScrollbar.__draw(gfx);
|
||||||
|
m_hScrollbar.__draw(gfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollableWidget::updateScrollbarsSize(void)
|
||||||
|
{
|
||||||
|
m_vScrollbar.setMargin({ 0, getPureContentBounds().y, 0, 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollableWidget::onMouseScrolled(const Event& event)
|
||||||
|
{
|
||||||
|
if (isVScrollAllowed())
|
||||||
|
{
|
||||||
|
bool mouseInsideHScrollbar = m_hScrollbar.isMouseInsideThumb({ event.mouse->position_x, event.mouse->position_y });
|
||||||
|
if (std::abs(event.mouse->scrollAmount.y) > 0 && !mouseInsideHScrollbar)
|
||||||
|
{
|
||||||
|
m_scrollVelocity.y += m_scrollSpeed * event.mouse->scrollAmount.y * m_scrollSpeedMultiplier;
|
||||||
|
if (m_smoothScrollTimer.isStopped())
|
||||||
|
m_smoothScrollTimer.restart();
|
||||||
|
event.handle();
|
||||||
|
}
|
||||||
|
else if (std::abs(event.mouse->scrollAmount.y) > 0)
|
||||||
|
{
|
||||||
|
m_scrollVelocity.x += m_scrollSpeed * event.mouse->scrollAmount.y * m_scrollSpeedMultiplier;
|
||||||
|
if (m_smoothScrollTimer.isStopped())
|
||||||
|
m_smoothScrollTimer.restart();
|
||||||
|
event.handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isHScrollAllowed())
|
||||||
|
{
|
||||||
|
if (std::abs(event.mouse->scrollAmount.x) > 0)
|
||||||
|
{
|
||||||
|
m_scrollVelocity.x += m_scrollSpeed * event.mouse->scrollAmount.x * m_scrollSpeedMultiplier;
|
||||||
|
if (m_smoothScrollTimer.isStopped())
|
||||||
|
m_smoothScrollTimer.restart();
|
||||||
|
event.handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollableWidget::setScrollOffset(const Vec2& offset)
|
||||||
|
{
|
||||||
|
auto ext = getContentExtents();
|
||||||
|
auto cont = getContentBounds();
|
||||||
|
f32 maxScrollY = -(ext.h - cont.h);
|
||||||
|
f32 maxScrollX = -(ext.w - cont.w);
|
||||||
|
|
||||||
|
m_scrollOffset = offset;
|
||||||
|
|
||||||
|
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 ScrollableWidget::addScrollOffset(const Vec2& offset)
|
||||||
|
{
|
||||||
|
auto ext = getContentExtents();
|
||||||
|
auto cont = getContentBounds();
|
||||||
|
f32 maxScrollY = -(ext.h - cont.h);
|
||||||
|
f32 maxScrollX = -(ext.w - cont.w);
|
||||||
|
|
||||||
|
m_scrollOffset += offset;
|
||||||
|
|
||||||
|
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 ScrollableWidget::needsVScroll(void) const
|
||||||
|
{
|
||||||
|
return isVScrollAllowed() && getContentExtents().h > getContentBounds().h;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScrollableWidget::needsHScroll(void) const
|
||||||
|
{
|
||||||
|
return isHScrollAllowed() && getContentExtents().w > getContentBounds().w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollableWidget::onWidgetAdded(Widget& child)
|
||||||
|
{
|
||||||
|
removeWidget(m_vScrollbar);
|
||||||
|
removeWidget(m_hScrollbar);
|
||||||
|
addWidget(m_vScrollbar, { 0, 0 }, true);
|
||||||
|
addWidget(m_hScrollbar, { 0, 0 }, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 ScrollableWidget::getVScrollbarSize(void) const
|
||||||
|
{
|
||||||
|
if (!isVScrollAllowed())
|
||||||
|
return 0;
|
||||||
|
if (!needsVScroll())
|
||||||
|
return 0;
|
||||||
|
return m_vScrollbar.getw();
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 ScrollableWidget::getHScrollbarSize(void) const
|
||||||
|
{
|
||||||
|
if (!isHScrollAllowed())
|
||||||
|
return 0;
|
||||||
|
if (!needsHScroll())
|
||||||
|
return 0;
|
||||||
|
return m_hScrollbar.geth();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ogfx/gui/widgets/Widget.hpp>
|
#include <ogfx/gui/widgets/Widget.hpp>
|
||||||
|
#include <ostd/utils/Time.hpp>
|
||||||
|
|
||||||
namespace ogfx
|
namespace ogfx
|
||||||
{
|
{
|
||||||
|
|
@ -104,6 +105,39 @@ namespace ogfx
|
||||||
Color m_thumbBorderColor { 150, 150, 150 };
|
Color m_thumbBorderColor { 150, 150, 150 };
|
||||||
bool m_thumbShowBorder { true };
|
bool m_thumbShowBorder { true };
|
||||||
};
|
};
|
||||||
|
class ScrollableWidget : public Widget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline ScrollableWidget(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(); }
|
||||||
|
ScrollableWidget& create(void);
|
||||||
|
virtual void onUpdate(void) override;
|
||||||
|
void drawScrollbars(ogfx::BasicRenderer2D& gfx);
|
||||||
|
void updateScrollbarsSize(void);
|
||||||
|
virtual void onMouseScrolled(const Event& event) override;
|
||||||
|
virtual void setScrollOffset(const Vec2& offset) override;
|
||||||
|
virtual void addScrollOffset(const Vec2& offset) override;
|
||||||
|
virtual bool needsVScroll(void) const override;
|
||||||
|
virtual bool needsHScroll(void) const override;
|
||||||
|
virtual void onWidgetAdded(Widget& child) override;
|
||||||
|
virtual f32 getVScrollbarSize(void) const override;
|
||||||
|
virtual f32 getHScrollbarSize(void) const override;
|
||||||
|
inline Vec2 getScrollOffset(void) const override { return m_scrollOffset; }
|
||||||
|
inline void setScrollSpeed(f32 speed) { m_scrollSpeed = speed; }
|
||||||
|
inline f32 getScrollSpeed(void) const { return m_scrollSpeed; }
|
||||||
|
inline void setScrollSmoothFactor(f32 speed) { m_scrollSmoothFactor = std::clamp(speed, 0.0f, 1.0f); }
|
||||||
|
inline f32 getScrollSmoothFactor(void) const { return m_scrollSmoothFactor; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
String m_title { "Panel" };
|
||||||
|
Vec2 m_scrollOffset { 0, 0 };
|
||||||
|
VerticalScrollBar m_vScrollbar { getWindow() };
|
||||||
|
HorizontalScrollbar m_hScrollbar { getWindow() };
|
||||||
|
ostd::StepTimer m_smoothScrollTimer;
|
||||||
|
f32 m_scrollSpeed { 0.8f };
|
||||||
|
Vec2 m_scrollVelocity { 0.0f, 0.0f };
|
||||||
|
f32 m_scrollSmoothFactor { 0.7f };
|
||||||
|
f32 m_scrollSpeedMultiplier { 15.0f };
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue