From 36c9c62e6d35e851f8a8d1eb5ccdcf2f89fc7450 Mon Sep 17 00:00:00 2001 From: OmniaX-Dev Date: Sun, 26 Apr 2026 12:38:55 +0200 Subject: [PATCH] Addressed a few bugs --- extra/DefaultThemeDark.oss | 2 + other/TODO.txt | 12 +++-- src/ogfx/gui/MenuBar.cpp | 4 +- src/ogfx/gui/MenuBar.hpp | 2 + src/ogfx/gui/ToolBar.cpp | 9 +++- src/ogfx/gui/ToolBar.hpp | 2 + src/ogfx/gui/Window.cpp | 81 ++++++++++++++++------------- src/ogfx/gui/Window.hpp | 3 ++ src/ogfx/gui/widgets/Containers.cpp | 32 +++++++++++- src/ogfx/gui/widgets/Containers.hpp | 11 +++- src/test/GuiTest.cpp | 11 ++-- 11 files changed, 121 insertions(+), 48 deletions(-) diff --git a/extra/DefaultThemeDark.oss b/extra/DefaultThemeDark.oss index fb65cf4..31d9cf2 100644 --- a/extra/DefaultThemeDark.oss +++ b/extra/DefaultThemeDark.oss @@ -301,6 +301,7 @@ const $backgroundColor = rgba(30, 30, 30, 255) textColor = $textColor selectionColor = $accentColor selectionTextColor = $accentColorLight + showBorder = false borderColor = $borderColor } % ===================== @@ -316,6 +317,7 @@ const $backgroundColor = rgba(30, 30, 30, 255) selectionColor = $accentColor selectionTextColor = $accentColorLight borderColor = $borderColor + showBorder = true } % ===================== (@tool_button button) { diff --git a/other/TODO.txt b/other/TODO.txt index 9c4cbd5..e15de79 100644 --- a/other/TODO.txt +++ b/other/TODO.txt @@ -20,21 +20,22 @@ ***Implement show/hide functionality for widgets ***Create reliable default stylesheet ***Implement global scale (probably query desktop scale and adjust accordingly) +***Add Dark Mode Default theme +***FIX: Optimize ListView +***FIX: Limit FPS even when continuous events happen Add theme caching Implement cursors in Stylesheet FIX: Window getting exponentially bigger when Desktop scale changes FIX: Refreshing scroll when content extent changes -Add Dark Mode Default theme, and see if I can query OS theme mode to saelect the right theme +See if I can query OS theme mode to saelect the right theme FIX: Float values in stylesheet needing to have decimal point to be read as float Make parsing of vec2 and rect in stylesheet, consistent with other value functions like gradients and animations Add buttons to scroll tabs in TabPanel Add Font class, to handle different font attributes Add multi-selection to ListView Cache getStringDimensions() call in TabPanel::draw_tabs -FIX: Optimize ListView FIX: Padding for ListView items Add icons to ListView -FIX: Limit FPS even when continuous events happen Add gradient to listbox selection Add gradient to menubar background and selection Add cursor stack @@ -43,6 +44,8 @@ Make label auto-size FIX: Tooltips XML Layout file? Add Hex Editor widget +Add Message Boxes +FIX: Widget Content extents increasing negatively not showing scrollbars @@ -78,3 +81,6 @@ Implement following widgets: Fill Text Input Text Area + Numeric Field + Color Picker + Calendar diff --git a/src/ogfx/gui/MenuBar.cpp b/src/ogfx/gui/MenuBar.cpp index d8504e5..77a0117 100644 --- a/src/ogfx/gui/MenuBar.cpp +++ b/src/ogfx/gui/MenuBar.cpp @@ -68,6 +68,7 @@ namespace ogfx setSelectionColor(theme.get("menubar.selectionColor", getSelectionColor(), {}, {})); setSelectionTextColor(theme.get("menubar.selectionTextColor", getSelectionTextColor(), {}, {})); setBorderColor(theme.get("menubar.borderColor", getBorderColor(), {}, {})); + enableBorder(theme.get("menubar.showBorder", isBorderEnabled(), {}, {})); setSize(m_window.getWindowWidth(), m_height); recompute_layout(); } @@ -141,7 +142,8 @@ namespace ogfx } // Bottom border line - gfx.drawLine({ { getx(), gety() + m_height }, { getx() + getw(), gety() + m_height } }, m_borderColor); + if (isBorderEnabled()) + gfx.drawLine({ { getx(), gety() + m_height }, { getx() + getw(), gety() + m_height } }, m_borderColor); } void MenuBar::update(void) diff --git a/src/ogfx/gui/MenuBar.hpp b/src/ogfx/gui/MenuBar.hpp index e9eb8c4..8a139b1 100644 --- a/src/ogfx/gui/MenuBar.hpp +++ b/src/ogfx/gui/MenuBar.hpp @@ -63,6 +63,7 @@ namespace ogfx OSTD_PARAM_GETSET(Color, SelectionColor, m_selectionColor); OSTD_PARAM_GETSET(Color, SelectionTextColor, m_selectionTextColor); OSTD_PARAM_GETSET(Color, BorderColor, m_borderColor); + OSTD_BOOL_PARAM_GETSET_E(Border, m_showBorder); private: struct Slot @@ -89,6 +90,7 @@ namespace ogfx f32 m_height { 26 }; Rectangle m_itemPadding { 12, 0, 12, 0 }; // x = left, y = top, w = right, h = bottom i32 m_fontSize { 16 }; + bool m_showBorder { false }; Color m_backgroundColor { "#6B0A1DFF" }; Color m_textColor { "#F16A85FF" }; Color m_selectionColor { "#DC143CFF" }; diff --git a/src/ogfx/gui/ToolBar.cpp b/src/ogfx/gui/ToolBar.cpp index 76805dc..36ef386 100644 --- a/src/ogfx/gui/ToolBar.cpp +++ b/src/ogfx/gui/ToolBar.cpp @@ -88,7 +88,9 @@ namespace ogfx setBackgroundColor(theme.get("toolbar.backgroundColor", getBackgroundColor(), {}, {})); setTextColor(theme.get("toolbar.textColor", getTextColor(), {}, {})); setBorderColor(theme.get("toolbar.borderColor", getBorderColor(), {}, {})); + enableBottomBorder(theme.get("toolbar.showBorder", isBottomBorderEnabled(), {}, {})); setSize(win.getWindowWidth(), m_height); + disableBorder(); } void ToolBar::onDraw(BasicRenderer2D& gfx) @@ -96,8 +98,11 @@ namespace ogfx gfx.fillRect(*this, m_backgroundColor); // Bottom border line - f32 lineOffset = (isStatusBar() ? 0.0f : m_height); - gfx.drawLine({ { getx(), gety() + lineOffset }, { getx() + getw(), gety() + lineOffset } }, m_borderColor); + if (isBottomBorderEnabled()) + { + f32 lineOffset = (isStatusBar() ? 0.0f : m_height); + gfx.drawLine({ { getx(), gety() + lineOffset }, { getx() + getw(), gety() + lineOffset } }, m_borderColor); + } } void ToolBar::onUpdate(void) diff --git a/src/ogfx/gui/ToolBar.hpp b/src/ogfx/gui/ToolBar.hpp index b377dd2..4c01297 100644 --- a/src/ogfx/gui/ToolBar.hpp +++ b/src/ogfx/gui/ToolBar.hpp @@ -52,6 +52,7 @@ namespace ogfx OSTD_PARAM_GETSET(Color, TextColor, m_textColor); OSTD_PARAM_GETSET(Color, BorderColor, m_borderColor); OSTD_BOOL_PARAM_GETSET_E_NEG(ButtonText, m_disableButtonText); + OSTD_BOOL_PARAM_GETSET_E(BottomBorder, m_bottomBorder); private: void refresh_size(void); @@ -62,6 +63,7 @@ namespace ogfx bool m_isStatusBar { false }; f32 m_height { 26 }; + bool m_bottomBorder { false }; i32 m_fontSize { 16 }; Color m_backgroundColor { "#6B0A1DFF" }; Color m_textColor { "#F16A85FF" }; diff --git a/src/ogfx/gui/Window.cpp b/src/ogfx/gui/Window.cpp index db5e510..3578b85 100644 --- a/src/ogfx/gui/Window.cpp +++ b/src/ogfx/gui/Window.cpp @@ -71,7 +71,7 @@ namespace ogfx m_window = SDL_CreateWindow("", m_windowWidth, m_windowHeight, SDL_WINDOW_RESIZABLE); m_renderer = SDL_CreateRenderer(m_window, nullptr); - SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight); + // SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight); setPosition(WindowsPositionCenter); SDL_SetWindowTitle(m_window, m_title.c_str()); SDL_StartTextInput(m_window); @@ -829,10 +829,14 @@ namespace ogfx setTypeName("ogfx::gui::Window"); m_gfx.init(*this); loadDefaultTHeme(); + setBlockingEventsRefreshFPS(30); m_fixedUpdateTimer.create(60.0, [this](f64 dt) { __on_fixed_update(); }); + m_mainLoopTimer.create(60.0, [this](f64 dt) { + __main_loop_cycle(); + }); m_lastFrameTime = ostd::StepTimer::Clock::now(); onInitialize(); m_rootWidget.setSize(cast(width), cast(height)); @@ -843,46 +847,51 @@ namespace ogfx onClose(); } + void Window::__main_loop_cycle(void) + { + auto now = ostd::StepTimer::Clock::now(); + f64 delta = std::chrono::duration(now - m_lastFrameTime).count(); + m_lastFrameTime = now; + + if (delta > 0.25) + delta = 0.25; + + __on_update(delta); + + before_render(); + m_rootWidget.__update(); + m_rootWidget.__draw(m_gfx); + onRedraw(m_gfx); + if (m_menubar.isVisible()) + m_menubar.draw(m_gfx); + m_toolbar.__update(); + m_toolbar.__draw(m_gfx); + m_statusbar.__update(); + m_statusbar.__draw(m_gfx); + if (m_cmenu.isVisible()) + { + stopTooltipTimer(); + m_cmenu.draw(m_gfx); + } + else if (isTooltipShown()) + { + auto textSize = m_gfx.getStringDimensions(getTooltipText(), m_rootWidget.getTooltipFontSize()); + Rectangle textBounds = { getMousePosition(), textSize }; + textBounds += Rectangle { 0, 0, 30, 10 }; + m_gfx.outlinedRect(textBounds, m_rootWidget.getTooltipBackgroundColor(), m_rootWidget.getTooltipBorderColor(), m_rootWidget.getTooltipBorderWidth()); + m_gfx.drawCenteredString(getTooltipText(), textBounds, m_rootWidget.getTooltipTextColor(), m_rootWidget.getTooltipFontSize()); + } + m_gfx.endFrame(); + after_render(); + } + void Window::__main_loop(void) { while (isRunning()) { - auto now = ostd::StepTimer::Clock::now(); - f64 delta = std::chrono::duration(now - m_lastFrameTime).count(); - m_lastFrameTime = now; - - if (delta > 0.25) - delta = 0.25; - - m_fixedUpdateTimer.update(); - __on_update(delta); - handle_events(); - before_render(); - m_rootWidget.__update(); - m_rootWidget.__draw(m_gfx); - onRedraw(m_gfx); - if (m_menubar.isVisible()) - m_menubar.draw(m_gfx); - m_toolbar.__update(); - m_toolbar.__draw(m_gfx); - m_statusbar.__update(); - m_statusbar.__draw(m_gfx); - if (m_cmenu.isVisible()) - { - stopTooltipTimer(); - m_cmenu.draw(m_gfx); - } - else if (isTooltipShown()) - { - auto textSize = m_gfx.getStringDimensions(getTooltipText(), m_rootWidget.getTooltipFontSize()); - Rectangle textBounds = { getMousePosition(), textSize }; - textBounds += Rectangle { 0, 0, 30, 10 }; - m_gfx.outlinedRect(textBounds, m_rootWidget.getTooltipBackgroundColor(), m_rootWidget.getTooltipBorderColor(), m_rootWidget.getTooltipBorderWidth()); - m_gfx.drawCenteredString(getTooltipText(), textBounds, m_rootWidget.getTooltipTextColor(), m_rootWidget.getTooltipFontSize()); - } - m_gfx.endFrame(); - after_render(); + m_fixedUpdateTimer.update(); + m_mainLoopTimer.update(); } } diff --git a/src/ogfx/gui/Window.hpp b/src/ogfx/gui/Window.hpp index a5e9eb0..af264d6 100644 --- a/src/ogfx/gui/Window.hpp +++ b/src/ogfx/gui/Window.hpp @@ -303,10 +303,13 @@ namespace ogfx void __on_update(f64 delta) override; void __on_fixed_update(void) override; + void __main_loop_cycle(void); + protected: widgets::RootWidget m_rootWidget { *this }; ostd::StepTimer m_fixedUpdateTimer; ostd::StepTimer::TimePoint m_lastFrameTime; + ostd::StepTimer m_mainLoopTimer; ContextMenu m_cmenu { *this }; MenuBar m_menubar { *this }; ToolBar m_toolbar { *this }; diff --git a/src/ogfx/gui/widgets/Containers.cpp b/src/ogfx/gui/widgets/Containers.cpp index 737618c..1972723 100644 --- a/src/ogfx/gui/widgets/Containers.cpp +++ b/src/ogfx/gui/widgets/Containers.cpp @@ -53,6 +53,32 @@ namespace ogfx setTitlebarType(getThemeValue(theme, "titlebarType", TitleBarTypes::None)); } + void Panel::onMousePressed(const Event& event) + { + if (!isDraggable()) + return; + if (m_titleBarBounds.contains({ event.mouse->position_x, event.mouse->position_y }, true)) + { + m_mousePressed = true; + m_mousePos = { event.mouse->position_x, event.mouse->position_y }; + } + } + + void Panel::onMouseReleased(const Event& event) + { + m_mousePressed = false; + } + + void Panel::onMouseDragged(const Event& event) + { + if (m_mousePressed) + { + Vec2 mpos { event.mouse->position_x, event.mouse->position_y }; + addPos(mpos - m_mousePos); + m_mousePos = mpos; + } + } + void Panel::afterDraw(ogfx::BasicRenderer2D& gfx) { draw_titlebar(gfx); @@ -106,6 +132,7 @@ namespace ogfx getGlobalPosition() + Vec2 { br, br }, Vec2 { getw(), m_titlebarHeight } - Vec2 { br * 2, br * 2 } }; + m_titleBarBounds = titleBarBounds; switch (m_titlebarType) { case TitleBarTypes::FullValue: @@ -256,13 +283,13 @@ namespace ogfx return setCurrentTab(index); } - bool TabPanel::setCurrentTab(i32 index) + bool TabPanel::setCurrentTab(i32 index, bool ignore_same_tab) { if (index < 0 || index >= (i32)m_tabs.size()) return false; auto curr = m_tabs[index].get(); - if (curr == m_currentTab && m_currentTab != nullptr) + if (!ignore_same_tab && curr == m_currentTab && m_currentTab != nullptr) return false; removeWidget(*m_currentTab); m_currentTabIndex = index; @@ -272,6 +299,7 @@ namespace ogfx m_currentTab->setPosition({ 0, 0 }); m_currentTab->reloadTheme(true); m_currentTab->resetScroll(); + m_currentTab->updateScrollbarsSize(); return addWidget(*m_currentTab); } diff --git a/src/ogfx/gui/widgets/Containers.hpp b/src/ogfx/gui/widgets/Containers.hpp index 7deb500..e9493d3 100644 --- a/src/ogfx/gui/widgets/Containers.hpp +++ b/src/ogfx/gui/widgets/Containers.hpp @@ -47,18 +47,26 @@ namespace ogfx Panel& create(void); void applyTheme(const ostd::Stylesheet& theme) override; void afterDraw(ogfx::BasicRenderer2D& gfx) override; + void onMousePressed(const Event& event) override; + void onMouseReleased(const Event& event) override; + void onMouseDragged(const Event& event) override; void onWindowResized(const Event& event) override; void setTitlebarType(const String& type); String getTitlebarType(void) const; inline String getTitle(void) const { return m_title; } inline void setTitle(const String& title) { m_title = title; } inline f32 getTitlebarHeight(void) const { return m_titlebarHeight; } + OSTD_BOOL_PARAM_GETSET_I(Draggable, m_draggable); private: void draw_titlebar(BasicRenderer2D& gfx); private: String m_title { "Panel" }; + Vec2 m_mousePos { 0, 0 }; + bool m_mousePressed { false }; + bool m_draggable { false }; + Rectangle m_titleBarBounds; Color m_titleColor { Colors::Black }; i32 m_titlebarType = TitleBarTypes::NoneValue; @@ -83,9 +91,10 @@ namespace ogfx bool removeTab(i32 index); bool removeTab(const String& title); bool setCurrentTab(Panel& tab); - bool setCurrentTab(i32 index); + bool setCurrentTab(i32 index, bool ignore_same_tab = false); void setTabBarHeight(f32 height); bool isMouseInsideTabBar(const Vec2& mousePos); + inline void refreshCurrentTab(void) { setCurrentTab(m_currentTabIndex, true); } inline f32 getTabBarHeight(void) const { return m_tabBarHeight; } OSTD_PARAM_GETSET(Color, TabBarBackgroundColor, m_tabBarBackgroundColor); diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index 97487a6..0172d73 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -124,6 +124,7 @@ class Window : public ogfx::gui::Window m_panel2.setTitle("Panel 2"); m_panel2.enableTooltip(); m_panel2.setTooltipText("PANEL tooltip"); + m_panel2.enableDraggable(); m_prog.setSize(300, 30); m_slide.setSize(300, 30); @@ -138,7 +139,7 @@ class Window : public ogfx::gui::Window m_list.setSize(200, 300); m_list.reloadTheme(); - for (i32 i = 0; i < 500; i++) + for (i32 i = 0; i < 10000; i++) { m_list.addLine(ostd::Random::getString(ostd::Random::getui8(1, 40))); } @@ -165,7 +166,7 @@ class Window : public ogfx::gui::Window } m_tabs.setSize(900, 700); - m_tabs.addThemeOverride("@.tabPanel.borderWidth", 1.0f); + m_tabs.addThemeOverride("@.tabPanel.showBorder", false); auto& t1 = m_tabs.addTab("Tab1"); auto& t2 = m_tabs.addTab("Tab2 Test"); auto& t3 = m_tabs.addTab("Long Tab Test"); @@ -200,6 +201,7 @@ class Window : public ogfx::gui::Window m_panel2.addWidget(m_img, { 20, 50 }); addWidget(m_tabs, { 0, 0 }); + getToolBar().reloadTheme(true); m_drawCallsLbl.addThemeOverride("@.label.fontSize", 20); m_drawCallsLbl.addThemeOverride("@.label.padding", ostd::Rectangle { 10, 5, 0, 0 }); @@ -270,7 +272,10 @@ class Window : public ogfx::gui::Window else if (signal.ID == ostd::BuiltinSignals::WindowResized) { auto& wrd = cast(signal.userData); - m_tabs.setSize(cast(wrd.new_width), cast(wrd.new_height - getMenuBar().geth() - getToolBar().geth() - getStatusBar().geth())); + m_tabs.setSize(cast(getWindowWidth()), cast(getWindowHeight() - getMenuBar().geth() - getToolBar().geth() - getStatusBar().geth())); + m_tabs.setPosition(0, -1); + m_tabs.refreshCurrentTab(); + } }