Compare commits
10 Commits
Prerelease
...
Prerelease
Author | SHA1 | Date | |
---|---|---|---|
9453a57616 | |||
781c9882d4 | |||
63ff2e6ef2 | |||
53a1d7bd9c | |||
ca75a143d3 | |||
07725ded44 | |||
67fa678ca6 | |||
1065933fcb | |||
cfce294bf2 | |||
48aaff669e |
@@ -33,27 +33,27 @@ set_target_properties(JUI PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME Event
|
||||
URL https://git.redacted.cc/josh/Event/archive/Release-10.zip
|
||||
URL https://git.redacted.cc/josh/Event/archive/Release-12.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME J3ML
|
||||
URL https://git.redacted.cc/josh/j3ml/archive/Release-3.1.zip
|
||||
URL https://git.redacted.cc/josh/j3ml/archive/Release-3.2.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME jlog
|
||||
URL https://git.redacted.cc/josh/jlog/archive/Prerelease-12.zip
|
||||
URL https://git.redacted.cc/josh/jlog/archive/Prerelease-16.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME ReWindow
|
||||
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-13.zip
|
||||
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-21.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME JGL
|
||||
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-32.zip
|
||||
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-37.zip
|
||||
)
|
||||
|
||||
target_include_directories(JUI PUBLIC ${Event_SOURCE_DIR}/include)
|
||||
|
@@ -27,6 +27,8 @@ Provided widgets include Scene, Rect, Text, TextRect, Button, TextButton, TextIn
|
||||
|
||||
Browse the src/Demos directories for examples of building and interacting with things in JUI.
|
||||
|
||||
## Dependencies
|
||||
|
||||
## Documentation
|
||||
|
||||
Documentation is automatically generated from latest commit and is hosted at https://doc.redacted.cc/jui .
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
#include <Event.h>
|
||||
#include <EventConnection.h>
|
||||
|
||||
#include <Color4.hpp>
|
||||
|
||||
namespace JUI
|
||||
@@ -36,12 +36,16 @@ namespace JUI
|
||||
//Event<Vector2> MousePress;
|
||||
//Event<Vector2, bool> MouseRelease;
|
||||
public:
|
||||
void SetCornerRounding(float radius);
|
||||
void SetCornerRounding(float tlRadius, float trRadius, float blRadius, float brRadius);
|
||||
void SetCornerRoundingTL(float radius);
|
||||
void SetCornerRoundingTR(float radius);
|
||||
void SetCornerRoundingBL(float radius);
|
||||
void SetCornerRoundingBR(float radius);
|
||||
void CornerRounding(float radius);
|
||||
|
||||
float CornerRounding() const;
|
||||
|
||||
// TODO: Implement per-corner rounding in JGL::Outline/FillRect
|
||||
//void CornerRounding(float tlRadius, float trRadius, float blRadius, float brRadius);
|
||||
//void CornerRoundingTL(float radius);
|
||||
//void CornerRoundingTR(float radius);
|
||||
//void CornerRoundingBL(float radius);
|
||||
//void CornerRoundingBR(float radius);
|
||||
|
||||
void SetClipsDescendants(bool clipping);
|
||||
void BGColor(const Color4& col);
|
||||
@@ -52,12 +56,9 @@ namespace JUI
|
||||
Color4 BGColor() const;
|
||||
Color4 GetBorderColor() const;
|
||||
float GetBorderWidth() const;
|
||||
BorderMode GetBorderMode() const;
|
||||
enum BorderMode BorderMode() const;
|
||||
|
||||
void SetBorderMode(const BorderMode& mode)
|
||||
{
|
||||
border_mode = mode;
|
||||
}
|
||||
void BorderMode(const enum BorderMode& mode);
|
||||
|
||||
bool GetClipsDescendants() const;
|
||||
|
||||
@@ -66,7 +67,7 @@ namespace JUI
|
||||
void Draw(const Vector2& pos, const Vector2& size);
|
||||
|
||||
protected:
|
||||
BorderMode border_mode = BorderMode::Middle;
|
||||
enum BorderMode border_mode = BorderMode::Middle;
|
||||
bool mouse_press_debounce;
|
||||
bool mouse_inside_debounce;
|
||||
float border_width = 1.f;
|
||||
|
@@ -7,20 +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 <EventConnection.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
|
||||
@@ -73,9 +72,8 @@ 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
|
||||
/// TODO: Use std::optional here and anywhere else a nullptr could be returned.
|
||||
Widget* FindFirstChild(const std::string& name);
|
||||
/// 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.
|
||||
std::vector<Widget*> GetDescendants();
|
||||
@@ -98,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.
|
||||
@@ -109,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);
|
||||
@@ -134,83 +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.
|
||||
/// In a well-formed JUI menu, this **should** always be a Scene.
|
||||
@@ -218,7 +214,9 @@ namespace JUI
|
||||
|
||||
bool IsMouseInside() const;
|
||||
|
||||
void SetAnchorPoint(const Vector2 &point);
|
||||
void AnchorPoint(const Vector2 &point);
|
||||
|
||||
[[nodiscard]] virtual AABB2D GetActualRenderBounds() const;
|
||||
|
||||
public:
|
||||
/// Renders the widget to the current OpenGL Context using JGL.
|
||||
@@ -266,97 +264,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;
|
||||
};
|
||||
}
|
||||
|
@@ -0,0 +1,38 @@
|
||||
/// 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 ScrollingRect.hpp
|
||||
/// @desc Scrolling Rectangle Widget
|
||||
/// @edit 2024-10-11
|
||||
|
||||
#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;
|
||||
};
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
/// 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 ScrollingRect.hpp
|
||||
/// @desc Scrolling Rectangle Widget
|
||||
/// @edit 2024-10-11
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
/// A mixin helper class that enables a widget to be docked into a DockingStation.
|
||||
class Dockable {};
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
/// 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 ScrollingRect.hpp
|
||||
/// @desc Scrolling Rectangle Widget
|
||||
/// @edit 2024-10-11
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Event.h>
|
||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
/// A mixin helper class that enables a widget to be dragged around by the mouse.
|
||||
class Draggable {
|
||||
public:
|
||||
Event<> OnDragBegan;
|
||||
Event<> OnDragEnded;
|
||||
bool Dragging() const { return dragging;}
|
||||
virtual void SetDrag(bool b) {
|
||||
this->dragging = b;
|
||||
}
|
||||
virtual void StartDragging(const Vector2& point)
|
||||
{
|
||||
initial_drag_offset = point;
|
||||
}
|
||||
virtual void StopDragging() {}
|
||||
virtual void Update(float delta) {}
|
||||
protected:
|
||||
bool dragging = false;
|
||||
Vector2 initial_drag_offset = {0, 0};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,37 @@
|
||||
/// 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 Hoverable.hpp
|
||||
/// @desc Hoverable Mixin Helper Class - Added to widgets that should have special behavior when hovered by the mouse.
|
||||
/// @edit 2024-10-11
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||
#include <Event.h>
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
/// 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);;
|
||||
virtual void OnExit(const Vector2& MousePos);;
|
||||
|
||||
void Update(const Vector2& m_pos, float delta);
|
||||
protected:
|
||||
bool hovered;
|
||||
bool hover_debounce;
|
||||
};
|
||||
}
|
34
include/JUI/Mixins/Resizable.hpp
Normal file
34
include/JUI/Mixins/Resizable.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/// 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 Resizable.hpp
|
||||
/// @desc Resizable Mixin Helper class
|
||||
/// @edit 2024-10-11
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Event.h>
|
||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
/// A mixin helper class that enables a widget to be resized by the mouse.
|
||||
class Resizable {
|
||||
public:
|
||||
Event<> OnDragBegan;
|
||||
Event<> OnDragEnded;
|
||||
[[nodiscard]] bool Resizing() const;
|
||||
virtual void SetResize(bool b);
|
||||
virtual void StartResizing(const Vector2& point);
|
||||
virtual void StopResizing();
|
||||
virtual void Update(float delta);
|
||||
protected:
|
||||
bool resizing = false;
|
||||
Vector2 initial_resize_offset = {0, 0};
|
||||
};
|
||||
}
|
||||
|
21
include/JUI/Mixins/Toggleable.hpp
Normal file
21
include/JUI/Mixins/Toggleable.hpp
Normal 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;
|
||||
};
|
||||
}
|
||||
|
@@ -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,
|
||||
@@ -30,37 +31,58 @@ namespace JUI
|
||||
//class Button : public Widget, public RectBase, public Clickable, public Hoverable
|
||||
class Button : public Widget, public RectBase, public Clickable, public Hoverable
|
||||
{
|
||||
|
||||
public:
|
||||
Event<> OnEnabled;
|
||||
Event<> OnDisabled;
|
||||
public:
|
||||
Button();
|
||||
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;
|
||||
Color4 GetDisabledBGColor() const;
|
||||
|
||||
Color4 GetHoveredBorderColor() const;
|
||||
Color4 GetBaseBorderColor() const;
|
||||
Color4 GetPressedBorderColor() const;
|
||||
Color4 GetDisabledBorderColor() const;
|
||||
Color4 HoveredBGColor() const;
|
||||
Color4 BaseBGColor() const;
|
||||
Color4 PressedBGColor() const;
|
||||
Color4 DisabledBGColor() const;
|
||||
|
||||
bool IsEnabled() const;
|
||||
Color4 HoveredBorderColor() const;
|
||||
Color4 BaseBorderColor() const;
|
||||
Color4 PressedBorderColor() const;
|
||||
Color4 DisabledBorderColor() const;
|
||||
|
||||
void HoveredBGColor(const Color4& color);
|
||||
void BaseBGColor(const Color4& color);
|
||||
void PressedBGColor(const Color4& color);
|
||||
void DisabledBGColor(const Color4& color);
|
||||
|
||||
void HoveredBorderColor(const Color4& color);
|
||||
void BaseBorderColor(const Color4& color);
|
||||
void PressedBorderColor(const Color4& color);
|
||||
void DisabledBorderColor(const Color4& color);
|
||||
|
||||
bool Enabled() const;
|
||||
bool Disabled() const;
|
||||
void SetEnabled(bool enabled);
|
||||
void Disable();
|
||||
void Enable();
|
||||
|
||||
void Draw() override;
|
||||
void Update(float delta) override;
|
||||
|
||||
void GotoHoverColor();
|
||||
|
||||
|
||||
void OnClick(const Vector2& mouse_pos, const MouseButton& btn) override;
|
||||
void OnRelease(const Vector2& mouse_pos, const MouseButton& bnt, bool still_hovering) override;
|
||||
void OnHover(const J3ML::LinearAlgebra::Vector2 &MousePos) override;
|
||||
void OnExit(const J3ML::LinearAlgebra::Vector2 &MousePos) override;
|
||||
protected:
|
||||
bool disabled;
|
||||
Color4 hover_bg;
|
||||
Color4 hover_border;
|
||||
Color4 pressed_bg;
|
||||
Color4 pressed_border;
|
||||
Color4 disabled_bg;
|
||||
Color4 disabled_border;
|
||||
Color4 base_bg;
|
||||
Color4 base_border;
|
||||
};
|
||||
|
||||
class TextButton : public Button, public TextBase {
|
||||
|
@@ -1,8 +1,32 @@
|
||||
//
|
||||
// Created by dawsh on 8/5/24.
|
||||
//
|
||||
/// 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.
|
||||
|
||||
#ifndef JUI_CHECKBOX_HPP
|
||||
#define JUI_CHECKBOX_HPP
|
||||
/// @file Checkbox.hpp
|
||||
/// @desc It's a checkbox.
|
||||
/// @edit 2024-10-28
|
||||
|
||||
#endif //JUI_CHECKBOX_HPP
|
||||
#pragma once
|
||||
|
||||
#include <JUI/Base/Widget.hpp>
|
||||
#include <JUI/Widgets/Rect.hpp>
|
||||
#include "JUI/Mixins/Clickable.hpp"
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
class Checkbox : public Rect, public Clickable
|
||||
{
|
||||
public:
|
||||
Checkbox();
|
||||
explicit Checkbox(Widget* parent);
|
||||
|
||||
|
||||
//bool
|
||||
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
@@ -1,8 +1,19 @@
|
||||
//
|
||||
// Created by dawsh on 8/1/24.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#ifndef JUI_NINESLICEIMAGE_HPP
|
||||
#define JUI_NINESLICEIMAGE_HPP
|
||||
#include <JUI/Base/Widget.hpp>
|
||||
#include <JUI/Widgets/Rect.hpp>
|
||||
|
||||
#endif //JUI_NINESLICEIMAGE_HPP
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
class NineSliceImage
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
||||
class NineSliceRect : public Rect, public NineSliceImage
|
||||
{
|
||||
|
||||
};
|
||||
}
|
@@ -11,6 +11,7 @@
|
||||
|
||||
|
||||
#include <JUI/Widgets/Button.hpp>
|
||||
#include <JUI/Mixins/Toggleable.hpp>
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <JUI/Base/Widget.hpp>
|
||||
#include <JUI/Base/RectBase.hpp>
|
||||
#include <J3ML/Geometry/AABB2D.hpp>
|
||||
|
||||
namespace JUI {
|
||||
|
||||
@@ -28,6 +29,10 @@ namespace JUI {
|
||||
~Rect() override {}
|
||||
|
||||
bool IsMouseInside() const;
|
||||
|
||||
AABB2D GetActualRenderBounds() const override;
|
||||
|
||||
|
||||
public:
|
||||
void Draw() override;
|
||||
void Update(float delta) override;
|
||||
|
@@ -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();
|
||||
|
@@ -1,8 +1,26 @@
|
||||
//
|
||||
// Created by dawsh on 8/1/24.
|
||||
//
|
||||
/// 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.
|
||||
|
||||
#ifndef JUI_SCROLLINGRECT_HPP
|
||||
#define JUI_SCROLLINGRECT_HPP
|
||||
/// @file ScrollingRect.hpp
|
||||
/// @desc Scrolling Rectangle Widget
|
||||
/// @edit 2024-10-11
|
||||
|
||||
#endif //JUI_SCROLLINGRECT_HPP
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <JUI/Widgets/Rect.hpp>
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
class ScrollingRect : public Rect
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
Vector2 canvas_size;
|
||||
private:
|
||||
};
|
||||
}
|
@@ -7,4 +7,37 @@
|
||||
|
||||
/// @file Widget.hpp
|
||||
/// @desc Base Widget Class - All JUI widgets extend their behavior from this class.
|
||||
/// @edit 2024-07-31
|
||||
/// @edit 2024-07-31
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "Button.hpp"
|
||||
#include "Rect.hpp"
|
||||
#include "JUI/Mixins/Draggable.hpp"
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
|
||||
class Scrubber : public Rect, public Draggable
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
class Slider : public Rect, public Clickable
|
||||
{
|
||||
public:
|
||||
Slider() = default;
|
||||
explicit Slider(JUI::Widget* parent);
|
||||
|
||||
Scrubber* ScrubberInstance() { return scrubber;}
|
||||
|
||||
|
||||
protected:
|
||||
private:
|
||||
float minimum;
|
||||
float maximum;
|
||||
float interval;
|
||||
Scrubber* scrubber;
|
||||
|
||||
};
|
||||
}
|
||||
|
@@ -13,96 +13,73 @@
|
||||
|
||||
#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/Hoverable.hpp>
|
||||
#include <JUI/Mixins/Clickable.hpp>
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
using J3ML::LinearAlgebra::Vector2;
|
||||
|
||||
/// A mixin helper class that enables a widget to be dragged around by the mouse.
|
||||
class Draggable {
|
||||
public:
|
||||
Event<> OnDragBegan;
|
||||
Event<> OnDragEnded;
|
||||
bool Dragging() const { return dragging;}
|
||||
virtual void SetDrag(bool b) {
|
||||
this->dragging = b;
|
||||
}
|
||||
virtual void StartDragging(const Vector2& point)
|
||||
{
|
||||
initial_drag_offset = point;
|
||||
}
|
||||
virtual void StopDragging() {}
|
||||
virtual void Update(float delta) {}
|
||||
protected:
|
||||
bool dragging = false;
|
||||
Vector2 initial_drag_offset = {0, 0};
|
||||
};
|
||||
|
||||
/// A mixin helper class that enables a widget to be resized by the mouse.
|
||||
class Resizable {
|
||||
public:
|
||||
Event<> OnDragBegan;
|
||||
Event<> OnDragEnded;
|
||||
bool Resizing() const { return resizing;}
|
||||
virtual void SetResize(bool b) {
|
||||
this->resizing = b;
|
||||
}
|
||||
virtual void StartResizing(const Vector2& point)
|
||||
{
|
||||
initial_resize_offset = point;
|
||||
}
|
||||
virtual void StopResizing() {}
|
||||
virtual void Update(float delta) {}
|
||||
protected:
|
||||
bool resizing = false;
|
||||
Vector2 initial_resize_offset = {0, 0};
|
||||
};
|
||||
|
||||
|
||||
/// A mixin helper class that enables a widget to be docked into a DockingStation.
|
||||
class Dockable {};
|
||||
|
||||
/// TODO: Scope out.
|
||||
class DockingStation {};
|
||||
|
||||
/// A container widget class, with title bar and buttons,
|
||||
/// which can be dragged around, resized, and docked into other applicable widgets.
|
||||
class Window : public Widget, RectBase, public Clickable, public Hoverable, public Draggable, public Resizable, public Dockable
|
||||
class Window : public Widget, public RectBase, public Clickable, public Hoverable, public Draggable, public Resizable, public Dockable
|
||||
{
|
||||
public:
|
||||
/// The default constructor sets a default style for this Window.
|
||||
Window();
|
||||
/// Construct a window widget by specifying it's parent.
|
||||
Window(Widget* parent);
|
||||
/// Returns the minimum size (in x,y pixels) that the Window widget is allowed to be.
|
||||
[[nodiscard]] Vector2 MinSize() const;
|
||||
/// Returns the maximum size (in x,y pixels) that the Window widget is allowed to be.
|
||||
[[nodiscard]] Vector2 MaxSize() const;
|
||||
|
||||
/// Returns the current size (in x,y pixels) of the Window widget.
|
||||
[[nodiscard]] Vector2 CurrentSize() const;
|
||||
|
||||
/// Returns the minimum size (in x,y pixels) that the Window widget is allowed to be.
|
||||
[[nodiscard]] Vector2 MinSize() const;
|
||||
/// Sets the minimum size (in x,y pixels) that the Window widget is allowed to be.
|
||||
void MinSize(const Vector2& constraint);
|
||||
/// Returns the maximum size (in x,y pixels) that the Window widget is allowed to be.
|
||||
[[nodiscard]] Vector2 MaxSize() const;
|
||||
/// Sets the maximum size (in x,y pixels) that the Window widget is allowed to be.
|
||||
void MaxSize(const Vector2& constraint);
|
||||
|
||||
|
||||
/// Returns the height (in pixels) of the Window's titlebar.
|
||||
// TODO: Decide if this will auto-scale with the titlebar's text height, or the other way around.
|
||||
int TitlebarHeight() const;
|
||||
|
||||
/// Returns the text displayed as the Window's title.
|
||||
[[nodiscard]] std::string Title() const;
|
||||
|
||||
|
||||
void SetTitle(const std::string& title);
|
||||
/// Returns whether dragging the window about with the mouse is enabled.
|
||||
/// @see class Draggable.
|
||||
bool IsDraggable() const;
|
||||
|
||||
|
||||
void SetDraggable(bool value);
|
||||
|
||||
/// Returns whether this Window is able to be 'Docked' into another widget.
|
||||
/// @see class Dockable.
|
||||
bool IsDockable() const;
|
||||
|
||||
void SetDockable(bool value);
|
||||
|
||||
/// Returns whether resizing the window via right-click is enabled.
|
||||
/// @see class Resizable
|
||||
bool IsResizable() const;
|
||||
|
||||
void SetResizable(bool value);
|
||||
|
||||
/// Returns a pointer to the Text Widget that is used to render the title bar's text.
|
||||
Text* GetTitleInstance();
|
||||
/// Returns a pointer to the Rect Widget that is used to layout the title bar contents.
|
||||
@@ -112,7 +89,11 @@ namespace JUI
|
||||
/// Returns a pointer to the Exit Button Widget.
|
||||
TextButton* GetExitButtonInstance();
|
||||
|
||||
/// Sets the font used by the title-bar text on this Window.
|
||||
void SetTitleFont(const Font& f);
|
||||
|
||||
|
||||
/// Toggles whether this window is actively being dragged by the mouse.
|
||||
/// @see class Draggable.
|
||||
void SetDrag(bool d) override;
|
||||
|
||||
|
102
main.cpp
102
main.cpp
@@ -19,6 +19,7 @@
|
||||
#include <JUI/Widgets/ListLayout.hpp>
|
||||
#include <JUI/Widgets/TextRect.hpp>
|
||||
#include <JUI/Widgets/Image.hpp>
|
||||
#include <JUI/Widgets/Slider.hpp>
|
||||
#include <rewindow/types/window.h>
|
||||
#include <jlog/Logger.hpp>
|
||||
|
||||
@@ -38,11 +39,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 +52,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 +66,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);
|
||||
@@ -90,32 +91,35 @@ JUI::Scene* CreateScene() {
|
||||
|
||||
|
||||
// Button //
|
||||
RadioButton *button_element = new RadioButton(root);
|
||||
button_element->SetName("BobJim");
|
||||
button_element->BGColor({0, 0, 64});
|
||||
button_element->SetSize({0, 0, 0.1f, 0.1f});
|
||||
button_element->SetClipsDescendants(true);
|
||||
button_element->BorderColor({255, 255, 255});
|
||||
Button *button_element = new Button(root);
|
||||
button_element->Name("BobJim");
|
||||
button_element->BaseBGColor({64, 0, 64});
|
||||
button_element->PressedBGColor({0, 64, 64});
|
||||
button_element->Size({0, 0, 0.1f, 0.1f});
|
||||
button_element->Position({0,0,0.25f,0.25f});
|
||||
//button_element->SetClipsDescendants(true);
|
||||
button_element->BaseBorderColor({255, 255, 255});
|
||||
button_element->SetBorderWidth(2.f);
|
||||
|
||||
auto bpos = rect_element->Size();
|
||||
|
||||
//exit(1);
|
||||
button_element->SetPosition(
|
||||
{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});
|
||||
};
|
||||
button_element->OnToggleOffEvent += [rect_element] () {
|
||||
rect_element->BGColor({0, 64, 0});
|
||||
};
|
||||
button_element->OnToggleEvent += [button_element] () {
|
||||
Color4 incbg = button_element->BGColor();
|
||||
//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});
|
||||
//};
|
||||
//button_element->OnToggleOffEvent += [rect_element] () {
|
||||
// rect_element->BGColor({0, 64, 0});
|
||||
//};
|
||||
//button_element->OnToggleEvent += [button_element] () {
|
||||
// Color4 incbg = button_element->BGColor();
|
||||
// Once an overflow occurs it will reset anyway
|
||||
// Thanks computer science
|
||||
if (incbg.b < 255)
|
||||
incbg.b += 10;
|
||||
button_element->BGColor(incbg);
|
||||
};
|
||||
// if (incbg.b < 255)
|
||||
// incbg.b += 10;
|
||||
// button_element->BGColor(incbg);
|
||||
//};
|
||||
Text* btntext = new Text(button_element);
|
||||
btntext->SetContent("I AM BUTTON");
|
||||
btntext->SetFont(FreeSans);
|
||||
@@ -126,19 +130,20 @@ 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->CornerRounding(5);
|
||||
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 +153,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 +161,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 +169,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);
|
||||
|
||||
@@ -174,12 +179,16 @@ JUI::Scene* CreateScene() {
|
||||
text->SetTextSize(48);
|
||||
text->SetTextColor({255, 0, 0});
|
||||
|
||||
auto darkie = new Image(win_element->GetViewportInstance(), sample_texture);
|
||||
auto darkie = new JUI::Image(win_element->GetViewportInstance(), sample_texture);
|
||||
darkie->FitImageToParent(true);
|
||||
darkie->Color({255,255,255,128});
|
||||
|
||||
root->SetViewportSize(800, 600);
|
||||
|
||||
|
||||
//Slider* slider = new JUI::Slider(root);
|
||||
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -226,6 +235,21 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnMouseButtonUp(const ReWindow::WindowEvents::MouseButtonUpEvent &) override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OnMouseButtonDown(const ReWindow::WindowEvents::MouseButtonDownEvent &) override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OnMouseMove(const ReWindow::WindowEvents::MouseMoveEvent &) override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//bool OnResizeRequest(const ReWindow::WindowResizeRequestEvent &e) override {}
|
||||
JUIDevelopmentTestWindow() : ReWindow::RWindow() {}
|
||||
};
|
||||
|
@@ -5,7 +5,7 @@ namespace JUI
|
||||
LayoutContainer::LayoutContainer() {}
|
||||
|
||||
LayoutContainer::LayoutContainer(Widget* parent) {
|
||||
this->SetParent(parent);
|
||||
this->Parent(parent);
|
||||
}
|
||||
|
||||
void LayoutContainer::Update(float delta)
|
||||
|
@@ -30,19 +30,45 @@ namespace JUI {
|
||||
void RectBase::Draw(const Vector2 &abs_pos, const Vector2 &abs_size) {
|
||||
// Background rect
|
||||
J2D::Begin();
|
||||
J2D::FillRect(bg_color, abs_pos, abs_size);
|
||||
|
||||
if (corner_rounding_radius > 0)
|
||||
J2D::FillRoundedRect(bg_color, abs_pos, abs_size, corner_rounding_radius);
|
||||
else
|
||||
J2D::FillRect(bg_color, abs_pos, abs_size);
|
||||
|
||||
// Outline rect
|
||||
|
||||
Vector2 border_offset = {border_width/2, border_width/2};
|
||||
Vector2 border_offset = {0, 0};
|
||||
|
||||
if (border_mode == BorderMode::Inset)
|
||||
border_offset = {0, 0};
|
||||
if (border_mode == BorderMode::Middle)
|
||||
border_offset = {border_width/2, border_width/2};
|
||||
if (border_mode == BorderMode::Outline)
|
||||
border_offset = {border_width, border_width};
|
||||
|
||||
|
||||
// TODO: implement border_mode behavior when rendering here.
|
||||
|
||||
if (corner_rounding_radius >= 0)
|
||||
if (corner_rounding_radius > 0)
|
||||
J2D::OutlineRoundedRect(border_color, abs_pos - border_offset, abs_size + (border_offset*2), corner_rounding_radius, border_width);
|
||||
else
|
||||
J2D::OutlineRect(border_color, abs_pos - border_offset, abs_size + (border_offset*2), border_width);
|
||||
|
||||
J2D::End();
|
||||
}
|
||||
|
||||
void RectBase::BorderMode(const enum BorderMode &mode) {
|
||||
border_mode = mode;
|
||||
}
|
||||
|
||||
BorderMode RectBase::BorderMode() const { return border_mode; }
|
||||
|
||||
void RectBase::CornerRounding(float radius) {
|
||||
corner_rounding_radius = radius;
|
||||
}
|
||||
|
||||
float RectBase::CornerRounding() const { return corner_rounding_radius; }
|
||||
|
||||
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
#include "JUI/Base/Widget.hpp"
|
||||
#include <JUI/Base/Widget.hpp>
|
||||
#include <jlog/Logger.hpp>
|
||||
|
||||
#include <J3ML/Geometry/AABB2D.hpp>
|
||||
|
||||
namespace JUI {
|
||||
|
||||
@@ -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) { this->pad_left = pad_left; }
|
||||
void Widget::PaddingTop (const UDim& pad_top) { this->pad_top = pad_top; }
|
||||
void Widget::PaddingRight (const UDim& pad_right) { this->pad_right = pad_right; }
|
||||
void Widget::PaddingBottom(const UDim& pad_bottom) { this->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};
|
||||
@@ -223,13 +223,12 @@ namespace JUI {
|
||||
}
|
||||
|
||||
|
||||
// TODO: Consider std::optional
|
||||
Widget* Widget::FindFirstChild(const std::string& search_name) {
|
||||
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 nullptr;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
@@ -322,12 +321,21 @@ 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; }
|
||||
|
||||
AABB2D Widget::GetActualRenderBounds() const {
|
||||
return {GetAbsolutePosition(), GetAbsoluteSize()};
|
||||
}
|
||||
|
||||
}
|
17
src/JUI/Mixins/Clickable.cpp
Normal file
17
src/JUI/Mixins/Clickable.cpp
Normal file
@@ -0,0 +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;
|
||||
}
|
1
src/JUI/Mixins/Dockable.cpp
Normal file
1
src/JUI/Mixins/Dockable.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include <JUI/Mixins/Dockable.hpp>
|
1
src/JUI/Mixins/Draggable.cpp
Normal file
1
src/JUI/Mixins/Draggable.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include <JUI/Mixins/Draggable.hpp>
|
21
src/JUI/Mixins/Hoverable.cpp
Normal file
21
src/JUI/Mixins/Hoverable.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <JUI/Mixins/Hoverable.hpp>
|
||||
|
||||
void JUI::Hoverable::OnHover(const Vector2 &MousePos) {
|
||||
OnHoverEvent.Invoke(MousePos);
|
||||
}
|
||||
|
||||
void JUI::Hoverable::OnExit(const Vector2 &MousePos) {
|
||||
OnExitEvent.Invoke(MousePos);
|
||||
}
|
||||
|
||||
void JUI::Hoverable::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;
|
||||
}
|
||||
}
|
15
src/JUI/Mixins/Resizable.cpp
Normal file
15
src/JUI/Mixins/Resizable.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <JUI/Mixins/Resizable.hpp>
|
||||
|
||||
void JUI::Resizable::SetResize(bool b) {
|
||||
this->resizing = b;
|
||||
}
|
||||
|
||||
void JUI::Resizable::StartResizing(const Vector2 &point) {
|
||||
initial_resize_offset = point;
|
||||
}
|
||||
|
||||
void JUI::Resizable::StopResizing() {}
|
||||
|
||||
void JUI::Resizable::Update(float delta) {}
|
||||
|
||||
bool JUI::Resizable::Resizing() const { return resizing; }
|
20
src/JUI/Mixins/Toggleable.cpp
Normal file
20
src/JUI/Mixins/Toggleable.cpp
Normal 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();
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ namespace JUI
|
||||
Button::Button(): Widget() {}
|
||||
|
||||
Button::Button(Widget *parent): Clickable() {
|
||||
this->SetParent(parent);
|
||||
this->Parent(parent);
|
||||
};
|
||||
|
||||
void Button::Draw() {
|
||||
@@ -54,14 +54,27 @@ namespace JUI
|
||||
|
||||
void Button::OnClick(const Vector2& mouse_pos, const MouseButton& btn)
|
||||
{
|
||||
if (disabled)
|
||||
return;
|
||||
|
||||
Clickable::OnClick(mouse_pos, btn);
|
||||
clicked = true;
|
||||
|
||||
BGColor(PressedBGColor());
|
||||
BorderColor(PressedBorderColor());
|
||||
}
|
||||
|
||||
void Button::OnRelease(const J3ML::LinearAlgebra::Vector2 &mouse_pos, const JUI::MouseButton &btn,
|
||||
bool still_hovering) {
|
||||
|
||||
if (disabled)
|
||||
return;
|
||||
|
||||
Clickable::OnRelease(mouse_pos, btn, still_hovering);
|
||||
clicked = false;
|
||||
|
||||
BGColor(BaseBGColor());
|
||||
BorderColor(BaseBorderColor());
|
||||
}
|
||||
|
||||
void Button::Update(float delta) {
|
||||
@@ -86,9 +99,95 @@ namespace JUI
|
||||
prev_mb_state = mb_state;
|
||||
}
|
||||
|
||||
void Button::Enable() {
|
||||
SetEnabled(true);
|
||||
}
|
||||
|
||||
void Button::Disable() {
|
||||
SetEnabled(false);
|
||||
}
|
||||
|
||||
bool Button::Enabled() const {
|
||||
return !disabled;
|
||||
}
|
||||
|
||||
bool Button::Disabled() const {
|
||||
return disabled;
|
||||
}
|
||||
|
||||
void Button::SetEnabled(bool enabled) {
|
||||
|
||||
|
||||
// if state actually changed
|
||||
if (disabled != enabled)
|
||||
return;
|
||||
|
||||
if (disabled)
|
||||
OnDisabled.Invoke();
|
||||
else
|
||||
OnEnabled.Invoke();
|
||||
|
||||
disabled = !enabled;
|
||||
|
||||
BGColor(DisabledBGColor());
|
||||
BorderColor(DisabledBorderColor());
|
||||
}
|
||||
|
||||
void Button::OnHover(const Vector2 &MousePos) {
|
||||
Hoverable::OnHover(MousePos);
|
||||
|
||||
if (Disabled() || IsClicked())
|
||||
return;
|
||||
|
||||
BGColor(HoveredBGColor());
|
||||
BorderColor(HoveredBorderColor());
|
||||
}
|
||||
|
||||
void Button::OnExit(const Vector2 &MousePos) {
|
||||
Hoverable::OnExit(MousePos);
|
||||
|
||||
if (Disabled() || IsClicked())
|
||||
return;
|
||||
|
||||
BGColor(BaseBGColor());
|
||||
BorderColor(BaseBorderColor());
|
||||
}
|
||||
|
||||
Color4 Button::HoveredBGColor() const { return hover_bg; }
|
||||
|
||||
Color4 Button::BaseBGColor() const { return base_bg; }
|
||||
|
||||
Color4 Button::PressedBGColor() const { return pressed_bg; }
|
||||
|
||||
Color4 Button::DisabledBGColor() const { return disabled_bg;}
|
||||
|
||||
Color4 Button::HoveredBorderColor() const { return hover_border;}
|
||||
|
||||
Color4 Button::BaseBorderColor() const { return base_border;}
|
||||
|
||||
Color4 Button::PressedBorderColor() const { return pressed_border;}
|
||||
|
||||
Color4 Button::DisabledBorderColor() const { return disabled_border;}
|
||||
|
||||
void Button::HoveredBGColor(const Color4 &color) { hover_bg = color;}
|
||||
|
||||
void Button::BaseBGColor(const Color4 &color) { base_bg = color;}
|
||||
|
||||
void Button::PressedBGColor(const Color4 &color) { pressed_bg = color;}
|
||||
|
||||
void Button::DisabledBGColor(const Color4 &color) { disabled_bg = color;}
|
||||
|
||||
void Button::HoveredBorderColor(const Color4 &color) { hover_border = color;}
|
||||
|
||||
void Button::BaseBorderColor(const Color4 &color) {base_border = color; }
|
||||
|
||||
void Button::PressedBorderColor(const Color4 &color) { pressed_border = color;}
|
||||
|
||||
void Button::DisabledBorderColor(const Color4 &color) { disabled_border = color; }
|
||||
|
||||
TextButton::TextButton() : Button(), TextBase() {}
|
||||
TextButton::TextButton(Widget* parent) : TextButton() {
|
||||
this->SetParent(parent);
|
||||
this->Parent(parent);
|
||||
}
|
||||
|
||||
void TextButton::Update(float delta) {
|
||||
|
1
src/JUI/Widgets/Checkbox.cpp
Normal file
1
src/JUI/Widgets/Checkbox.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include <JUI/Widgets/Checkbox.hpp>
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
#include <JUI/Mixins/Toggleable.hpp>
|
||||
#include <JUI/Widgets/RadioButton.hpp>
|
||||
|
||||
namespace JUI
|
||||
@@ -5,7 +6,7 @@ namespace JUI
|
||||
|
||||
RadioButton::RadioButton() : Button(), Toggleable() {}
|
||||
RadioButton::RadioButton(Widget* parent) : RadioButton() {
|
||||
this->SetParent(parent);
|
||||
this->Parent(parent);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#include "JGL/JGL.h"
|
||||
#include "JUI/Widgets/Rect.hpp"
|
||||
#include <JGL/JGL.h>
|
||||
#include <JUI/Widgets/Rect.hpp>
|
||||
#include <jlog/Logger.hpp>
|
||||
|
||||
namespace JUI {
|
||||
Rect::Rect(): Widget(), RectBase() {}
|
||||
|
||||
Rect::Rect(Widget *parent): Rect() {
|
||||
this->SetParent(parent);
|
||||
this->Parent(parent);
|
||||
}
|
||||
|
||||
void Rect::Draw() {
|
||||
@@ -82,6 +82,22 @@ namespace JUI {
|
||||
return false;
|
||||
}
|
||||
|
||||
AABB2D Rect::GetActualRenderBounds() const {
|
||||
|
||||
Vector2 border = {border_width, border_width};
|
||||
|
||||
if (border_mode == BorderMode::Inset)
|
||||
return { GetAbsolutePosition(), GetAbsoluteSize()};
|
||||
|
||||
if (border_mode == BorderMode::Outline)
|
||||
return {GetAbsolutePosition() - border, GetAbsoluteSize() + border};
|
||||
|
||||
if (border_mode == BorderMode::Middle)
|
||||
return { GetAbsolutePosition() - (border/2), GetAbsoluteSize() + (border/2)};
|
||||
|
||||
return { GetAbsolutePosition(), GetAbsoluteSize()};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4,4 +4,8 @@
|
||||
namespace JUI
|
||||
{
|
||||
|
||||
Slider::Slider(JUI::Widget *parent)
|
||||
{
|
||||
this->Parent(parent);
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ namespace JUI {
|
||||
|
||||
Text::Text(Widget* parent) : Text()
|
||||
{
|
||||
this->SetParent(parent);
|
||||
this->Parent(parent);
|
||||
}
|
||||
|
||||
Text::~Text() {}
|
||||
|
@@ -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) {
|
||||
|
@@ -6,13 +6,13 @@
|
||||
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});
|
||||
this->SetBorderWidth(2);
|
||||
this->SetBorderMode(BorderMode::Outline);
|
||||
this->BorderMode(BorderMode::Outline);
|
||||
|
||||
//this->OnHoverEvent += [&] (Vector2 MousePos) {
|
||||
|
||||
@@ -42,22 +42,23 @@ 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->BorderColor({128, 128, 128, 255});
|
||||
|
||||
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->BorderColor({128, 128, 128, 0});
|
||||
//Topbar->SetBorderWidth(1);
|
||||
|
||||
TitleLabel = new Text(Topbar);
|
||||
@@ -70,9 +71,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 +87,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 +100,7 @@ namespace JUI
|
||||
}
|
||||
|
||||
Window::Window(Widget* parent) : Window() {
|
||||
this->SetParent(parent);
|
||||
this->Parent(parent);
|
||||
}
|
||||
|
||||
Vector2 Window::MinSize() const { return min_size; }
|
||||
@@ -162,7 +163,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 +171,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 +179,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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -220,4 +221,24 @@ namespace JUI
|
||||
void Window::SetTitle(const std::string &title) {
|
||||
GetTitleInstance()->SetContent(title);
|
||||
}
|
||||
|
||||
void Window::MinSize(const Vector2 &constraint) {
|
||||
min_size = constraint;
|
||||
}
|
||||
|
||||
void Window::MaxSize(const Vector2 &constraint) {
|
||||
max_size = constraint;
|
||||
}
|
||||
|
||||
void Window::SetDraggable(bool value) {
|
||||
draggable = value;
|
||||
}
|
||||
|
||||
void Window::SetDockable(bool value) {
|
||||
dockable = value;
|
||||
}
|
||||
|
||||
void Window::SetResizable(bool value) {
|
||||
resizable = value;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user