diff --git a/extra/testTheme.txt b/extra/testTheme.txt index 0712b7a..0c9f27c 100644 --- a/extra/testTheme.txt +++ b/extra/testTheme.txt @@ -42,6 +42,7 @@ $accentColor = Color(rgb(255, 0, 0)) (@testLabel2 label) { showBackground = false + margin = Rect(30, 0, 30, 30) } (@testLabel2 label:hover) { diff --git a/other/TODO.txt b/other/TODO.txt index ef6f45b..9c934b4 100644 --- a/other/TODO.txt +++ b/other/TODO.txt @@ -7,10 +7,10 @@ ***Implement Drag And Drop ***Implement a way to determine on what widget (in the hierarchy chain) and event must stop ***Implement const in stylesheet +***Implement color constants in stylesheet +***Implement margin for widgets +***Implement mouse scroll callback Add theme caching -Implement mouse scroll callback -Implement margin for widgets -Implement color constants in stylesheet Implement following widgets: diff --git a/src/ogfx/gui/Events.hpp b/src/ogfx/gui/Events.hpp index a55a53f..d8bc734 100644 --- a/src/ogfx/gui/Events.hpp +++ b/src/ogfx/gui/Events.hpp @@ -48,6 +48,7 @@ namespace ogfx class MouseEventData : public ostd::BaseObject { public: enum class eButton { None = 0, Left, Middle, Right }; + public: enum class eScrollDirection { None = 0, Up, Down }; public: inline MouseEventData(WindowCore& parent, float mousex, float mousey, eButton btn) : parentWindow(parent), position_x(mousex), position_y(mousey), button(btn) { @@ -59,6 +60,7 @@ namespace ogfx float position_x; float position_y; eButton button; + eScrollDirection scroll { eScrollDirection::None }; gui::Widget* mousePressedOnWidget { nullptr }; WindowCore& parentWindow; }; diff --git a/src/ogfx/gui/WidgetManager.cpp b/src/ogfx/gui/WidgetManager.cpp index c69fe83..c2efb3d 100644 --- a/src/ogfx/gui/WidgetManager.cpp +++ b/src/ogfx/gui/WidgetManager.cpp @@ -216,6 +216,21 @@ namespace ogfx } } + void WidgetManager::onMouseScrolled(const Event& event) + { + for (int32_t i = m_widgetList.size() - 1; i >= 0; i--) + { + Widget* w = m_widgetList[i]; + if (w == nullptr) continue; + if (w->isInvalid()) continue; + if (!w->contains(event.mouse->position_x, event.mouse->position_y, true)) + continue; + w->__onMouseScrolled(event); + if (event.isHandled() || w->m_stopEvents) + break; + } + } + void WidgetManager::onMouseDragged(const Event& event) { for (int32_t i = m_widgetList.size() - 1; i >= 0; i--) diff --git a/src/ogfx/gui/WidgetManager.hpp b/src/ogfx/gui/WidgetManager.hpp index 1e841f1..1a65a9e 100644 --- a/src/ogfx/gui/WidgetManager.hpp +++ b/src/ogfx/gui/WidgetManager.hpp @@ -49,6 +49,7 @@ namespace ogfx void onMousePressed(const Event& event); void onMouseReleased(const Event& event); void onMouseMoved(const Event& event); + void onMouseScrolled(const Event& event); void onMouseDragged(const Event& event); void onKeyPressed(const Event& event); void onKeyReleased(const Event& event); diff --git a/src/ogfx/gui/Window.cpp b/src/ogfx/gui/Window.cpp index e1f900c..137e461 100644 --- a/src/ogfx/gui/Window.cpp +++ b/src/ogfx/gui/Window.cpp @@ -132,7 +132,7 @@ namespace ogfx connectSignal(ostd::BuiltinSignals::MousePressed); connectSignal(ostd::BuiltinSignals::MouseReleased); connectSignal(ostd::BuiltinSignals::MouseMoved); - connectSignal(ostd::BuiltinSignals::MouseMoved); + connectSignal(ostd::BuiltinSignals::MouseScrolled); connectSignal(ostd::BuiltinSignals::OnGuiEvent); connectSignal(ostd::BuiltinSignals::WindowClosed); connectSignal(ostd::BuiltinSignals::WindowResized); @@ -373,6 +373,17 @@ namespace ogfx MouseEventData mmd = get_mouse_state(); ostd::SignalHandler::emitSignal(ostd::BuiltinSignals::MouseMoved, ostd::Signal::Priority::RealTime, mmd); } + else if (event.type == SDL_EVENT_MOUSE_WHEEL) + { + MouseEventData mmd = get_mouse_state(); + if (event.wheel.y == -1) + mmd.scroll = MouseEventData::eScrollDirection::Down; + else if (event.wheel.y == 1) + mmd.scroll = MouseEventData::eScrollDirection::Up; + else + mmd.scroll = MouseEventData::eScrollDirection::None; + ostd::SignalHandler::emitSignal(ostd::BuiltinSignals::MouseScrolled, ostd::Signal::Priority::RealTime, mmd); + } else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { MouseEventData mmd = get_mouse_state(); @@ -635,6 +646,12 @@ namespace ogfx evt.__original_signal_id = ostd::BuiltinSignals::MouseMoved; m_rootWidget.__onMouseMoved(evt); } + else if (signal.ID == ostd::BuiltinSignals::MouseScrolled) + { + evt.mouse = &(ogfx::MouseEventData&)signal.userData; + evt.__original_signal_id = ostd::BuiltinSignals::MouseScrolled; + m_rootWidget.__onMouseScrolled(evt); + } else if (signal.ID == ostd::BuiltinSignals::MousePressed) { evt.mouse = &(ogfx::MouseEventData&)signal.userData; diff --git a/src/ogfx/gui/widgets/Label.cpp b/src/ogfx/gui/widgets/Label.cpp index b52399d..1322821 100644 --- a/src/ogfx/gui/widgets/Label.cpp +++ b/src/ogfx/gui/widgets/Label.cpp @@ -50,6 +50,7 @@ namespace ogfx m_borderColor = getThemeValue(theme, "label.borderColor", ostd::Colors::White); enableBackground(getThemeValue(theme, "label.showBackground", false)); setPadding(getThemeValue(theme, "label.padding", { 5, 5, 5, 5 })); + setMargin(getThemeValue(theme, "label.margin", { 0, 0, 0, 0 })); } void Label::onDraw(ogfx::BasicRenderer2D& gfx) diff --git a/src/ogfx/gui/widgets/Widget.cpp b/src/ogfx/gui/widgets/Widget.cpp index adae7ed..aa26311 100644 --- a/src/ogfx/gui/widgets/Widget.cpp +++ b/src/ogfx/gui/widgets/Widget.cpp @@ -50,6 +50,7 @@ namespace ogfx ostd::Vec2 glob = getPosition(); if (!m_rootChild && m_parent != nullptr) glob += m_parent->getGlobalPosition() + m_parent->getPadding().getPosition(); + glob += m_margin.getPosition(); return glob; } @@ -60,7 +61,7 @@ namespace ogfx ostd::Rectangle Widget::getGlobalBounds(void) const { - return { getGlobalPosition(), getSize() }; + return { getGlobalPosition(), getSize() + (m_margin.getSize() * 2) }; } ostd::Rectangle Widget::getContentBounds(void) const @@ -86,9 +87,9 @@ namespace ogfx setThemeQualifier("disabled", !enable); } - void Widget::addThemeOverride(const ostd::String& fullKey, ostd::Stylesheet::TypeVariant value, bool propagate) + void Widget::addThemeOverride(const ostd::String& fullKey, ostd::Stylesheet::TypeVariant value) { - m_themeOverrides.push_back({ fullKey, value, propagate }); + m_themeOverrides.push_back({ fullKey, value }); } void Widget::reloadTheme(void) @@ -115,8 +116,8 @@ namespace ogfx currentValue = *currentValuePtr; backup.push_back({ currentValuePtr, currentValue, rule.fullKey }); const_cast_theme.setFull(rule.fullKey, rule.value); - __applyTheme(const_cast_theme, rule.propagate); } + __applyTheme(const_cast_theme, false); for (auto&[ptr, val, key] : backup) { if (ptr == nullptr) @@ -234,6 +235,18 @@ namespace ogfx } } + void Widget::__onMouseScrolled(const Event& event) + { + if (hasChildren()) + m_widgets.onMouseScrolled(event); + if (!event.isHandled()) + { + if (callback_onMouseScrolled) + callback_onMouseScrolled(event); + onMouseScrolled(event); + } + } + void Widget::__onMouseEntered(const Event& event) { setThemeQualifier("hover"); diff --git a/src/ogfx/gui/widgets/Widget.hpp b/src/ogfx/gui/widgets/Widget.hpp index 32ffaaf..6131a8c 100644 --- a/src/ogfx/gui/widgets/Widget.hpp +++ b/src/ogfx/gui/widgets/Widget.hpp @@ -37,7 +37,6 @@ namespace ogfx { ostd::String fullKey; ostd::Stylesheet::TypeVariant value; - bool propagate; }; public: using EventCallback = std::function; public: @@ -52,7 +51,7 @@ namespace ogfx bool contains(ostd::Vec2 p, bool includeBounds = false) const override; void enable(bool enable = true); virtual void applyTheme(const ostd::Stylesheet& theme) = 0; - void addThemeOverride(const ostd::String& fullKey, ostd::Stylesheet::TypeVariant value, bool propagate = true); + void addThemeOverride(const ostd::String& fullKey, ostd::Stylesheet::TypeVariant value); void reloadTheme(void); void setThemeQualifier(const ostd::String& qualifier, bool value = true); bool getThemeQualifier(const ostd::String& qualifier) const; @@ -66,6 +65,7 @@ namespace ogfx inline virtual void onMousePressed(const Event& event) { } inline virtual void onMouseReleased(const Event& event) { } inline virtual void onMouseMoved(const Event& event) { } + inline virtual void onMouseScrolled(const Event& event) { } inline virtual void onDragAndDrop(const Event& event) { } inline virtual void onMouseEntered(const Event& event) { } inline virtual void onMouseExited(const Event& event) { } @@ -86,6 +86,7 @@ namespace ogfx void __onMouseReleased(const Event& event); void __onDragAndDrop(const Event& event); void __onMouseMoved(const Event& event); + void __onMouseScrolled(const Event& event); void __onMouseEntered(const Event& event); void __onMouseExited(const Event& event); void __onMouseDragged(const Event& event); @@ -101,6 +102,7 @@ namespace ogfx inline virtual void setMousePressedCallback(EventCallback callback) { callback_onMousePressed = callback; } inline virtual void setMouseReleasedCallback(EventCallback callback) { callback_onMouseReleased = callback; } inline virtual void setMouseMovedCallback(EventCallback callback) { callback_onMouseMoved = callback; } + inline virtual void setMouseScrolledCallback(EventCallback callback) { callback_onMouseScrolled = callback; } inline virtual void setDragAndDropCallback(EventCallback callback) { callback_onDragAndDrop = callback; } inline virtual void setMouseEnteredCallback(EventCallback callback) { callback_onMouseEntered = callback; } inline virtual void setMouseExitedCallback(EventCallback callback) { callback_onMouseExited = callback; } @@ -123,7 +125,9 @@ namespace ogfx inline int32_t getZIndex(void) const { return m_zIndex; } inline bool isChildrenEnabled(void) const { return m_allowChildren; } inline void setPadding(const ostd::Rectangle& pad) { m_padding = pad; } + inline void setMargin(const ostd::Rectangle& margin) { m_margin = margin; } inline Rectangle getPadding(void) const { return m_padding; } + inline Rectangle getMargin(void) const { return m_margin; } inline bool isMouseInside(void) const { return m_mouseInside; } inline ogfx::MouseEventData::eButton getPressedMouseButton(void) const { return m_pressedButton; } inline const std::vector& getThemeIDList(void) const { return m_themeIDList; } @@ -166,6 +170,7 @@ namespace ogfx EventCallback callback_onMouseReleased { nullptr }; EventCallback callback_onDragAndDrop { nullptr }; EventCallback callback_onMouseMoved { nullptr }; + EventCallback callback_onMouseScrolled { nullptr }; EventCallback callback_onMouseEntered { nullptr }; EventCallback callback_onMouseExited { nullptr }; EventCallback callback_onMouseDragged { nullptr }; @@ -207,8 +212,8 @@ namespace ogfx ostd::Color m_drawBoxColor { 255, 0, 0 }; ostd::Rectangle m_padding { 0, 0, 0, 0 }; + ostd::Rectangle m_margin { 0, 0, 0, 0 }; - public: static ostd::BaseObject* s_dragAndDropData; static bool s_hasDragAndDropData; diff --git a/src/ostd/io/Stylesheet.cpp b/src/ostd/io/Stylesheet.cpp index f107f66..8598413 100644 --- a/src/ostd/io/Stylesheet.cpp +++ b/src/ostd/io/Stylesheet.cpp @@ -56,13 +56,11 @@ namespace ostd if (!parseThemeFileLine(line, variables)) l_warn("Error"); }; - for (const auto&[var, val] : variables) - std::cout << var << " = " << val.first << "\n"; uint8_t lineNumberMaxWidth = ostd::String("").add(lines.size()).len(); ostd::String groupSelector = ""; bool groupLines = true; std::vector group; - bool debug_print = true; + bool debug_print = false; for (auto& line : lines) { lineNumber++; diff --git a/src/ostd/utils/Signals.hpp b/src/ostd/utils/Signals.hpp index 9455875..946c380 100755 --- a/src/ostd/utils/Signals.hpp +++ b/src/ostd/utils/Signals.hpp @@ -39,6 +39,7 @@ namespace ostd inline static constexpr uint32_t MouseMoved = 0x0005; inline static constexpr uint32_t MouseDragged = 0x0006; inline static constexpr uint32_t TextEntered = 0x0007; + inline static constexpr uint32_t MouseScrolled = 0x0008; inline static constexpr uint32_t OnGuiEvent = 0x2001; inline static constexpr uint32_t FileDragAndDropped = 0x2002; diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index 7082670..de2a1c4 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -42,6 +42,9 @@ class Window : public ogfx::gui::Window m_panel1.addPos(pos2 - pos); pos = pos2; }); + m_panel1.setMouseScrolledCallback([&](const ogfx::gui::Event& event) -> void { + std::cout << "SCROLLED IN THE PANEL LOL \n"; + }); m_panel2.setSize(600, 400); @@ -59,6 +62,9 @@ class Window : public ogfx::gui::Window m_label1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void { std::cout << "PRESS!\n"; }); + m_label1.setMouseScrolledCallback([&](const ogfx::gui::Event& event) -> void { + std::cout << "SCROLL!\n"; + }); addWidget(m_label1); m_panel2.addChild(m_panel1); addWidget(m_panel2); @@ -80,6 +86,9 @@ class Window : public ogfx::gui::Window std::cout << data.textOrFilePath << "\n"; } }); + m_label2.setMouseScrolledCallback([&](const ogfx::gui::Event& event) -> void { + std::cout << "BARBABARBA!\n"; + }); m_label2.enableDragAndDrop(); m_label2.setDragAndDropCallback([&](const ogfx::gui::Event& event) -> void { if (event.drop.userObject->getTypeName() == "ogfx::gui::widgets::Label") @@ -103,7 +112,7 @@ class Window : public ogfx::gui::Window setTheme(m_theme); - std::cout << m_theme.get("panel.titlebarType", "", {}, {}) << " \n"; + // std::cout << m_theme.get("panel.titlebarType", "", {}, {}) << " \n"; } inline void onSignal(ostd::Signal& signal) override