Refactoring in progress

This commit is contained in:
2024-10-12 19:35:17 -04:00
parent 67fa678ca6
commit 07725ded44
20 changed files with 264 additions and 259 deletions

View File

@@ -7,19 +7,19 @@
/// @file Widget.hpp
/// @desc Base Widget Class - All JUI widgets extend their behavior from this class.
/// @edit 2024-07-31
/// @edit 2024-10-11
#pragma once
#include <Event.h>
#include <string>
#include <vector>
#include "J3ML/LinearAlgebra.hpp"
#include "JUI/UDim2.hpp"
#include <J3ML/LinearAlgebra.hpp>
#include <JUI/UDim2.hpp>
#include <Color3.hpp>
#include <Color4.hpp>
#include <JGL/JGL.h>
using namespace JGL;
namespace JUI
@@ -72,7 +72,7 @@ namespace JUI
bool IsAncestorOf(Widget* descendant) const;
bool IsDescendantOf(Widget* ancestor) const;
/// Returns the first child widget that has the given symbolic name, Otherwise, a nullpointer is returned
/// Returns the first child widget that has the given symbolic name
std::optional<Widget*> FindFirstChild(const std::string& name);
/// Returns a flat list of all nodes that are lower in the hierarchy list.
@@ -96,8 +96,8 @@ namespace JUI
/// @see class UDim2, Position(const UDim2&),
[[nodiscard]] UDim2 Position() const;
/// Retrieves this widgets z-index. This value determines the order in which a widget
/// renders to the screen relative to other Widgets.
/// Returns the Z-Index of this widget.
/// This value determines the order in which a widget renders to the screen relative to other Widgets.
/// @note This applies in ascending priority order,
/// meaning lower values are rendered first, placing higher values on top of lower values.
/// @note The range of valid values is -MAX_INT to MAX_INT.
@@ -107,23 +107,23 @@ namespace JUI
/// Sets this widgets z-index.
/// @see ZIndex().
void SetZIndex(int zindex);
void ZIndex(int);
/// Returns the menu-coordinates that are used to size this widget in relation to its parent.
/// @see SetSize(), class UDim2
/// @see Size(), class UDim2
[[nodiscard]] UDim2 Size() const;
/// Sets the widgets pixel and scalar position using a combined data type.
/// This position is centered around the object's anchor point.
/// @see Position(), SetAnchorPoint(), GetAnchorPoint(), class UDim2.
void SetPosition(const UDim2 &pos);
/// @see Position(), AnchorPoint(), AnchorPoint(), class UDim2.
void Position(const UDim2&);
/// Sets this widget's pixel and scalar size using a combined data type.
/// @see Size(), class UDim2.
void SetSize(const UDim2 &s);
void Size(const UDim2&);
/// Sets the parent object of this widget. Positioning and sizing of a widget is relative to it's parent.
void SetParent(Widget*);
void Parent(Widget*);
/// Returns true if this widget is a 'descendant' of the specified potential ancestor. Otherwise returns false.
bool IsDescendantOf(Widget *ancestor);
@@ -132,82 +132,81 @@ namespace JUI
bool IsAncestorOf(Widget *descendant);
/// Determines the origin point of a Widget, relative to it's absolute size.
[[nodiscard]] Vector2 GetAnchorPoint() const;
[[nodiscard]] Vector2 AnchorPoint() const;
/// Returns the padding factor on the left of this widget.
/// @see SetPaddingLeft(), class UDim.
[[nodiscard]] UDim GetPaddingLeft() const;
/// @see PaddingLeft(), class UDim.
[[nodiscard]] UDim PaddingLeft() const;
/// Returns the padding factor on the top of this widget.
/// @see SetPaddingTop(), class UDim.
[[nodiscard]] UDim GetPaddingTop() const;
/// @see PaddingTop(), class UDim.
[[nodiscard]] UDim PaddingTop() const;
/// Returns the padding factor on the right of this widget.
/// @see SetPaddingRight(), class UDim.
[[nodiscard]] UDim GetPaddingRight() const;
/// @see PaddingRight(), class UDim.
[[nodiscard]] UDim PaddingRight() const;
/// Returns the padding factor on the bottom of this widget.
/// @see SetPaddingBottom(), class UDim.
[[nodiscard]] UDim GetPaddingBottom() const;
/// @see PaddingBottom(), class UDim.
[[nodiscard]] UDim PaddingBottom() const;
void SetPaddingLeft(const UDim &pad_left);
void SetPaddingTop(const UDim &pad_top);
void SetPaddingRight(const UDim &pad_right);
void SetPaddingBottom(const UDim &pad_bottom);
void PaddingLeft(const UDim &pad_left);
void PaddingTop(const UDim &pad_top);
void PaddingRight(const UDim &pad_right);
void PaddingBottom(const UDim &pad_bottom);
void SetPadding(const UDim& left, const UDim& top, const UDim& right, const UDim& bottom);
void Padding(const UDim& left, const UDim& top, const UDim& right, const UDim& bottom);
void SetPadding(const UDim& padding);
void Padding(const UDim& padding);
/// Returns the margin factor on the left of this widget.
[[nodiscard]] UDim GetMarginLeft() const;
[[nodiscard]] UDim MarginLeft() const;
/// Returns the margin factor on the top of this widget.
[[nodiscard]] UDim GetMarginTop() const;
[[nodiscard]] UDim MarginTop() const;
/// Returns the margin factor on the right of this widget.
[[nodiscard]] UDim GetMarginRight() const;
[[nodiscard]] UDim MarginRight() const;
/// Returns the margin factor on the bottom of this widget.
[[nodiscard]] UDim GetMarginBottom() const;
[[nodiscard]] UDim MarginBottom() const;
/// Sets the amount (in Pixels + Scale) to apply margin on the left-side of the widget.
/// @see UDim, SetMargin()
void SetMarginLeft(const UDim &ml);
/// @see UDim, Margin()
void MarginLeft(const UDim &ml);
/// Sets the amount (in Pixels + Scale) to apply margin on the top-side of the widget.
/// @see UDim, SetMargin()
void SetMarginTop(const UDim &mt);
/// @see UDim, Margin()
void MarginTop(const UDim &mt);
/// Sets the amount (in Pixels + Scale) to apply margin on the right-side of the widget.
/// @see UDim, SetMargin()
void SetMarginRight(const UDim &mr);
/// @see UDim, Margin()
void MarginRight(const UDim &mr);
/// Sets the amount (in Pixels + Scale) to apply margin on the bottom-side of the widget.
/// @see UDim, SetMargin()
void SetMarginBottom(const UDim &mb);
/// @see UDim, Margin()
void MarginBottom(const UDim &mb);
/// Sets the margin factor of each side of the widget.
/// @param left The amount of margin to apply on the left. (Pixels, Scale)
/// @param top The amount of margin to apply on the top.
/// @param right The amount of margin to apply on the right.
/// @param bottom The amount of margin to apply on the bottom.
void SetMargin(const UDim& left, const UDim& top, const UDim& right, const UDim& bottom);
void Margin(const UDim& left, const UDim& top, const UDim& right, const UDim& bottom);
/// Sets the margin factor on all four sides of this widget to the same value.
/// @see SetMargin(const UDim&, const UDim&, const UDim&, const UDim&).
void SetMargin(const UDim& margin);
/// @see Margin(const UDim&, const UDim&, const UDim&, const UDim&).
void Margin(const UDim& margin);
/// Returns this widgets mnemonic name.
/// Widgets can optionally be assigned a name that can be used to retrieve it from a widget tree node.
/// @see GetName().
[[nodiscard]] std::string GetName() const;
/// @see Name().
[[nodiscard]] std::string Name() const;
/// Sets this widgets mnemonic name.
/// Widgets can optionally be assigned a name that can be used to retrieve it from a widget tree node.
/// @see GetName().
void SetName(const std::string &new_name);
/// @see Name().
void Name(const std::string &new_name);
/// Returns whether the widget is to be rendered.
/// This function does not indicate whether the widget is **actually seeable** on-screen.
/// @see SetVisible().
/// @see Visible().
[[nodiscard]] bool IsVisible() const;
/// Sets whether the widget is to be rendered. Children are also not rendered if disabled.
/// @see IsVisible().
void SetVisible(bool enabled);
void Visible(bool enabled);
/// Returns the first ancestor in this widgets hierarchy that does not have its own parent.
@@ -216,7 +215,7 @@ namespace JUI
bool IsMouseInside() const;
void SetAnchorPoint(const Vector2 &point);
void AnchorPoint(const Vector2 &point);
public:
/// Renders the widget to the current OpenGL Context using JGL.
@@ -264,97 +263,10 @@ namespace JUI
bool visible = true;
Widget* next = nullptr;
Widget* prev = nullptr;
int zindex;
};
/// A mixin helper class that provides behavior for hoverable objects.
/// A hoverable object pays attention to when the mouse enters and leaves it's bounds.
class Hoverable {
public:
Event<Vector2> OnHoverEvent;
Event<Vector2> OnExitEvent;
public:
bool IsHovered() const { return hovered; };
public:
virtual void OnHover(const Vector2& MousePos) {
OnHoverEvent.Invoke(MousePos);
};
virtual void OnExit(const Vector2& MousePos) {
OnExitEvent.Invoke(MousePos);
};
void Update(const Vector2& m_pos, float delta)
{
if (IsHovered() && !hover_debounce) {
OnHover(m_pos);
hover_debounce = true;
}
if (!IsHovered() && hover_debounce) {
OnExit(m_pos);
hover_debounce = false;
}
}
protected:
bool hovered;
bool hover_debounce;
};
/// A mixin helper class that provides behavior and events for clickable widgets.
class Clickable
{
public:
Event<Vector2, MouseButton> OnClickEvent;
Event<Vector2, MouseButton, bool> OnReleaseEvent;
public:
bool IsClicked() const { return clicked; };
void SetClicked(bool manual_click)
{
clicked = manual_click;
}
public:
virtual void OnClick(const Vector2& MousePos, const MouseButton& MouseButton) {
OnClickEvent.Invoke(MousePos, MouseButton);
};
virtual void OnRelease(const Vector2& MousePos, const MouseButton& MouseButton, bool MouseStillOver) {
OnReleaseEvent.Invoke(MousePos, MouseButton, MouseStillOver);
};
void Update(const Vector2& mpos, const MouseButton& btn, bool hovering)
{
}
protected:
bool clicked = false;
bool click_debounce = false;
};
/// A mixin helper class that provides behavior and events for a binary-state togglable widget.
class Toggleable {
public:
Event<> OnToggleEvent;
Event<> OnToggleOnEvent;
Event<> OnToggleOffEvent;
public:
virtual void OnToggleOn() {
OnToggleOnEvent.Invoke();
}
virtual void OnToggleOff() {
OnToggleOffEvent.Invoke();
}
virtual void Update() {
OnToggleEvent.Invoke();
toggled = !toggled;
if (toggled) {
OnToggleOn();
} else {
OnToggleOff();
}
}
protected:
bool toggled = false;
};
}

View File

@@ -11,7 +11,28 @@
#pragma once
#include <J3ML/LinearAlgebra/Vector2.hpp>
#include <JUI/Base/Widget.hpp>
namespace JUI
{
/// A mixin helper class that provides behavior and events for clickable widgets.
class Clickable
{
public:
Event<Vector2, MouseButton> OnClickEvent;
Event<Vector2, MouseButton, bool> OnReleaseEvent;
public:
bool IsClicked() const { return clicked; };
void SetClicked(bool manual_click);
public:
virtual void OnClick(const Vector2& MousePos, const MouseButton& MouseButton);;
virtual void OnRelease(const Vector2& MousePos, const MouseButton& MouseButton, bool MouseStillOver);;
void Update(const Vector2& mpos, const MouseButton& btn, bool hovering);
protected:
bool clicked = false;
bool click_debounce = false;
};
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include <Event.h>
namespace JUI
{
/// A mixin helper class that provides behavior and events for a binary-state togglable widget.
class Toggleable {
public:
Event<> OnToggleEvent;
Event<> OnToggleOnEvent;
Event<> OnToggleOffEvent;
public:
virtual void OnToggleOn();
virtual void OnToggleOff();
virtual void Update();
protected:
bool toggled = false;
};
}

View File

@@ -11,13 +11,14 @@
#pragma once
#include "JUI/Base/Widget.hpp"
#include "JUI/Base/RectBase.hpp"
#include "JUI/Base/TextBase.hpp"
#include <JUI/Base/Widget.hpp>
#include <JUI/Base/RectBase.hpp>
#include <JUI/Base/TextBase.hpp>
#include <JUI/Mixins/Clickable.hpp>
#include <JUI/Mixins/Hoverable.hpp>
namespace JUI
{
enum class ButtonState
{
Base,
@@ -36,9 +37,7 @@ namespace JUI
explicit Button(Widget* parent);
~Button() override {};
public:
// TODO: These suffice for now as a proof-of-concept
// But I want more sophisticated style-animation support
// for the various states of the button
Color4 GetHoveredBGColor() const;
Color4 GetBaseBGColor() const;
Color4 GetPressedBGColor() const;

View File

@@ -46,7 +46,7 @@ namespace JUI
// TODO: Implement widget.LayoutOrder property
// TODO: Sort children by LayoutOrder
consumed_height += pad_top.Pixels;
child_widget->SetPosition({0, consumed_height, 0, 0});
child_widget->Position({0, consumed_height, 0, 0});
consumed_height += child_widget->GetAbsoluteSize().y;
consumed_height += pad_bottom.Pixels;
}
@@ -66,7 +66,7 @@ namespace JUI
for (auto &child_widget : children)
{
consumed_width += pad_left.Pixels;
child_widget->SetPosition({consumed_width, 0, 0, 0});
child_widget->Position({consumed_width, 0, 0, 0});
consumed_width += child_widget->GetAbsoluteSize().x;
consumed_width += pad_right.Pixels;
}
@@ -78,7 +78,7 @@ namespace JUI
for (auto &child_widget : children)
{
consumed_width -= pad_left.Pixels;
child_widget->SetPosition({consumed_width, 0, 0, 0});
child_widget->Position({consumed_width, 0, 0, 0});
consumed_width -= child_widget->GetAbsoluteSize().x;
consumed_width -= pad_right.Pixels;
}

View File

@@ -1,9 +1,20 @@
/// Josh's User Interface Library
/// A C++20 Library for creating, styling, and rendering of a UI/UX widgets.
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
/// Special Thanks to William Tomasine II and Maxine Hayes.
/// (c) 2024 Redacted Software
/// This work is dedicated to the public domain.
/// @file Scene.hpp
/// @desc Scene class - The root class of a menu that contains child elements.
/// @edit 2024-10-11
#pragma once
#include <JUI/Base/Widget.hpp>
namespace JUI
{
// TODO: SceneSizingBehavior - FillToWindow, CustomSized
///
class Scene : public Widget {
public:
Scene();

View File

@@ -13,14 +13,15 @@
#include <J3ML/LinearAlgebra.hpp>
#include <JUI/Base/Widget.hpp>
#include <JUI/Base/RectBase.hpp>
#include <JUI/Widgets/Rect.hpp>
#include <JUI/Widgets/Text.hpp>
#include <JUI/Widgets/Button.hpp>
#include "JUI/Mixins/Draggable.hpp"
#include "JUI/Mixins/Resizable.hpp"
#include "JUI/Mixins/Dockable.hpp"
#include <JUI/Mixins/Draggable.hpp>
#include <JUI/Mixins/Resizable.hpp>
#include <JUI/Mixins/Dockable.hpp>
#include <JUI/Mixins/Hoverable.hpp>
#include <JUI/Mixins/Clickable.hpp>
namespace JUI
{

View File

@@ -38,11 +38,11 @@ JUI::Scene* CreateScene() {
JUI->SetContent("Josh User Interface");
JUI->AlignBottom();
JUI->AlignCenterHorizontally();
JUI->SetAnchorPoint(Vector2(0.5f, 0.5f));
JUI->SetPosition({50_percent, 50_percent});
//JUI->SetSize({30_percent, 10_percent});
JUI->AnchorPoint(Vector2(0.5f, 0.5f));
JUI->Position({50_percent, 50_percent});
//JUI->Size({30_percent, 10_percent});
JUI->FitText(true);
JUI->SetPadding(20_px);
JUI->Padding(20_px);
JUI->BGColor({64, 64, 64, 128});
JUI->SetBorderWidth(2);
JUI->BorderColor({255, 255, 255, 128});
@@ -51,13 +51,13 @@ JUI::Scene* CreateScene() {
Redacted->SetTextSize(32);
Redacted->SetTextColor({255, 255, 255});
Redacted->SetContent("Redacted Software Group");
Redacted->SetPosition({50_percent, 60_percent});
//Redacted->SetSize({30_percent, 10_percent});
Redacted->Position({50_percent, 60_percent});
//Redacted->Size({30_percent, 10_percent});
Redacted->AlignCenterHorizontally();
Redacted->AlignTop();
Redacted->SetAnchorPoint(Vector2(0.5f, .5f));
Redacted->AnchorPoint(Vector2(0.5f, .5f));
Redacted->FitText(true);
Redacted->SetPadding(10_px);
Redacted->Padding(10_px);
Redacted->BGColor({32, 48, 192});
Redacted->SetBorderWidth(1);
Redacted->BorderColor({64, 64, 64});
@@ -65,14 +65,14 @@ JUI::Scene* CreateScene() {
// Rect //
Rect *rect_element = new Rect(root);
rect_element->SetName("JimBob");
rect_element->Name("JimBob");
//Rect* element = new Rect(root);
//rect_element->SetName("JimBob");
//rect_element->Name("JimBob");
//element->BGColor({0,255,0});
rect_element->BGColor({0, 64, 0});
rect_element->SetSize({0, 0, 0.1f, 0.2f});
rect_element->Size({0, 0, 0.1f, 0.2f});
rect_element->SetClipsDescendants(true);
rect_element->BorderColor({255, 255, 255});
rect_element->SetBorderWidth(2.f);
@@ -91,16 +91,16 @@ JUI::Scene* CreateScene() {
// Button //
RadioButton *button_element = new RadioButton(root);
button_element->SetName("BobJim");
button_element->Name("BobJim");
button_element->BGColor({0, 0, 64});
button_element->SetSize({0, 0, 0.1f, 0.1f});
button_element->Size({0, 0, 0.1f, 0.1f});
button_element->SetClipsDescendants(true);
button_element->BorderColor({255, 255, 255});
button_element->SetBorderWidth(2.f);
auto bpos = rect_element->Size();
//exit(1);
button_element->SetPosition(
button_element->Position(
{bpos.X.Pixels, bpos.Y.Pixels, bpos.X.Scale - 0.2f, 0}); // I don't know how to use sx and sy - maxine
button_element->OnToggleOnEvent += [rect_element] () {
rect_element->BGColor({64, 0, 0});
@@ -126,19 +126,19 @@ JUI::Scene* CreateScene() {
// Window //
JUI::Window* win_element = new JUI::Window(root);
win_element->SetTitleFont(FreeSans);
win_element->SetSize({50_percent, 50_percent});
win_element->Size({50_percent, 50_percent});
win_element->SetTitle("JUI Example Window Widget");
//win_element->SetPadding(1_px);
//win_element->Padding(1_px);
// End Window //
auto list = new VerticalListLayout(win_element->GetViewportInstance());
list->SetPadding(10_px);
list->Padding(10_px);
TextRect* a = new TextRect(list);
a->SetTextSize(16);
a->SetFont(FreeSans);
a->SetSize({0, 20, 1, 0});
a->Size({0, 20, 1, 0});
//a->FitText(true);
a->Center();
a->SetContent("Greetings. This is the JUI demo program!");
@@ -148,7 +148,7 @@ JUI::Scene* CreateScene() {
b->SetTextSize(16);
b->SetContent("JUI is my home-coded game menu building toolkit.");
//b->FitText(true);
b->SetSize({0, 20, 1, 0});
b->Size({0, 20, 1, 0});
b->Center();
b->SetFont(FreeSans);
@@ -156,7 +156,7 @@ JUI::Scene* CreateScene() {
c->SetTextSize(16);
c->SetContent("Settings");
//c->FitText(true);
c->SetSize({0, 20, 1, 0});
c->Size({0, 20, 1, 0});
c->Center();
c->SetFont(FreeSans);
@@ -164,7 +164,7 @@ JUI::Scene* CreateScene() {
d->SetTextSize(16);
d->SetContent("Exit");
//d->FitText(true);
d->SetSize({0, 20, 1, 0});
d->Size({0, 20, 1, 0});
d->Center();
d->SetFont(FreeSans);

View File

@@ -5,7 +5,7 @@ namespace JUI
LayoutContainer::LayoutContainer() {}
LayoutContainer::LayoutContainer(Widget* parent) {
this->SetParent(parent);
this->Parent(parent);
}
void LayoutContainer::Update(float delta)

View File

@@ -11,26 +11,26 @@ namespace JUI {
Widget::Widget(Widget* parent) : Widget()
{
this->SetParent(parent);
this->Parent(parent);
}
void Widget::SetParent(Widget* parent) {
void Widget::Parent(Widget* newParent) {
// hold a reference to this so it doesn't get collected as we're working.
Widget* oldParent = this->parent;
// New parent is old parent, do nothing, maybe raise a warning.
if (parent == oldParent)
if (newParent == oldParent)
return;
// Don't allow for an instance to be parented to itself
if (this == parent)
if (this == newParent)
throw std::runtime_error("Cannot parent a widget to itself.");
// You're trying to break the linearity of the object hierarchy by creating a circle in the graph.
if (this->IsAncestorOf(parent))
if (this->IsAncestorOf(newParent))
throw std::runtime_error("Cannot create circular reference.");
for (Widget* ancestor: this->GetAncestors()) {
if (oldParent && !ancestor->IsAncestorOf(parent) && parent != ancestor) {
if (oldParent && !ancestor->IsAncestorOf(newParent) && newParent != ancestor) {
ancestor->DescendantRemoved(this);
for (Widget* descendant : this->GetDescendants()) {
ancestor->DescendantRemoved(descendant);
@@ -41,21 +41,21 @@ namespace JUI {
// Remove ourselves from our parent (if we have one)
if (this->parent) {
// this->parent->ChildRemoved(this)
std::erase(parent->children, this);
std::erase(newParent->children, this);
}
// Update our old parent to the new one
this->parent = parent;
this->parent = newParent;
// If our parent is set to nullptr, we can't update it's vector of children
if (!parent) return;
if (!newParent) return;
// Add ourselves to our new parent's list of children
parent->children.emplace_back(this);
newParent->children.emplace_back(this);
//newParent->ChildAdded(this);
for (Widget* ancestor : this->GetAncestors()) {
if (!oldParent || (!oldParent->IsDescendantOf(parent) && oldParent != ancestor)) {
if (!oldParent || (!oldParent->IsDescendantOf(newParent) && oldParent != ancestor)) {
// Don't fire unless an instance is actually a new descendant
ancestor->DescendantAdded(this);
for (Widget* descendant: this->GetDescendants()) {
@@ -88,65 +88,65 @@ namespace JUI {
return false;
}
Vector2 Widget::GetAnchorPoint() const {
Vector2 Widget::AnchorPoint() const {
return anchor_point;
}
UDim Widget::GetPaddingLeft() const { return pad_left;}
UDim Widget::GetPaddingTop() const { return pad_top;}
UDim Widget::GetPaddingRight() const { return pad_right;}
UDim Widget::GetPaddingBottom() const { return pad_bottom;}
UDim Widget::PaddingLeft() const { return pad_left;}
UDim Widget::PaddingTop() const { return pad_top;}
UDim Widget::PaddingRight() const { return pad_right;}
UDim Widget::PaddingBottom() const { return pad_bottom;}
void Widget::SetPaddingLeft (const UDim& pl) { pad_left = pl;}
void Widget::SetPaddingTop (const UDim& pt) { pad_top = pt;}
void Widget::SetPaddingRight (const UDim& pr) { pad_right = pr;}
void Widget::SetPaddingBottom(const UDim& pb) { pad_bottom = pb;}
void Widget::PaddingLeft (const UDim& pad_left) { pad_left = pad_left;}
void Widget::PaddingTop (const UDim& pad_top) { pad_top = pad_top;}
void Widget::PaddingRight (const UDim& pad_right) { pad_right = pad_right;}
void Widget::PaddingBottom(const UDim& pad_bottom) { pad_bottom = pad_bottom;}
void Widget::SetPadding(const UDim &left, const UDim &top, const UDim &right, const UDim &bottom) {
SetPaddingLeft(left);
SetPaddingTop(top);
SetPaddingRight(right);
SetPaddingBottom(bottom);
void Widget::Padding(const UDim &left, const UDim &top, const UDim &right, const UDim &bottom) {
PaddingLeft(left);
PaddingTop(top);
PaddingRight(right);
PaddingBottom(bottom);
}
void Widget::SetPadding(const UDim &padding) {
SetPadding(padding, padding, padding, padding);
void Widget::Padding(const UDim &padding) {
Padding(padding, padding, padding, padding);
}
UDim Widget::GetMarginLeft () const { return margin_left;}
UDim Widget::GetMarginTop () const { return margin_top;}
UDim Widget::GetMarginRight () const { return margin_right;}
UDim Widget::GetMarginBottom() const { return margin_bottom;}
UDim Widget::MarginLeft () const { return margin_left;}
UDim Widget::MarginTop () const { return margin_top;}
UDim Widget::MarginRight () const { return margin_right;}
UDim Widget::MarginBottom() const { return margin_bottom;}
void Widget::SetMarginLeft(const UDim& ml) { margin_left = ml;}
void Widget::SetMarginTop(const UDim& mt) { margin_top = mt;}
void Widget::SetMarginRight(const UDim& mr) { margin_right = mr;}
void Widget::SetMarginBottom(const UDim& mb) { margin_bottom = mb;}
void Widget::MarginLeft(const UDim& ml) { margin_left = ml;}
void Widget::MarginTop(const UDim& mt) { margin_top = mt;}
void Widget::MarginRight(const UDim& mr) { margin_right = mr;}
void Widget::MarginBottom(const UDim& mb) { margin_bottom = mb;}
void Widget::SetMargin(const UDim &left, const UDim &top, const UDim &right, const UDim &bottom) {
SetMarginLeft(left);
SetMarginTop(top);
SetMarginRight(right);
SetMarginBottom(bottom);
void Widget::Margin(const UDim &left, const UDim &top, const UDim &right, const UDim &bottom) {
MarginLeft(left);
MarginTop(top);
MarginRight(right);
MarginBottom(bottom);
}
void Widget::SetMargin(const UDim &margin) {
SetMargin(margin, margin, margin, margin);
void Widget::Margin(const UDim &margin) {
Margin(margin, margin, margin, margin);
}
std::string Widget::GetName() const { return name; }
void Widget::SetName(const std::string& new_name) { name = new_name;}
std::string Widget::Name() const { return name; }
void Widget::Name(const std::string& new_name) { name = new_name;}
bool Widget::IsVisible() const { return visible; }
void Widget::SetVisible(bool enabled) { visible = enabled;}
void Widget::Visible(bool enabled) { visible = enabled;}
Widget* Widget::GetParent() const { return parent;}
UDim2 Widget::Position() const { return position; }
void Widget::SetPosition(const UDim2& pos) { position = pos; }
void Widget::Position(const UDim2& pos) { position = pos; }
UDim2 Widget::Size() const { return size;}
void Widget::SetSize(const UDim2& s) { size = s; }
void Widget::Size(const UDim2& s) { size = s; }
float Widget::GetAbsoluteRotation() const {
// TODO: implement rotation correctly!!
@@ -184,10 +184,10 @@ namespace JUI {
auto abs_size = GetAbsoluteSize();
auto anchor_offset = abs_size * GetAnchorPoint();
auto anchor_offset = abs_size * AnchorPoint();
UDim padding_h = parent->GetPaddingLeft();
UDim padding_v = parent->GetPaddingTop();
UDim padding_h = parent->PaddingLeft();
UDim padding_v = parent->PaddingTop();
float calculated_padding_x = padding_h.Pixels + (padding_h.Scale * parent_abs_size.x);
float calculated_padding_y = padding_v.Pixels + (padding_v.Scale * parent_abs_size.y);
@@ -208,10 +208,10 @@ namespace JUI {
Vector2 parent_abs_size = this->GetParent()->GetAbsoluteSize();
UDim padding_h = parent->GetPaddingLeft() + parent->GetPaddingRight();
UDim padding_h = parent->PaddingLeft() + parent->PaddingRight();
float final_pad_x = padding_h.Pixels + (padding_h.Scale * parent->GetAbsoluteSize().x);
UDim padding_v = parent->GetPaddingTop() + parent->GetPaddingBottom();
UDim padding_v = parent->PaddingTop() + parent->PaddingBottom();
float final_pad_y = padding_v.Pixels + (padding_v.Scale * parent->GetAbsoluteSize().y);
Vector2 pad_size_reduction = {final_pad_x, final_pad_y};
@@ -225,7 +225,7 @@ namespace JUI {
std::optional<Widget*> Widget::FindFirstChild(const std::string& search_name) {
for (auto& child : children) {
if (child->GetName() == search_name)
if (child->Name() == search_name)
return child;
}
return std::nullopt;
@@ -321,12 +321,17 @@ namespace JUI {
}
Widget *Widget::Add(Widget *newChild) {
newChild->SetParent(this);
newChild->Parent(this);
return newChild;
}
void Widget::SetAnchorPoint(const Vector2& point) {
void Widget::AnchorPoint(const Vector2& point) {
anchor_point = point;
}
// TODO: Implement Z-Index sorting in render routine.
int Widget::ZIndex() const { return zindex;}
void Widget::ZIndex(int new_zindex) { zindex = new_zindex; }
}

View File

@@ -1,2 +1,17 @@
#include <JUI/Mixins/Clickable.hpp>
void JUI::Clickable::Update(const Vector2 &mpos, const JUI::MouseButton &btn, bool hovering) {
}
void JUI::Clickable::OnRelease(const Vector2 &MousePos, const JUI::MouseButton &MouseButton, bool MouseStillOver) {
OnReleaseEvent.Invoke(MousePos, MouseButton, MouseStillOver);
}
void JUI::Clickable::OnClick(const Vector2 &MousePos, const JUI::MouseButton &MouseButton) {
OnClickEvent.Invoke(MousePos, MouseButton);
}
void JUI::Clickable::SetClicked(bool manual_click) {
clicked = manual_click;
}

View File

@@ -0,0 +1,20 @@
#include <JUI/Mixins/Toggleable.hpp>
void JUI::Toggleable::OnToggleOn() {
OnToggleOnEvent.Invoke();
}
void JUI::Toggleable::OnToggleOff() {
OnToggleOffEvent.Invoke();
}
void JUI::Toggleable::Update() {
OnToggleEvent.Invoke();
toggled = !toggled;
if (toggled) {
OnToggleOn();
} else {
OnToggleOff();
}
}

View File

@@ -7,7 +7,7 @@ namespace JUI
Button::Button(): Widget() {}
Button::Button(Widget *parent): Clickable() {
this->SetParent(parent);
this->Parent(parent);
};
void Button::Draw() {
@@ -88,7 +88,7 @@ namespace JUI
TextButton::TextButton() : Button(), TextBase() {}
TextButton::TextButton(Widget* parent) : TextButton() {
this->SetParent(parent);
this->Parent(parent);
}
void TextButton::Update(float delta) {

View File

@@ -9,12 +9,12 @@ namespace JUI
Image::Image(Widget* parent) : Image()
{
SetParent(parent);
Parent(parent);
}
Image::Image(Widget *parent, JGL::Texture *tex) : Widget(), ImageBase(tex)
{
this->SetParent(parent);
this->Parent(parent);
}
Vector2 Image::GetAbsoluteSize() const {

View File

@@ -8,13 +8,13 @@ namespace JUI
VerticalListLayout::VerticalListLayout() : ListLayout() {}
VerticalListLayout::VerticalListLayout(Widget* parent) : VerticalListLayout()
{
this->SetParent(parent);
this->Parent(parent);
}
HorizontalListLayout::HorizontalListLayout() : ListLayout() {}
HorizontalListLayout::HorizontalListLayout(Widget* parent) : HorizontalListLayout() {
SetParent(parent);
Parent(parent);
}
}

View File

@@ -5,7 +5,7 @@ namespace JUI
RadioButton::RadioButton() : Button(), Toggleable() {}
RadioButton::RadioButton(Widget* parent) : RadioButton() {
this->SetParent(parent);
this->Parent(parent);
}

View File

@@ -6,7 +6,7 @@ namespace JUI {
Rect::Rect(): Widget(), RectBase() {}
Rect::Rect(Widget *parent): Rect() {
this->SetParent(parent);
this->Parent(parent);
}
void Rect::Draw() {

View File

@@ -6,7 +6,7 @@ namespace JUI {
Text::Text(Widget* parent) : Text()
{
this->SetParent(parent);
this->Parent(parent);
}
Text::~Text() {}

View File

@@ -3,7 +3,7 @@
namespace JUI {
TextRect::TextRect() : Rect(), TextBase() {}
TextRect::TextRect(Widget* parent) : TextRect() {
this->SetParent(parent);
this->Parent(parent);
}
void TextRect::Update(float delta) {

View File

@@ -6,8 +6,8 @@
namespace JUI
{
Window::Window() : Widget(), Clickable(), Hoverable(), RectBase(), Draggable(), Resizable(), Dockable() {
this->SetPosition({200, 200, 0, 0});
this->SetSize({400, 200, 0, 0});
this->Position({200, 200, 0, 0});
this->Size({400, 200, 0, 0});
min_size = {400, 200};
this->BGColor({0,0,0,0});
this->BorderColor({92,92,192});
@@ -42,20 +42,20 @@ namespace JUI
};
Viewport = new Rect(this);
Viewport->SetName("Viewport");
Viewport->Name("Viewport");
Viewport->BGColor({64,64,64, 255});
Viewport->SetSize({0, -20, 1, 1});
Viewport->SetPosition({0,20,0,0});
// TODO: Viewport->SetAnchorPoint({0.f, 0.f});
Viewport->Size({0, -20, 1, 1});
Viewport->Position({0, 20, 0, 0});
// TODO: Viewport->AnchorPoint({0.f, 0.f});
//Viewport->BorderColor({128, 128, 128, 255});
//Viewport->SetBorderWidth(1);
//Viewport->SetPadding(1_px);
//Viewport->Padding(1_px);
// TODO: Viewport->SetBorderRadius(0);
Topbar = new Rect(this);
Topbar->SetPosition({0_px, 0_px});
Topbar->SetSize({100_percent, 20_px});
Topbar->Position({0_px, 0_px});
Topbar->Size({100_percent, 20_px});
Topbar->BGColor({92,92,192, 255});
//Topbar->BorderColor({128, 128, 128, 255});
//Topbar->SetBorderWidth(1);
@@ -70,9 +70,9 @@ namespace JUI
// TODO: exit_btn
exit_btn = new TextButton(Topbar);
//exit_btn->SetAnchorPoint({1.f, 0.f});
//exit_btn->SetSize({30_px, 100_percent});
exit_btn->SetSize({titlebar_height, titlebar_height, 0, 0});
//exit_btn->AnchorPoint({1.f, 0.f});
//exit_btn->Size({30_px, 100_percent});
exit_btn->Size({titlebar_height, titlebar_height, 0, 0});
//exit_btn->BorderColor({128, 128, 128, 255});
//exit_btn->SetBaseColor({192, 64, 64, 255});
//exit_btn->SetHoverColor({255, 0, 0, 255});
@@ -86,7 +86,7 @@ namespace JUI
//exit_btn->Center();
exit_btn->OnClickEvent += [&] (auto... _) {
this->SetVisible(false);
this->Visible(false);
};
jlog::Debug(std::format("{} {} {} {}", Topbar->Size().X.Pixels, Topbar->Size().Y.Pixels, Topbar->Size().X.Scale,
@@ -99,7 +99,7 @@ namespace JUI
}
Window::Window(Widget* parent) : Window() {
this->SetParent(parent);
this->Parent(parent);
}
Vector2 Window::MinSize() const { return min_size; }
@@ -162,7 +162,7 @@ namespace JUI
if (dragging) {
jlog::Debug(std::format("mpos {} {}", last_known_mouse_pos.x, last_known_mouse_pos.y));
Vector2 mpos = last_known_mouse_pos - initial_drag_offset;
this->SetPosition(UDim2{(int)mpos.x, (int)mpos.y, 0,0});
this->Position(UDim2{(int) mpos.x, (int) mpos.y, 0, 0});
}
if (resizing) {
@@ -170,7 +170,7 @@ namespace JUI
Vector2 resize_amt = mpos - initial_resize_offset;
SetSize(size_when_restart_began + UDim2(resize_amt.x, resize_amt.y, 0, 0));
Size(size_when_restart_began + UDim2(resize_amt.x, resize_amt.y, 0, 0));
Vector2 abs_size = this->GetAbsoluteSize();
@@ -178,14 +178,14 @@ namespace JUI
if (abs_size.x < min_size.x)
{
float needed_amt_to_resize = min_size.x - abs_size.x;
SetSize(Size() + UDim2(needed_amt_to_resize, 0, 0, 0));
Size(Size() + UDim2(needed_amt_to_resize, 0, 0, 0));
}
// Clamp Y-axis.
if (abs_size.y < min_size.y)
{
float needed_amt_to_resize = min_size.y - abs_size.y;
SetSize(Size() + UDim2(0, needed_amt_to_resize, 0, 0));
Size(Size() + UDim2(0, needed_amt_to_resize, 0, 0));
}
}