From 4fb5e24bb92467bb8081c5c66ed7f865ed6b2329 Mon Sep 17 00:00:00 2001 From: OmniaX-Dev Date: Tue, 28 Apr 2026 06:48:47 +0200 Subject: [PATCH] Started work on ComboBox --- CMakeLists.txt | 1 + extra/DefaultThemeDark.oss | 26 +++++++++- src/ogfx/gui/Widgets.hpp | 1 + src/ogfx/gui/widgets/ComboBox.cpp | 86 +++++++++++++++++++++++++++++++ src/ogfx/gui/widgets/ComboBox.hpp | 53 +++++++++++++++++++ src/test/GuiTest.cpp | 4 ++ 6 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 src/ogfx/gui/widgets/ComboBox.cpp create mode 100644 src/ogfx/gui/widgets/ComboBox.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a33b3b3..73a1d49 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,6 +101,7 @@ list(APPEND OGFX_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/ProgressBar.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Slider.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/ListView.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/ComboBox.cpp # render ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp diff --git a/extra/DefaultThemeDark.oss b/extra/DefaultThemeDark.oss index 31d9cf2..273df15 100644 --- a/extra/DefaultThemeDark.oss +++ b/extra/DefaultThemeDark.oss @@ -230,7 +230,7 @@ const $backgroundColor = rgba(30, 30, 30, 255) useProgressGradient = true progressGradient = gradientV($accentColor - $accentColorDark) } -% =================== +% ========================= @@ -319,7 +319,6 @@ const $backgroundColor = rgba(30, 30, 30, 255) borderColor = $borderColor showBorder = true } -% ===================== (@tool_button button) { fontSize = 18 padding = rect(5, 0, 5, 0) @@ -347,3 +346,26 @@ const $backgroundColor = rgba(30, 30, 30, 255) tint = $accentColorLight } } +% ===================== + + + +% ====== ComboBox ====== +(combo) { + borderColor = $accentColor + backgroundColor = $darkColor + borderWidth = 1 + showBackground = true + showBorder = true + triangleIndicatorColor = $accentColor + triangleIndicatorPadding = 8.0 +} +(combo:hover) { + triangleIndicatorColor = $accentColorLight + borderColor = $accentColorLight +} +(combo:active) { + triangleIndicatorColor = $accentColorDark + borderColor = $accentColorDark +} +% ====================== diff --git a/src/ogfx/gui/Widgets.hpp b/src/ogfx/gui/Widgets.hpp index 181ce23..0b0e26e 100644 --- a/src/ogfx/gui/Widgets.hpp +++ b/src/ogfx/gui/Widgets.hpp @@ -29,3 +29,4 @@ #include #include #include +#include diff --git a/src/ogfx/gui/widgets/ComboBox.cpp b/src/ogfx/gui/widgets/ComboBox.cpp new file mode 100644 index 0000000..c3a8e98 --- /dev/null +++ b/src/ogfx/gui/widgets/ComboBox.cpp @@ -0,0 +1,86 @@ +/* + 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 . +*/ + +#include "ComboBox.hpp" +#include "../../render/BasicRenderer.hpp" + +namespace ogfx +{ + namespace gui + { + ComboBox& ComboBox::create(void) + { + setPadding({ 5, 5, 5, 5 }); + setTypeName("ogfx::gui::ComboBox"); + disableChildren(); + setStylesheetCategoryName("combo"); + connectSignal(ostd::BuiltinSignals::MouseReleased); + validate(); + return *this; + } + + void ComboBox::onDraw(ogfx::BasicRenderer2D& gfx) + { + gfx.outlinedRect(*this, getBackgroundColor(), getBorderColor(), getBorderWidth()); + + // Triangle Indicator + const f32 triPad = getTriangleIndicatorPadding(); + const f32 triSide = geth() - (triPad * 2); + Triangle tri { + getGlobalPosition() + Vec2 { getw() - triPad - triSide, triPad }, + getGlobalPosition() + Vec2 { getw() - triPad, triPad }, + getGlobalPosition() + Vec2 { getw() - triPad - (triSide * 0.5f), geth() - triPad } + }; + gfx.fillTriangle(tri, getTriangleIndicatorColor()); + } + + void ComboBox::onUpdate(void) + { + + } + + void ComboBox::onMouseReleased(const Event& event) + { + if (isMouseInside()) + { + setThemeQualifier("active", true); + m_dropDownShown = true; + } + } + + void ComboBox::applyTheme(const ostd::Stylesheet& theme) + { + setTriangleIndicatorColor(getThemeValue(theme, "triangleIndicatorColor", getTriangleIndicatorColor())); + setTriangleIndicatorPadding(getThemeValue(theme, "triangleIndicatorPadding", getTriangleIndicatorPadding())); + } + + void ComboBox::handleSignal(ostd::Signal& signal) + { + if (signal.ID == ostd::BuiltinSignals::MouseReleased) + { + if (isMouseInside()) + return; + if (!m_dropDownShown) + return; + setThemeQualifier("active", false); + } + } + } +} diff --git a/src/ogfx/gui/widgets/ComboBox.hpp b/src/ogfx/gui/widgets/ComboBox.hpp new file mode 100644 index 0000000..d32e4fe --- /dev/null +++ b/src/ogfx/gui/widgets/ComboBox.hpp @@ -0,0 +1,53 @@ +/* + 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 . +*/ + +#pragma once + +#include +#include + +namespace ogfx +{ + namespace gui + { + class ComboBox : public Widget + { + public: + inline ComboBox(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(); } + ComboBox& create(void); + + void onDraw(ogfx::BasicRenderer2D& gfx) override; + void onUpdate(void) override; + void onMouseReleased(const Event& event) override; + void applyTheme(const ostd::Stylesheet& theme) override; + void handleSignal(ostd::Signal& signal) override; + + OSTD_PARAM_GETSET(Color, TriangleIndicatorColor, m_triangleColor); + OSTD_PARAM_GETSET(f32, TriangleIndicatorPadding, m_trianglePadding); + + private: + bool m_dropDownShown { false }; + ContextMenu::Instance m_menu; + + Color m_triangleColor { "#008000FF" }; + f32 m_trianglePadding { 8.0f }; + }; + } +} diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index 625778d..db0b40b 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -186,6 +186,7 @@ class TestWindow : public Window t1.addWidget(m_slideLbl, { 340, 240 }); t1.addWidget(m_list, { 30, 300 }); t1.addWidget(m_panel2, { 500, 100 }); + t1.addWidget(m_combo, { 400, 600 }); t2.setLayout(BoxLayout::Orientation::Vertical); t2.getLayout()->setSpacing(16); @@ -199,6 +200,8 @@ class TestWindow : public Window auto* footer = new Button(*this); footer->layoutHint().preferred = { -1, 24 }; + m_combo.setSize(200, 30); + t2.addWidget(*header); // each addWidget() call triggers a relayout t2.addWidget(*body); for (i32 i = 0; i < 100; i++) @@ -324,6 +327,7 @@ class TestWindow : public Window Label m_slideLbl { *this }; ListView m_list { *this }; Label m_drawCallsLbl { *this }; + ComboBox m_combo { *this }; enum MenuId : i32 { New = 1, Open, Save, SaveAs, Exit, CopyRaw, CopyFormatted };