Added gradient functionality to BasicRenderer2D
This commit is contained in:
parent
44354a80c2
commit
d521c609b3
8 changed files with 243 additions and 15 deletions
|
|
@ -117,3 +117,33 @@ window.backgroundColor = rgba(160, 160, 160, 255)
|
||||||
margin = Rect(0, 0, 0, 0)
|
margin = Rect(0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
% ===================
|
% ===================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% ====== Label ======
|
||||||
|
(button) {
|
||||||
|
textColor = $textColor
|
||||||
|
backgroundColor = #999999FF
|
||||||
|
backgroundGradient = gradientH(#000000FF, #555555FF, #999999FF)
|
||||||
|
backgroundGradient = w_vgradientV(#000000FF, 0.2, #555555FF, 0.8, #999999FF)
|
||||||
|
borderColor = $accentColorDark
|
||||||
|
fontSize = 20
|
||||||
|
borderRadius = 0
|
||||||
|
borderWidth = 1
|
||||||
|
showBackground = true
|
||||||
|
showBorder = true
|
||||||
|
useBackgroundGradient = true
|
||||||
|
padding = Rect(15, 5, 15, 5)
|
||||||
|
margin = Rect(0, 0, 0, 0)
|
||||||
|
icon = file("testIcon.png")
|
||||||
|
}
|
||||||
|
(button:hover) {
|
||||||
|
borderColor = $accentColor
|
||||||
|
backgroundColor = #BBBBBBFF
|
||||||
|
}
|
||||||
|
(button:pressed) {
|
||||||
|
borderColor = #BBBBBBFF
|
||||||
|
textColor = #DDDDDDFF
|
||||||
|
backgroundColor = #555555FF
|
||||||
|
}
|
||||||
|
% ===================
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,4 @@
|
||||||
#include <ogfx/gui/widgets/Label.hpp>
|
#include <ogfx/gui/widgets/Label.hpp>
|
||||||
#include <ogfx/gui/widgets/CheckBox.hpp>
|
#include <ogfx/gui/widgets/CheckBox.hpp>
|
||||||
#include <ogfx/gui/widgets/Scrollbar.hpp>
|
#include <ogfx/gui/widgets/Scrollbar.hpp>
|
||||||
|
#include <ogfx/gui/widgets/Button.hpp>
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,60 @@ namespace ogfx
|
||||||
{
|
{
|
||||||
namespace widgets
|
namespace widgets
|
||||||
{
|
{
|
||||||
|
Button& Button::create(const String& text)
|
||||||
|
{
|
||||||
|
setText(text);
|
||||||
|
setPadding({ 5, 5, 5, 5 });
|
||||||
|
setTypeName("ogfx::gui::widgets::Button");
|
||||||
|
disableDrawBox();
|
||||||
|
disableChildren();
|
||||||
|
enableBackground(false);
|
||||||
|
validate();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::applyTheme(const ostd::Stylesheet& theme)
|
||||||
|
{
|
||||||
|
setTextColor(getThemeValue<Color>(theme, "button.textColor", Colors::White));
|
||||||
|
setBackGroundColor(getThemeValue<Color>(theme, "button.backgroundColor", Colors::Transparent));
|
||||||
|
setFontSize(getThemeValue<i32>(theme, "button.fontSize", 20));
|
||||||
|
setBorderRadius(getThemeValue<i32>(theme, "button.borderRadius", 10));
|
||||||
|
setBorderWidth(getThemeValue<i32>(theme, "button.borderWidth", 2));
|
||||||
|
enableBorder(getThemeValue<bool>(theme, "button.showBorder", false));
|
||||||
|
setBorderColor(getThemeValue<Color>(theme, "button.borderColor", Colors::White));
|
||||||
|
enableBackground(getThemeValue<bool>(theme, "button.showBackground", false));
|
||||||
|
setPadding(getThemeValue<Rectangle>(theme, "button.padding", { 5, 5, 5, 5 }));
|
||||||
|
setMargin(getThemeValue<Rectangle>(theme, "button.margin", { 0, 0, 0, 0 }));
|
||||||
|
m_useBackgroundGradient = getThemeValue<bool>(theme, "button.useBackgroundGradient", false);
|
||||||
|
if (m_useBackgroundGradient && isBackgoundEnabled())
|
||||||
|
enableBackground(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::onDraw(ogfx::BasicRenderer2D& gfx)
|
||||||
|
{
|
||||||
|
if (m_textChanged)
|
||||||
|
__update_size(gfx);
|
||||||
|
if (m_useBackgroundGradient)
|
||||||
|
gfx.fillGradientRect(getGlobalBounds(), m_backgroundGradient);
|
||||||
|
gfx.drawString(getText(), getGlobalContentPosition(), getTextColor(), getFontSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::setText(const String& text)
|
||||||
|
{
|
||||||
|
m_text = text;
|
||||||
|
m_textChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::__update_size(ogfx::BasicRenderer2D& gfx)
|
||||||
|
{
|
||||||
|
auto size = gfx.getStringDimensions(getText(), getFontSize());
|
||||||
|
size.x += getPadding().left();
|
||||||
|
size.x += getPadding().right();
|
||||||
|
size.y += getPadding().top();
|
||||||
|
size.y += getPadding().bottom();
|
||||||
|
setSize({ cast<f32>(size.x), cast<f32>(size.y) });
|
||||||
|
m_textChanged = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,35 @@ namespace ogfx
|
||||||
{
|
{
|
||||||
namespace widgets
|
namespace widgets
|
||||||
{
|
{
|
||||||
|
class Button : public Widget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline Button(WindowCore& window) : Widget({ 0, 0, 0, 0 }, window) { create(""); }
|
||||||
|
inline Button(WindowCore& window, const String& text) : Widget({ 0, 0, 0, 0 }, window) { create(text); }
|
||||||
|
Button& create(const String& text);
|
||||||
|
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||||
|
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||||
|
void setText(const String& text);
|
||||||
|
inline String getText(void) const { return m_text; }
|
||||||
|
inline Color getTextColor(void) const { return m_textColor; }
|
||||||
|
inline void setTextColor(const Color& color) { m_textColor = color; }
|
||||||
|
inline i32 getFontSize(void) const { return m_fontSize; }
|
||||||
|
inline void setFontSize(i32 fontSize) { m_fontSize = fontSize; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void __update_size(ogfx::BasicRenderer2D& gfx);
|
||||||
|
|
||||||
|
private:
|
||||||
|
String m_text { "" };
|
||||||
|
bool m_textChanged { false };
|
||||||
|
i32 m_fontSize { 20 };
|
||||||
|
Color m_textColor { 255, 255, 255 };
|
||||||
|
bool m_useBackgroundGradient { false };
|
||||||
|
ColorGradient m_backgroundGradient {
|
||||||
|
{ Color { 160, 160, 160 }, Color { 120, 120, 120 } },
|
||||||
|
{ 1.0f }
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,68 @@ namespace ogfx
|
||||||
drawImage(img, position, size, anim.getFrameRect());
|
drawImage(img, position, size, anim.getFrameRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BasicRenderer2D::fillGradientRect(const Rectangle& rect, ColorGradient& gradient)
|
||||||
|
{
|
||||||
|
auto& colors = gradient.getColors();
|
||||||
|
auto& weights = gradient.getWeights();
|
||||||
|
f32 angle_radians = gradient.getAngleRad();
|
||||||
|
if (!m_initialized || colors.size() < 2) return;
|
||||||
|
if (weights.size() != colors.size() - 1) return; // N colors = N-1 weights
|
||||||
|
|
||||||
|
// Normalize weights
|
||||||
|
f32 total = 0;
|
||||||
|
for (auto w : weights) total += w;
|
||||||
|
for (auto& w : weights) w /= total;
|
||||||
|
|
||||||
|
// Compute cumulative positions along gradient (0 to 1)
|
||||||
|
stdvec<f32> stops(colors.size());
|
||||||
|
stops[0] = 0.0f;
|
||||||
|
for (size_t i = 0; i < weights.size(); i++)
|
||||||
|
stops[i + 1] = stops[i] + weights[i];
|
||||||
|
|
||||||
|
// Center of rect for rotation
|
||||||
|
Vec2 center = { rect.x + rect.w * 0.5f, rect.y + rect.h * 0.5f };
|
||||||
|
f32 cs = std::cos(angle_radians);
|
||||||
|
f32 sn = std::sin(angle_radians);
|
||||||
|
|
||||||
|
auto rotate = [&](Vec2 p) -> Vec2 {
|
||||||
|
p -= center;
|
||||||
|
return { center.x + p.x * cs - p.y * sn,
|
||||||
|
center.y + p.x * sn + p.y * cs };
|
||||||
|
};
|
||||||
|
|
||||||
|
// For each color band, push a quad
|
||||||
|
for (size_t i = 0; i < colors.size() - 1; i++)
|
||||||
|
{
|
||||||
|
f32 y0 = rect.y + rect.h * stops[i];
|
||||||
|
f32 y1 = rect.y + rect.h * stops[i + 1];
|
||||||
|
|
||||||
|
Vec2 tl = rotate({ rect.x, y0 });
|
||||||
|
Vec2 tr = rotate({ rect.x + rect.w, y0 });
|
||||||
|
Vec2 br = rotate({ rect.x + rect.w, y1 });
|
||||||
|
Vec2 bl = rotate({ rect.x, y1 });
|
||||||
|
|
||||||
|
if (m_vertexCount + 4 >= MaxVertices || m_indexCount + 6 >= MaxIndices)
|
||||||
|
flushBatch();
|
||||||
|
if (m_texture != nullptr)
|
||||||
|
flushBatch();
|
||||||
|
m_texture = nullptr;
|
||||||
|
|
||||||
|
SDL_FColor c0 = COLOR_CAST(colors[i]);
|
||||||
|
SDL_FColor c1 = COLOR_CAST(colors[i + 1]);
|
||||||
|
|
||||||
|
i32 base = m_vertexCount;
|
||||||
|
m_vertices[m_vertexCount++] = { { tl.x, tl.y }, c0, { 0, 0 } };
|
||||||
|
m_vertices[m_vertexCount++] = { { tr.x, tr.y }, c0, { 0, 0 } };
|
||||||
|
m_vertices[m_vertexCount++] = { { br.x, br.y }, c1, { 0, 0 } };
|
||||||
|
m_vertices[m_vertexCount++] = { { bl.x, bl.y }, c1, { 0, 0 } };
|
||||||
|
|
||||||
|
u32 inds[6] = QUAD_INDICES_ARR;
|
||||||
|
for (i32 j = 0; j < 6; j++)
|
||||||
|
m_indices[m_indexCount++] = base + inds[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BasicRenderer2D::drawString(const String& str, const Vec2& position, const Color& color, i32 fontSize, f32 scale)
|
void BasicRenderer2D::drawString(const String& str, const Vec2& position, const Color& color, i32 fontSize, f32 scale)
|
||||||
{
|
{
|
||||||
if (!isValid()) return;
|
if (!isValid()) return;
|
||||||
|
|
@ -398,7 +460,7 @@ namespace ogfx
|
||||||
if (!rounded || thickness < 4)
|
if (!rounded || thickness < 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i32 segments = std::max(6, i32(thickness * 0.75f));
|
i32 segments = std::max(16, i32(thickness * 1.5f));
|
||||||
generate_half_circle(p1, -dir, half, segments, color);
|
generate_half_circle(p1, -dir, half, segments, color);
|
||||||
generate_half_circle(p2, dir, half, segments, color);
|
generate_half_circle(p2, dir, half, segments, color);
|
||||||
}
|
}
|
||||||
|
|
@ -475,7 +537,7 @@ namespace ogfx
|
||||||
drawLine({ {x1, y2 - rBL}, {x1, y1 + rTL} }, color, thickness, false); // left
|
drawLine({ {x1, y2 - rBL}, {x1, y1 + rTL} }, color, thickness, false); // left
|
||||||
|
|
||||||
// Corner arcs
|
// Corner arcs
|
||||||
auto segments = [](f32 r) -> i32 { return std::max(6, i32(r * 0.75f)); };
|
auto segments = [](f32 r) -> i32 { return std::max(16, i32(r * 1.5f)); };
|
||||||
|
|
||||||
if (rTL > 0) generate_ellipse_stroke({ x1 + rTL, y1 + rTL }, rTL, rTL, thickness, M_PI, M_PI * 1.5f, color, segments(rTL));
|
if (rTL > 0) generate_ellipse_stroke({ x1 + rTL, y1 + rTL }, rTL, rTL, thickness, M_PI, M_PI * 1.5f, color, segments(rTL));
|
||||||
if (rTR > 0) generate_ellipse_stroke({ x2 - rTR, y1 + rTR }, rTR, rTR, thickness, M_PI * 1.5f, M_PI * 2.0f, color, segments(rTR));
|
if (rTR > 0) generate_ellipse_stroke({ x2 - rTR, y1 + rTR }, rTR, rTR, thickness, M_PI * 1.5f, M_PI * 2.0f, color, segments(rTR));
|
||||||
|
|
@ -487,7 +549,7 @@ namespace ogfx
|
||||||
{
|
{
|
||||||
if (!m_initialized || thickness <= 0)
|
if (!m_initialized || thickness <= 0)
|
||||||
return;
|
return;
|
||||||
i32 segments = std::max(12, i32(radius * 0.75f));
|
i32 segments = std::max(16, i32(radius * 1.5f));
|
||||||
generate_ellipse_stroke(center, radius, radius, thickness, 0.0f, 2.0f * M_PI, color, segments);
|
generate_ellipse_stroke(center, radius, radius, thickness, 0.0f, 2.0f * M_PI, color, segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -513,8 +575,7 @@ namespace ogfx
|
||||||
Vec2 center = { rect.x + rect.w*0.5f, rect.y + rect.h*0.5f };
|
Vec2 center = { rect.x + rect.w*0.5f, rect.y + rect.h*0.5f };
|
||||||
f32 rx = rect.w * 0.5f;
|
f32 rx = rect.w * 0.5f;
|
||||||
f32 ry = rect.h * 0.5f;
|
f32 ry = rect.h * 0.5f;
|
||||||
|
i32 segments = std::max(16, i32(std::max(rx, ry) * 1.5f));
|
||||||
i32 segments = std::max(12, i32(std::max(rx, ry) * 0.75f));
|
|
||||||
generate_ellipse_stroke(center, rx, ry, thickness, 0.0f, 2.0f * M_PI, color, segments);
|
generate_ellipse_stroke(center, rx, ry, thickness, 0.0f, 2.0f * M_PI, color, segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -723,7 +784,7 @@ namespace ogfx
|
||||||
}
|
}
|
||||||
|
|
||||||
// Corner fills
|
// Corner fills
|
||||||
auto segments = [](f32 r) -> i32 { return std::max(6, i32(r * 0.75f)); };
|
auto segments = [](f32 r) -> i32 { return std::max(16, i32(r * 1.5f)); };
|
||||||
|
|
||||||
if (rTL > 0) generate_filled_ellipse_stroke({ x1 + rTL, y1 + rTL }, rTL, rTL, M_PI, color, segments(rTL));
|
if (rTL > 0) generate_filled_ellipse_stroke({ x1 + rTL, y1 + rTL }, rTL, rTL, M_PI, color, segments(rTL));
|
||||||
if (rTR > 0) generate_filled_ellipse_stroke({ x2 - rTR, y1 + rTR }, rTR, rTR, M_PI * 1.5f, color, segments(rTR));
|
if (rTR > 0) generate_filled_ellipse_stroke({ x2 - rTR, y1 + rTR }, rTR, rTR, M_PI * 1.5f, color, segments(rTR));
|
||||||
|
|
@ -736,7 +797,7 @@ namespace ogfx
|
||||||
if (!m_initialized)
|
if (!m_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i32 segments = std::max(12, i32(radius * 0.75f));
|
i32 segments = std::max(16, i32(radius * 1.5f));
|
||||||
generate_filled_ellipse(center, radius, radius, color, segments);
|
generate_filled_ellipse(center, radius, radius, color, segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -767,7 +828,7 @@ namespace ogfx
|
||||||
f32 radiusX = rect.w * 0.5f;
|
f32 radiusX = rect.w * 0.5f;
|
||||||
f32 radiusY = rect.h * 0.5f;
|
f32 radiusY = rect.h * 0.5f;
|
||||||
|
|
||||||
i32 segments = std::max(12, i32(std::max(radiusX, radiusY) * 0.75f));
|
i32 segments = std::max(16, i32(std::max(radiusX, radiusY) * 1.5f));
|
||||||
generate_filled_ellipse(center, radiusX, radiusY, color, segments);
|
generate_filled_ellipse(center, radiusX, radiusY, color, segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ namespace ogfx
|
||||||
|
|
||||||
void drawImage(const ogfx::Image& image, const Vec2& position, const Vec2& size = { 0, 0 }, const Rectangle& srcRect = { 0, 0, 0, 0 });
|
void drawImage(const ogfx::Image& image, const Vec2& position, const Vec2& size = { 0, 0 }, const Rectangle& srcRect = { 0, 0, 0, 0 });
|
||||||
void drawAnimation(const Animation& anim, const Vec2& position, const Vec2& size = { 0, 0 });
|
void drawAnimation(const Animation& anim, const Vec2& position, const Vec2& size = { 0, 0 });
|
||||||
|
void fillGradientRect(const Rectangle& rect, ColorGradient& gradient);
|
||||||
|
|
||||||
void drawString(const String& str, const Vec2& position, const Color& color, i32 fontSize = 0, f32 scale = 1.0f);
|
void drawString(const String& str, const Vec2& position, const Color& color, i32 fontSize = 0, f32 scale = 1.0f);
|
||||||
void drawCenteredString(const String& str, const Vec2& center, const Color& color, i32 fontSize = 0, f32 scale = 1.0f);
|
void drawCenteredString(const String& str, const Vec2& center, const Color& color, i32 fontSize = 0, f32 scale = 1.0f);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <ostd/data/Types.hpp>
|
#include <ostd/data/Types.hpp>
|
||||||
#include <ostd/data/BaseObject.hpp>
|
#include <ostd/data/BaseObject.hpp>
|
||||||
#include <ostd/string/String.hpp>
|
#include <ostd/string/String.hpp>
|
||||||
|
#include <ostd/math/Geometry.hpp>
|
||||||
|
|
||||||
namespace ostd
|
namespace ostd
|
||||||
{
|
{
|
||||||
|
|
@ -98,6 +99,31 @@ namespace ostd
|
||||||
|
|
||||||
public:
|
public:
|
||||||
};
|
};
|
||||||
|
class ColorGradient : public BaseObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline ColorGradient(void) { }
|
||||||
|
inline ColorGradient(const stdvec<Color>& colors, const stdvec<f32>& weights) { m_colors = colors; m_weights = weights; }
|
||||||
|
inline void addColor(const Color& color) { m_colors.push_back(color); }
|
||||||
|
inline void addWeight(f32 w) { m_weights.push_back(w); }
|
||||||
|
inline stdvec<Color>& getColors(void) { return m_colors; }
|
||||||
|
inline stdvec<f32>& getWeights(void) { return m_weights; }
|
||||||
|
inline void setAngleDeg(f32 angle_degrees) { m_angleDeg = angle_degrees; }
|
||||||
|
inline void setAngleRad(f32 angle_radians) { m_angleDeg = RAD_TO_DEG(angle_radians); }
|
||||||
|
inline f32 getAngleDeg(void) const { return m_angleDeg; }
|
||||||
|
inline f32 getAngleRad(void) const { return DEG_TO_RAD(m_angleDeg); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
stdvec<Color> m_colors;
|
||||||
|
stdvec<f32> m_weights;
|
||||||
|
float m_angleDeg { VerticalDeg };
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline static constexpr f32 HorizontalDeg { 90.0f };
|
||||||
|
inline static constexpr f32 VerticalDeg { 0.0f };
|
||||||
|
inline static constexpr f32 DiagonalDeg { 45.0f };
|
||||||
|
inline static constexpr f32 Diagonal2Deg { 135.0f };
|
||||||
|
};
|
||||||
struct Colors
|
struct Colors
|
||||||
{
|
{
|
||||||
inline static const Color Transparent { 0, 0, 0, 0 };
|
inline static const Color Transparent { 0, 0, 0, 0 };
|
||||||
|
|
@ -159,4 +185,5 @@ using Colors = ostd::Colors;
|
||||||
namespace ogfx
|
namespace ogfx
|
||||||
{
|
{
|
||||||
using Color = ostd::Color;
|
using Color = ostd::Color;
|
||||||
|
using ColorGradient = ostd::ColorGradient;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include <ogfx/ogfx.hpp>
|
#include <ogfx/ogfx.hpp>
|
||||||
|
|
||||||
ostd::ConsoleOutputHandler out;
|
ostd::ConsoleOutputHandler out;
|
||||||
|
using namespace ogfx::gui::widgets;
|
||||||
|
|
||||||
class Window : public ogfx::gui::Window
|
class Window : public ogfx::gui::Window
|
||||||
{
|
{
|
||||||
|
|
@ -63,10 +64,15 @@ class Window : public ogfx::gui::Window
|
||||||
|
|
||||||
m_check1.setText("Check this out!");
|
m_check1.setText("Check this out!");
|
||||||
m_check1.setChecked(true);
|
m_check1.setChecked(true);
|
||||||
m_check1.setStateChangedCallback([&](ogfx::gui::widgets::CheckBox& sender, bool state) -> void {
|
m_check1.setStateChangedCallback([&](CheckBox& sender, bool state) -> void {
|
||||||
m_panel1.setVisible(state);
|
m_panel1.setVisible(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_btn1.setText("BUTTON");
|
||||||
|
m_btn1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
m_label2.setText("Label2");
|
m_label2.setText("Label2");
|
||||||
m_label3.setText("Label3");
|
m_label3.setText("Label3");
|
||||||
|
|
||||||
|
|
@ -80,6 +86,7 @@ class Window : public ogfx::gui::Window
|
||||||
m_panel2.addWidget(m_label3);
|
m_panel2.addWidget(m_label3);
|
||||||
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 });
|
||||||
|
|
||||||
addWidget(m_check1, { 30, 30 });
|
addWidget(m_check1, { 30, 30 });
|
||||||
addWidget(m_panel2, { 30, 100 });
|
addWidget(m_panel2, { 30, 100 });
|
||||||
|
|
@ -101,6 +108,12 @@ class Window : public ogfx::gui::Window
|
||||||
void onRedraw(ogfx::BasicRenderer2D& gfx) override
|
void onRedraw(ogfx::BasicRenderer2D& gfx) override
|
||||||
{
|
{
|
||||||
// gfx.drawAnimation(m_anim, { 200, 200 });
|
// gfx.drawAnimation(m_anim, { 200, 200 });
|
||||||
|
// static f32 angle = 0.0f;
|
||||||
|
// angle += 0.5f; // degrees per frame, adjust to taste
|
||||||
|
// if (angle >= 360.0f) angle = 0.0f;
|
||||||
|
// m_grad.setAngleDeg(angle);
|
||||||
|
|
||||||
|
// gfx.fillGradientRect({ 200, 200, 300, 300 }, m_grad);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFixedUpdate(void) override
|
void onFixedUpdate(void) override
|
||||||
|
|
@ -109,16 +122,28 @@ class Window : public ogfx::gui::Window
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ogfx::gui::widgets::Label m_label1 { *this };
|
Label m_label1 { *this };
|
||||||
ogfx::gui::widgets::Label m_label2 { *this };
|
Label m_label2 { *this };
|
||||||
ogfx::gui::widgets::Label m_label3 { *this };
|
Label m_label3 { *this };
|
||||||
ogfx::gui::widgets::Panel m_panel1 { *this };
|
Panel m_panel1 { *this };
|
||||||
ogfx::gui::widgets::Panel m_panel2 { *this };
|
Panel m_panel2 { *this };
|
||||||
ogfx::gui::widgets::CheckBox m_check1 { *this };
|
CheckBox m_check1 { *this };
|
||||||
|
Button m_btn1 { *this };
|
||||||
|
|
||||||
ostd::Stylesheet m_theme;
|
ostd::Stylesheet m_theme;
|
||||||
ogfx::Animation m_anim;
|
ogfx::Animation m_anim;
|
||||||
ogfx::Image m_img;
|
ogfx::Image m_img;
|
||||||
|
ogfx::ColorGradient m_grad { {
|
||||||
|
{ 255, 0, 0 }, // red
|
||||||
|
{ 255, 165, 0 }, // orange
|
||||||
|
{ 255, 255, 0 }, // yellow
|
||||||
|
{ 0, 255, 0 }, // green
|
||||||
|
{ 0, 0, 255 }, // blue
|
||||||
|
{ 148, 0, 211 }, // violet
|
||||||
|
{ 255, 0, 0 }, // red again to loop cleanly
|
||||||
|
},
|
||||||
|
{ 1, 1, 1, 1, 1, 1 }, // equal weights, gets normalized
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
i32 main(i32 argc, char** argv)
|
i32 main(i32 argc, char** argv)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue