Made VerticalScrollbar a top-most widget

This commit is contained in:
OmniaX-Dev 2026-04-17 03:55:26 +02:00
parent 7d8a5be286
commit 44354a80c2
13 changed files with 114 additions and 11 deletions

View file

@ -92,6 +92,7 @@ list(APPEND OGFX_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/RootWidget.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/RootWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/CheckBox.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/CheckBox.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Scrollbar.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Scrollbar.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Button.cpp
# render # render
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp

View file

@ -19,8 +19,8 @@
***Implement Panel title ***Implement Panel title
***Implement show/hide functionality for widgets ***Implement show/hide functionality for widgets
***Create reliable default stylesheet ***Create reliable default stylesheet
***Implement global scale (probably query desktop scale and adjust accordingly)
Add theme caching Add theme caching
Implement global scale (probably query desktop scale and adjust accordingly)
Implement cursors in Stylesheet Implement cursors in Stylesheet

View file

@ -22,6 +22,7 @@
#include "widgets/Widget.hpp" #include "widgets/Widget.hpp"
#include "../render/BasicRenderer.hpp" #include "../render/BasicRenderer.hpp"
#include "../utils/Keycodes.hpp" #include "../utils/Keycodes.hpp"
#include "../../ostd/io/Memory.hpp"
namespace ogfx namespace ogfx
{ {
@ -68,12 +69,20 @@ namespace ogfx
if (hasWidget(widget)) return false; if (hasWidget(widget)) return false;
widget.m_parent = &m_owner; widget.m_parent = &m_owner;
m_widgetList.push_back(&widget); m_widgetList.push_back(&widget);
if (widget.m_topMost)
return true;
std::ranges::sort(m_widgetList, {}, [](Widget* w) { std::ranges::sort(m_widgetList, {}, [](Widget* w) {
return w->m_zIndex; return w->m_zIndex;
}); });
return true; return true;
} }
bool WidgetManager::removeWidget(Widget& widget)
{
STDVEC_REMOVE(m_widgetList, &widget);
return true;
}
Widget* WidgetManager::focusNext(void) Widget* WidgetManager::focusNext(void)
{ {
if (m_widgetList.empty()) if (m_widgetList.empty())
@ -107,6 +116,7 @@ namespace ogfx
if (w == nullptr) continue; if (w == nullptr) continue;
if (w->isInvalid()) continue; if (w->isInvalid()) continue;
if (!w->isVisible()) continue; if (!w->isVisible()) continue;
if (w->isManualDrawEnabled()) continue;
gfx.pushClippingRect({ w->getGlobalPosition(), w->getSize() }, true); gfx.pushClippingRect({ w->getGlobalPosition(), w->getSize() }, true);
w->__draw(gfx); w->__draw(gfx);
gfx.popClippingRect(); gfx.popClippingRect();

View file

@ -41,6 +41,7 @@ namespace ogfx
bool hasWidget(Widget& widget); bool hasWidget(Widget& widget);
bool requestFocus(Widget& widget); bool requestFocus(Widget& widget);
bool addWidget(Widget& widget); bool addWidget(Widget& widget);
bool removeWidget(Widget& widget);
Widget* focusNext(void); Widget* focusNext(void);
void draw(ogfx::BasicRenderer2D& gfx); void draw(ogfx::BasicRenderer2D& gfx);

View file

@ -0,0 +1,32 @@
/*
OmniaFramework - A collection of useful functionality
Copyright (C) 2025 OmniaX-Dev
This file is part of OmniaFramework.
OmniaFramework is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OmniaFramework is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Button.hpp"
#include "../../render/BasicRenderer.hpp"
namespace ogfx
{
namespace gui
{
namespace widgets
{
}
}
}

View file

@ -0,0 +1,33 @@
/*
OmniaFramework - A collection of useful functionality
Copyright (C) 2025 OmniaX-Dev
This file is part of OmniaFramework.
OmniaFramework is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OmniaFramework is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <ogfx/gui/widgets/Widget.hpp>
namespace ogfx
{
namespace gui
{
namespace widgets
{
}
}
}

View file

@ -36,6 +36,9 @@ namespace ogfx
disableFocus(); disableFocus();
enableStopEvents(); enableStopEvents();
allowScroll(true); allowScroll(true);
m_scrollbar.setMargin({ 0, getTitlebarHeight(), 0, 0 });
m_scrollbar.enableManualDraw(true);
addWidget(m_scrollbar);
validate(); validate();
return *this; return *this;
} }
@ -71,6 +74,7 @@ namespace ogfx
void Panel::afterDraw(ogfx::BasicRenderer2D& gfx) void Panel::afterDraw(ogfx::BasicRenderer2D& gfx)
{ {
draw_titlebar(gfx); draw_titlebar(gfx);
m_scrollbar.__draw(gfx);
} }
void Panel::onMouseScrolled(const Event& event) void Panel::onMouseScrolled(const Event& event)
@ -143,7 +147,13 @@ namespace ogfx
bool Panel::needsScroll(void) const bool Panel::needsScroll(void) const
{ {
return getContentExtents().h > getContentBounds().h; return isScrollAllowed() && getContentExtents().h > getContentBounds().h;
}
void Panel::onWidgetAdded(Widget& child)
{
removeWidget(m_scrollbar);
addWidget(m_scrollbar, { 0, 0 }, true);
} }
void Panel::draw_titlebar(BasicRenderer2D& gfx) void Panel::draw_titlebar(BasicRenderer2D& gfx)

View file

@ -21,6 +21,7 @@
#pragma once #pragma once
#include <ogfx/gui/widgets/Widget.hpp> #include <ogfx/gui/widgets/Widget.hpp>
#include <ogfx/gui/widgets/Scrollbar.hpp>
namespace ogfx namespace ogfx
{ {
@ -52,6 +53,7 @@ namespace ogfx
void setScrollOffset(const Vec2& offset) override; void setScrollOffset(const Vec2& offset) override;
void addScrollOffset(const Vec2& offset) override; void addScrollOffset(const Vec2& offset) override;
bool needsScroll(void) const override; bool needsScroll(void) const override;
void onWidgetAdded(Widget& child) 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; }
@ -65,6 +67,7 @@ namespace ogfx
private: private:
String m_title { "Panel" }; String m_title { "Panel" };
Vec2 m_scrollOffset { 0, 0 }; Vec2 m_scrollOffset { 0, 0 };
VerticalScrollBar m_scrollbar { getWindow() };
Color m_titleColor { Colors::Black }; Color m_titleColor { Colors::Black };
i32 m_titlebarType = TitleBarTypes::NoneValue; i32 m_titlebarType = TitleBarTypes::NoneValue;

View file

@ -28,7 +28,6 @@ namespace ogfx
{ {
namespace widgets namespace widgets
{ {
class Label : public Widget class Label : public Widget
{ {
public: public:

View file

@ -36,6 +36,7 @@ namespace ogfx
disableChildren(); disableChildren();
enableBackground(true); enableBackground(true);
enableBorder(false); enableBorder(false);
enableTopMost(true);
allowIgnoreScroll(true); allowIgnoreScroll(true);
validate(); validate();
return *this; return *this;

View file

@ -36,14 +36,23 @@ namespace ogfx
m_window = &window; m_window = &window;
} }
bool Widget::addWidget(Widget& child, const Vec2& position) bool Widget::addWidget(Widget& child, const Vec2& position, bool __skip_callback)
{ {
if (!m_allowChildren) if (!m_allowChildren)
return false; return false;
if (position.x != 0 || position.y != 0) if (position.x != 0 || position.y != 0)
child.setPosition(position); child.setPosition(position);
child.reloadTheme(); child.reloadTheme();
return m_widgets.addWidget(child); bool result = m_widgets.addWidget(child);
if (!result) return false;
if (!__skip_callback)
onWidgetAdded(child);
return result;
}
bool Widget::removeWidget(Widget& child)
{
return m_widgets.removeWidget(child);
} }
Vec2 Widget::getGlobalPosition(void) const Vec2 Widget::getGlobalPosition(void) const

View file

@ -41,7 +41,8 @@ namespace ogfx
public: using EventCallback = std::function<void(const Event&)>; public: using EventCallback = std::function<void(const Event&)>;
public: public:
Widget(const Rectangle& bounds, WindowCore& window); Widget(const Rectangle& bounds, WindowCore& window);
bool addWidget(Widget& child, const Vec2& position = { 0, 0 }); bool addWidget(Widget& child, const Vec2& position = { 0, 0 }, bool __skip_callback = false);
bool removeWidget(Widget& child);
virtual Vec2 getGlobalPosition(void) const; virtual Vec2 getGlobalPosition(void) const;
virtual Vec2 getGlobalContentPosition(void) const; virtual Vec2 getGlobalContentPosition(void) const;
virtual Rectangle getGlobalBounds(void) const; virtual Rectangle getGlobalBounds(void) const;
@ -68,6 +69,7 @@ namespace ogfx
inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { } inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { }
inline virtual void afterDraw(ogfx::BasicRenderer2D& gfx) { } inline virtual void afterDraw(ogfx::BasicRenderer2D& gfx) { }
inline virtual void onUpdate(void) { } inline virtual void onUpdate(void) { }
inline virtual void onWidgetAdded(Widget& child) { }
inline virtual void onMousePressed(const Event& event) { } inline virtual void onMousePressed(const Event& event) { }
inline virtual void onMouseReleased(const Event& event) { } inline virtual void onMouseReleased(const Event& event) { }
@ -155,6 +157,10 @@ namespace ogfx
inline Color getBorderColor(void) { return m_borderColor; } inline Color getBorderColor(void) { return m_borderColor; }
inline void enableBorder(bool enable = true) { m_showBorder = enable; } inline void enableBorder(bool enable = true) { m_showBorder = enable; }
inline bool isBorderEnabled(void) const { return m_showBorder; } inline bool isBorderEnabled(void) const { return m_showBorder; }
inline void enableManualDraw(bool enable = true) { m_manualDraw = enable; }
inline bool isManualDrawEnabled(void) const { return m_manualDraw; }
inline void enableTopMost(bool enable = true) { m_topMost = enable; }
inline bool isTopMostEnabled(void) const { return m_topMost; }
inline void setBorderRadius(i32 br) { m_borderRadius = br; } inline void setBorderRadius(i32 br) { m_borderRadius = br; }
inline i32 getBorderRadius(void) const { return m_borderRadius; } inline i32 getBorderRadius(void) const { return m_borderRadius; }
inline void setBorderWidth(i32 bw) { m_borderWidth = bw; } inline void setBorderWidth(i32 bw) { m_borderWidth = bw; }
@ -227,6 +233,8 @@ namespace ogfx
bool m_visible { true }; bool m_visible { true };
bool m_allowScroll { false }; bool m_allowScroll { false };
bool m_ignoreScroll { false}; bool m_ignoreScroll { false};
bool m_manualDraw { false };
bool m_topMost { false };
MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None }; MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None };
stdvec<String> m_themeIDList; stdvec<String> m_themeIDList;

View file

@ -75,14 +75,11 @@ class Window : public ogfx::gui::Window
m_panel2.setSize(600, 400); m_panel2.setSize(600, 400);
m_scroll.setMargin({ 0, m_panel2.getTitlebarHeight(), 0, 0 });
m_panel1.addWidget(m_label2); m_panel1.addWidget(m_label2);
m_panel2.addWidget(m_label3); m_panel2.addWidget(m_label3);
m_panel2.addWidget(m_panel1, { 0, 50 }); m_panel2.addWidget(m_panel1, { 400, 50 });
m_panel2.addWidget(m_label1, { 0, 500 }); m_panel2.addWidget(m_label1, { 0, 500 });
m_panel2.addWidget(m_scroll);
addWidget(m_check1, { 30, 30 }); addWidget(m_check1, { 30, 30 });
addWidget(m_panel2, { 30, 100 }); addWidget(m_panel2, { 30, 100 });
@ -118,7 +115,6 @@ class Window : public ogfx::gui::Window
ogfx::gui::widgets::Panel m_panel1 { *this }; ogfx::gui::widgets::Panel m_panel1 { *this };
ogfx::gui::widgets::Panel m_panel2 { *this }; ogfx::gui::widgets::Panel m_panel2 { *this };
ogfx::gui::widgets::CheckBox m_check1 { *this }; ogfx::gui::widgets::CheckBox m_check1 { *this };
ogfx::gui::widgets::VerticalScrollBar m_scroll { *this };
ostd::Stylesheet m_theme; ostd::Stylesheet m_theme;
ogfx::Animation m_anim; ogfx::Animation m_anim;