Implemented ImageLabel widget

This commit is contained in:
OmniaX-Dev 2026-04-20 08:50:38 +02:00
parent 67a2b5f10e
commit 27feac8fb7
15 changed files with 211 additions and 123 deletions

View file

@ -156,7 +156,6 @@ window.backgroundColor = rgba(160, 160, 160, 255)
} }
% ==================== % ====================
(image) { (image) {
path = file("img.png") path = file("img.png")
animated = true animated = true
@ -166,14 +165,11 @@ window.backgroundColor = rgba(160, 160, 160, 255)
rows: 4, \ rows: 4, \
frameWidth: 256, \ frameWidth: 256, \
frameHeight: 256) frameHeight: 256)
backgroundColor = #999999FF useBackgroundGradient = true
backgroundGradient = gradientV(rgb(160, 160, 160) - rgb(120, 120, 120)) backgroundGradient = gradientV(color_crimson - $accentColorDark)
showBorder = true
borderWidth = 1
borderColor = $accentColorDark borderColor = $accentColorDark
borderRadius = 0 borderRadius = 0
borderWidth = 1 padding = rect(15, 15, 15, 15)
showBackground = true
showBorder = true
useBackgroundGradient = true
padding = rect(15, 8, 15, 8)
margin = rect(0, 0, 0, 0)
} }

View file

@ -25,6 +25,8 @@ Implement cursors in Stylesheet
FIX: Window getting exponentially bigger when Desktop scale changes FIX: Window getting exponentially bigger when Desktop scale changes
FIX: Refreshing scroll when content extent changes FIX: Refreshing scroll when content extent changes
Add Dark Mode Default theme Add Dark Mode Default theme
FIX: Float values in stylesheet needing to have decimal point to be read as float
Make parsing of vec2 and rect in stylesheet, consistent with other value functions like gradients and animations
@ -34,14 +36,14 @@ Implement following widgets:
***Panel / Container ***Panel / Container
***Title Label ***Title Label
***ScrollView ***ScrollView
Button ***Image / Icon
***Button
Image/Icon Image/Icon
Radio Button Radio Button
Grouping Grouping
Text Input Text Input
Horizontal Slider Horizontal Slider
Vertical Slider Vertical Slider
Image / Icon
ListBox ListBox
ComboBox ComboBox
TreeView TreeView

View file

@ -1 +1 @@
2071 2072

View file

@ -105,6 +105,7 @@ namespace ogfx
inline ostd::Stylesheet::VariableList& getDefaultStylesheetVariableList(void) { return m_defaultStylesheetVariables; } inline ostd::Stylesheet::VariableList& getDefaultStylesheetVariableList(void) { return m_defaultStylesheetVariables; }
inline virtual void setTheme(const ostd::Stylesheet& theme) { } inline virtual void setTheme(const ostd::Stylesheet& theme) { }
inline BasicRenderer2D& getGFX(void) { return m_gfx; }
inline bool isInitialized(void) const { return m_initialized; } inline bool isInitialized(void) const { return m_initialized; }
inline bool isRunning(void) const { return m_running; } inline bool isRunning(void) const { return m_running; }
inline bool isVisible(void) const { return m_visible; } inline bool isVisible(void) const { return m_visible; }
@ -145,6 +146,7 @@ namespace ogfx
protected: protected:
SDL_Window* m_window { nullptr }; SDL_Window* m_window { nullptr };
SDL_Renderer* m_renderer { nullptr }; SDL_Renderer* m_renderer { nullptr };
BasicRenderer2D m_gfx;
ostd::ConsoleOutputHandler m_out; ostd::ConsoleOutputHandler m_out;
GraphicsWindowOutputHandler m_wout; GraphicsWindowOutputHandler m_wout;
const ostd::Stylesheet* m_guiTheme { nullptr }; const ostd::Stylesheet* m_guiTheme { nullptr };
@ -263,7 +265,6 @@ namespace ogfx
void __on_fixed_update(void) override; void __on_fixed_update(void) override;
protected: protected:
BasicRenderer2D m_gfx;
widgets::RootWidget m_rootWidget { *this }; widgets::RootWidget m_rootWidget { *this };
ostd::StepTimer m_fixedUpdateTimer; ostd::StepTimer m_fixedUpdateTimer;
ostd::StepTimer::TimePoint m_lastFrameTime; ostd::StepTimer::TimePoint m_lastFrameTime;

View file

@ -20,6 +20,8 @@
#include "Label.hpp" #include "Label.hpp"
#include "../../render/BasicRenderer.hpp" #include "../../render/BasicRenderer.hpp"
#include "../../../ostd/io/FileSystem.hpp"
#include "../Window.hpp"
namespace ogfx namespace ogfx
{ {
@ -62,6 +64,62 @@ namespace ogfx
setSize({ cast<f32>(size.x), cast<f32>(size.y) }); setSize({ cast<f32>(size.x), cast<f32>(size.y) });
m_textChanged = false; m_textChanged = false;
} }
ImageLabel& ImageLabel::create(const String& filePath)
{
setImage(filePath);
setPadding({ 0, 0, 0, 0 });
setTypeName("ogfx::gui::widgets::ImageLabel");
disableChildren();
disableBackground();
disableBorder();
setStylesheetCategoryName("image");
setSize(64, 64);
validate();
return *this;
}
void ImageLabel::applyTheme(const ostd::Stylesheet& theme)
{
enableAnimated(getThemeValue<bool>(theme, "animated", m_animated));
setAnimationData(getThemeValue<AnimationData>(theme, "animation", m_animData));
String filePath = getThemeValue<String>(theme, "path", m_image.getFilePath());
if (filePath != m_image.getFilePath())
setImage(filePath);
setSize(getThemeValue<Vec2>(theme, "size", getSize()));
if (isAnimatedEnabled())
{
m_anim.create(m_animData);
m_anim.setSpriteSheet(m_image);
}
}
void ImageLabel::onDraw(ogfx::BasicRenderer2D& gfx)
{
if (isAnimatedEnabled())
gfx.drawAnimation(m_anim, getGlobalPosition() + getPadding().topLeft(), getSize() - getPadding().bottomRight());
else
gfx.drawImage(m_image, getGlobalPosition() + getPadding().topLeft(), getSize() - getPadding().bottomRight());
}
void ImageLabel::onUpdate(void)
{
if (isAnimatedEnabled())
m_anim.update();
}
void ImageLabel::setImage(const String& filePath)
{
if (filePath == "") return;
if (!ostd::FileSystem::fileExists(filePath))
return;
m_image.destroy();
m_image.loadFromFile(filePath, getWindow().getGFX());
}
} }
} }
} }

View file

@ -21,6 +21,8 @@
#pragma once #pragma once
#include <ogfx/gui/widgets/Widget.hpp> #include <ogfx/gui/widgets/Widget.hpp>
#include <ogfx/resources/Image.hpp>
#include <ogfx/utils/Animation.hpp>
namespace ogfx namespace ogfx
{ {
@ -45,6 +47,26 @@ namespace ogfx
String m_text { "" }; String m_text { "" };
bool m_textChanged { false }; bool m_textChanged { false };
}; };
class ImageLabel : public Widget
{
public:
inline ImageLabel(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(""); }
inline ImageLabel(WindowCore& window, const String& text) : Widget({ 0, 0, 0, 0 }, window) { create(text); }
ImageLabel& create(const String& filePath);
void applyTheme(const ostd::Stylesheet& theme) override;
void onDraw(ogfx::BasicRenderer2D& gfx) override;
void onUpdate(void) override;
void setImage(const String& filePath);
inline Image& getImage(void) { return m_image; }
OSTD_BOOL_PARAM_GETSET_E(Animated, m_animated);
OSTD_PARAM_GETSET(AnimationData, AnimationData, m_animData);
private:
Image m_image;
Animation m_anim;
AnimationData m_animData;
bool m_animated { false };
};
} }
} }
} }

View file

@ -323,7 +323,7 @@ namespace ogfx
{ {
if (isVScrollEnabled()) if (isVScrollEnabled())
{ {
bool mouseInsideHScrollbar = m_hScrollbar.isMouseInsideThumb({ event.mouse->position_x, event.mouse->position_y }) && needsHScroll(); bool mouseInsideHScrollbar = m_hScrollbar.isMouseInside() && needsHScroll();
if (std::abs(event.mouse->scrollAmount.y) > 0 && !mouseInsideHScrollbar) if (std::abs(event.mouse->scrollAmount.y) > 0 && !mouseInsideHScrollbar)
{ {
m_scrollVelocity.y += m_scrollSpeed * event.mouse->scrollAmount.y * m_scrollSpeedMultiplier; m_scrollVelocity.y += m_scrollSpeed * event.mouse->scrollAmount.y * m_scrollSpeedMultiplier;

View file

@ -244,7 +244,7 @@ namespace ogfx
if (!isVisible()) if (!isVisible())
return; return;
beforeDraw(gfx); beforeDraw(gfx);
if (m_useBackgroundGradient && m_showBorder) if (m_useBackgroundGradient)
gfx.fillGradientRect({ getGlobalPosition(), getSize() }, m_backgroundGradient); gfx.fillGradientRect({ getGlobalPosition(), getSize() }, m_backgroundGradient);
else if (m_showBackground) else if (m_showBackground)
gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius); gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius);

View file

@ -218,7 +218,8 @@ namespace ogfx
return set_error_state(tErrors::NoFont); return set_error_state(tErrors::NoFont);
if (m_font == nullptr) if (m_font == nullptr)
return set_error_state(tErrors::NullFont); return set_error_state(tErrors::NullFont);
if (fontSize == m_fontSize || fontSize <= 0) return set_error_state(tErrors::NoError); if (fontSize == m_fontSize || fontSize <= 0)
return set_error_state(tErrors::NoError);
TTF_SetFontSize(m_font, fontSize); TTF_SetFontSize(m_font, fontSize);
m_fontSize = fontSize; m_fontSize = fontSize;
return set_error_state(tErrors::NoError); return set_error_state(tErrors::NoError);

View file

@ -1,21 +1,21 @@
/* /*
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/>.
*/ */
#include "Image.hpp" #include "Image.hpp"
@ -25,19 +25,24 @@
namespace ogfx namespace ogfx
{ {
void Image::destroy(void) void Image::destroy(void)
{ {
SDL_DestroyTexture(m_sdl_texture); if (isValid() && isLoaded())
m_loaded = false; SDL_DestroyTexture(m_sdl_texture);
m_sdl_texture = nullptr; m_loaded = false;
m_width = 0; m_sdl_texture = nullptr;
m_height = 0; m_width = 0;
} m_height = 0;
m_filePath = "";
invalidate();
}
Image& Image::loadFromFile(const String& filePath, BasicRenderer2D& gfx) Image& Image::loadFromFile(const String& filePath, BasicRenderer2D& gfx)
{ {
if (isLoaded() && isValid())
return *this;
if (!gfx.isInitialized()) if (!gfx.isInitialized())
return *this; //TODO: Error return *this; //TODO: Error
m_sdl_texture = IMG_LoadTexture(gfx.getWindow().getSDLRenderer(), filePath.c_str()); m_sdl_texture = IMG_LoadTexture(gfx.getWindow().getSDLRenderer(), filePath.c_str());
if (!m_sdl_texture) if (!m_sdl_texture)
{ {
@ -45,9 +50,10 @@ namespace ogfx
return *this; return *this;
} }
SDL_GetTextureSize(m_sdl_texture, &m_width, &m_height); SDL_GetTextureSize(m_sdl_texture, &m_width, &m_height);
m_filePath = filePath;
m_loaded = true; m_loaded = true;
setTypeName("ogfx::Image"); setTypeName("ogfx::Image");
validate(); validate();
return *this; return *this;
} }
} }

View file

@ -1,21 +1,21 @@
/* /*
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
@ -26,23 +26,25 @@
namespace ogfx namespace ogfx
{ {
class BasicRenderer2D; class BasicRenderer2D;
class Image : public ostd::BaseObject class Image : public ostd::BaseObject
{ {
public: public:
inline Image(void) { invalidate(); } inline Image(void) { invalidate(); }
inline Image(const String& filePath, BasicRenderer2D& gfx) { loadFromFile(filePath, gfx); } inline Image(const String& filePath, BasicRenderer2D& gfx) { loadFromFile(filePath, gfx); }
inline ~Image(void) { destroy(); } inline ~Image(void) { destroy(); }
void destroy(void); void destroy(void);
Image& loadFromFile(const String& filePath, BasicRenderer2D& gfx); Image& loadFromFile(const String& filePath, BasicRenderer2D& gfx);
inline Vec2 getSize(void) const { return { m_width, m_height }; } inline Vec2 getSize(void) const { return { m_width, m_height }; }
inline bool isLoaded(void) const { return m_loaded; } inline bool isLoaded(void) const { return m_loaded; }
inline SDL_Texture* getSDLTexture(void) const { return m_sdl_texture; } inline SDL_Texture* getSDLTexture(void) const { return m_sdl_texture; }
inline String getFilePath(void) const { return m_filePath; }
private: private:
SDL_Texture* m_sdl_texture { nullptr }; SDL_Texture* m_sdl_texture { nullptr };
f32 m_width { 0 }; String m_filePath { "" };
f32 m_height { 0 }; f32 m_width { 0 };
bool m_loaded { false }; f32 m_height { 0 };
}; bool m_loaded { false };
};
} }

View file

@ -253,7 +253,7 @@ namespace ostd
return false; return false;
String key = line.new_substr(0, line.indexOf("=")).trim(); String key = line.new_substr(0, line.indexOf("=")).trim();
String valuePreserveCase = line.new_substr(line.indexOf("=") + 1).trim(); String valuePreserveCase = line.new_substr(line.indexOf("=") + 1).trim();
String value = line.new_substr(line.indexOf("=") + 1).trim().toLower(); String value = valuePreserveCase.new_toLower();
if (key == "") if (key == "")
return false; return false;
String themeID = ""; String themeID = "";
@ -286,7 +286,7 @@ namespace ostd
}; };
auto l_isFile = [this](String& value) -> bool { auto l_isFile = [this](String& value) -> bool {
value.trim(); value.trim();
if (value.startsWith("file(") && value.endsWith(")")) if (value.new_toLower().startsWith("file(") && value.endsWith(")"))
{ {
value.substr(5, value.len() - 1).trim(); value.substr(5, value.len() - 1).trim();
if (value.startsWith("\"") && value.endsWith("\"")) if (value.startsWith("\"") && value.endsWith("\""))
@ -299,7 +299,7 @@ namespace ostd
}; };
auto l_isAnim = [this](String& value) -> bool { auto l_isAnim = [this](String& value) -> bool {
value.trim(); value.trim();
if (value.startsWith("anim(") && value.endsWith(")")) if (value.new_toLower().startsWith("anim(") && value.endsWith(")"))
{ {
value.substr(5, value.len() - 1).trim(); value.substr(5, value.len() - 1).trim();
return true; return true;
@ -331,25 +331,25 @@ namespace ostd
} }
else if (l_isColorGradientValue(value)) else if (l_isColorGradientValue(value))
{ {
ColorGradient grad = parseColorGradient(value); ColorGradient grad = parseColorGradient(valuePreserveCase, variables);
if (grad.isInvalid()) if (grad.isInvalid())
return false; return false;
set(key, grad, themeID); set(key, grad, themeID);
} }
else if (l_isAnim(value)) else if (l_isAnim(valuePreserveCase))
{ {
bool outError = false; bool outError = false;
AnimationData ad = parseAnim(value, outError); AnimationData ad = parseAnim(valuePreserveCase, outError, variables);
if (outError) if (outError)
return false; return false;
set(key, ad, themeID); set(key, ad, themeID);
} }
else if (l_isFile(value)) else if (l_isFile(valuePreserveCase))
{ {
bool exists = ostd::FileSystem::fileExists(value) || bool exists = ostd::FileSystem::fileExists(valuePreserveCase) ||
ostd::FileSystem::fileExists("./" + value); ostd::FileSystem::fileExists("./" + valuePreserveCase);
if (exists) if (exists)
set(key, value, themeID); set(key, valuePreserveCase, themeID);
else else
return false; return false;
} }
@ -392,20 +392,7 @@ namespace ostd
{ {
if (exitCondition) if (exitCondition)
return false; return false;
String lineCopy = line; return parseThemeFileLine(replaceVariables(line, variables), variables, true);
std::vector<std::pair<String, std::pair<String, bool>>> sortedVars(variables.begin(), variables.end());
std::sort(sortedVars.begin(), sortedVars.end(), [](const auto& a, const auto& b) {
return a.first.len() > b.first.len();
});
for (const auto&[var, val] : sortedVars)
{
if (lineCopy.contains(var))
{
lineCopy.replaceAll(var, val.first);
break;
}
}
return parseThemeFileLine(lineCopy, variables, true);
} }
return true; return true;
} }
@ -477,13 +464,13 @@ namespace ostd
return newLines; return newLines;
} }
ColorGradient Stylesheet::parseColorGradient(const String& _value) ColorGradient Stylesheet::parseColorGradient(const String& _value, const VariableList& variables)
{ {
String value = _value.new_toLower().trim(); String value = _value.new_trim();
ColorGradient grad; ColorGradient grad;
f32 angle = 0.0f; f32 angle = 0.0f;
bool weighted = false; bool weighted = false;
String gradientFunc = value.new_substr(0, value.indexOf("(")).trim(); String gradientFunc = value.new_substr(0, value.indexOf("(")).trim().toLower();
String gradientVal = value.substr(value.indexOf("(") + 1, value.lastIndexOf(")")).trim(); String gradientVal = value.substr(value.indexOf("(") + 1, value.lastIndexOf(")")).trim();
if (gradientVal == "" || !gradientVal.contains("-")) if (gradientVal == "" || !gradientVal.contains("-"))
@ -511,6 +498,9 @@ namespace ostd
i32 index = 0; i32 index = 0;
for (auto& token : tokens) for (auto& token : tokens)
{ {
token = replaceVariables(token, variables);
if (token.new_toLower().startsWith("color(") && token.new_toLower().endsWith(")"))
token.substr(6, token.len() - 1).trim();
grad.addColor(Color(token)); grad.addColor(Color(token));
if (index > 0) if (index > 0)
grad.addWeight(1.0f); grad.addWeight(1.0f);
@ -525,10 +515,14 @@ namespace ostd
{ {
if (is_color) if (is_color)
{ {
token = replaceVariables(token, variables);
if (token.new_toLower().startsWith("color(") && token.new_toLower().endsWith(")"))
token.substr(6, token.len() - 1).trim();
grad.addColor(Color(token)); grad.addColor(Color(token));
} }
else else
{ {
token = replaceVariables(token, variables);
if (!token.isNumeric(true)) if (!token.isNumeric(true))
return ColorGradient(); return ColorGradient();
grad.addWeight(token.toFloat()); grad.addWeight(token.toFloat());
@ -541,9 +535,9 @@ namespace ostd
return grad; return grad;
} }
AnimationData Stylesheet::parseAnim(const String& _value, bool& outError) AnimationData Stylesheet::parseAnim(const String& _value, bool& outError, const VariableList& variables)
{ {
String value = _value.new_toLower().trim(); String value = _value.new_trim();
AnimationData ad; AnimationData ad;
auto tokens = value.tokenize(","); auto tokens = value.tokenize(",");
auto l_error = [&](bool err) -> AnimationData { auto l_error = [&](bool err) -> AnimationData {
@ -554,8 +548,9 @@ namespace ostd
{ {
if (tok.count(":") != 1 || tok.startsWith(":") || tok.endsWith(":")) if (tok.count(":") != 1 || tok.startsWith(":") || tok.endsWith(":"))
return l_error(true); return l_error(true);
String prop = tok.new_substr(0, tok.indexOf(":")).trim(); String prop = tok.new_substr(0, tok.indexOf(":")).trim().toLower();
String val = tok.new_substr(tok.indexOf(":") + 1).trim(); String val = tok.new_substr(tok.indexOf(":") + 1).trim();
val = replaceVariables(val, variables);
if (prop == "framecount") if (prop == "framecount")
{ {
if (!val.isInt()) if (!val.isInt())
@ -648,6 +643,25 @@ namespace ostd
return l_error(false); return l_error(false);
} }
String Stylesheet::replaceVariables(const String& line, const VariableList& variables, bool stop_at_first_match)
{
String lineCopy = line;
std::vector<std::pair<String, std::pair<String, bool>>> sortedVars(variables.begin(), variables.end());
std::sort(sortedVars.begin(), sortedVars.end(), [](const auto& a, const auto& b) {
return a.first.len() > b.first.len();
});
for (const auto&[var, val] : sortedVars)
{
if (lineCopy.contains(var))
{
lineCopy.replaceAll(var, val.first);
if (stop_at_first_match)
break;
}
}
return lineCopy;
}
void Stylesheet::debugPrint(void) void Stylesheet::debugPrint(void)
{ {
for (const auto&[key, value] : m_values) for (const auto&[key, value] : m_values)

View file

@ -63,8 +63,9 @@ namespace ostd
bool parseThemeFileLine(const String& line, const VariableList& variables, bool exitCondition = false); bool parseThemeFileLine(const String& line, const VariableList& variables, bool exitCondition = false);
String parseGroupSelector(const String& rawSelector) const; String parseGroupSelector(const String& rawSelector) const;
stdvec<String> parseGroup(const String& selector, const stdvec<String>& group); stdvec<String> parseGroup(const String& selector, const stdvec<String>& group);
ColorGradient parseColorGradient(const String& _value); ColorGradient parseColorGradient(const String& _value, const VariableList& variables);
AnimationData parseAnim(const String& _value, bool& outError); AnimationData parseAnim(const String& _value, bool& outError, const VariableList& variables);
String replaceVariables(const String& line, const VariableList& variables, bool stop_at_first_match = true);
private: private:
stdumap<String, TypeVariant> m_values; stdumap<String, TypeVariant> m_values;

View file

@ -369,13 +369,14 @@ namespace ostd
inline virtual Vec2 topRight(void) const { return Vec2(getx() + getw(), gety()); } inline virtual Vec2 topRight(void) const { return Vec2(getx() + getw(), gety()); }
inline virtual Vec2 bottomLeft(void) const { return Vec2(getx(), gety() + geth()); } inline virtual Vec2 bottomLeft(void) const { return Vec2(getx(), gety() + geth()); }
inline virtual Vec2 bottomRight(void) const { return Vec2(getx() + getw(), gety() + geth()); } inline virtual Vec2 bottomRight(void) const { return Vec2(getx() + getw(), gety() + geth()); }
inline virtual Rectangle edgeRect(void) const { return { getx(), gety(), getx() + getw(), gety() + getw() }; }
inline virtual f32 left(void) const { return getx(); } inline virtual f32 left(void) const { return getx(); }
inline virtual f32 right(void) const { return getw(); } inline virtual f32 right(void) const { return getw(); }
inline virtual f32 top(void) const { return gety(); } inline virtual f32 top(void) const { return gety(); }
inline virtual f32 bottom(void) const { return geth(); } inline virtual f32 bottom(void) const { return geth(); }
inline String toString(void) const override { return String("{ ").add(x).add(", ").add(y).add(", ").add(w).add(", ").add(h).add(" }"); } inline virtual String toString(void) const override { return String("{ ").add(x).add(", ").add(y).add(", ").add(w).add(", ").add(h).add(" }"); }
inline virtual bool intersects(Rectangle rect, bool includeBounds = true) const inline virtual bool intersects(Rectangle rect, bool includeBounds = true) const
{ {

View file

@ -32,18 +32,6 @@ class Window : public ogfx::gui::Window
inline Window(void) { } inline Window(void) { }
inline void onInitialize(void) override inline void onInitialize(void) override
{ {
m_img.loadFromFile("./img.png", m_gfx);
ogfx::AnimationData ad;
ad.columns = 9;
ad.rows = 4;
ad.frameWidth = 256;
ad.frameHeight = 256;
ad.frameCount = 36;
ad.fps = 60;
m_anim.create(ad);
m_anim.setSpriteSheet(m_img);
m_label1.setText("Show Panel2"); m_label1.setText("Show Panel2");
m_label1.setCallback(ogfx::gui::Widget::eCallback::MousePressed, [&](const ogfx::gui::Event& event) -> void { m_label1.setCallback(ogfx::gui::Widget::eCallback::MousePressed, [&](const ogfx::gui::Event& event) -> void {
m_check1.setChecked(!m_check1.isChecked()); m_check1.setChecked(!m_check1.isChecked());
@ -100,6 +88,7 @@ class Window : public ogfx::gui::Window
m_panel2.addWidget(m_panel1, { 400, 50 }); m_panel2.addWidget(m_panel1, { 400, 50 });
m_panel2.addWidget(m_label1, { 0, 500 }); m_panel2.addWidget(m_label1, { 0, 500 });
m_panel2.addWidget(m_btn1, { 0, 300 }); m_panel2.addWidget(m_btn1, { 0, 300 });
m_panel2.addWidget(m_img, { 20, 150 });
addWidget(m_check1, { 30, 30 }); addWidget(m_check1, { 30, 30 });
addWidget(m_panel2, { 500, 100 }); addWidget(m_panel2, { 500, 100 });
@ -120,14 +109,10 @@ class Window : public ogfx::gui::Window
void onRedraw(ogfx::BasicRenderer2D& gfx) override void onRedraw(ogfx::BasicRenderer2D& gfx) override
{ {
gfx.drawAnimation(m_anim, { 200, 200 });
// std::cout << (i32)gfx.getDrawCallCount() << "\n";
// gfx.fillRect(m_panel2.getGlobalPureContentBounds(), { 0, 255, 0, 120 });
} }
void onFixedUpdate(void) override void onFixedUpdate(void) override
{ {
m_anim.update();
} }
private: private:
@ -141,10 +126,9 @@ class Window : public ogfx::gui::Window
Panel m_panel3 { *this }; Panel m_panel3 { *this };
CheckBox m_check1 { *this }; CheckBox m_check1 { *this };
Button m_btn1 { *this }; Button m_btn1 { *this };
ImageLabel m_img { *this };
ostd::Stylesheet m_theme; ostd::Stylesheet m_theme;
ogfx::Animation m_anim;
ogfx::Image m_img;
}; };
i32 main(i32 argc, char** argv) i32 main(i32 argc, char** argv)