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/CheckBox.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Scrollbar.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Button.cpp
# render
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp

View file

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

View file

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

View file

@ -41,6 +41,7 @@ namespace ogfx
bool hasWidget(Widget& widget);
bool requestFocus(Widget& widget);
bool addWidget(Widget& widget);
bool removeWidget(Widget& widget);
Widget* focusNext(void);
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();
enableStopEvents();
allowScroll(true);
m_scrollbar.setMargin({ 0, getTitlebarHeight(), 0, 0 });
m_scrollbar.enableManualDraw(true);
addWidget(m_scrollbar);
validate();
return *this;
}
@ -71,6 +74,7 @@ namespace ogfx
void Panel::afterDraw(ogfx::BasicRenderer2D& gfx)
{
draw_titlebar(gfx);
m_scrollbar.__draw(gfx);
}
void Panel::onMouseScrolled(const Event& event)
@ -143,7 +147,13 @@ namespace ogfx
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)

View file

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

View file

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

View file

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

View file

@ -36,14 +36,23 @@ namespace ogfx
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)
return false;
if (position.x != 0 || position.y != 0)
child.setPosition(position);
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

View file

@ -41,7 +41,8 @@ namespace ogfx
public: using EventCallback = std::function<void(const Event&)>;
public:
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 getGlobalContentPosition(void) const;
virtual Rectangle getGlobalBounds(void) const;
@ -68,6 +69,7 @@ namespace ogfx
inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { }
inline virtual void afterDraw(ogfx::BasicRenderer2D& gfx) { }
inline virtual void onUpdate(void) { }
inline virtual void onWidgetAdded(Widget& child) { }
inline virtual void onMousePressed(const Event& event) { }
inline virtual void onMouseReleased(const Event& event) { }
@ -155,6 +157,10 @@ namespace ogfx
inline Color getBorderColor(void) { return m_borderColor; }
inline void enableBorder(bool enable = true) { m_showBorder = enable; }
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 i32 getBorderRadius(void) const { return m_borderRadius; }
inline void setBorderWidth(i32 bw) { m_borderWidth = bw; }
@ -227,6 +233,8 @@ namespace ogfx
bool m_visible { true };
bool m_allowScroll { false };
bool m_ignoreScroll { false};
bool m_manualDraw { false };
bool m_topMost { false };
MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None };
stdvec<String> m_themeIDList;

View file

@ -75,14 +75,11 @@ class Window : public ogfx::gui::Window
m_panel2.setSize(600, 400);
m_scroll.setMargin({ 0, m_panel2.getTitlebarHeight(), 0, 0 });
m_panel1.addWidget(m_label2);
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_scroll);
addWidget(m_check1, { 30, 30 });
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_panel2 { *this };
ogfx::gui::widgets::CheckBox m_check1 { *this };
ogfx::gui::widgets::VerticalScrollBar m_scroll { *this };
ostd::Stylesheet m_theme;
ogfx::Animation m_anim;