Added Horizontal scrollbar

This commit is contained in:
OmniaX-Dev 2026-04-19 05:42:03 +02:00
parent 891e17948a
commit 510ce50684
9 changed files with 143 additions and 58 deletions

View file

@ -43,13 +43,12 @@ window.backgroundColor = rgba(160, 160, 160, 255)
(scrollbar) { (scrollbar) {
(thumb) { (thumb) {
color = rgb(140, 140, 140) color = rgb(140, 140, 140)
borderRadius = 16 borderRadius = 0.0
borderColor = rgb(150, 150, 150) borderColor = rgb(150, 150, 150)
showBorder = true showBorder = true
} }
(track) { (track) {
color = rgb(90, 90, 90) color = rgb(90, 90, 90)
borderRadii = rect(0, 0, 10, 0)
} }
width = 18.0 width = 18.0
} }
@ -145,7 +144,7 @@ window.backgroundColor = rgba(160, 160, 160, 255)
} }
(button:pressed) { (button:pressed) {
borderColor = $accentColorDark borderColor = $accentColorDark
textColor = #DDDDDDFF textColor = #BBBBBBFF
backgroundGradient = gradientV(rgb(120, 120, 120) - rgb(160, 160, 160)) backgroundGradient = gradientV(rgb(120, 120, 120) - rgb(160, 160, 160))
} }
% ==================== % ====================

View file

@ -35,7 +35,8 @@ namespace ogfx
disableDrawBox(); disableDrawBox();
disableFocus(); disableFocus();
enableStopEvents(); enableStopEvents();
allowScroll(true); allowVScroll(true);
allowHScroll(true);
m_vScrollbar.setMargin({ 0, getTitlebarHeight(), 0, 0 }); m_vScrollbar.setMargin({ 0, getTitlebarHeight(), 0, 0 });
m_vScrollbar.enableManualDraw(true); m_vScrollbar.enableManualDraw(true);
addWidget(m_vScrollbar); addWidget(m_vScrollbar);
@ -72,7 +73,6 @@ namespace ogfx
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); 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_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_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);
@ -103,18 +103,34 @@ namespace ogfx
void Panel::onMouseScrolled(const Event& event) void Panel::onMouseScrolled(const Event& event)
{ {
if (!isScrollAllowed()) if (isVScrollAllowed())
return; {
bool mouseInsideHScrollbar = m_hScrollbar.isMouseInsideThumb({ event.mouse->position_x, event.mouse->position_y });
if (std::abs(event.mouse->scrollAmount.y) > 0) if (std::abs(event.mouse->scrollAmount.y) > 0 && !mouseInsideHScrollbar)
m_scrollVelocity.y += m_scrollSpeed * event.mouse->scrollAmount.y * 15.0f; {
if (std::abs(event.mouse->scrollAmount.x) > 0) m_scrollVelocity.y += m_scrollSpeed * event.mouse->scrollAmount.y * m_scrollSpeedMultiplier;
m_scrollVelocity.x += m_scrollSpeed * event.mouse->scrollAmount.x * 15.0f; if (m_smoothScrollTimer.isStopped())
m_smoothScrollTimer.restart();
if (m_smoothScrollTimer.isStopped()) event.handle();
m_smoothScrollTimer.restart(); }
else if (std::abs(event.mouse->scrollAmount.y) > 0)
event.handle(); {
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)
@ -122,17 +138,17 @@ namespace ogfx
String t = type.new_toLower().trim(); String t = type.new_toLower().trim();
if (t == TitleBarTypes::None) if (t == TitleBarTypes::None)
{ {
setPadding(m_basePadding); setContentOffset({ 0, 0 });
m_titlebarType = TitleBarTypes::NoneValue; m_titlebarType = TitleBarTypes::NoneValue;
} }
else if (t == TitleBarTypes::Minimal) else if (t == TitleBarTypes::Minimal)
{ {
setPadding(m_basePadding + Rectangle { 0, m_titlebarHeight, 0, 0 }); setContentOffset({ 0, m_titlebarHeight });
m_titlebarType = TitleBarTypes::MinimalValue; m_titlebarType = TitleBarTypes::MinimalValue;
} }
else if (t == TitleBarTypes::Full) else if (t == TitleBarTypes::Full)
{ {
setPadding(m_basePadding + Rectangle { 0, m_titlebarHeight, 0, 0 }); setContentOffset({ 0, m_titlebarHeight });
m_titlebarType = TitleBarTypes::FullValue; m_titlebarType = TitleBarTypes::FullValue;
} }
} }
@ -180,12 +196,12 @@ namespace ogfx
bool Panel::needsVScroll(void) const bool Panel::needsVScroll(void) const
{ {
return isScrollAllowed() && getContentExtents().h > getContentBounds().h; return isVScrollAllowed() && getContentExtents().h > getContentBounds().h;
} }
bool Panel::needsHScroll(void) const bool Panel::needsHScroll(void) const
{ {
return isScrollAllowed() && getContentExtents().w > getContentBounds().w; return isHScrollAllowed() && getContentExtents().w > getContentBounds().w;
} }
void Panel::onWidgetAdded(Widget& child) void Panel::onWidgetAdded(Widget& child)
@ -196,6 +212,24 @@ namespace ogfx
addWidget(m_hScrollbar, { 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());

View file

@ -57,6 +57,8 @@ namespace ogfx
bool needsVScroll(void) const override; bool needsVScroll(void) const override;
bool needsHScroll(void) const override; bool needsHScroll(void) const override;
void onWidgetAdded(Widget& child) 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; }
@ -81,12 +83,12 @@ namespace ogfx
i32 m_titlebarFontSize { 26 }; i32 m_titlebarFontSize { 26 };
Color m_titlebarColor { Colors::Transparent }; Color m_titlebarColor { Colors::Transparent };
Color m_titlebarBorderColor { Colors::Black }; Color m_titlebarBorderColor { Colors::Black };
Rectangle m_basePadding { 0, 0, 0, 0 };
i32 m_titleTextAlign { 0 }; i32 m_titleTextAlign { 0 };
f32 m_scrollSpeed { 0.8f }; f32 m_scrollSpeed { 0.8f };
Vec2 m_scrollVelocity { 0.0f, 0.0f }; Vec2 m_scrollVelocity { 0.0f, 0.0f };
f32 m_scrollSmoothFactor { 0.7f }; f32 m_scrollSmoothFactor { 0.7f };
f32 m_scrollSpeedMultiplier { 15.0f };
}; };
} }
} }

View file

@ -50,7 +50,6 @@ 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 });
m_trackBorderRadii = getThemeValue<Rectangle>(theme, "scrollbar.track.borderRadii", { 0, 0, 10, 0 });
} }
void VerticalScrollBar::afterDraw(ogfx::BasicRenderer2D& gfx) void VerticalScrollBar::afterDraw(ogfx::BasicRenderer2D& gfx)
@ -66,7 +65,7 @@ namespace ogfx
if (!m_mousePressed) if (!m_mousePressed)
return; return;
if (is_mouse_in_thumb({ event.mouse->position_x, event.mouse->position_y })) if (isMouseInsideThumb({ event.mouse->position_x, event.mouse->position_y }))
m_mouseDragged = true; m_mouseDragged = true;
if (m_mouseDragged) if (m_mouseDragged)
@ -103,11 +102,16 @@ namespace ogfx
update_thumb(); update_thumb();
} }
bool VerticalScrollBar::isMouseInsideThumb(const Vec2& mouse_pos)
{
return m_thumbGlobalBounds.contains(mouse_pos, true);
}
void VerticalScrollBar::update_thumb(void) void VerticalScrollBar::update_thumb(void)
{ {
x = getParent()->getSize().x - w; x = getParent()->getSize().x - w;
y = 0; y = 0;
h = getParent()->getGlobalContentBounds().h; h = getParent()->getGlobalPureContentBounds().h;
auto ext = getParent()->getContentExtents(); auto ext = getParent()->getContentExtents();
auto cont = getParent()->getContentBounds(); auto cont = getParent()->getContentBounds();
@ -127,6 +131,8 @@ namespace ogfx
void VerticalScrollBar::set_thumb_y(f32 thumby) void VerticalScrollBar::set_thumb_y(f32 thumby)
{ {
if (!getParent()->needsVScroll())
return;
auto bounds = getGlobalBounds() - m_correctionOffset; auto bounds = getGlobalBounds() - m_correctionOffset;
auto ext = getParent()->getContentExtents(); auto ext = getParent()->getContentExtents();
auto cont = getParent()->getContentBounds(); auto cont = getParent()->getContentBounds();
@ -139,11 +145,6 @@ namespace ogfx
getParent()->setScrollOffset(parentScrollOffset); getParent()->setScrollOffset(parentScrollOffset);
} }
bool VerticalScrollBar::is_mouse_in_thumb(const Vec2& mouse_pos)
{
return m_thumbGlobalBounds.contains(mouse_pos, true);
}
@ -172,8 +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 });
m_trackBorderRadii = getThemeValue<Rectangle>(theme, "scrollbar.track.borderRadii", { 0, 0, 10, 10 }); }
}
void HorizontalScrollbar::afterDraw(ogfx::BasicRenderer2D& gfx) void HorizontalScrollbar::afterDraw(ogfx::BasicRenderer2D& gfx)
{ {
@ -188,7 +188,7 @@ namespace ogfx
if (!m_mousePressed) if (!m_mousePressed)
return; return;
if (is_mouse_in_thumb({ event.mouse->position_x, event.mouse->position_y })) if (isMouseInsideThumb({ event.mouse->position_x, event.mouse->position_y }))
m_mouseDragged = true; m_mouseDragged = true;
if (m_mouseDragged) if (m_mouseDragged)
@ -225,11 +225,16 @@ namespace ogfx
update_thumb(); update_thumb();
} }
bool HorizontalScrollbar::isMouseInsideThumb(const Vec2& mouse_pos)
{
return m_thumbGlobalBounds.contains(mouse_pos, true);
}
void HorizontalScrollbar::update_thumb(void) void HorizontalScrollbar::update_thumb(void)
{ {
x = 0; x = 0;
y = getParent()->getSize().y - h; y = getParent()->getSize().y - h;
w = getParent()->getGlobalBounds().w; w = getParent()->getGlobalBounds().w - getParent()->getVScrollbarSize();
auto ext = getParent()->getContentExtents(); auto ext = getParent()->getContentExtents();
auto cont = getParent()->getContentBounds(); auto cont = getParent()->getContentBounds();
@ -245,11 +250,13 @@ namespace ogfx
auto bounds = getGlobalBounds() - m_correctionOffset; auto bounds = getGlobalBounds() - m_correctionOffset;
m_thumbGlobalBounds = { bounds.x + 2 + m_thumbX, bounds.y + gety(), m_thumbWidth, geth() - 4 }; m_thumbGlobalBounds = { bounds.x + 2 + m_thumbX, bounds.y + gety(), m_thumbWidth, geth() - 4 };
std::cout << Rectangle::toString() << "\n"; m_thumbGlobalBounds = { bounds.x + getx() + m_thumbX, bounds.y + 2, m_thumbWidth, geth() - 4 };
} }
void HorizontalScrollbar::set_thumb_x(f32 thumbx) void HorizontalScrollbar::set_thumb_x(f32 thumbx)
{ {
if (!getParent()->needsHScroll())
return;
auto bounds = getGlobalBounds() - m_correctionOffset; auto bounds = getGlobalBounds() - m_correctionOffset;
auto ext = getParent()->getContentExtents(); auto ext = getParent()->getContentExtents();
auto cont = getParent()->getContentBounds(); auto cont = getParent()->getContentBounds();
@ -261,11 +268,6 @@ namespace ogfx
parentScrollOffset.x = maxScroll * scrollProgress; parentScrollOffset.x = maxScroll * scrollProgress;
getParent()->setScrollOffset(parentScrollOffset); getParent()->setScrollOffset(parentScrollOffset);
} }
bool HorizontalScrollbar::is_mouse_in_thumb(const Vec2& mouse_pos)
{
return m_thumbGlobalBounds.contains(mouse_pos, true);
}
} }
} }
} }

View file

@ -39,6 +39,7 @@ namespace ogfx
void onMousePressed(const Event& event) override; void onMousePressed(const Event& event) override;
void onMouseReleased(const Event& event) override; void onMouseReleased(const Event& event) override;
void onUpdate(void) override; void onUpdate(void) override;
bool isMouseInsideThumb(const Vec2& mouse_pos);
inline void setx(f32 xx) override { } inline void setx(f32 xx) override { }
inline void sety(f32 yy) override { } inline void sety(f32 yy) override { }
@ -48,7 +49,6 @@ namespace ogfx
private: private:
void update_thumb(void); void update_thumb(void);
void set_thumb_y(f32 thumby); void set_thumb_y(f32 thumby);
bool is_mouse_in_thumb(const Vec2& mouse_pos);
private: private:
f32 m_thumbHeight { 0 }; f32 m_thumbHeight { 0 };
@ -77,6 +77,7 @@ namespace ogfx
void onMousePressed(const Event& event) override; void onMousePressed(const Event& event) override;
void onMouseReleased(const Event& event) override; void onMouseReleased(const Event& event) override;
void onUpdate(void) override; void onUpdate(void) override;
bool isMouseInsideThumb(const Vec2& mouse_pos);
inline void setx(f32 xx) override { } inline void setx(f32 xx) override { }
inline void sety(f32 yy) override { } inline void sety(f32 yy) override { }
@ -86,7 +87,6 @@ namespace ogfx
private: private:
void update_thumb(void); void update_thumb(void);
void set_thumb_x(f32 thumbx); void set_thumb_x(f32 thumbx);
bool is_mouse_in_thumb(const Vec2& mouse_pos);
private: private:
f32 m_thumbWidth { 0 }; f32 m_thumbWidth { 0 };
@ -97,7 +97,7 @@ namespace ogfx
f32 m_dragGrabOffset { 0 }; f32 m_dragGrabOffset { 0 };
Rectangle m_correctionOffset { 0, 0, 0, 0 }; Rectangle m_correctionOffset { 0, 0, 0, 0 };
Rectangle m_trackBorderRadii { 0, 0, 10, 10 }; Rectangle m_trackBorderRadii { 0, 0, 0, 10 };
f32 m_thumbBorderRadius { 16 }; f32 m_thumbBorderRadius { 16 };
Color m_trackColor { 70, 70, 70 }; Color m_trackColor { 70, 70, 70 };
Color m_thumbColor { 120, 120, 120 }; Color m_thumbColor { 120, 120, 120 };

View file

@ -64,6 +64,7 @@ namespace ogfx
if (!isIgnoreScrollAllowed()) if (!isIgnoreScrollAllowed())
{ {
glob += m_parent->getPadding().getPosition(); glob += m_parent->getPadding().getPosition();
glob += m_parent->getContentOffset();
glob += m_parent->getScrollOffset(); glob += m_parent->getScrollOffset();
} }
} }
@ -84,15 +85,24 @@ namespace ogfx
Rectangle Widget::getContentBounds(void) const Rectangle Widget::getContentBounds(void) const
{ {
auto pad = getPadding(); auto pad = getPadding();
return { pad.getPosition(), (getSize() - (pad.getSize() * 2)) }; return { Vec2 { m_contentOffset.x, m_contentOffset.y } + pad.getPosition(), (getSize() - m_contentOffset - (pad.getSize() * 2)) };
}
Rectangle Widget::getPureContentBounds(void) const
{
return { { m_contentOffset.x, m_contentOffset.y }, (getSize() - m_contentOffset) };
} }
Rectangle Widget::getGlobalContentBounds(void) const Rectangle Widget::getGlobalContentBounds(void) const
{ {
auto pad = getPadding();
return { getGlobalContentPosition(), getContentBounds().getSize() }; return { getGlobalContentPosition(), getContentBounds().getSize() };
} }
Rectangle Widget::getGlobalPureContentBounds(void) const
{
return { getGlobalPosition() + getContentOffset(), getPureContentBounds().getSize() };
}
Rectangle Widget::getContentExtents(void) const Rectangle Widget::getContentExtents(void) const
{ {
f32 maxX = 0, maxY = 0; f32 maxX = 0, maxY = 0;
@ -218,8 +228,12 @@ namespace ogfx
gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius); gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius);
} }
onDraw(gfx); onDraw(gfx);
// gfx.fillRect(getGlobalPureContentBounds(), { 0, 255, 0, 120 });
gfx.pushClippingRect(getGlobalPureContentBounds(), true);
if (hasChildren()) if (hasChildren())
m_widgets.draw(gfx); m_widgets.draw(gfx);
gfx.popClippingRect();
if (m_showBorder) if (m_showBorder)
gfx.drawRoundRect({ getGlobalPosition(), getSize() }, m_borderColor, m_borderRadius, m_borderWidth); gfx.drawRoundRect({ getGlobalPosition(), getSize() }, m_borderColor, m_borderRadius, m_borderWidth);
afterDraw(gfx); afterDraw(gfx);

View file

@ -47,7 +47,9 @@ namespace ogfx
virtual Vec2 getGlobalContentPosition(void) const; virtual Vec2 getGlobalContentPosition(void) const;
virtual Rectangle getGlobalBounds(void) const; virtual Rectangle getGlobalBounds(void) const;
virtual Rectangle getContentBounds(void) const; virtual Rectangle getContentBounds(void) const;
virtual Rectangle getPureContentBounds(void) const;
virtual Rectangle getGlobalContentBounds(void) const; virtual Rectangle getGlobalContentBounds(void) const;
virtual Rectangle getGlobalPureContentBounds(void) const;
virtual Rectangle getContentExtents(void) const; virtual Rectangle getContentExtents(void) const;
using Rectangle::contains; using Rectangle::contains;
bool contains(Vec2 p, bool includeBounds = false) const override; bool contains(Vec2 p, bool includeBounds = false) const override;
@ -58,6 +60,8 @@ namespace ogfx
inline virtual void addScrollOffset(const Vec2& offset) { } inline virtual void addScrollOffset(const Vec2& offset) { }
inline virtual bool needsVScroll(void) const { return false; } inline virtual bool needsVScroll(void) const { return false; }
inline virtual bool needsHScroll(void) const { return false; } inline virtual bool needsHScroll(void) const { return false; }
inline virtual f32 getVScrollbarSize(void) const { return 0; }
inline virtual f32 getHScrollbarSize(void) const { return 0; }
void addThemeOverride(const String& fullKey, ostd::Stylesheet::TypeVariant value); void addThemeOverride(const String& fullKey, ostd::Stylesheet::TypeVariant value);
void reloadTheme(bool propagate = false); void reloadTheme(bool propagate = false);
void setThemeQualifier(const String& qualifier, bool value = true); void setThemeQualifier(const String& qualifier, bool value = true);
@ -137,8 +141,10 @@ namespace ogfx
inline bool isChildrenEnabled(void) const { return m_allowChildren; } inline bool isChildrenEnabled(void) const { return m_allowChildren; }
inline void setPadding(const Rectangle& pad) { m_padding = pad; } inline void setPadding(const Rectangle& pad) { m_padding = pad; }
inline void setMargin(const Rectangle& margin) { m_margin = margin; } inline void setMargin(const Rectangle& margin) { m_margin = margin; }
inline void setContentOffset(const Vec2& offset) { m_contentOffset = offset; }
inline Rectangle getPadding(void) const { return m_padding; } inline Rectangle getPadding(void) const { return m_padding; }
inline Rectangle getMargin(void) const { return m_margin; } inline Rectangle getMargin(void) const { return m_margin; }
inline Vec2 getContentOffset(void) const { return m_contentOffset; }
inline bool isMouseInside(void) const { return m_mouseInside; } inline bool isMouseInside(void) const { return m_mouseInside; }
inline ogfx::MouseEventData::eButton getPressedMouseButton(void) const { return m_pressedButton; } inline ogfx::MouseEventData::eButton getPressedMouseButton(void) const { return m_pressedButton; }
inline const stdvec<String>& getThemeIDList(void) const { return m_themeIDList; } inline const stdvec<String>& getThemeIDList(void) const { return m_themeIDList; }
@ -170,8 +176,10 @@ namespace ogfx
inline bool isVisible(void) const { return m_visible; } inline bool isVisible(void) const { return m_visible; }
inline void show(void) { setVisible(true); } inline void show(void) { setVisible(true); }
inline void hide(void) { setVisible(false); } inline void hide(void) { setVisible(false); }
inline void allowScroll(bool allow = true) { m_allowScroll = allow; } inline void allowVScroll(bool allow = true) { m_vScrollEnabled = allow; }
inline bool isScrollAllowed(void) const { return m_allowScroll; } inline bool isVScrollAllowed(void) const { return m_vScrollEnabled; }
inline void allowHScroll(bool allow = true) { m_hScrollEnabled = allow; }
inline bool isHScrollAllowed(void) const { return m_hScrollEnabled; }
inline void allowIgnoreScroll(bool allow = true) { m_ignoreScroll = allow; } inline void allowIgnoreScroll(bool allow = true) { m_ignoreScroll = allow; }
inline bool isIgnoreScrollAllowed(void) const { return m_ignoreScroll; } inline bool isIgnoreScrollAllowed(void) const { return m_ignoreScroll; }
@ -233,10 +241,11 @@ namespace ogfx
bool m_clipContents { true }; bool m_clipContents { true };
bool m_acceptDragAndDrop { false }; bool m_acceptDragAndDrop { false };
bool m_visible { true }; bool m_visible { true };
bool m_allowScroll { false };
bool m_ignoreScroll { false}; bool m_ignoreScroll { false};
bool m_manualDraw { false }; bool m_manualDraw { false };
bool m_topMost { false }; bool m_topMost { false };
bool m_vScrollEnabled { false };
bool m_hScrollEnabled { false };
MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None }; MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None };
stdvec<String> m_themeIDList; stdvec<String> m_themeIDList;
@ -254,6 +263,7 @@ namespace ogfx
Rectangle m_padding { 0, 0, 0, 0 }; Rectangle m_padding { 0, 0, 0, 0 };
Rectangle m_margin { 0, 0, 0, 0 }; Rectangle m_margin { 0, 0, 0, 0 };
Vec2 m_contentOffset { 0, 0 };
static ostd::BaseObject* s_dragAndDropData; static ostd::BaseObject* s_dragAndDropData;
static bool s_hasDragAndDropData; static bool s_hasDragAndDropData;

View file

@ -102,7 +102,10 @@ namespace ogfx
finalRect = m_clipStack.back().getIntersection(rect, false); finalRect = m_clipStack.back().getIntersection(rect, false);
if (!m_clipStack.empty() && m_clipStack.back() == finalRect) if (!m_clipStack.empty() && m_clipStack.back() == finalRect)
{
m_clipStack.push_back(finalRect);
return; return;
}
flushBatch(); flushBatch();
m_clipStack.push_back(finalRect); m_clipStack.push_back(finalRect);
@ -121,22 +124,26 @@ namespace ogfx
if (!m_initialized) return; if (!m_initialized) return;
if (m_clipStack.empty()) return; if (m_clipStack.empty()) return;
Rectangle popped = m_clipStack.back();
m_clipStack.pop_back(); m_clipStack.pop_back();
flushBatch();
if (m_clipStack.empty()) if (m_clipStack.empty())
{ {
flushBatch();
SDL_SetRenderClipRect(m_window->getSDLRenderer(), nullptr); SDL_SetRenderClipRect(m_window->getSDLRenderer(), nullptr);
return; return;
} }
const auto& rect = m_clipStack.back(); const auto& prev = m_clipStack.back();
if (prev == popped)
return;
flushBatch();
SDL_Rect r; SDL_Rect r;
r.x = (i32)std::round(rect.x); r.x = (i32)std::round(prev.x);
r.y = (i32)std::round(rect.y); r.y = (i32)std::round(prev.y);
r.w = (i32)std::round(rect.w); r.w = (i32)std::round(prev.w);
r.h = (i32)std::round(rect.h); r.h = (i32)std::round(prev.h);
SDL_SetRenderClipRect(m_window->getSDLRenderer(), &r); SDL_SetRenderClipRect(m_window->getSDLRenderer(), &r);
} }

View file

@ -71,13 +71,27 @@ class Window : public ogfx::gui::Window
m_label2.setText("Label2"); m_label2.setText("Label2");
m_label3.setText("Label3"); m_label3.setText("Label3");
m_label4.setText("Label4");
m_label5.setText("Label5");
m_panel1.setSize(300, 140); m_panel1.setSize(300, 300);
m_panel1.allowScroll(false); m_panel1.allowVScroll(false);
m_panel1.allowHScroll(false);
m_panel1.setTitle("Panel 1");
m_panel3.setSize(150, 150);
m_panel3.allowVScroll(false);
m_panel3.allowHScroll(false);
m_panel3.setTitle("Panel 3");
m_panel2.setSize(600, 400); m_panel2.setSize(600, 400);
m_panel2.setTitle("Panel 2");
m_panel3.addWidget(m_label4);
m_panel1.addWidget(m_label2); m_panel1.addWidget(m_label2);
m_panel1.addWidget(m_panel3, { 100, 50 });
m_panel1.addWidget(m_label5, { 0, 60 });
m_panel2.addWidget(m_label3); m_panel2.addWidget(m_label3);
m_panel2.addWidget(m_panel1, { 400, 50 }); m_panel2.addWidget(m_panel1, { 400, 50 });
@ -104,7 +118,7 @@ class Window : public ogfx::gui::Window
void onRedraw(ogfx::BasicRenderer2D& gfx) override void onRedraw(ogfx::BasicRenderer2D& gfx) override
{ {
gfx.drawAnimation(m_anim, { 200, 200 }); gfx.drawAnimation(m_anim, { 200, 200 });
// gfx.fillRect(m_panel2.getGlobalContentBounds(), { 0, 255, 0, 120 }); // gfx.fillRect(m_panel2.getGlobalPureContentBounds(), { 0, 255, 0, 120 });
} }
void onFixedUpdate(void) override void onFixedUpdate(void) override
@ -116,8 +130,11 @@ class Window : public ogfx::gui::Window
Label m_label1 { *this }; Label m_label1 { *this };
Label m_label2 { *this }; Label m_label2 { *this };
Label m_label3 { *this }; Label m_label3 { *this };
Label m_label4 { *this };
Label m_label5 { *this };
Panel m_panel1 { *this }; Panel m_panel1 { *this };
Panel m_panel2 { *this }; Panel m_panel2 { *this };
Panel m_panel3 { *this };
CheckBox m_check1 { *this }; CheckBox m_check1 { *this };
Button m_btn1 { *this }; Button m_btn1 { *this };