Added Basic Panel widget
This commit is contained in:
parent
c695c0ad85
commit
260c7054bc
19 changed files with 722 additions and 426 deletions
3
.clangd
3
.clangd
|
|
@ -1,2 +1,3 @@
|
||||||
CompileFlags:
|
CompileFlags:
|
||||||
CompilationDatabase: bin
|
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/RawTextInput.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/Window.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/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
|
# render
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ window.backgroundColor = Color(rgba(120, 120, 120, 255))
|
||||||
|
|
||||||
(panel) {
|
(panel) {
|
||||||
backgroundColor = Color(#AAAAAAFF)
|
backgroundColor = Color(#AAAAAAFF)
|
||||||
borderColor = Color(#000000FF)
|
borderColor = Color(#00FF00FF)
|
||||||
borderRadius = 8
|
borderRadius = 8
|
||||||
borderWidth = 2
|
borderWidth = 4
|
||||||
showBorder = true
|
showBorder = true
|
||||||
padding = Rect(15, 15, 15, 15)
|
padding = Rect(15, 15, 15, 15)
|
||||||
}
|
}
|
||||||
|
|
@ -42,6 +42,11 @@ window.backgroundColor = Color(rgba(120, 120, 120, 255))
|
||||||
borderColor = Color(#208080FF)
|
borderColor = Color(#208080FF)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
% (@testLabel2 label:pressed [mouseButton=left or mouseButton=right]) {
|
||||||
|
% ...
|
||||||
|
|
||||||
|
|
||||||
(@testLabel2 label:pressed) {
|
(@testLabel2 label:pressed) {
|
||||||
showBackground = true
|
showBackground = true
|
||||||
}
|
}
|
||||||
|
|
@ -70,4 +75,13 @@ window.backgroundColor = Color(rgba(120, 120, 120, 255))
|
||||||
%borderColor = Color(#000000FF)
|
%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
|
***Fix mouse detection currently using local coordinates
|
||||||
***implement file theme loading
|
***implement file theme loading
|
||||||
***Implemenmt MouseDragged callback
|
***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
|
# OGFX
|
||||||
mkdir -p $RELEASE_DIR/include/ogfx/vendor/sdl3_gfx
|
mkdir -p $RELEASE_DIR/include/ogfx/vendor/sdl3_gfx
|
||||||
mkdir -p $RELEASE_DIR/include/ogfx/gui
|
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/render
|
||||||
mkdir -p $RELEASE_DIR/include/ogfx/resources
|
mkdir -p $RELEASE_DIR/include/ogfx/resources
|
||||||
mkdir -p $RELEASE_DIR/include/ogfx/utils
|
mkdir -p $RELEASE_DIR/include/ogfx/utils
|
||||||
find ../src/ogfx -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx \;
|
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 -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/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/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 \;
|
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
|
OmniaFramework - A collection of useful functionality
|
||||||
Copyright (C) 2025 OmniaX-Dev
|
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
|
OmniaFramework is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
OmniaFramework is distributed in the hope that it will be useful,
|
OmniaFramework is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gui/Events.hpp"
|
#include <ogfx/gui/widgets/Containers.hpp>
|
||||||
#include <ostd/data/BaseObject.hpp>
|
#include <ogfx/gui/widgets/Label.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 };
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
#include <ostd/utils/Time.hpp>
|
#include <ostd/utils/Time.hpp>
|
||||||
#include <ostd/io/IOHandlers.hpp>
|
#include <ostd/io/IOHandlers.hpp>
|
||||||
#include <ogfx/gui/Events.hpp>
|
#include <ogfx/gui/Events.hpp>
|
||||||
#include <ogfx/gui/Widgets.hpp>
|
#include <ogfx/gui/widgets/Widget.hpp>
|
||||||
#include <ogfx/render/BasicRenderer.hpp>
|
#include <ogfx/render/BasicRenderer.hpp>
|
||||||
#include <ogfx/gui/WindowOutputHandler.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/>.
|
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Widgets.hpp"
|
#include "Widget.hpp"
|
||||||
#include "gui/Events.hpp"
|
#include "gui/Events.hpp"
|
||||||
#include "io/Memory.hpp"
|
#include "io/Memory.hpp"
|
||||||
#include "utils/Keycodes.hpp"
|
#include "utils/Keycodes.hpp"
|
||||||
#include <ogfx/render/BasicRenderer.hpp>
|
#include "../..//render/BasicRenderer.hpp"
|
||||||
#include <ogfx/gui/Window.hpp>
|
#include "../Window.hpp"
|
||||||
|
|
||||||
namespace ogfx
|
namespace ogfx
|
||||||
{
|
{
|
||||||
|
|
@ -107,7 +107,9 @@ namespace ogfx
|
||||||
{
|
{
|
||||||
if (w == nullptr) continue;
|
if (w == nullptr) continue;
|
||||||
if (w->isInvalid()) continue;
|
if (w->isInvalid()) continue;
|
||||||
|
gfx.pushClippingRect({ w->getGlobalPosition(), w->getSize() }, true);
|
||||||
w->__draw(gfx);
|
w->__draw(gfx);
|
||||||
|
gfx.popClippingRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,7 +144,7 @@ namespace ogfx
|
||||||
continue;
|
continue;
|
||||||
w->__onMousePressed(event);
|
w->__onMousePressed(event);
|
||||||
m_mousePressedOnWidget = w;
|
m_mousePressedOnWidget = w;
|
||||||
if (event.isHandled())
|
if (event.isHandled() || w->m_stopEvents)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -191,8 +193,20 @@ namespace ogfx
|
||||||
else
|
else
|
||||||
w->__onMouseMoved(event);
|
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;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -291,6 +305,7 @@ namespace ogfx
|
||||||
{
|
{
|
||||||
if (!m_allowChildren)
|
if (!m_allowChildren)
|
||||||
return false;
|
return false;
|
||||||
|
child.reloadTheme();
|
||||||
return m_widgets.addWidget(child);
|
return m_widgets.addWidget(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,10 +313,32 @@ namespace ogfx
|
||||||
{
|
{
|
||||||
ostd::Vec2 glob = getPosition();
|
ostd::Vec2 glob = getPosition();
|
||||||
if (!m_rootChild && m_parent != nullptr)
|
if (!m_rootChild && m_parent != nullptr)
|
||||||
glob += m_parent->getGlobalPosition();
|
glob += m_parent->getGlobalPosition() + m_parent->getPadding().getPosition();
|
||||||
return glob;
|
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
|
bool Widget::contains(ostd::Vec2 p, bool includeBounds) const
|
||||||
{
|
{
|
||||||
return ostd::Rectangle(getGlobalPosition(), getSize()).contains(p, includeBounds);
|
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);
|
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/RawTextInput.hpp>
|
||||||
#include <ogfx/gui/Window.hpp>
|
#include <ogfx/gui/Window.hpp>
|
||||||
#include <ogfx/gui/WindowOutputHandler.hpp>
|
#include <ogfx/gui/WindowOutputHandler.hpp>
|
||||||
|
#include <ogfx/gui/Widgets.hpp>
|
||||||
|
|
||||||
#include <ogfx/render/BasicRenderer.hpp>
|
#include <ogfx/render/BasicRenderer.hpp>
|
||||||
#include <ogfx/render/PixelRenderer.hpp>
|
#include <ogfx/render/PixelRenderer.hpp>
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,50 @@ namespace ogfx
|
||||||
setDefaultFont();
|
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)
|
void BasicRenderer2D::setFont(const ostd::String& fontFilePath)
|
||||||
{
|
{
|
||||||
if (!m_initialized) return;
|
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);
|
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;
|
if (!m_initialized) return;
|
||||||
fillRect(rect, fillColor);
|
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;
|
if (!m_initialized) return;
|
||||||
fillRoundRect(rect, fillColor, radius);
|
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;
|
if (!m_initialized) return;
|
||||||
fillCircle(center, radius, fillColor);
|
fillCircle(center, radius, fillColor);
|
||||||
|
radius = (outlineInward ? radius : radius + outlineThickness);
|
||||||
drawCircle(center, radius, outlineColor, 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 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 WindowCore& getWindow(void) { return *m_window; }
|
||||||
inline bool isInitialized(void) { return m_initialized; }
|
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 setFont(const ostd::String& fontFilePath);
|
||||||
void setDefaultFont(void);
|
void setDefaultFont(void);
|
||||||
void setFontSize(int32_t fontSize);
|
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 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 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 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);
|
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);
|
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:
|
private:
|
||||||
TTFRenderer m_ttfr;
|
TTFRenderer m_ttfr;
|
||||||
WindowCore* m_window { nullptr };
|
WindowCore* m_window { nullptr };
|
||||||
bool m_initialized { false };
|
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; }
|
inline Rectangle(Vec2 position, Vec2 size) { x = position.x; y = position.y; w = size.x; h = size.y; }
|
||||||
virtual ~Rectangle(void) = default;
|
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 getx(void) const { return x; }
|
||||||
inline virtual float gety(void) const { return y; }
|
inline virtual float gety(void) const { return y; }
|
||||||
inline virtual float getw(void) const { return w; }
|
inline virtual float getw(void) const { return w; }
|
||||||
|
|
|
||||||
|
|
@ -18,26 +18,6 @@
|
||||||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
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/utils/Keycodes.hpp>
|
||||||
#include <ogfx/ogfx.hpp>
|
#include <ogfx/ogfx.hpp>
|
||||||
|
|
||||||
|
|
@ -60,6 +40,10 @@ class Window : public ogfx::gui::Window
|
||||||
pos = pos2;
|
pos = pos2;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
m_panel2.setSize(300, 140);
|
||||||
|
m_panel2.setPosition(130, 200);
|
||||||
|
|
||||||
m_label1.setPosition(100, 200);
|
m_label1.setPosition(100, 200);
|
||||||
m_label1.setText("Hello World!");
|
m_label1.setText("Hello World!");
|
||||||
m_label1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void {
|
m_label1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void {
|
||||||
|
|
@ -67,9 +51,9 @@ class Window : public ogfx::gui::Window
|
||||||
});
|
});
|
||||||
addWidget(m_label1);
|
addWidget(m_label1);
|
||||||
addWidget(m_panel1);
|
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.setText("Ciccia Bella!");
|
||||||
m_label2.addThemeID("testLabel");
|
m_label2.addThemeID("testLabel");
|
||||||
m_label2.addThemeID("testLabel2");
|
m_label2.addThemeID("testLabel2");
|
||||||
|
|
@ -78,14 +62,16 @@ class Window : public ogfx::gui::Window
|
||||||
m_label1.addThemeOverride("@:pressed.label.textColor", ostd::Colors::Crimson);
|
m_label1.addThemeOverride("@:pressed.label.textColor", ostd::Colors::Crimson);
|
||||||
|
|
||||||
m_theme.loadFromFile("./testTheme.txt");
|
m_theme.loadFromFile("./testTheme.txt");
|
||||||
setTheme(m_theme);
|
|
||||||
|
|
||||||
m_label2.addThemeOverride("@:hover.label.showBackground", true);
|
m_label2.addThemeOverride("@:hover.label.showBackground", true);
|
||||||
m_label2.addThemeOverride("@:hover.label.backgroundColor", ostd::Colors::DarkGreen);
|
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
|
inline void onSignal(ostd::Signal& signal) override
|
||||||
|
|
@ -106,7 +92,9 @@ class Window : public ogfx::gui::Window
|
||||||
private:
|
private:
|
||||||
ogfx::gui::widgets::Label m_label1 { *this };
|
ogfx::gui::widgets::Label m_label1 { *this };
|
||||||
ogfx::gui::widgets::Label m_label2 { *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_panel1 { *this };
|
||||||
|
ogfx::gui::widgets::Panel m_panel2 { *this };
|
||||||
ostd::Stylesheet m_theme;
|
ostd::Stylesheet m_theme;
|
||||||
ostd::Vec2 pos { 0, 0 };
|
ostd::Vec2 pos { 0, 0 };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue