diff --git a/CMakeLists.txt b/CMakeLists.txt index 585e2c7..53e6a9b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,7 @@ list(APPEND OGFX_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Containers.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Label.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/RootWidget.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/CheckBox.cpp # render ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp diff --git a/extra/testTheme.txt b/extra/testTheme.txt index 0c9f27c..26422b3 100644 --- a/extra/testTheme.txt +++ b/extra/testTheme.txt @@ -21,6 +21,34 @@ $accentColor = Color(rgb(255, 0, 0)) padding = Rect(15, 15, 15, 15) } +(checkbox) { + textColor = color_black + fontSize = 28 + showBackground = false + showBorder = false + borderRadius = 0 + borderWidth = 2 + + checkBorderRadius = 8 + checkBorderWidth = 2 + checkBorderColor = color_skyblue + checkBoxColor = color_skyblue + padding = Rect(15, 15, 15, 15) +} + +(checkbox:hover) { + checkBorderColor = color_white +} + +(checkbox:pressed) { + checkBoxColor = color_lightgray + textColor = color_darkgray +} + +(checkbox:active) { + textColor = Color(#000050FF) +} + (panel) { backgroundColor = Color(#AAAAAAFF) borderColor = Color(#000000FF) diff --git a/other/TODO.txt b/other/TODO.txt index 9c934b4..0ba0158 100644 --- a/other/TODO.txt +++ b/other/TODO.txt @@ -15,11 +15,11 @@ Add theme caching Implement following widgets: ***Label + ***Checkbox Button Image/Icon Panel / Container Title Label - Checkbox Radio Button Grouping Text Input @@ -32,3 +32,7 @@ Implement following widgets: TreeView Save/Open File Dialogs (and folder dialogs) Tab Panel + Layouts + Vertical + Horizontal + Grid diff --git a/src/ogfx/gui/Widgets.hpp b/src/ogfx/gui/Widgets.hpp index d0912eb..368239d 100644 --- a/src/ogfx/gui/Widgets.hpp +++ b/src/ogfx/gui/Widgets.hpp @@ -22,3 +22,4 @@ #include #include +#include diff --git a/src/ogfx/gui/widgets/CheckBox.cpp b/src/ogfx/gui/widgets/CheckBox.cpp new file mode 100644 index 0000000..f59c3c5 --- /dev/null +++ b/src/ogfx/gui/widgets/CheckBox.cpp @@ -0,0 +1,100 @@ +/* + 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 "CheckBox.hpp" +#include "../../render/BasicRenderer.hpp" + +namespace ogfx +{ + namespace gui + { + namespace widgets + { + CheckBox& CheckBox::create(const ostd::String& text) + { + setText(text); + setPadding({ 5, 5, 5, 5 }); + setTypeName("ogfx::gui::widgets::Label"); + disableDrawBox(); + disableChildren(); + enableBackground(false); + validate(); + return *this; + } + + void CheckBox::applyTheme(const ostd::Stylesheet& theme) + { + setCheckBorderColor(getThemeValue(theme, "checkbox.checkBorderColor", ostd::Colors::White)); + setCheckBoxColor(getThemeValue(theme, "checkbox.checkBoxColor", ostd::Colors::White)); + setTextColor(getThemeValue(theme, "checkbox.textColor", ostd::Colors::Black)); + setBackGroundColor(getThemeValue(theme, "checkbox.backgroundColor", ostd::Colors::Transparent)); + setFontSize(getThemeValue(theme, "checkbox.fontSize", 28)); + m_borderRadius = getThemeValue(theme, "checkbox.borderRadius", 10); + m_borderWidth = getThemeValue(theme, "checkbox.borderWidth", 2); + m_showBorder = getThemeValue(theme, "checkbox.showBorder", false); + m_borderColor = getThemeValue(theme, "checkbox.borderColor", ostd::Colors::White); + enableBackground(getThemeValue(theme, "checkbox.showBackground", false)); + setPadding(getThemeValue(theme, "checkbox.padding", { 5, 5, 5, 5 })); + setMargin(getThemeValue(theme, "checkbox.margin", { 0, 0, 0, 0 })); + m_checkBorderRadius = getThemeValue(theme, "checkbox.checkBorderRadius", 5); + m_checkBorderWidth = getThemeValue(theme, "checkbox.checkBorderWidth", 1); + } + + void CheckBox::onDraw(ogfx::BasicRenderer2D& gfx) + { + if (m_textChanged) + __update_size(gfx); + if (m_showBackground) + gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius); + if (m_showBorder) + gfx.drawRoundRect({ getGlobalPosition(), getSize() }, m_borderColor, m_borderRadius, m_borderWidth); + gfx.drawRoundRect({ getGlobalContentPosition(), m_checkSize }, getCheckBorderColor(), m_checkBorderRadius, m_checkBorderWidth); + if (isChecked()) + gfx.fillRoundRect({ getGlobalContentPosition() + 5, m_checkSize - 10 }, getCheckBoxColor(), m_checkBorderRadius / 2); + gfx.drawString(getText(), getGlobalContentPosition() + ostd::Vec2 { m_checkSize.x + m_spacing, 0 }, getTextColor(), getFontSize()); + } + + void CheckBox::onMouseReleased(const Event& event) + { + m_checked = !m_checked; + setThemeQualifier("active", m_checked); + } + + void CheckBox::setText(const ostd::String& text) + { + m_text = text; + m_textChanged = true; + } + + void CheckBox::__update_size(ogfx::BasicRenderer2D& gfx) + { + auto size = gfx.getStringSize(getText(), getFontSize()); + m_checkSize = { static_cast(size.y), static_cast(size.y) }; + size.x += m_spacing + m_checkSize.x; + size.x += getPadding().left(); + size.x += getPadding().right(); + size.y += getPadding().top(); + size.y += getPadding().bottom(); + setSize({ static_cast(size.x), static_cast(size.y) }); + m_textChanged = false; + } + } + } +} diff --git a/src/ogfx/gui/widgets/CheckBox.hpp b/src/ogfx/gui/widgets/CheckBox.hpp new file mode 100644 index 0000000..7987c20 --- /dev/null +++ b/src/ogfx/gui/widgets/CheckBox.hpp @@ -0,0 +1,79 @@ +/* + 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 "math/Geometry.hpp" +#include + +namespace ogfx +{ + namespace gui + { + namespace widgets + { + + class CheckBox : public Widget + { + public: + inline CheckBox(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(""); } + inline CheckBox(WindowCore& window, const ostd::String& text) : Widget({ 0, 0, 0, 0 }, window) { create(text); } + CheckBox& create(const ostd::String& text); + void applyTheme(const ostd::Stylesheet& theme) override; + void onDraw(ogfx::BasicRenderer2D& gfx) override; + void onMouseReleased(const Event& event) override; + void setText(const ostd::String& text); + inline ostd::String getText(void) const { return m_text; } + inline ostd::Color getCheckBorderColor(void) const { return m_checkBorderColor; } + inline void setCheckBorderColor(const ostd::Color& color) { m_checkBorderColor = color; } + inline ostd::Color getCheckBoxColor(void) const { return m_checkBoxColor; } + inline void setCheckBoxColor(const ostd::Color& color) { m_checkBoxColor = color; } + inline ostd::Color getTextColor(void) const { return m_textColor; } + inline void setTextColor(const ostd::Color& color) { m_textColor = color; } + inline int32_t getFontSize(void) const { return m_fontSize; } + inline void setFontSize(int32_t fontSize) { m_fontSize = fontSize; } + inline void setBackGroundColor(const ostd::Color& color) { m_backgroundColor = color; } + inline ostd::Color getBackgroundColor(void) { return m_backgroundColor; } + inline void enableBackground(bool enable = true) { m_showBackground = enable; } + inline bool isBackgoundEnabled(void) const { return m_showBackground; } + inline bool isChecked(void) const { return m_checked; } + inline void setChecked(bool checked) { m_checked = checked; } + + private: + void __update_size(ogfx::BasicRenderer2D& gfx); + + private: + bool m_checked { false }; + ostd::String m_text { "" }; + bool m_textChanged { false }; + int32_t m_fontSize { 20 }; + ostd::Color m_textColor { 255, 255, 255 }; + bool m_showBackground { false }; + ostd::Color m_backgroundColor { ostd::Colors::Transparent }; + float m_spacing { 10 }; + ostd::Vec2 m_checkSize { 0, 0 }; + int32_t m_checkBorderRadius { 5 }; + int32_t m_checkBorderWidth { 1 }; + ostd::Color m_checkBorderColor { 255, 255, 255 }; + ostd::Color m_checkBoxColor { 255, 255, 255 }; + }; + } + } +} diff --git a/src/ogfx/gui/widgets/Label.cpp b/src/ogfx/gui/widgets/Label.cpp index 1322821..645001d 100644 --- a/src/ogfx/gui/widgets/Label.cpp +++ b/src/ogfx/gui/widgets/Label.cpp @@ -61,7 +61,7 @@ namespace ogfx gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius); if (m_showBorder) gfx.drawRoundRect({ getGlobalPosition(), getSize() }, m_borderColor, m_borderRadius, m_borderWidth); - gfx.drawString(getText(), getGlobalPosition() + ostd::Vec2 { getPadding().left(), getPadding().top() }, getColor(), getFontSize()); + gfx.drawString(getText(), getGlobalContentPosition(), getColor(), getFontSize()); } void Label::setText(const ostd::String& text) diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index de2a1c4..4af12ca 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -69,6 +69,11 @@ class Window : public ogfx::gui::Window m_panel2.addChild(m_panel1); addWidget(m_panel2); + + m_check1.setPosition(30, 30); + m_check1.setText("Check this out!"); + addWidget(m_check1); + m_label2.setPosition(0, 0); m_label2.setText("Ciccia Bella!"); m_label2.connectSignal(ostd::BuiltinSignals::FileDragAndDropped); @@ -136,6 +141,7 @@ class Window : public ogfx::gui::Window ogfx::gui::widgets::Label m_label3 { *this }; ogfx::gui::widgets::Panel m_panel1 { *this }; ogfx::gui::widgets::Panel m_panel2 { *this }; + ogfx::gui::widgets::CheckBox m_check1 { *this }; ostd::Stylesheet m_theme; ostd::Vec2 pos { 0, 0 }; };