Added Basic Panel widget
This commit is contained in:
parent
c695c0ad85
commit
260c7054bc
19 changed files with 722 additions and 426 deletions
1
.clangd
1
.clangd
|
|
@ -1,2 +1,3 @@
|
|||
CompileFlags:
|
||||
CompilationDatabase: bin
|
||||
Add: ["--target=x86_64-w64-mingw32"]
|
||||
|
|
@ -89,7 +89,11 @@ list(APPEND OGFX_SOURCE_FILES
|
|||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/RawTextInput.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/Window.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/WindowOutputHandler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/Widgets.cpp
|
||||
|
||||
# gui/widgets
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Widget.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Containers.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Label.cpp
|
||||
|
||||
# render
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ window.backgroundColor = Color(rgba(120, 120, 120, 255))
|
|||
|
||||
(panel) {
|
||||
backgroundColor = Color(#AAAAAAFF)
|
||||
borderColor = Color(#000000FF)
|
||||
borderColor = Color(#00FF00FF)
|
||||
borderRadius = 8
|
||||
borderWidth = 2
|
||||
borderWidth = 4
|
||||
showBorder = true
|
||||
padding = Rect(15, 15, 15, 15)
|
||||
}
|
||||
|
|
@ -42,6 +42,11 @@ window.backgroundColor = Color(rgba(120, 120, 120, 255))
|
|||
borderColor = Color(#208080FF)
|
||||
}
|
||||
|
||||
|
||||
% (@testLabel2 label:pressed [mouseButton=left or mouseButton=right]) {
|
||||
% ...
|
||||
|
||||
|
||||
(@testLabel2 label:pressed) {
|
||||
showBackground = true
|
||||
}
|
||||
|
|
@ -70,4 +75,13 @@ window.backgroundColor = Color(rgba(120, 120, 120, 255))
|
|||
%borderColor = Color(#000000FF)
|
||||
}
|
||||
|
||||
(@label3 label) {
|
||||
textColor = $color2
|
||||
backgroundColor = Color(#000000FF)
|
||||
fontSize = 20
|
||||
borderColor = Color(#FF0000FF)
|
||||
borderWidth = 4
|
||||
borderRadius = 15
|
||||
}
|
||||
|
||||
% ===================================================
|
||||
|
|
|
|||
|
|
@ -3,3 +3,30 @@
|
|||
***Fix mouse detection currently using local coordinates
|
||||
***implement file theme loading
|
||||
***Implemenmt MouseDragged callback
|
||||
***Add scissoring to only draw inside the bounds of containers
|
||||
Add theme caching
|
||||
Implement mouse scroll callback
|
||||
Implement a way to determine on what widget (in the hierarchy chain) and event must stop
|
||||
Implement margin for widgets
|
||||
Implement conditional statements for stylesheet rules
|
||||
|
||||
|
||||
Implement following widgets:
|
||||
***Label
|
||||
Button
|
||||
Image/Icon
|
||||
Panel / Container
|
||||
Title Label
|
||||
Checkbox
|
||||
Radio Button
|
||||
Grouping
|
||||
Text Input
|
||||
Horizontal Slider
|
||||
Vertical Slider
|
||||
Image / Icon
|
||||
ScrollView
|
||||
ListBox
|
||||
ComboBox
|
||||
TreeView
|
||||
Save/Open File Dialogs (and folder dialogs)
|
||||
Tab Panel
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2046
|
||||
2049
|
||||
|
|
|
|||
|
|
@ -58,11 +58,13 @@ cp -r ../src/ostd/vendor/nlohmann $RELEASE_DIR/include/ostd/vendor/
|
|||
# OGFX
|
||||
mkdir -p $RELEASE_DIR/include/ogfx/vendor/sdl3_gfx
|
||||
mkdir -p $RELEASE_DIR/include/ogfx/gui
|
||||
mkdir -p $RELEASE_DIR/include/ogfx/gui/widgets
|
||||
mkdir -p $RELEASE_DIR/include/ogfx/render
|
||||
mkdir -p $RELEASE_DIR/include/ogfx/resources
|
||||
mkdir -p $RELEASE_DIR/include/ogfx/utils
|
||||
find ../src/ogfx -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx \;
|
||||
find ../src/ogfx/gui -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/gui \;
|
||||
find ../src/ogfx/gui/widgets -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/gui/widgets \;
|
||||
find ../src/ogfx/render -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/render \;
|
||||
find ../src/ogfx/resources -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/resources \;
|
||||
find ../src/ogfx/utils -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/utils \;
|
||||
|
|
|
|||
|
|
@ -1,301 +1,24 @@
|
|||
/*
|
||||
OmniaFramework - A collection of useful functionality
|
||||
Copyright (C) 2025 OmniaX-Dev
|
||||
OmniaFramework - A collection of useful functionality
|
||||
Copyright (C) 2025 OmniaX-Dev
|
||||
|
||||
This file is part of OmniaFramework.
|
||||
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 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.
|
||||
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/>.
|
||||
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 "gui/Events.hpp"
|
||||
#include <ostd/data/BaseObject.hpp>
|
||||
#include <ostd/math/Geometry.hpp>
|
||||
#include <ostd/data/Color.hpp>
|
||||
#include <ostd/io/Stylesheet.hpp>
|
||||
#include <ostd/utils/Time.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
class BasicRenderer2D;
|
||||
class WindowCore;
|
||||
namespace gui
|
||||
{
|
||||
class Event;
|
||||
class Widget;
|
||||
class WidgetManager
|
||||
{
|
||||
public:
|
||||
WidgetManager(WindowCore& window, Widget& owner);
|
||||
bool hasWidget(Widget& widget);
|
||||
bool requestFocus(Widget& widget);
|
||||
bool addWidget(Widget& widget);
|
||||
Widget* focusNext(void);
|
||||
|
||||
void draw(ogfx::BasicRenderer2D& gfx);
|
||||
void update(void);
|
||||
void onThemeApplied(const ostd::Stylesheet& theme);
|
||||
void onMousePressed(const Event& event);
|
||||
void onMouseReleased(const Event& event);
|
||||
void onMouseMoved(const Event& event);
|
||||
void onMouseDragged(const Event& event);
|
||||
void onKeyPressed(const Event& event);
|
||||
void onKeyReleased(const Event& event);
|
||||
void onTextEntered(const Event& event);
|
||||
void onWindowClosed(const Event& event);
|
||||
void onWindowResized(const Event& event);
|
||||
void onWindowFocused(const Event& event);
|
||||
void onWindowFocusLost(const Event& event);
|
||||
|
||||
inline int32_t widgetCount(void) const { return m_widgetList.size(); }
|
||||
inline WindowCore& getWindow(void) { return m_window; }
|
||||
|
||||
private:
|
||||
WindowCore& m_window;
|
||||
Widget& m_owner;
|
||||
std::vector<Widget*> m_widgetList;
|
||||
Widget* m_focused { nullptr };
|
||||
bool m_tabNavigationEnabled { true };
|
||||
Widget* m_mousePressedOnWidget { nullptr };
|
||||
};
|
||||
class Widget : public ostd::BaseObject, public ostd::Rectangle
|
||||
{
|
||||
private: struct ThemeOverride
|
||||
{
|
||||
ostd::String fullKey;
|
||||
ostd::Stylesheet::TypeVariant value;
|
||||
bool propagate;
|
||||
};
|
||||
public: using EventCallback = std::function<void(const Event&)>;
|
||||
public:
|
||||
Widget(const ostd::Rectangle& bounds, WindowCore& window);
|
||||
bool addChild(Widget& child);
|
||||
ostd::Vec2 getGlobalPosition(void) const;
|
||||
using ostd::Rectangle::contains;
|
||||
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 reloadTheme(void);
|
||||
void setThemeQualifier(const ostd::String& qualifier, bool value = true);
|
||||
bool getThemeQualifier(const ostd::String& qualifier);
|
||||
bool addThemeID(const ostd::String& id);
|
||||
bool removeThemeID(const ostd::String& id);
|
||||
inline const ostd::Stylesheet::QualifierList& getThemeQualifierList(void) const { return m_qualifierList; }
|
||||
|
||||
inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { }
|
||||
inline virtual void onUpdate(void) { }
|
||||
|
||||
inline virtual void onMousePressed(const Event& event) { }
|
||||
inline virtual void onMouseReleased(const Event& event) { }
|
||||
inline virtual void onMouseMoved(const Event& event) { }
|
||||
inline virtual void onMouseEntered(const Event& event) { }
|
||||
inline virtual void onMouseExited(const Event& event) { }
|
||||
inline virtual void onMouseDragged(const Event& event) { }
|
||||
inline virtual void onKeyPressed(const Event& event) { }
|
||||
inline virtual void onKeyReleased(const Event& event) { }
|
||||
inline virtual void onTextEntered(const Event& event) { }
|
||||
inline virtual void onFocusGained(const Event& event) { }
|
||||
inline virtual void onFocusLost(const Event& event) { }
|
||||
inline virtual void onWindowClosed(const Event& event) { }
|
||||
inline virtual void onWindowResized(const Event& event) { }
|
||||
inline virtual void onWindowFocused(const Event& event) { }
|
||||
inline virtual void onWindowFocusLost(const Event& event) { }
|
||||
|
||||
void __draw(ogfx::BasicRenderer2D& gfx);
|
||||
void __update(void);
|
||||
void __onMousePressed(const Event& event);
|
||||
void __onMouseReleased(const Event& event);
|
||||
void __onMouseMoved(const Event& event);
|
||||
void __onMouseEntered(const Event& event);
|
||||
void __onMouseExited(const Event& event);
|
||||
void __onMouseDragged(const Event& event);
|
||||
void __onKeyPressed(const Event& event);
|
||||
void __onKeyReleased(const Event& event);
|
||||
void __onTextEntered(const Event& event);
|
||||
void __onWindowClosed(const Event& event);
|
||||
void __onWindowResized(const Event& event);
|
||||
void __onWIndowFocused(const Event& event);
|
||||
void __onWindowFocusLost(const Event& event);
|
||||
void __applyTheme(const ostd::Stylesheet& theme, bool propagate);
|
||||
|
||||
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 setMouseEnteredCallback(EventCallback callback) { callback_onMouseEntered = callback; }
|
||||
inline virtual void setMouseExitedCallback(EventCallback callback) { callback_onMouseExited = callback; }
|
||||
inline virtual void setMouseDraggedCallback(EventCallback callback) { callback_onMouseDragged = callback; }
|
||||
inline virtual void setKeyPressedCallback(EventCallback callback) { callback_onKeyPressed = callback; }
|
||||
inline virtual void setKeyReleasedCallback(EventCallback callback) { callback_onKeyReleased = callback; }
|
||||
inline virtual void setTextEnteredCallback(EventCallback callback) { callback_onTextEntered = callback; }
|
||||
inline virtual void setWindowClosedCallback(EventCallback callback) { callback_onWindowClosed = callback; }
|
||||
inline virtual void setWindowResizedCallback(EventCallback callback) { callback_onWindowResized = callback; }
|
||||
inline virtual void setWIndowFocusedCallback(EventCallback callback) { callback_onWindowFocused = callback; }
|
||||
inline virtual void setWindowFocusLostCallback(EventCallback callback) { callback_onWindowFocusLost = callback; }
|
||||
|
||||
inline bool hasChildren(void) const { return m_allowChildren && m_widgets.widgetCount() > 0; }
|
||||
inline virtual bool isInvalid(void) const override { return ostd::BaseObject::isInvalid() || (m_parent == nullptr && !m_rootChild); }
|
||||
inline void setTabIndex(int32_t tabIndex) { m_tabIndex = tabIndex; }
|
||||
inline int32_t getTabIndex(void) const { return m_tabIndex; }
|
||||
inline bool isFocused(void) const { return m_focused; }
|
||||
inline WindowCore& getWindow(void) { return *m_window; }
|
||||
inline Widget* getParent(void) { return m_parent; }
|
||||
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 Rectangle getPadding(void) { return m_padding; }
|
||||
inline bool isMouseInside(void) const { return m_mouseInside; }
|
||||
inline ogfx::MouseEventData::eButton getPressedMouseButton(void) const { return m_pressedButton; }
|
||||
inline const std::vector<ostd::String>& getThemeIDList(void) const { return m_themeIDList; }
|
||||
inline bool isEnabled(void) const { return m_enabled; }
|
||||
inline bool isFocusEnabled(void) const { return m_allowFocus; }
|
||||
inline void enableFocus(bool enable = true) { m_allowFocus = enable; }
|
||||
inline void disableFocus(void) { enableFocus(false); }
|
||||
inline void disabble(void) { enable(false); }
|
||||
inline void enableStopEvents(bool enable = true) { m_stopEvents = enable; }
|
||||
|
||||
template<typename T>
|
||||
inline T getThemeValue(const ostd::Stylesheet &theme, const ostd::String& key, const T& fallback)
|
||||
{
|
||||
return theme.get<T>(key, fallback, getThemeIDList(), getThemeQualifierList());
|
||||
}
|
||||
|
||||
protected:
|
||||
inline void disableChildren(void) { m_allowChildren = false; }
|
||||
inline void disableDrawBox(void) { m_drawBox = false; }
|
||||
inline void enableDrawBox(void) { m_drawBox = true; }
|
||||
inline bool isDrawBoxEnabled(void) const { return m_drawBox; }
|
||||
inline void setDrawBoxColor(const ostd::Color& color) { m_drawBoxColor = color; }
|
||||
inline ostd::Color getDrawBoxColor(void) { return m_drawBoxColor; }
|
||||
|
||||
protected:
|
||||
bool m_rootChild { false };
|
||||
|
||||
EventCallback callback_onMousePressed { nullptr };
|
||||
EventCallback callback_onMouseReleased { nullptr };
|
||||
EventCallback callback_onMouseMoved { nullptr };
|
||||
EventCallback callback_onMouseEntered { nullptr };
|
||||
EventCallback callback_onMouseExited { nullptr };
|
||||
EventCallback callback_onMouseDragged { nullptr };
|
||||
EventCallback callback_onKeyPressed { nullptr };
|
||||
EventCallback callback_onKeyReleased { nullptr };
|
||||
EventCallback callback_onTextEntered { nullptr };
|
||||
EventCallback callback_onWindowClosed { nullptr };
|
||||
EventCallback callback_onWindowResized { nullptr };
|
||||
EventCallback callback_onWindowFocused { nullptr };
|
||||
EventCallback callback_onWindowFocusLost { nullptr };
|
||||
|
||||
private:
|
||||
WindowCore* m_window { nullptr };
|
||||
Widget* m_parent { nullptr };
|
||||
bool m_focused { false };
|
||||
int32_t m_tabIndex { -1 };
|
||||
int32_t m_zIndex { -1 };
|
||||
WidgetManager m_widgets;
|
||||
bool m_allowChildren { true };
|
||||
bool m_mouseInside { false };
|
||||
bool m_allowFocus { true };
|
||||
bool m_enabled { true };
|
||||
bool m_stopEvents { false };
|
||||
MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None };
|
||||
|
||||
std::vector<ostd::String> m_themeIDList;
|
||||
ostd::Stylesheet::QualifierList m_qualifierList {
|
||||
{ "disabled", false },
|
||||
{ "pressed", false },
|
||||
{ "hover", false },
|
||||
{ "focused", false },
|
||||
{ "active", false }
|
||||
};
|
||||
std::vector<ThemeOverride> m_themeOverrides;
|
||||
|
||||
bool m_drawBox { true };
|
||||
ostd::Color m_drawBoxColor { 255, 0, 0 };
|
||||
|
||||
ostd::Rectangle m_padding { 0, 0, 0, 0 };
|
||||
|
||||
friend class WidgetManager;
|
||||
};
|
||||
namespace widgets
|
||||
{
|
||||
class RootWidget : public Widget
|
||||
{
|
||||
public:
|
||||
RootWidget(WindowCore& window);
|
||||
void onWindowResized(const Event& event) override;
|
||||
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||
|
||||
private:
|
||||
ostd::Color m_color { ostd::Colors::Transparent };
|
||||
};
|
||||
class Label : public Widget
|
||||
{
|
||||
public:
|
||||
inline Label(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(""); }
|
||||
inline Label(WindowCore& window, const ostd::String& text) : Widget({ 0, 0, 0, 0 }, window) { create(text); }
|
||||
Label& create(const ostd::String& text);
|
||||
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||
void setText(const ostd::String& text);
|
||||
inline ostd::String getText(void) const { return m_text; }
|
||||
inline ostd::Color getColor(void) const { return m_color; }
|
||||
inline void setColor(const ostd::Color& color) { m_color = 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; }
|
||||
|
||||
private:
|
||||
void __update_size(ogfx::BasicRenderer2D& gfx);
|
||||
|
||||
private:
|
||||
ostd::String m_text { "" };
|
||||
bool m_textChanged { false };
|
||||
int32_t m_fontSize { 20 };
|
||||
ostd::Color m_color { 255, 255, 255 };
|
||||
int32_t m_borderRadius { 10 };
|
||||
int32_t m_borderWidth { 2 };
|
||||
bool m_showBorder { false };
|
||||
bool m_showBackground { false };
|
||||
ostd::Color m_backgroundColor { ostd::Colors::Transparent };
|
||||
ostd::Color m_borderColor { 255, 255, 255 };
|
||||
|
||||
private:
|
||||
};
|
||||
class Panel : public Widget
|
||||
{
|
||||
public:
|
||||
inline Panel(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(); }
|
||||
Panel& create(void);
|
||||
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||
inline void setBackGroundColor(const ostd::Color& color) { m_backgroundColor = color; }
|
||||
inline ostd::Color getBackgroundColor(void) { return m_backgroundColor; }
|
||||
|
||||
private:
|
||||
ostd::Color m_backgroundColor { 150, 150, 150 };
|
||||
ostd::Color m_borderColor { 0, 0, 0 };
|
||||
int32_t m_borderRadius { 10 };
|
||||
int32_t m_borderWidth { 2 };
|
||||
bool m_showBorder { false };
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#include <ogfx/gui/widgets/Containers.hpp>
|
||||
#include <ogfx/gui/widgets/Label.hpp>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include <ostd/utils/Time.hpp>
|
||||
#include <ostd/io/IOHandlers.hpp>
|
||||
#include <ogfx/gui/Events.hpp>
|
||||
#include <ogfx/gui/Widgets.hpp>
|
||||
#include <ogfx/gui/widgets/Widget.hpp>
|
||||
#include <ogfx/render/BasicRenderer.hpp>
|
||||
#include <ogfx/gui/WindowOutputHandler.hpp>
|
||||
|
||||
|
|
|
|||
61
src/ogfx/gui/widgets/Containers.cpp
Normal file
61
src/ogfx/gui/widgets/Containers.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
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 "Containers.hpp"
|
||||
#include "../../render/BasicRenderer.hpp"
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
namespace widgets
|
||||
{
|
||||
Panel& Panel::create(void)
|
||||
{
|
||||
setPadding({ 5, 5, 5, 5 });
|
||||
setTypeName("ogfx::gui::widgets::Panel");
|
||||
disableDrawBox();
|
||||
disableFocus();
|
||||
enableStopEvents();
|
||||
validate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Panel::applyTheme(const ostd::Stylesheet& theme)
|
||||
{
|
||||
setBackGroundColor(getThemeValue<ostd::Color>(theme, "panel.backgroundColor", ostd::Colors::Gray));
|
||||
m_borderRadius = getThemeValue<int32_t>(theme, "panel.borderRadius", 8);
|
||||
m_borderWidth = getThemeValue<int32_t>(theme, "panel.borderWidth", 2);
|
||||
m_showBorder = getThemeValue<bool>(theme, "panel.showBorder", true);
|
||||
m_borderColor = getThemeValue<ostd::Color>(theme, "panel.borderColor", ostd::Colors::Black);
|
||||
setPadding(getThemeValue<ostd::Rectangle>(theme, "panel.padding", { 15, 15, 15, 15 }));
|
||||
}
|
||||
|
||||
void Panel::onDraw(ogfx::BasicRenderer2D& gfx)
|
||||
{
|
||||
if (m_showBorder)
|
||||
gfx.outlinedRoundRect({ getGlobalPosition(), getSize() }, getBackgroundColor(), m_borderColor, m_borderRadius, m_borderWidth);
|
||||
else
|
||||
gfx.fillRoundRect({ getGlobalPosition(), getSize() }, getBackgroundColor(), m_borderRadius);
|
||||
gfx.drawRect(getGlobalContentBounds(), ostd::Colors::Aquamarine, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/ogfx/gui/widgets/Containers.hpp
Normal file
47
src/ogfx/gui/widgets/Containers.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
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
|
||||
{
|
||||
class Panel : public Widget
|
||||
{
|
||||
public:
|
||||
inline Panel(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(); }
|
||||
Panel& create(void);
|
||||
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||
inline void setBackGroundColor(const ostd::Color& color) { m_backgroundColor = color; }
|
||||
inline ostd::Color getBackgroundColor(void) { return m_backgroundColor; }
|
||||
|
||||
private:
|
||||
ostd::Color m_backgroundColor { 150, 150, 150 };
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
84
src/ogfx/gui/widgets/Label.cpp
Normal file
84
src/ogfx/gui/widgets/Label.cpp
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
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 "Label.hpp"
|
||||
#include "../../render/BasicRenderer.hpp"
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
namespace widgets
|
||||
{
|
||||
Label& Label::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 Label::applyTheme(const ostd::Stylesheet& theme)
|
||||
{
|
||||
setColor(getThemeValue<ostd::Color>(theme, "label.textColor", ostd::Colors::White));
|
||||
setBackGroundColor(getThemeValue<ostd::Color>(theme, "label.backgroundColor", ostd::Colors::Transparent));
|
||||
setFontSize(getThemeValue<int32_t>(theme, "label.fontSize", 20));
|
||||
m_borderRadius = getThemeValue<int32_t>(theme, "label.borderRadius", 10);
|
||||
m_borderWidth = getThemeValue<int32_t>(theme, "label.borderWidth", 2);
|
||||
m_showBorder = getThemeValue<bool>(theme, "label.showBorder", false);
|
||||
m_borderColor = getThemeValue<ostd::Color>(theme, "label.borderColor", ostd::Colors::White);
|
||||
enableBackground(getThemeValue<bool>(theme, "label.showBackground", false));
|
||||
setPadding(getThemeValue<ostd::Rectangle>(theme, "label.padding", { 5, 5, 5, 5 }));
|
||||
}
|
||||
|
||||
void Label::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.drawString(getText(), getGlobalPosition() + ostd::Vec2 { getPadding().left(), getPadding().top() }, getColor(), getFontSize());
|
||||
}
|
||||
|
||||
void Label::setText(const ostd::String& text)
|
||||
{
|
||||
m_text = text;
|
||||
m_textChanged = true;
|
||||
}
|
||||
|
||||
void Label::__update_size(ogfx::BasicRenderer2D& gfx)
|
||||
{
|
||||
auto size = gfx.getStringSize(getText(), getFontSize());
|
||||
size.x += getPadding().left();
|
||||
size.x += getPadding().right();
|
||||
size.y += getPadding().top();
|
||||
size.y += getPadding().bottom();
|
||||
setSize({ static_cast<float>(size.x), static_cast<float>(size.y) });
|
||||
m_textChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/ogfx/gui/widgets/Label.hpp
Normal file
66
src/ogfx/gui/widgets/Label.hpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
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
|
||||
{
|
||||
|
||||
class Label : public Widget
|
||||
{
|
||||
public:
|
||||
inline Label(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(""); }
|
||||
inline Label(WindowCore& window, const ostd::String& text) : Widget({ 0, 0, 0, 0 }, window) { create(text); }
|
||||
Label& create(const ostd::String& text);
|
||||
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||
void setText(const ostd::String& text);
|
||||
inline ostd::String getText(void) const { return m_text; }
|
||||
inline ostd::Color getColor(void) const { return m_color; }
|
||||
inline void setColor(const ostd::Color& color) { m_color = 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; }
|
||||
|
||||
private:
|
||||
void __update_size(ogfx::BasicRenderer2D& gfx);
|
||||
|
||||
private:
|
||||
ostd::String m_text { "" };
|
||||
bool m_textChanged { false };
|
||||
int32_t m_fontSize { 20 };
|
||||
ostd::Color m_color { 255, 255, 255 };
|
||||
bool m_showBackground { false };
|
||||
ostd::Color m_backgroundColor { ostd::Colors::Transparent };
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,12 +18,12 @@
|
|||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Widgets.hpp"
|
||||
#include "Widget.hpp"
|
||||
#include "gui/Events.hpp"
|
||||
#include "io/Memory.hpp"
|
||||
#include "utils/Keycodes.hpp"
|
||||
#include <ogfx/render/BasicRenderer.hpp>
|
||||
#include <ogfx/gui/Window.hpp>
|
||||
#include "../..//render/BasicRenderer.hpp"
|
||||
#include "../Window.hpp"
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
|
|
@ -107,7 +107,9 @@ namespace ogfx
|
|||
{
|
||||
if (w == nullptr) continue;
|
||||
if (w->isInvalid()) continue;
|
||||
gfx.pushClippingRect({ w->getGlobalPosition(), w->getSize() }, true);
|
||||
w->__draw(gfx);
|
||||
gfx.popClippingRect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +144,7 @@ namespace ogfx
|
|||
continue;
|
||||
w->__onMousePressed(event);
|
||||
m_mousePressedOnWidget = w;
|
||||
if (event.isHandled())
|
||||
if (event.isHandled() || w->m_stopEvents)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -191,8 +193,20 @@ namespace ogfx
|
|||
else
|
||||
w->__onMouseMoved(event);
|
||||
}
|
||||
if (event.isHandled())
|
||||
if (event.isHandled() || w->m_stopEvents)
|
||||
{
|
||||
bool mouseOut = false;
|
||||
for (int32_t j = i - 1; j >= 0; j--)
|
||||
{
|
||||
Widget* ww = m_widgetList[j];
|
||||
if (ww->m_mouseInside)
|
||||
{
|
||||
ww->m_mouseInside = false;
|
||||
ww->__onMouseExited(event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -291,6 +305,7 @@ namespace ogfx
|
|||
{
|
||||
if (!m_allowChildren)
|
||||
return false;
|
||||
child.reloadTheme();
|
||||
return m_widgets.addWidget(child);
|
||||
}
|
||||
|
||||
|
|
@ -298,10 +313,32 @@ namespace ogfx
|
|||
{
|
||||
ostd::Vec2 glob = getPosition();
|
||||
if (!m_rootChild && m_parent != nullptr)
|
||||
glob += m_parent->getGlobalPosition();
|
||||
glob += m_parent->getGlobalPosition() + m_parent->getPadding().getPosition();
|
||||
return glob;
|
||||
}
|
||||
|
||||
ostd::Vec2 Widget::getGlobalContentPosition(void) const
|
||||
{
|
||||
return getGlobalPosition() + getContentBounds().getPosition();
|
||||
}
|
||||
|
||||
ostd::Rectangle Widget::getGlobalBounds(void) const
|
||||
{
|
||||
return { getGlobalPosition(), getSize() };
|
||||
}
|
||||
|
||||
ostd::Rectangle Widget::getContentBounds(void) const
|
||||
{
|
||||
auto pad = getPadding();
|
||||
return { pad.getPosition(), (getSize() - (pad.getSize() * 2)) };
|
||||
}
|
||||
|
||||
ostd::Rectangle Widget::getGlobalContentBounds(void) const
|
||||
{
|
||||
auto pad = getPadding();
|
||||
return { getGlobalContentPosition(), getContentBounds().getSize() };
|
||||
}
|
||||
|
||||
bool Widget::contains(ostd::Vec2 p, bool includeBounds) const
|
||||
{
|
||||
return ostd::Rectangle(getGlobalPosition(), getSize()).contains(p, includeBounds);
|
||||
|
|
@ -594,94 +631,6 @@ namespace ogfx
|
|||
{
|
||||
gfx.fillRect({ 0, 0, static_cast<float>(getWindow().getWindowWidth()), static_cast<float>(getWindow().getWindowHeight()) }, m_color);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Label& Label::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 Label::applyTheme(const ostd::Stylesheet& theme)
|
||||
{
|
||||
setColor(getThemeValue<ostd::Color>(theme, "label.textColor", ostd::Colors::White));
|
||||
setBackGroundColor(getThemeValue<ostd::Color>(theme, "label.backgroundColor", ostd::Colors::Transparent));
|
||||
setFontSize(getThemeValue<int32_t>(theme, "label.fontSize", 20));
|
||||
m_borderRadius = getThemeValue<int32_t>(theme, "label.borderRadius", 10);
|
||||
m_borderWidth = getThemeValue<int32_t>(theme, "label.borderWidth", 2);
|
||||
m_showBorder = getThemeValue<bool>(theme, "label.showBorder", false);
|
||||
m_borderColor = getThemeValue<ostd::Color>(theme, "label.borderColor", ostd::Colors::White);
|
||||
enableBackground(getThemeValue<bool>(theme, "label.showBackground", false));
|
||||
setPadding(getThemeValue<ostd::Rectangle>(theme, "label.padding", { 5, 5, 5, 5 }));
|
||||
}
|
||||
|
||||
void Label::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.drawString(getText(), getGlobalPosition() + ostd::Vec2 { getPadding().left(), getPadding().top() }, getColor(), getFontSize());
|
||||
}
|
||||
|
||||
void Label::setText(const ostd::String& text)
|
||||
{
|
||||
m_text = text;
|
||||
m_textChanged = true;
|
||||
}
|
||||
|
||||
void Label::__update_size(ogfx::BasicRenderer2D& gfx)
|
||||
{
|
||||
auto size = gfx.getStringSize(getText(), getFontSize());
|
||||
size.x += getPadding().left();
|
||||
size.x += getPadding().right();
|
||||
size.y += getPadding().top();
|
||||
size.y += getPadding().bottom();
|
||||
setSize({ static_cast<float>(size.x), static_cast<float>(size.y) });
|
||||
m_textChanged = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Panel& Panel::create(void)
|
||||
{
|
||||
setPadding({ 5, 5, 5, 5 });
|
||||
setTypeName("ogfx::gui::widgets::Panel");
|
||||
disableDrawBox();
|
||||
disableFocus();
|
||||
enableStopEvents();
|
||||
validate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Panel::applyTheme(const ostd::Stylesheet& theme)
|
||||
{
|
||||
setBackGroundColor(getThemeValue<ostd::Color>(theme, "panel.backgroundColor", ostd::Colors::Gray));
|
||||
m_borderRadius = getThemeValue<int32_t>(theme, "panel.borderRadius", 8);
|
||||
m_borderWidth = getThemeValue<int32_t>(theme, "panel.borderWidth", 2);
|
||||
m_showBorder = getThemeValue<bool>(theme, "panel.showBorder", true);
|
||||
m_borderColor = getThemeValue<ostd::Color>(theme, "panel.borderColor", ostd::Colors::Black);
|
||||
setPadding(getThemeValue<ostd::Rectangle>(theme, "panel.padding", { 15, 15, 15, 15 }));
|
||||
}
|
||||
|
||||
void Panel::onDraw(ogfx::BasicRenderer2D& gfx)
|
||||
{
|
||||
if (m_showBorder)
|
||||
gfx.outlinedRoundRect({ getGlobalPosition(), getSize() }, getBackgroundColor(), m_borderColor, m_borderRadius, m_borderWidth);
|
||||
else
|
||||
gfx.fillRoundRect({ getGlobalPosition(), getSize() }, getBackgroundColor(), m_borderRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
256
src/ogfx/gui/widgets/Widget.hpp
Normal file
256
src/ogfx/gui/widgets/Widget.hpp
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
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/Events.hpp>
|
||||
#include <ostd/data/BaseObject.hpp>
|
||||
#include <ostd/math/Geometry.hpp>
|
||||
#include <ostd/data/Color.hpp>
|
||||
#include <ostd/io/Stylesheet.hpp>
|
||||
#include <ostd/utils/Time.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
class BasicRenderer2D;
|
||||
class WindowCore;
|
||||
namespace gui
|
||||
{
|
||||
class Event;
|
||||
class Widget;
|
||||
class WidgetManager
|
||||
{
|
||||
public:
|
||||
WidgetManager(WindowCore& window, Widget& owner);
|
||||
bool hasWidget(Widget& widget);
|
||||
bool requestFocus(Widget& widget);
|
||||
bool addWidget(Widget& widget);
|
||||
Widget* focusNext(void);
|
||||
|
||||
void draw(ogfx::BasicRenderer2D& gfx);
|
||||
void update(void);
|
||||
void onThemeApplied(const ostd::Stylesheet& theme);
|
||||
void onMousePressed(const Event& event);
|
||||
void onMouseReleased(const Event& event);
|
||||
void onMouseMoved(const Event& event);
|
||||
void onMouseDragged(const Event& event);
|
||||
void onKeyPressed(const Event& event);
|
||||
void onKeyReleased(const Event& event);
|
||||
void onTextEntered(const Event& event);
|
||||
void onWindowClosed(const Event& event);
|
||||
void onWindowResized(const Event& event);
|
||||
void onWindowFocused(const Event& event);
|
||||
void onWindowFocusLost(const Event& event);
|
||||
|
||||
inline int32_t widgetCount(void) const { return m_widgetList.size(); }
|
||||
inline WindowCore& getWindow(void) { return m_window; }
|
||||
|
||||
private:
|
||||
WindowCore& m_window;
|
||||
Widget& m_owner;
|
||||
std::vector<Widget*> m_widgetList;
|
||||
Widget* m_focused { nullptr };
|
||||
bool m_tabNavigationEnabled { true };
|
||||
Widget* m_mousePressedOnWidget { nullptr };
|
||||
};
|
||||
class Widget : public ostd::BaseObject, public ostd::Rectangle
|
||||
{
|
||||
private: struct ThemeOverride
|
||||
{
|
||||
ostd::String fullKey;
|
||||
ostd::Stylesheet::TypeVariant value;
|
||||
bool propagate;
|
||||
};
|
||||
public: using EventCallback = std::function<void(const Event&)>;
|
||||
public:
|
||||
Widget(const ostd::Rectangle& bounds, WindowCore& window);
|
||||
bool addChild(Widget& child);
|
||||
ostd::Vec2 getGlobalPosition(void) const;
|
||||
ostd::Vec2 getGlobalContentPosition(void) const;
|
||||
ostd::Rectangle getGlobalBounds(void) const;
|
||||
ostd::Rectangle getContentBounds(void) const;
|
||||
ostd::Rectangle getGlobalContentBounds(void) const;
|
||||
using ostd::Rectangle::contains;
|
||||
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 reloadTheme(void);
|
||||
void setThemeQualifier(const ostd::String& qualifier, bool value = true);
|
||||
bool getThemeQualifier(const ostd::String& qualifier);
|
||||
bool addThemeID(const ostd::String& id);
|
||||
bool removeThemeID(const ostd::String& id);
|
||||
inline const ostd::Stylesheet::QualifierList& getThemeQualifierList(void) const { return m_qualifierList; }
|
||||
|
||||
inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { }
|
||||
inline virtual void onUpdate(void) { }
|
||||
|
||||
inline virtual void onMousePressed(const Event& event) { }
|
||||
inline virtual void onMouseReleased(const Event& event) { }
|
||||
inline virtual void onMouseMoved(const Event& event) { }
|
||||
inline virtual void onMouseEntered(const Event& event) { }
|
||||
inline virtual void onMouseExited(const Event& event) { }
|
||||
inline virtual void onMouseDragged(const Event& event) { }
|
||||
inline virtual void onKeyPressed(const Event& event) { }
|
||||
inline virtual void onKeyReleased(const Event& event) { }
|
||||
inline virtual void onTextEntered(const Event& event) { }
|
||||
inline virtual void onFocusGained(const Event& event) { }
|
||||
inline virtual void onFocusLost(const Event& event) { }
|
||||
inline virtual void onWindowClosed(const Event& event) { }
|
||||
inline virtual void onWindowResized(const Event& event) { }
|
||||
inline virtual void onWindowFocused(const Event& event) { }
|
||||
inline virtual void onWindowFocusLost(const Event& event) { }
|
||||
|
||||
void __draw(ogfx::BasicRenderer2D& gfx);
|
||||
void __update(void);
|
||||
void __onMousePressed(const Event& event);
|
||||
void __onMouseReleased(const Event& event);
|
||||
void __onMouseMoved(const Event& event);
|
||||
void __onMouseEntered(const Event& event);
|
||||
void __onMouseExited(const Event& event);
|
||||
void __onMouseDragged(const Event& event);
|
||||
void __onKeyPressed(const Event& event);
|
||||
void __onKeyReleased(const Event& event);
|
||||
void __onTextEntered(const Event& event);
|
||||
void __onWindowClosed(const Event& event);
|
||||
void __onWindowResized(const Event& event);
|
||||
void __onWIndowFocused(const Event& event);
|
||||
void __onWindowFocusLost(const Event& event);
|
||||
void __applyTheme(const ostd::Stylesheet& theme, bool propagate);
|
||||
|
||||
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 setMouseEnteredCallback(EventCallback callback) { callback_onMouseEntered = callback; }
|
||||
inline virtual void setMouseExitedCallback(EventCallback callback) { callback_onMouseExited = callback; }
|
||||
inline virtual void setMouseDraggedCallback(EventCallback callback) { callback_onMouseDragged = callback; }
|
||||
inline virtual void setKeyPressedCallback(EventCallback callback) { callback_onKeyPressed = callback; }
|
||||
inline virtual void setKeyReleasedCallback(EventCallback callback) { callback_onKeyReleased = callback; }
|
||||
inline virtual void setTextEnteredCallback(EventCallback callback) { callback_onTextEntered = callback; }
|
||||
inline virtual void setWindowClosedCallback(EventCallback callback) { callback_onWindowClosed = callback; }
|
||||
inline virtual void setWindowResizedCallback(EventCallback callback) { callback_onWindowResized = callback; }
|
||||
inline virtual void setWIndowFocusedCallback(EventCallback callback) { callback_onWindowFocused = callback; }
|
||||
inline virtual void setWindowFocusLostCallback(EventCallback callback) { callback_onWindowFocusLost = callback; }
|
||||
|
||||
inline bool hasChildren(void) const { return m_allowChildren && m_widgets.widgetCount() > 0; }
|
||||
inline virtual bool isInvalid(void) const override { return ostd::BaseObject::isInvalid() || (m_parent == nullptr && !m_rootChild); }
|
||||
inline void setTabIndex(int32_t tabIndex) { m_tabIndex = tabIndex; }
|
||||
inline int32_t getTabIndex(void) const { return m_tabIndex; }
|
||||
inline bool isFocused(void) const { return m_focused; }
|
||||
inline WindowCore& getWindow(void) { return *m_window; }
|
||||
inline Widget* getParent(void) { return m_parent; }
|
||||
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 Rectangle getPadding(void) const { return m_padding; }
|
||||
inline bool isMouseInside(void) const { return m_mouseInside; }
|
||||
inline ogfx::MouseEventData::eButton getPressedMouseButton(void) const { return m_pressedButton; }
|
||||
inline const std::vector<ostd::String>& getThemeIDList(void) const { return m_themeIDList; }
|
||||
inline bool isEnabled(void) const { return m_enabled; }
|
||||
inline bool isFocusEnabled(void) const { return m_allowFocus; }
|
||||
inline void enableFocus(bool enable = true) { m_allowFocus = enable; }
|
||||
inline void disableFocus(void) { enableFocus(false); }
|
||||
inline void disabble(void) { enable(false); }
|
||||
inline void enableStopEvents(bool enable = true) { m_stopEvents = enable; }
|
||||
|
||||
template<typename T>
|
||||
inline T getThemeValue(const ostd::Stylesheet &theme, const ostd::String& key, const T& fallback)
|
||||
{
|
||||
return theme.get<T>(key, fallback, getThemeIDList(), getThemeQualifierList());
|
||||
}
|
||||
|
||||
protected:
|
||||
inline void disableChildren(void) { m_allowChildren = false; }
|
||||
inline void disableDrawBox(void) { m_drawBox = false; }
|
||||
inline void enableDrawBox(void) { m_drawBox = true; }
|
||||
inline bool isDrawBoxEnabled(void) const { return m_drawBox; }
|
||||
inline void setDrawBoxColor(const ostd::Color& color) { m_drawBoxColor = color; }
|
||||
inline ostd::Color getDrawBoxColor(void) { return m_drawBoxColor; }
|
||||
|
||||
protected:
|
||||
bool m_rootChild { false };
|
||||
int32_t m_borderRadius { 10 };
|
||||
int32_t m_borderWidth { 2 };
|
||||
ostd::Color m_borderColor { 255, 255, 255 };
|
||||
bool m_showBorder { false };
|
||||
|
||||
EventCallback callback_onMousePressed { nullptr };
|
||||
EventCallback callback_onMouseReleased { nullptr };
|
||||
EventCallback callback_onMouseMoved { nullptr };
|
||||
EventCallback callback_onMouseEntered { nullptr };
|
||||
EventCallback callback_onMouseExited { nullptr };
|
||||
EventCallback callback_onMouseDragged { nullptr };
|
||||
EventCallback callback_onKeyPressed { nullptr };
|
||||
EventCallback callback_onKeyReleased { nullptr };
|
||||
EventCallback callback_onTextEntered { nullptr };
|
||||
EventCallback callback_onWindowClosed { nullptr };
|
||||
EventCallback callback_onWindowResized { nullptr };
|
||||
EventCallback callback_onWindowFocused { nullptr };
|
||||
EventCallback callback_onWindowFocusLost { nullptr };
|
||||
|
||||
private:
|
||||
WindowCore* m_window { nullptr };
|
||||
Widget* m_parent { nullptr };
|
||||
bool m_focused { false };
|
||||
int32_t m_tabIndex { -1 };
|
||||
int32_t m_zIndex { -1 };
|
||||
WidgetManager m_widgets;
|
||||
bool m_allowChildren { true };
|
||||
bool m_mouseInside { false };
|
||||
bool m_allowFocus { true };
|
||||
bool m_enabled { true };
|
||||
bool m_stopEvents { true };
|
||||
bool m_clipContents { true };
|
||||
MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None };
|
||||
|
||||
std::vector<ostd::String> m_themeIDList;
|
||||
ostd::Stylesheet::QualifierList m_qualifierList {
|
||||
{ "disabled", false },
|
||||
{ "pressed", false },
|
||||
{ "hover", false },
|
||||
{ "focused", false },
|
||||
{ "active", false }
|
||||
};
|
||||
std::vector<ThemeOverride> m_themeOverrides;
|
||||
|
||||
bool m_drawBox { true };
|
||||
ostd::Color m_drawBoxColor { 255, 0, 0 };
|
||||
|
||||
ostd::Rectangle m_padding { 0, 0, 0, 0 };
|
||||
|
||||
friend class WidgetManager;
|
||||
};
|
||||
namespace widgets
|
||||
{
|
||||
class RootWidget : public Widget
|
||||
{
|
||||
public:
|
||||
RootWidget(WindowCore& window);
|
||||
void onWindowResized(const Event& event) override;
|
||||
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||
|
||||
private:
|
||||
ostd::Color m_color { ostd::Colors::Transparent };
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include <ogfx/gui/RawTextInput.hpp>
|
||||
#include <ogfx/gui/Window.hpp>
|
||||
#include <ogfx/gui/WindowOutputHandler.hpp>
|
||||
#include <ogfx/gui/Widgets.hpp>
|
||||
|
||||
#include <ogfx/render/BasicRenderer.hpp>
|
||||
#include <ogfx/render/PixelRenderer.hpp>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,50 @@ namespace ogfx
|
|||
setDefaultFont();
|
||||
}
|
||||
|
||||
void BasicRenderer2D::pushClippingRect(const ostd::Rectangle& rect, bool additive)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
|
||||
ostd::Rectangle finalRect = rect;
|
||||
|
||||
if (additive && !m_clipStack.empty())
|
||||
finalRect = m_clipStack.back().getIntersection(rect, false);
|
||||
|
||||
m_clipStack.push_back(finalRect);
|
||||
|
||||
SDL_Rect r;
|
||||
r.x = (int)std::round(finalRect.x);
|
||||
r.y = (int)std::round(finalRect.y);
|
||||
r.w = (int)std::round(finalRect.w);
|
||||
r.h = (int)std::round(finalRect.h);
|
||||
|
||||
SDL_SetRenderClipRect(m_window->getSDLRenderer(), &r);
|
||||
}
|
||||
|
||||
void BasicRenderer2D::popClippingRect(void)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
if (m_clipStack.empty()) return;
|
||||
|
||||
m_clipStack.pop_back();
|
||||
|
||||
if (m_clipStack.empty())
|
||||
{
|
||||
SDL_SetRenderClipRect(m_window->getSDLRenderer(), nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& rect = m_clipStack.back();
|
||||
|
||||
SDL_Rect r;
|
||||
r.x = (int)std::round(rect.x);
|
||||
r.y = (int)std::round(rect.y);
|
||||
r.w = (int)std::round(rect.w);
|
||||
r.h = (int)std::round(rect.h);
|
||||
|
||||
SDL_SetRenderClipRect(m_window->getSDLRenderer(), &r);
|
||||
}
|
||||
|
||||
void BasicRenderer2D::setFont(const ostd::String& fontFilePath)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
|
|
@ -172,24 +216,33 @@ namespace ogfx
|
|||
filledCircleRGBA(m_window->getSDLRenderer(), (int32_t)std::round(center.x), (int32_t)std::round(center.y), radius, color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void BasicRenderer2D::outlinedRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness)
|
||||
void BasicRenderer2D::outlinedRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness, bool outlineInward)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
fillRect(rect, fillColor);
|
||||
drawRect(rect, outlineColor, outlineThickness);
|
||||
float t = static_cast<float>(outlineThickness);
|
||||
ostd::Rectangle offset = { 0, 0, 0, 0 };
|
||||
if (!outlineInward)
|
||||
offset = { -t, -t, t * 2, t * 2 };
|
||||
drawRect(rect + offset , outlineColor, outlineThickness);
|
||||
}
|
||||
|
||||
void BasicRenderer2D::outlinedRoundRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t radius, int32_t outlineThickness)
|
||||
void BasicRenderer2D::outlinedRoundRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t radius, int32_t outlineThickness, bool outlineInward)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
fillRoundRect(rect, fillColor, radius);
|
||||
drawRoundRect(rect, outlineColor, radius, outlineThickness);
|
||||
float t = static_cast<float>(outlineThickness);
|
||||
ostd::Rectangle offset = { 0, 0, 0, 0 };
|
||||
if (!outlineInward)
|
||||
offset = { -t, -t, t * 2, t * 2 };
|
||||
drawRoundRect(rect + offset, outlineColor, radius, outlineThickness);
|
||||
}
|
||||
|
||||
void BasicRenderer2D::outlinedCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness)
|
||||
void BasicRenderer2D::outlinedCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness, bool outlineInward)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
fillCircle(center, radius, fillColor);
|
||||
radius = (outlineInward ? radius : radius + outlineThickness);
|
||||
drawCircle(center, radius, outlineColor, outlineThickness);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ namespace ogfx
|
|||
inline ostd::IPoint getStringSize(const ostd::String str, int32_t fontSize = 0) { return m_ttfr.getStringDimensions(str, fontSize); }
|
||||
inline WindowCore& getWindow(void) { return *m_window; }
|
||||
inline bool isInitialized(void) { return m_initialized; }
|
||||
void pushClippingRect(const ostd::Rectangle& rect, bool additive = false);
|
||||
void popClippingRect(void);
|
||||
void setFont(const ostd::String& fontFilePath);
|
||||
void setDefaultFont(void);
|
||||
void setFontSize(int32_t fontSize);
|
||||
|
|
@ -58,13 +60,14 @@ namespace ogfx
|
|||
void fillRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, int32_t radius);
|
||||
void fillCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& color);
|
||||
|
||||
void outlinedRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1);
|
||||
void outlinedRoundRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t radius, int32_t outlineThickness = 1);
|
||||
void outlinedCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1);
|
||||
void outlinedRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1, bool outlineInward = true);
|
||||
void outlinedRoundRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t radius, int32_t outlineThickness = 1, bool outlineInward = true);
|
||||
void outlinedCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1, bool outlineInward = true);
|
||||
|
||||
private:
|
||||
TTFRenderer m_ttfr;
|
||||
WindowCore* m_window { nullptr };
|
||||
bool m_initialized { false };
|
||||
std::vector<ostd::Rectangle> m_clipStack;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,6 +268,23 @@ namespace ostd
|
|||
inline Rectangle(Vec2 position, Vec2 size) { x = position.x; y = position.y; w = size.x; h = size.y; }
|
||||
virtual ~Rectangle(void) = default;
|
||||
|
||||
inline bool operator==(const Rectangle& op2) const { return x == op2.x && y == op2.y && w == op2.w && h == op2.h; }
|
||||
inline bool operator!=(const Rectangle& op2) const { return !(*this == op2); }
|
||||
inline Rectangle operator+(const Rectangle& op2) const { return { x + op2.x, y + op2.y, w + op2.w, h + op2.h }; }
|
||||
inline Rectangle operator-(const Rectangle& op2) const { return { x - op2.x, y - op2.y, w - op2.w, h - op2.h }; }
|
||||
inline Rectangle operator+(float s) const { return { x + s, y + s, w + s, h + s }; }
|
||||
inline Rectangle operator-(float s) const { return { x - s, y - s, w - s, h - s }; }
|
||||
inline Rectangle operator*(float s) const { return { x * s, y * s, w * s, h * s }; }
|
||||
inline Rectangle operator/(float s) const { return { x / s, y / s, w / s, h / s }; }
|
||||
inline Rectangle& operator=(const Rectangle& r) { x = r.x; y = r.y; w = r.w; h = r.h; return *this; }
|
||||
inline Rectangle& operator=(float s) { x = s; y = s; w = s; h = s; return *this; }
|
||||
inline Rectangle& operator+=(const Rectangle& op2) { x += op2.x; y += op2.y; w += op2.w; h += op2.h; return *this; }
|
||||
inline Rectangle& operator-=(const Rectangle& op2) { x -= op2.x; y -= op2.y; w -= op2.w; h -= op2.h; return *this; }
|
||||
inline Rectangle& operator+=(float s) { x += s; y += s; w += s; h += s; return *this; }
|
||||
inline Rectangle& operator-=(float s) { x -= s; y -= s; w -= s; h -= s; return *this; }
|
||||
inline Rectangle& operator*=(float s) { x *= s; y *= s; w *= s; h *= s; return *this; }
|
||||
inline Rectangle& operator/=(float s) { x /= s; y /= s; w /= s; h /= s; return *this; }
|
||||
|
||||
inline virtual float getx(void) const { return x; }
|
||||
inline virtual float gety(void) const { return y; }
|
||||
inline virtual float getw(void) const { return w; }
|
||||
|
|
|
|||
|
|
@ -18,26 +18,6 @@
|
|||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* --- Label
|
||||
* Button
|
||||
* Panel / Container
|
||||
* Checkbox
|
||||
* Radio Button (Group)
|
||||
* Text Input
|
||||
* Horizontal Slider
|
||||
* Image / Icon
|
||||
* ScrollView
|
||||
* ListBox
|
||||
* ComboBox
|
||||
* TreeView
|
||||
* Save/Open File Dialogs (and folder dialogs)
|
||||
* Tab Panel
|
||||
*/
|
||||
|
||||
#include <ogfx/utils/Keycodes.hpp>
|
||||
#include <ogfx/ogfx.hpp>
|
||||
|
||||
|
|
@ -60,6 +40,10 @@ class Window : public ogfx::gui::Window
|
|||
pos = pos2;
|
||||
});
|
||||
|
||||
|
||||
m_panel2.setSize(300, 140);
|
||||
m_panel2.setPosition(130, 200);
|
||||
|
||||
m_label1.setPosition(100, 200);
|
||||
m_label1.setText("Hello World!");
|
||||
m_label1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void {
|
||||
|
|
@ -67,9 +51,9 @@ class Window : public ogfx::gui::Window
|
|||
});
|
||||
addWidget(m_label1);
|
||||
addWidget(m_panel1);
|
||||
// m_label1.setThemeQualifier("disabled");
|
||||
addWidget(m_panel2);
|
||||
|
||||
m_label2.setPosition(10, 10);
|
||||
m_label2.setPosition(0, 0);
|
||||
m_label2.setText("Ciccia Bella!");
|
||||
m_label2.addThemeID("testLabel");
|
||||
m_label2.addThemeID("testLabel2");
|
||||
|
|
@ -78,14 +62,16 @@ class Window : public ogfx::gui::Window
|
|||
m_label1.addThemeOverride("@:pressed.label.textColor", ostd::Colors::Crimson);
|
||||
|
||||
m_theme.loadFromFile("./testTheme.txt");
|
||||
setTheme(m_theme);
|
||||
|
||||
m_label2.addThemeOverride("@:hover.label.showBackground", true);
|
||||
m_label2.addThemeOverride("@:hover.label.backgroundColor", ostd::Colors::DarkGreen);
|
||||
m_theme.debugPrint();
|
||||
m_label2.reloadTheme();
|
||||
|
||||
m_theme.debugPrint();
|
||||
m_label3.setPosition(0, 30);
|
||||
m_label3.setText("Bella!");
|
||||
m_label3.addThemeID("label3");
|
||||
m_panel1.addChild(m_label3);
|
||||
|
||||
setTheme(m_theme);
|
||||
}
|
||||
|
||||
inline void onSignal(ostd::Signal& signal) override
|
||||
|
|
@ -106,7 +92,9 @@ class Window : public ogfx::gui::Window
|
|||
private:
|
||||
ogfx::gui::widgets::Label m_label1 { *this };
|
||||
ogfx::gui::widgets::Label m_label2 { *this };
|
||||
ogfx::gui::widgets::Label m_label3 { *this };
|
||||
ogfx::gui::widgets::Panel m_panel1 { *this };
|
||||
ogfx::gui::widgets::Panel m_panel2 { *this };
|
||||
ostd::Stylesheet m_theme;
|
||||
ostd::Vec2 pos { 0, 0 };
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue