Started work on Panel Widget

This commit is contained in:
OmniaX-Dev 2026-04-05 14:12:16 +02:00
parent 25e06eba0a
commit c695c0ad85
6 changed files with 146 additions and 38 deletions

View file

@ -5,20 +5,29 @@ $accentColor = Color(rgba(255, 0, 255, 255))
$color2 = Color(#0000FFFF)
% -------------------
window.backgroundColor = Color(rgba(40, 0, 0, 255))
window.backgroundColor = Color(rgba(120, 120, 120, 255))
(label) {
textColor = $accentColor
backgroundColor = Color(#000000FF)
borderColor = $accentColor
fontSize = 50
borderRadius = 20
borderRadius = 0
borderWidth = 2
showBackground = true
showBorder = true
padding = Rect(15, 15, 15, 15)
}
(panel) {
backgroundColor = Color(#AAAAAAFF)
borderColor = Color(#000000FF)
borderRadius = 8
borderWidth = 2
showBorder = true
padding = Rect(15, 15, 15, 15)
}
(@testLabel label) {
textColor = $color2
backgroundColor = Color(#000000FF)

View file

@ -52,12 +52,14 @@ namespace ogfx
{
w->m_focused = false;
w->onFocusLost(Event(m_window));
w->setThemeQualifier("focused", true);
}
else
w->m_focused = false;
}
widget.m_focused = true;
widget.onFocusGained(Event(m_window));
widget.setThemeQualifier("focused", true);
m_focused = &widget;
return true;
}
@ -305,6 +307,12 @@ namespace ogfx
return ostd::Rectangle(getGlobalPosition(), getSize()).contains(p, includeBounds);
}
void Widget::enable(bool enable)
{
m_enabled = enable;
setThemeQualifier("disabled", !enable);
}
void Widget::addThemeOverride(const ostd::String& fullKey, ostd::Stylesheet::TypeVariant value, bool propagate)
{
m_themeOverrides.push_back({ fullKey, value, propagate });
@ -319,14 +327,29 @@ namespace ogfx
applyTheme(theme);
ostd::Stylesheet& const_cast_theme = const_cast<ostd::Stylesheet&>(theme);
struct tBackup {
const ostd::Stylesheet::TypeVariant* ptr;
ostd::Stylesheet::TypeVariant val;
ostd::String key;
};
std::vector<tBackup> backup;
for (auto& rule : m_themeOverrides)
{
auto currentValue = theme.getFull(rule.fullKey);
if (currentValue == nullptr)
return;
auto currentValuePtr = theme.getFull(rule.fullKey);
ostd::Stylesheet::TypeVariant currentValue;
if (currentValuePtr)
currentValue = *currentValuePtr;
backup.push_back({ currentValuePtr, currentValue, rule.fullKey });
const_cast_theme.setFull(rule.fullKey, rule.value);
__applyTheme(const_cast_theme, rule.propagate);
const_cast_theme.setFull(rule.fullKey, *currentValue);
}
for (auto&[ptr, val, key] : backup)
{
if (ptr == nullptr)
const_cast_theme.removeRule(key);
else
const_cast_theme.setFull(key, val);
}
}
@ -581,6 +604,7 @@ namespace ogfx
setPadding({ 5, 5, 5, 5 });
setTypeName("ogfx::gui::widgets::Label");
disableDrawBox();
disableChildren();
enableBackground(false);
validate();
return *this;
@ -627,6 +651,37 @@ namespace ogfx
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);
}
}
}
}

View file

@ -86,6 +86,7 @@ namespace ogfx
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);
@ -159,6 +160,12 @@ namespace ogfx
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)
@ -200,6 +207,9 @@ namespace ogfx
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;
@ -247,7 +257,7 @@ namespace ogfx
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(const ostd::Color& color) { return m_backgroundColor; }
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; }
@ -268,6 +278,24 @@ namespace ogfx
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 };
};
}
}
}

View file

@ -146,6 +146,11 @@ namespace ostd
setFull(fullKey, value);
}
void Stylesheet::removeRule(const ostd::String& fullKey)
{
m_values.erase(fullKey);
}
void Stylesheet::setFull(const ostd::String& fullKey, TypeVariant value)
{
m_values[fullKey] = std::move(value);
@ -305,25 +310,25 @@ namespace ostd
{
std::cout << key << " = " << typeVariantToString(value) << "\n";
}
std::cout << "\n";
}
ostd::String Stylesheet::typeVariantToString(const TypeVariant& v)
{
ostd::String str = "";
// if (auto p = std::get_if<int32_t>(&v))
// str.add(*p);
// else if (auto p = std::get_if<float>(&v))
// str.add(*p);
// else if (auto p = std::get_if<bool>(&v))
// str.add(STR_BOOL(*p));
// else if (auto p = std::get_if<ostd::String>(&v))
// str.add(*p);
// else if (auto p = std::get_if<ostd::Color>(&v))
// str.add(*p);
// else if (auto p = std::get_if<ostd::Rectangle>(&v))
// std::cout << std::format("{{ {}, {}, {}, {} }}", (*p).x, (*p).y, (*p).w, (*p).h);
// else if (auto p = std::get_if<ostd::Vec2>(&v))
// std::cout << *p;
return str;
if (auto p = std::get_if<int32_t>(&v))
return String("").add(*p);
else if (auto p = std::get_if<float>(&v))
return String("").add(*p);
else if (auto p = std::get_if<bool>(&v))
return STR_BOOL(*p);
else if (auto p = std::get_if<ostd::String>(&v))
return *p;
else if (auto p = std::get_if<ostd::Color>(&v))
return *p;
else if (auto p = std::get_if<ostd::Rectangle>(&v))
return *p;
else if (auto p = std::get_if<ostd::Vec2>(&v))
return *p;
return "";
}
}

View file

@ -37,6 +37,7 @@ namespace ostd
Stylesheet& loadFromFile(const ostd::String& filePath, bool clearCurrentRules = true);
Stylesheet& loadFromString(const ostd::String& content, const ostd::String& filePath = "memory://", bool clearCurrentRules = true);
void set(const std::string& key, TypeVariant value, const ostd::String& themeID);
void removeRule(const ostd::String& fullKey);
void setFull(const ostd::String& fullKey, TypeVariant value);
const TypeVariant* getVariant(const ostd::String& key, const std::vector<ostd::String>& themeIDList, const QualifierList& qualifierList) const;
const TypeVariant* getFull(const ostd::String& fullKey) const;

View file

@ -22,7 +22,7 @@
/*
* Label
* --- Label
* Button
* Panel / Container
* Checkbox
@ -49,32 +49,40 @@ class Window : public ogfx::gui::Window
inline Window(void) { }
inline void onInitialize(void) override
{
m_panel1.setSize(300, 140);
m_panel1.setPosition(200, 150);
m_panel1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void {
pos = { event.mouse->position_x, event.mouse->position_y };
});
m_panel1.setMouseDraggedCallback([&](const ogfx::gui::Event& event) -> void {
ostd::Vec2 pos2 { event.mouse->position_x, event.mouse->position_y };
m_panel1.addPos(pos2 - pos);
pos = pos2;
});
m_label1.setPosition(100, 200);
m_label1.setText("Hello World!");
// m_label1.setMouseEnteredCallback([&](const ogfx::gui::Event& event) -> void {
// m_label1.applyThemeValue(m_theme, "label.backgroundColor", ostd::Colors::DarkBlue, false);
// this->setCursor(eCursor::Move);
// });
// m_label1.setMouseExitedCallback([&](const ogfx::gui::Event& event) -> void {
// m_label1.applyThemeValue(m_theme, "label.backgroundColor", ostd::Colors::DarkRed, false);
// this->setCursor(eCursor::Default);
// });
// m_label1.setMouseDraggedCallback([&](const ogfx::gui::Event& event) -> void {
// m_label1.applyThemeValue(m_theme, "label.backgroundColor", ostd::Colors::DarkGreen, false);
// });
m_label1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void {
std::cout << "PRESS!\n";
});
addWidget(m_label1);
addWidget(m_panel1);
// m_label1.setThemeQualifier("disabled");
m_label2.setPosition(100, 400);
m_label2.setPosition(10, 10);
m_label2.setText("Ciccia Bella!");
m_label2.addThemeID("testLabel");
m_label2.addThemeID("testLabel2");
addWidget(m_label2);
m_panel1.addChild(m_label2);
m_label1.addThemeOverride("@:pressed.label.textColor", ostd::Colors::Crimson);
m_theme.loadFromFile("./testTheme.txt");
setTheme(m_theme);
m_label2.addThemeOverride("@:hover.label.fontSize", 10);
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();
@ -98,7 +106,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::Panel m_panel1 { *this };
ostd::Stylesheet m_theme;
ostd::Vec2 pos { 0, 0 };
};
int main(int argc, char** argv)