Refactor TextBase to TextStyler mixin.

This commit is contained in:
2025-05-12 17:10:12 -05:00
parent 75f30b062a
commit 0ff787fd95
18 changed files with 371 additions and 203 deletions

View File

@@ -16,6 +16,8 @@
#include <JGL/JGL.h>
#include <JGL/types/Font.h>
#include "../Style/TextStyler.hpp"
using J3ML::LinearAlgebra::Vector2;
namespace JUI {
class TextBase;
@@ -40,22 +42,22 @@ namespace JUI::TextAlign {
}
/// TextBase class, implements core mechanics of drawing text in JUI, and is used by Text Widget class.
class JUI::TextBase {
private:
bool state_redraw = true;
protected:
RenderTarget* text_canvas;
std::string content = "Sample Text";
Color4 text_color = {255,255,255};
float text_outline = 1.f;
Color4 outline_color = {255,255,255};
bool word_wrap = false;
TextAlign::H h_align = TextAlign::H::Left;
TextAlign::V v_align = TextAlign::V::Top;
TextOverflowMode overflow_mode;
JGL::Font set_font = JGL::Fonts::Jupiteroid;
u32 text_size = 12;
protected:
class JUI::TextBase : public TextStyler {
public:
#pragma region Constructors
~TextBase() { delete text_canvas; };
TextBase() : TextStyler(), text_canvas(new RenderTarget({1, 1}, {0,0,0,0})) {};
#pragma endregion
//TextBase() : set_font(JGL::Fonts::Jupiteroid), state_redraw(true), text_canvas(new RenderTarget({1, 1}, {0, 0, 0, 0})) {};
public:
#pragma region Getters
#pragma endregion
public:
#pragma region Setters
#pragma endregion
void Update(float delta);
// I don't know why this function even exists, or why it was public. It lets you circumvent
// the whole purpose of storing the state things are in :/ - Redacted.
void Draw(const Vector2& abs_pos, const Vector2& abs_size, const std::string& content, unsigned int size, const Color4& color);
@@ -63,40 +65,60 @@ protected:
/// Renders the aligned text string within a bounding-box specified by abs_pos (top-left corner), and abs_size.
/// @see Widget::Draw(), Text::Draw().
void Draw(const Vector2& abs_pos, const Vector2& abs_size);
private:
bool state_redraw = true;
protected:
RenderTarget* text_canvas;
std::string content = "Sample Text";
float text_outline = 1.f;
Color4 outline_color = {255,255,255};
bool word_wrap = false;
TextAlign::H h_align = TextAlign::H::Left;
TextAlign::V v_align = TextAlign::V::Top;
TextOverflowMode overflow_mode;
//Color4 text_color = {255,255,255};
//JGL::Font set_font = JGL::Fonts::Jupiteroid;
//u32 text_size = 12;
protected:
public:
[[nodiscard]] std::string GetContent() const;
[[nodiscard]] Color4 GetTextColor() const;
[[nodiscard]] Color4 GetOutlineColor() const;
[[nodiscard]] TextAlign::H GetHorizontalTextAlign() const;
[[nodiscard]] TextAlign::V GetVerticalTextAlign() const;
TextOverflowMode GetOverflowMode() const;
[[nodiscard]] Vector2 GetTextBounds();
[[nodiscard]] Vector2 GetTextPosition() const;
[[nodiscard]] JGL::Font GetFont() const;
[[nodiscard]] u32 GetTextSize() const;
[[nodiscard]] std::string Content() const;
[[nodiscard]] Color4 OutlineColor() const;
[[nodiscard]] TextAlign::H HorizontalTextAlign() const;
[[nodiscard]] TextAlign::V VerticalTextAlign() const;
TextOverflowMode OverflowMode() const;
[[nodiscard]] Vector2 TextBounds();
[[nodiscard]] Vector2 TextPosition() const;
public:
void Update(float delta);
void SetWordWrap(bool wrap);
void SetOverflowMode(const TextOverflowMode& mode);
void SetTextSize(u32 size);
void SetFont(const JGL::Font& font);
void SetContent(const std::string& content);
void SetTextColor(const Color4& color);
void SetOutlineColor(const Color4& color);
void WordWrap(bool wrap);
void OverflowMode(const TextOverflowMode& mode);
void Content(const std::string& content);
/// @note This member is deprecated in favor of TextSize().
void TextSize(int size) override;
/// @note This member is deprecated in favor of Font().
void Font(const JGL::Font& font) override;
/// @note This member is deprecated in favor of TextColor().
void TextColor(const Color4& color) override;
void OutlineColor(const Color4& color);
/// Set the horizontal alignment of this text widget in relation to it's parent,
/// while keeping the text retained inside the parent widget's bounds.
/// @see TextAlign::H
void SetHorizontalTextAlign(const TextAlign::H& align);
void HorizontalTextAlign(const TextAlign::H& align);
/// Set the vertical alignment of this text widget in relation to it's parent,
/// while keeping the text retained inside the parent widget's bounds.
/// @see TextAlign::V
void SetVerticalTextAlign(const TextAlign::V& align);
void VerticalTextAlign(const TextAlign::V& align);
/// Sets the horizontal and vertical alignment of this text widget.
/// @see TextAlign::H and TextAlign::V.
void SetTextAlign(const TextAlign::H& h_align, const TextAlign::V& v_align);
void Align(const TextAlign::H& h_align, const TextAlign::V& v_align);
/// Aligns the text of this widget to the left-hand-side of the parent's bounding box.
/// @see SetHorizontalTextAlign, TextAlign::H
@@ -126,7 +148,5 @@ public:
/// Aligns the text of this widget to the vertical center of the parent's bounding box.
void AlignCenterVertically();
public:
~TextBase() { delete text_canvas; };
TextBase() : set_font(JGL::Fonts::Jupiteroid), state_redraw(true), text_canvas(new RenderTarget({1, 1}, {0, 0, 0, 0})) {};
};

View File

@@ -40,7 +40,7 @@ namespace JUI {
/// and apply a default style in this constructor. Be aware of this, as this is not "idiomatic C++".
Widget();
/// Construct a new widget by specifying it's parent,
Widget(Widget* parent);
explicit Widget(Widget* parent);
virtual ~Widget() {}
public:
#pragma region Events
@@ -366,8 +366,8 @@ namespace JUI {
UDim2 position = {0_px, 0_px};
UDim2 size = {50_px, 50_px};
Widget* parent = nullptr;
std::vector<Widget*> children;
std::vector<Tween*> tweens;
std::vector<Widget*> children{};
std::vector<Tween*> tweens{};
float rotation = 0;
std::string name;
bool selected = false;

View File

@@ -1,20 +0,0 @@
#pragma once
namespace JUI {
// TODO: Observe and design all the base interfaces for various style categories.
/// Defines interface for widgets with textual elements which are to be styled as a group.
class TextStyleInterface {
public:
virtual ~TextStyleInterface() = default;
virtual JGL::Font Font() const = 0;
virtual int TextSize() const = 0;
virtual Color4 TextColor() const = 0;
virtual bool WordWrap() const = 0;
virtual void Font(const JGL::Font& value) = 0;
virtual void TextSize(int value) = 0;
virtual void TextColor(const Color4& color) = 0;
};
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include <Color4.hpp>
#include <Colors.hpp>
#include "JGL/JGL.h"
#include "JGL/types/Font.h"
namespace JUI {
struct TextStyle {
Color4 color;
JGL::Font font;
int size;
};
/// Defines interface for widgets with textual elements.
/// Any object that renders text will use these methods to apply style.
class TextStyler {
public:
virtual ~TextStyler() = default;
public:
#pragma region Getters
/// @returns the font of this widget.
virtual JGL::Font Font() const;
/// @return The text-point-size of this widget.
virtual int TextSize() const;
/// @return The text-color of this widget. @see class Color4.
virtual Color4 TextColor() const;
#pragma endregion
public:
#pragma region Setters
virtual void Font(const JGL::Font& value);
virtual void TextSize(int value);
virtual void TextColor(const Color4& color);
virtual void Style(const JGL::Font& font, int size, const Color4& color);
#pragma endregion
protected:
JGL::Font font = Fonts::Jupiteroid;
int text_size = 12;
Color4 text_color = Colors::White;
};
}

View File

@@ -3,25 +3,60 @@
#include <JUI/Widgets/Rect.hpp>
#include <JUI/Widgets/TextRect.hpp>
#include <JUI/Widgets/ListLayout.hpp>
#include <JUI/Widgets/Text.hpp>
#include "../Style/TextStyler.hpp"
namespace JUI {
std::string rgb2hex(int r, int g, int b, bool with_head)
{
std::stringstream ss;
if (with_head)
ss << "#";
ss << std::hex << (r << 16 | g << 8 | b );
return ss.str();
}
/// A JUI Widget that displays a HSV color input dialog.
class ColorPicker : public Rect {
class ColorPicker : public Rect, public TextStyler {
public:
void Font(const JGL::Font &value) override {
TextStyler::Font(value);
hue_label->Font(value);
sat_label->Font(value);
bri_label->Font(value);
hex_label->Font(value);
}
void TextSize(int size) override {
TextStyler::TextSize(size);
hue_label->TextSize(size);
sat_label->TextSize(size);
bri_label->TextSize(size);
hex_label->TextSize(size);
}
void TextColor(const Color4 &color) override {
TextStyler::TextColor(color);
hue_label->TextColor(color);
sat_label->TextColor(color);
bri_label->TextColor(color);
hex_label->TextColor(color);
}
Event<Color4> OnColorValueChanged;
void SetColorValue(const Color4& color);
Color4 GetColorValue() const;
JUI::TextRect* hex_label;
float hue = 0;
float sat = 1.f;
float bri = 1.f; // AKA val
ColorPicker() : Rect() {
Name("ColorPicker");
Size({100_percent, 100_percent});
auto* row_layout = new JUI::VerticalListLayout(this);
@@ -32,73 +67,101 @@ namespace JUI {
hue_slider->Minimum(0.f); hue_slider->Maximum(1.f);
hue_slider->Interval(1e-3f);
hue_slider->ValueChanged += [this] (float val) mutable {
hue_label->SetContent(std::format("Hue: {}", Math::FloorInt(val*360)));
hue_label->Content(std::format("Hue: {}", Math::FloorInt(val*360)));
hue = val * 360;
hue_slider->ScrubberColor(Color4::FromHSV(hue, 1.f, 1.f));
OnColorValueChanged.Invoke(Color4::FromHSV(hue, sat, bri));
Color4 computed = Color4::FromHSV(hue, sat, bri);
hex_label->TextColor(computed);
hex_label->Content(std::format("{}", rgb2hex(computed.r, computed.g, computed.b, true)));
};
hue_label = new JUI::Text(hue_slider);
hue_label->AlignCenterHorizontally();
hue_label->AlignTop();
hue_label->SetTextColor(Colors::Black);
hue_label->SetContent("Hue: 0");
hue_label->TextColor(Colors::Black);
hue_label->Content("Hue: 0");
sat_slider = new JUI::Slider(row_layout);
sat_slider->Size({100_percent, 28_px});
sat_slider->Minimum(0); sat_slider->Maximum(1);
sat_slider->Interval(1e-3f);
sat_slider->ValueChanged += [this] (float val) mutable {
sat_label->SetContent(std::format("Saturation: {}%", val*100.f));
sat_label->Content(std::format("Saturation: {}%", Math::Floor(val*100.f)));
sat = val;
OnColorValueChanged.Invoke(Color4::FromHSV(hue, sat, bri));
Color4 computed = Color4::FromHSV(hue, sat, bri);
hex_label->TextColor(computed);
hex_label->Content(std::format("{}", rgb2hex(computed.r, computed.g, computed.b, true)));
};
sat_label = new JUI::Text(sat_slider);
sat_label->AlignCenterHorizontally();
sat_label->AlignTop();
sat_label->SetTextColor(Colors::Black);
sat_label->SetContent("Saturation: 100%");
sat_label->TextColor(Colors::Black);
sat_label->Content("Saturation: 100%");
bri_slider = new JUI::Slider(row_layout);
bri_slider->Size({100_percent, 28_px});
bri_slider->Minimum(0); bri_slider->Maximum(1);
bri_slider->Interval(1e-3f);
bri_slider->ValueChanged += [this] (float val) mutable {
bri_label->SetContent(std::format("Brightness: {}%", val*100.f));
bri_label->Content(std::format("Brightness: {}%", Math::Floor(val*100.f)));
bri = val;
OnColorValueChanged.Invoke(Color4::FromHSV(hue, sat, bri));
Color4 computed = Color4::FromHSV(hue, sat, bri);
hex_label->TextColor(computed);
hex_label->Content(std::format("{}", rgb2hex(computed.r, computed.g, computed.b, true)));
};
bri_label = new JUI::Text(bri_slider);
bri_label->AlignCenterHorizontally();
bri_label->AlignTop();
bri_label->SetTextColor(Colors::Black);
bri_label->SetContent("Brightness: 100%");
bri_label->TextColor(Colors::Black);
bri_label->Content("Brightness: 100%");
//auto* hue_box = new JUI::Rect();
auto* hue_box = new JUI::Rect();
hex_label = new JUI::TextRect(row_layout);
hex_label->AlignCenterHorizontally();
hex_label->Size({100_percent, 28_px});
hex_label->Content("#FFZZGG");
}
explicit ColorPicker(Widget* parent) : ColorPicker() {
Parent(parent);
}
public: /// Subcomponents.
/*JUI::Text* HueLabel() { return hue_label; }
JUI::Text* SatLabel() { return sat_label; }
JUI::Text* BriLabel() { return bri_label; }
JUI::Slider* HueSlider() { return hue_slider; }
JUI::Slider* SatSlider() { return sat_slider; }
JUI::Slider* BriSlider() { return bri_slider; }
JUI::TextRect* HexLabel() { return hex_label; }*/
protected:
JUI::Slider* hue_slider;
JUI::Slider* sat_slider;
JUI::Slider* bri_slider;
JUI::Text* hue_label;
JUI::Text* sat_label;
JUI::Text* bri_label;
JUI::Slider* hue_slider = nullptr;
JUI::Slider* sat_slider = nullptr;
JUI::Slider* bri_slider = nullptr;
JUI::Text* hue_label = nullptr;
JUI::Text* sat_label = nullptr;
JUI::Text* bri_label = nullptr;
JUI::TextRect* hex_label = nullptr;
private:
};
}
}

View File

@@ -16,7 +16,7 @@
#include "ListLayout.hpp"
#include "Separator.hpp"
#include "JUI/Mixins/Pinnable.hpp"
#include "JUI/Mixins/TextStyleInterface.hpp"
#include "../Style/TextStyler.hpp"
namespace JUI {
@@ -58,7 +58,7 @@ namespace JUI {
// TODO: Work in progress.
void PropogateTextSize(int value) {
for (auto* child : children) {
TextStyleInterface* textual = dynamic_cast<TextStyleInterface *>(child);
TextStyler* textual = dynamic_cast<TextStyler *>(child);
if (textual)
textual->TextSize(value);

View File

@@ -148,6 +148,10 @@ namespace JUI {
this->BGColor(Style::Window::UnfocusedOutlineColor);
}
/// @return whether this window will consume this observed mouse movement.
/// @note This is to prevent a user-mouse-action from being picked up by multiple widgets.
bool ObserveMouseMovement(const Vector2 &latest_known_pos) override;
bool ObserveMouseInput(JUI::MouseButton btn, bool pressed) override
{
// TODO: Consider how this plays with Clickable::OnClick and Clickable::OnRelease

126
main.cpp
View File

@@ -34,6 +34,8 @@
#include <JUI/Widgets/Collapsible.hpp>
#include <JUI/Widgets/CommandLine.hpp>
#include "JUI/Widgets/ColorPicker.hpp"
using namespace JUI;
@@ -41,16 +43,16 @@ float ui_scale = 1.f;
float accum = 0;
int iter = 0;
JUI::Scene* scene;
JGL::Texture* sample_texture;
JGL::Texture* slicer;
JUI::VerticalListLayout* list;
JUI::Window* scroller_window;
JUI::ScrollingRect* scroller;
JUI::TextRect* widget_count;
JUI::CommandLine* console;
JUI::Window* nineslice_demo_window;
JUI::UtilityBar* topbar;
JUI::Scene* scene = nullptr;
JGL::Texture* sample_texture = nullptr;
JGL::Texture* slicer = nullptr;
JUI::VerticalListLayout* list = nullptr;
JUI::Window* scroller_window = nullptr;
JUI::ScrollingRect* scroller = nullptr;
JUI::TextRect* widget_count = nullptr;
JUI::CommandLine* console = nullptr;
JUI::Window* nineslice_demo_window = nullptr;
JUI::UtilityBar* topbar = nullptr;
/// Returns the sum total of widgets that are considered "descendnats" of the given widget.
/// A descendant is classified as being a child, or child of a child, and so on, of a given widget.
@@ -75,20 +77,20 @@ JUI::Window* CreateInfoboxWindow(JUI::Widget* root) {
auto make_dialog_btn = [controls_layout] (const std::string& label) {
auto* btn = new JUI::TextButton(controls_layout);
btn->SetContent(label);
btn->Content(label);
//btn->Position({100_percent - 125_px, 100_percent - 20_px});
// TODO: AUTO SIZE - HORIZONTAL.
btn->Size({125_px, 20_px});
btn->SetTextColor(Colors::Black);
btn->TextColor(Colors::Black);
return btn;
};
auto* ok_btn = new JUI::TextButton(controls_layout);
ok_btn->SetContent("OK, Stop Yapping.");
ok_btn->Content("OK, Stop Yapping.");
ok_btn->Position({100_percent - 125_px, 100_percent - 20_px});
ok_btn->Size({125_px, 20_px});
ok_btn->SetTextColor(Colors::Black);
ok_btn->TextColor(Colors::Black);
ok_btn->OnClickEvent += [window] (...) mutable {
window->Close();
};
@@ -123,15 +125,15 @@ JUI::Window* CreateNinesliceWindow(JUI::Widget* root) {
auto* darkie = new JUI::Image(nineslice_demo_window->ViewportInstance(), sample_texture); {
darkie->FitImageToParent(true);
darkie->Color({255,255,255,128});
auto* list = new VerticalListLayout(nineslice_demo_window->ViewportInstance()); {
list->Padding(10_px);
TextRect* a = new TextRect(list); {
a->SetTextSize(16); a->Size({0, 20, 1, 0}); a->Center();
a->SetContent("This is a virtual window.");
auto* t_list = new VerticalListLayout(nineslice_demo_window->ViewportInstance()); {
t_list->Padding(10_px);
TextRect* a = new TextRect(t_list); {
a->TextSize(16); a->Size({0, 20, 1, 0}); a->Center();
a->Content("This is a virtual window.");
}
TextRect* b = new TextRect(list); {
b->SetTextSize(16); b->Size({0, 20, 1, 0}); b->Center();
b->SetContent("You can drag it around via left-click, and resize via right-click. Isn't that cool??");
TextRect* b = new TextRect(t_list); {
b->TextSize(16); b->Size({0, 20, 1, 0}); b->Center();
b->Content("You can drag it around via left-click, and resize via right-click. Isn't that cool??");
}
}
}
@@ -188,7 +190,7 @@ JUI::UtilityBar* CreateUtilityBar(JUI::Widget* root) {
widget_count->AnchorPoint({1, 0});
widget_count->Position({100_percent, 0_percent});
widget_count->BGColor(Colors::Transparent);
widget_count->SetTextColor(Colors::Black);
widget_count->TextColor(Colors::Black);
widget_count->BorderColor(Colors::Transparent);
widget_count->BorderWidth(0);
widget_count->Center();
@@ -217,26 +219,26 @@ JUI::Rect* CreateWidgetList(JUI::Widget* root) {
auto* button = new TextButton(btn_h_layout1);
//button->Position({5, 105, 0, 0});
button->Size({0, 20, 0.32f, 0});
button->SetTextColor(Colors::Black);
button->SetContent("Button");
button->TextColor(Colors::Black);
button->Content("Button");
button->AlignLeft();
//button->Padding(5_px);
auto* tt2 = new JUI::Tooltip(button);
tt2->SetContent("Test 123");
tt2->Content("Test 123");
auto* button2 = new TextButton(btn_h_layout1);
//button2->Position({5, 105, 0, 0});
button2->Size({0, 20, 0.32f, 0});
button2->SetTextColor(Colors::Black);
button2->SetContent("Button");
button2->TextColor(Colors::Black);
button2->Content("Button");
button2->AlignCenterHorizontally();
auto* button3 = new TextButton(btn_h_layout1);
//button2->Position({5, 105, 0, 0});
button3->Size({0, 20, 0.32f, 0});
button3->SetTextColor(Colors::Black);
button3->SetContent("Button");
button3->TextColor(Colors::Black);
button3->Content("Button");
button3->AlignRight();
auto* btn_container2 = new Rect(column_layout);
@@ -249,24 +251,24 @@ JUI::Rect* CreateWidgetList(JUI::Widget* root) {
auto* button4 = new TextButton(btn_h_layout2);
//button->Position({5, 105, 0, 0});
button4->Size({0, 20, 0.32f, 0});
button4->SetTextColor(Colors::Black);
button4->SetContent("Button");
button4->TextColor(Colors::Black);
button4->Content("Button");
button4->AlignLeft();
//button4->CornerRounding(4);
auto* button5 = new TextButton(btn_h_layout2);
//button2->Position({5, 105, 0, 0});
button5->Size({0, 20, 0.32f, 0});
button5->SetTextColor(Colors::Black);
button5->SetContent("Button");
button5->TextColor(Colors::Black);
button5->Content("Button");
button5->AlignCenterHorizontally();
//button5->CornerRounding(4);
auto* button6 = new TextButton(btn_h_layout2);
//button2->Position({5, 105, 0, 0});
button6->Size({0, 20, 0.32f, 0});
button6->SetTextColor(Colors::Black);
button6->SetContent("Button");
button6->TextColor(Colors::Black);
button6->Content("Button");
button6->AlignRight();
//button6->CornerRounding(4);
@@ -277,7 +279,7 @@ JUI::Rect* CreateWidgetList(JUI::Widget* root) {
checkbox_horiz->Padding(2_px);
auto* label = new TextRect(checkbox_horiz);
label->SetContent("Checkboxes");
label->Content("Checkboxes");
label->BorderWidth(0);
label->AutoFitSizeToText(true);
@@ -294,8 +296,8 @@ JUI::Rect* CreateWidgetList(JUI::Widget* root) {
auto* input_form = new TextInputForm(column_layout);
input_form->Size({0,24, 1, 0});
input_form->SetContent("");
input_form->SetTextSize(14);
input_form->Content("");
input_form->TextSize(14);
auto* collapsible = new Collapsible(column_layout);
collapsible->Size({100_percent, 200_px});
@@ -313,8 +315,8 @@ JUI::Rect* CreateWidgetList(JUI::Widget* root) {
radio_a_label->BorderWidth(0);
radio_a_label->Size({20_px, 20_px});
radio_a_label->AutoFitSizeToText(true);
radio_a_label->SetContent("A ");
radio_a_label->SetTextSize(12);
radio_a_label->Content("A ");
radio_a_label->TextSize(12);
auto* radio_b_btn = new Checkbox(radio_btn_set_layout);
radio_b_btn->Size({20_px, 20_px});
@@ -323,38 +325,42 @@ JUI::Rect* CreateWidgetList(JUI::Widget* root) {
radio_b_label->BorderWidth(0);
radio_b_label->Size({20_px, 20_px});
radio_b_label->AutoFitSizeToText(true);
radio_b_label->SetContent("B ");
radio_b_label->SetTextSize(12);
radio_b_label->Content("B ");
radio_b_label->TextSize(12);
auto* radio_c_btn = new Checkbox(radio_btn_set_layout);
radio_c_btn->Size({20_px, 20_px});
auto* radio_c_label = new TextRect(radio_btn_set_layout);
// What the FUCK?
/*auto* radio_c_label = new TextRect(radio_btn_set_layout);
radio_c_label->BorderWidth(0);
radio_c_label->Size({20_px, 20_px});
radio_c_label->AutoFitSizeToText(true);
radio_c_label->SetContent("C ");
radio_c_label->SetTextSize(12);
radio_c_label->SetTextSize(12);*/
return widget_list;
}
JUI::Window* CreateScrollDemoWindow(Widget* root) {
auto* scroller_demo = new JUI::Window(root);
scroller_demo->Name("ScrollDemo Window");
scroller_demo->Position({10_percent, 10_percent});
scroller_demo->Size({30_percent, 25_percent});
scroller_demo->SetTitle("ScrollingRect Demonstration");
Tween* t = scroller_demo->TweenPosition({50_percent, 50_percent}, {.time = 5});
/*Tween* t = scroller_demo->TweenPosition({50_percent, 50_percent}, {.time = 5});
t->Completed += [] () { std::cout << "Tween type test!!" << std::endl; };
scroller = new JUI::ScrollingRect(scroller_demo->ViewportInstance());
scroller = new JUI::ScrollingRect(scroller_demo->Content());
scroller->Size({100_percent, 100_percent});
scroller->BGColor(Colors::Reds::LightCoral);
list = new JUI::VerticalListLayout(scroller);
list->LayoutOrder(JUI::LayoutOrder::V::BOTTOM);
list->LayoutOrder(JUI::LayoutOrder::V::BOTTOM);*/
return scroller_demo;
}
@@ -368,21 +374,27 @@ JUI::Scene* CreateScene() {
auto *root = new Scene();
auto* colorpicker_wnd = new JUI::Window(root);
colorpicker_wnd->Name("Slider ColorPicker");
colorpicker_wnd->Size({100_px, 150_px});
colorpicker_wnd->MinSize({100, 150});
auto* cpicker = new JUI::ColorPicker(colorpicker_wnd->Content());
topbar = CreateUtilityBar(root);
nineslice_demo_window = CreateNinesliceWindow(root);
scroller_window = CreateScrollDemoWindow(root);
CreateInfoboxWindow(root);
// TODO: This instance will segfault on it's first call to be updated and I have **NO** idea why...
//scroller_window = CreateScrollDemoWindow(root);
CreateInfoboxWindow(root);
console = new JUI::CommandLine(root); {
console->Close();
JUI::UILogs.OnLog += [&] (const std::string& msg, Color4 c){ console->Log(msg, c);};
}
auto* widget_list = CreateWidgetList(root);
@@ -424,7 +436,7 @@ public:
void Update(float elapsed)
{
widget_count->SetContent(std::format("Widgets: {}", count_descendants(scene)));
widget_count->Content(std::format("Widgets: {}", count_descendants(scene)));
using namespace JUI::UDimLiterals;
@@ -437,16 +449,14 @@ public:
if (accum > 1.f) {
iter--;
accum = 0.f;
auto* text = new JUI::TextRect(list);
/*auto* text = new JUI::TextRect(list);
text->Size({50_percent, 20_px});
text->ZIndex(iter);
text->LayoutOrder(-iter);
text->SetContent(std::format("{} Sampled Delta: {}ms", -iter, Math::Floor(elapsed*1000.f)));
scroller->canvas_height += text->GetAbsoluteSize().y;
scroller->canvas_height += text->GetAbsoluteSize().y;*/
}
}
void Draw()

View File

@@ -2,45 +2,43 @@
#include <JGL/JGL.h>
using namespace JUI;
void TextBase::SetContent(const std::string& content) { this->content = content; state_redraw = true; }
void TextBase::Content(const std::string& content) { this->content = content; state_redraw = true; }
void TextBase::SetTextColor(const Color4& color) { this->text_color = color; state_redraw = true; }
void TextBase::OutlineColor(const Color4& color) { this->outline_color = color; }
void TextBase::SetOutlineColor(const Color4& color) { this->outline_color = color; }
void TextBase::HorizontalTextAlign(const TextAlign::H& align) { this->h_align = align;}
void TextBase::SetHorizontalTextAlign(const TextAlign::H& align) { this->h_align = align;}
void TextBase::VerticalTextAlign(const TextAlign::V& align) { this->v_align = align; }
void TextBase::SetVerticalTextAlign(const TextAlign::V& align) { this->v_align = align; }
void TextBase::SetTextAlign(const TextAlign::H& h_align, const TextAlign::V& v_align) {
SetHorizontalTextAlign(h_align);
SetVerticalTextAlign(v_align);
void TextBase::Align(const TextAlign::H& h_align, const TextAlign::V& v_align) {
HorizontalTextAlign(h_align);
VerticalTextAlign(v_align);
}
void TextBase::AlignLeft() { SetHorizontalTextAlign(TextAlign::H::Left); }
void TextBase::AlignLeft() { HorizontalTextAlign(TextAlign::H::Left); }
void TextBase::AlignRight() { SetHorizontalTextAlign(TextAlign::H::Right); }
void TextBase::AlignRight() { HorizontalTextAlign(TextAlign::H::Right); }
void TextBase::AlignTop() { SetVerticalTextAlign(TextAlign::V::Top); }
void TextBase::AlignTop() { VerticalTextAlign(TextAlign::V::Top); }
void TextBase::AlignBottom() { SetVerticalTextAlign(TextAlign::V::Bottom); }
void TextBase::AlignBottom() { VerticalTextAlign(TextAlign::V::Bottom); }
void TextBase::AlignCenterBoth() {
SetVerticalTextAlign(TextAlign::V::Center);
SetHorizontalTextAlign(TextAlign::H::Center);
VerticalTextAlign(TextAlign::V::Center);
HorizontalTextAlign(TextAlign::H::Center);
}
void TextBase::Center() { AlignCenterBoth(); }
void TextBase::AlignCenterHorizontally() {
SetHorizontalTextAlign(TextAlign::H::Center);
HorizontalTextAlign(TextAlign::H::Center);
}
void TextBase::AlignCenterVertically() {
SetVerticalTextAlign(TextAlign::V::Center);
VerticalTextAlign(TextAlign::V::Center);
}
void TextBase::SetWordWrap(bool wrap) { word_wrap = wrap; }
void TextBase::WordWrap(bool wrap) { word_wrap = wrap; }
void TextBase::Draw(const Vector2& abs_pos, const Vector2& abs_size, const std::string& content, unsigned int size, const Color4& color) {
// Calculate how much to origin the text based on alignment.
@@ -62,7 +60,7 @@ void TextBase::Draw(const Vector2& abs_pos, const Vector2& abs_size, const std::
}*/
auto bounds = this->GetFont().MeasureString(content, size);
auto bounds = TextStyler::Font().MeasureString(content, size);
// Do nothing if there is no text.
if (bounds.x == 0 || bounds.y == 0)
return;
@@ -96,7 +94,7 @@ void TextBase::Draw(const Vector2& abs_pos, const Vector2& abs_size, const std::
if (state_redraw) {
text_canvas->Resize({(int) bounds.x, (int) bounds.y});
J2D::Begin(text_canvas, true);
J2D::DrawString(color, content, 0, 0, scale, size, this->set_font);
J2D::DrawString(color, content, 0, 0, scale, size, this->font);
J2D::End();
state_redraw = false;
}
@@ -107,7 +105,7 @@ void TextBase::Draw(const Vector2& abs_pos, const Vector2& abs_size, const std::
//J2D::Begin();
//J2D::OutlineRect(color, text_pos, bounds); // Draw bounding box for debugging.
use_render_target ? J2D::DrawRenderTarget(text_canvas, {align_x, align_y})
: J2D::DrawString(color, content, align_x, align_y, scale, size, this->set_font);
: J2D::DrawString(color, content, align_x, align_y, scale, size, this->font);
//J2D::End();
}
@@ -115,29 +113,30 @@ void TextBase::Draw(const Vector2& abs_pos, const Vector2& abs_size) {
Draw(abs_pos, abs_size, this->content, this->text_size, this->text_color);
}
std::string TextBase::GetContent() const { return content; }
std::string TextBase::Content() const { return content; }
Color4 TextBase::GetTextColor() const { return text_color; }
Color4 TextBase::GetOutlineColor() const { return outline_color; }
Color4 TextBase::OutlineColor() const { return outline_color; }
TextAlign::H TextBase::GetHorizontalTextAlign() const { return h_align; }
TextAlign::H TextBase::HorizontalTextAlign() const { return h_align; }
TextAlign::V TextBase::GetVerticalTextAlign() const { return v_align; }
TextAlign::V TextBase::VerticalTextAlign() const { return v_align; }
Vector2 TextBase::GetTextBounds() { return GetFont().MeasureString(content, text_size); }
Vector2 TextBase::TextBounds() { return TextStyler::Font().MeasureString(content, text_size); }
JGL::Font TextBase::GetFont() const { return set_font; }
u32 TextBase::GetTextSize() const { return text_size; }
void TextBase::SetFont(const JGL::Font& font) {
set_font = font;
void TextBase::Font(const JGL::Font& font) {
TextStyler::Font(font);
state_redraw = true;
}
void TextBase::SetTextSize(u32 size) {
text_size = size;
void TextBase::TextSize(int size) {
TextStyler::TextSize(size);
state_redraw = true;
}
void TextBase::TextColor(const Color4& color) {
TextStyler::TextColor(color);
state_redraw = true;
}

View File

@@ -8,7 +8,7 @@ Widget::Widget() {
name = "Widget";
children = std::vector<Widget *>();
}
Widget::Widget(Widget* parent) : Widget() {
Widget::Widget(Widget* parent) : Widget() {
this->Parent(parent);
}
@@ -293,12 +293,12 @@ zIndexSort;
void Widget::DrawChildWidgets() {
std::sort(children.begin(), children.end(), zIndexSort);
for (auto child : children)
for (auto* child : children)
child->Draw();
}
void Widget::UpdateChildWidgets(float delta) {
for (auto child : children)
for (auto* child : children)
child->Update(delta);
}
@@ -428,7 +428,7 @@ AABB2D Widget::GetActualRenderBounds() const {
void Widget::SetViewportSize(const Vector2 &vps) {
viewport_size = vps;
for(auto& child : children)
for(auto* child : children)
child->SetViewportSize(viewport_size);
}

View File

@@ -0,0 +1,25 @@
#include <JUI/Style/TextStyler.hpp>
JGL::Font JUI::TextStyler::Font() const { return font;}
int JUI::TextStyler::TextSize() const { return text_size; }
Color4 JUI::TextStyler::TextColor() const { return text_color; }
void JUI::TextStyler::Font(const JGL::Font &value) {
font = value;
}
void JUI::TextStyler::TextSize(int value) {
text_size = value;
}
void JUI::TextStyler::TextColor(const Color4 &color) {
text_color = color;
}
void JUI::TextStyler::Style(const JGL::Font &font, int size, const Color4 &color) {
Font(font);
TextSize(size);
TextColor(color);
}

View File

@@ -29,13 +29,14 @@ namespace JUI {
TextButton * ContextMenu::AddButton(const std::string &name) {
auto* line_item = new TextButton(layout);
line_item->SetFont(font);
line_item->SetContent(name);
line_item->SetTextSize(16);
line_item->SetTextColor(Colors::Black);
line_item->Style(font, 16, Colors::Black);
line_item->Font(font);
line_item->Content(name);
line_item->TextSize(16);
line_item->TextColor(Colors::Black);
line_item->Size({0, 20, 1, 0});
float line_width = GuesstimateTextWidth(line_item->GetContent(), line_item->GetTextSize());
float line_width = GuesstimateTextWidth(line_item->Content(), line_item->TextStyler::TextSize());
if (line_width > estimated_width)
estimated_width = line_width + 10;

View File

@@ -5,7 +5,9 @@ namespace JUI
ListLayout::ListLayout() : LayoutContainer() {
Name("ListLayout");
}
ListLayout::ListLayout(Widget* parent) : ListLayout() {}
ListLayout::ListLayout(Widget* parent) : ListLayout() {
Parent(parent);
}
VerticalListLayout::VerticalListLayout() : ListLayout() {}
VerticalListLayout::VerticalListLayout(Widget* parent) : VerticalListLayout() {

View File

@@ -95,12 +95,13 @@ const Vector2i default_initialize_canvas_size {1024, 4096};
ScrollingRect::~ScrollingRect() { delete canvas; }
ScrollingRect::ScrollingRect() : canvas(new RenderTarget(default_initialize_canvas_size)) {
ScrollingRect::ScrollingRect() : Rect(), canvas(new RenderTarget(default_initialize_canvas_size)) {
Name("ScrollingRect");
//bool success = canvas->SetMSAAEnabled(JGL::SampleRate::X8);
}
ScrollingRect::ScrollingRect(Widget *parent) : Rect(parent), canvas(new RenderTarget(default_initialize_canvas_size)) {
ScrollingRect::ScrollingRect(Widget *parent) : ScrollingRect() {
Parent(parent);
//bool success = canvas->SetMSAAEnabled(JGL::MSAA_SAMPLE_RATE::MSAA_8X);
}

View File

@@ -96,9 +96,9 @@ namespace JUI {
std::string result = input_buffer;
result.insert(cursor_position, 1, '|');
SetContent(result);
Content(result);
} else {
SetContent(input_buffer);
Content(input_buffer);
}
}
}

View File

@@ -27,7 +27,7 @@ namespace JUI {
pad_bottom.Pixels + (pad_right.Scale * abs_size.y)
};
Vector2 size = this->set_font.MeasureString(this->content, this->text_size);
Vector2 size = this->font.MeasureString(this->content, this->text_size);
//size += pad_shrinks_size_by*2.f;
if (abs_size.x < size.x)

View File

@@ -45,12 +45,12 @@ namespace JUI {
auto str_width = Fonts::Jupiteroid.MeasureString(name, 14);
auto* btn = new TextButton(layout);
btn->SetFont(Fonts::Jupiteroid);
btn->SetTextSize(14);
btn->SetTextColor(Colors::Black);
btn->Font(Fonts::Jupiteroid);
btn->TextSize(14);
btn->TextColor(Colors::Black);
btn->Size({static_cast<int>(str_width.x)+16, 0, 0, 1});
btn->BorderWidth(0.f);
btn->SetContent(name);
btn->Content(name);
//buttons.push_back(btn);

View File

@@ -43,8 +43,8 @@ namespace JUI {
TitleLabel = new Text(Topbar);
TitleLabel->Center();
TitleLabel->SetContent(title);
TitleLabel->SetTextSize(title_font_size);
TitleLabel->Content(title);
TitleLabel->TextSize(title_font_size);
// TODO: Pull out this circle image generation code, make a Circle widget.
@@ -125,7 +125,7 @@ namespace JUI {
}
void Window::SetTitleFont(const Font& f) {
TitleLabel->SetFont(f);
TitleLabel->Font(f);
//exit_btn->SetFont(f);
}
@@ -233,7 +233,7 @@ namespace JUI {
}
void Window::SetTitle(const std::string &title) {
TitleInstance()->SetContent(title);
TitleInstance()->Content(title);
}
void Window::MinSize(const Vector2 &constraint) {
@@ -316,5 +316,23 @@ namespace JUI {
void Window::Open() { SetOpen(true); }
bool Window::ObserveMouseMovement(const Vector2 &latest_known_pos) {
/// 1. If dragging or resizing, or check if any children are observing.
if (!this->visible && !this->focused)
return false;
if (Widget::ObserveMouseMovement(latest_known_pos))
return true;
if (dragging || resizing)
return true;
return false;
}
bool Window::IsOpen() const { return open;}
}