Implemented ImageLabel widget
This commit is contained in:
parent
67a2b5f10e
commit
27feac8fb7
15 changed files with 211 additions and 123 deletions
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
2071
|
2072
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 };
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 };
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue