Adding Anchors and Decorator Widget types.
This commit is contained in:
@@ -129,6 +129,8 @@ namespace JUI {
|
|||||||
[[nodiscard]] virtual Vector2 GetAbsolutePosition() const;
|
[[nodiscard]] virtual Vector2 GetAbsolutePosition() const;
|
||||||
[[nodiscard]] virtual float GetAbsoluteRotation() const;
|
[[nodiscard]] virtual float GetAbsoluteRotation() const;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual Vector2 GetAbsoluteCentroid() const;
|
||||||
|
|
||||||
/// Returns the parent of this widget, or a nullptr if there is no parent.
|
/// Returns the parent of this widget, or a nullptr if there is no parent.
|
||||||
/// @see GetFamilyTreeRoot().
|
/// @see GetFamilyTreeRoot().
|
||||||
Widget* GetParent() const;
|
Widget* GetParent() const;
|
||||||
|
62
include/JUI/Mixins/Focusable.hpp
Normal file
62
include/JUI/Mixins/Focusable.hpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/// 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 Focusable {
|
||||||
|
public:
|
||||||
|
Event<> OnGrabFocus;
|
||||||
|
Event<> OnDropFocus;
|
||||||
|
|
||||||
|
[[nodiscard]] bool Focused() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsFocused() const { return focused;}
|
||||||
|
[[nodiscard]] bool HasFocus() const { return focused;}
|
||||||
|
virtual void GrabFocus() { SetFocused(true);}
|
||||||
|
virtual void DropFocus(const Vector2& point) {
|
||||||
|
if (do_focus_cooldown_hack && focus_hack_cooldown > time_focused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetFocused(false);
|
||||||
|
}
|
||||||
|
virtual void SetFocused(bool value) {
|
||||||
|
focused = value;
|
||||||
|
if (do_focus_cooldown_hack && value) time_focused = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Update(float delta) {
|
||||||
|
if (do_focus_cooldown_hack)
|
||||||
|
time_focused += delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoFocusHackCooldown(bool value) { do_focus_cooldown_hack = value; }
|
||||||
|
bool DoFocusHackCooldown() const { return do_focus_cooldown_hack; }
|
||||||
|
|
||||||
|
float FocusHackCooldown() const { return focus_hack_cooldown; }
|
||||||
|
void FocusHackCooldown(float value) {
|
||||||
|
focus_hack_cooldown = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool focused = false;
|
||||||
|
float time_focused = 0;
|
||||||
|
|
||||||
|
bool do_focus_cooldown_hack = false;
|
||||||
|
float focus_hack_cooldown = 0.1f;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
namespace JUI
|
namespace JUI
|
||||||
{
|
{
|
||||||
|
|
||||||
using namespace J3ML::LinearAlgebra;
|
using namespace J3ML::LinearAlgebra;
|
||||||
|
|
||||||
/// Funky Coordinate system purpose-built for screen positioning
|
/// Funky Coordinate system purpose-built for screen positioning
|
||||||
@@ -26,6 +25,17 @@ namespace JUI
|
|||||||
/// @see UDim.hpp
|
/// @see UDim.hpp
|
||||||
class UDim2
|
class UDim2
|
||||||
{
|
{
|
||||||
|
public: // Constants
|
||||||
|
static const UDim2 Center;
|
||||||
|
static const UDim2 TopLeft;
|
||||||
|
static const UDim2 BottomRight;
|
||||||
|
static const UDim2 BottomLeft;
|
||||||
|
static const UDim2 TopRight;
|
||||||
|
|
||||||
|
static const UDim2 TopCenter;
|
||||||
|
static const UDim2 LeftCenter;
|
||||||
|
static const UDim2 BottomCenter;
|
||||||
|
static const UDim2 RightCenter;
|
||||||
public: // Properties
|
public: // Properties
|
||||||
UDim X;
|
UDim X;
|
||||||
UDim Y;
|
UDim Y;
|
||||||
|
88
include/JUI/Widgets/Anchor.hpp
Normal file
88
include/JUI/Widgets/Anchor.hpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <JUI/Base/Widget.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace JUI {
|
||||||
|
|
||||||
|
/// An invisible, point-like widget which is used to attach decorator-type widgets at a given point.
|
||||||
|
/// For example: The CurveSegment Widget uses two Anchors for it's endpoints.
|
||||||
|
class Anchor : public Widget {
|
||||||
|
public:
|
||||||
|
Anchor() : Widget() {
|
||||||
|
|
||||||
|
}
|
||||||
|
explicit Anchor(Widget* parent) : Anchor() {
|
||||||
|
Parent(parent);
|
||||||
|
};
|
||||||
|
explicit Anchor(Widget* parent, const UDim2& position) : Anchor(parent) {
|
||||||
|
Position(position);
|
||||||
|
Size({0_px, 0_px});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(float elapsed) override {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Draw() override {
|
||||||
|
Color4 debug_color = Colors::Red;
|
||||||
|
float debug_size = 4;
|
||||||
|
|
||||||
|
J2D::FillCircle(debug_color, GetAbsolutePosition(), debug_size, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Point() { return GetAbsolutePosition(); }
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class Decorator : public Widget {
|
||||||
|
public:
|
||||||
|
Decorator() : Widget(){
|
||||||
|
|
||||||
|
}
|
||||||
|
explicit Decorator(Widget* parent) : Decorator() {
|
||||||
|
Parent(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ArrowDecorator : public Decorator {
|
||||||
|
public:
|
||||||
|
explicit ArrowDecorator(Widget* parent, Anchor* a, Anchor* b) : Decorator() {
|
||||||
|
Parent(parent);
|
||||||
|
origin = a;
|
||||||
|
goal = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Draw() override {
|
||||||
|
using namespace J3ML;
|
||||||
|
Color4 line_color = Colors::Green;
|
||||||
|
float line_size = 4;
|
||||||
|
|
||||||
|
J2D::DrawLine(line_color, origin->Point(), goal->Point(), line_size);
|
||||||
|
|
||||||
|
Vector2 lookback_dir = goal->Point() - origin->Point();
|
||||||
|
|
||||||
|
Rotation angle = lookback_dir.AimedAngle();
|
||||||
|
|
||||||
|
angle += 10_degrees;
|
||||||
|
|
||||||
|
Vector2 fan_vector_left = (Math::Cos(angle), Math::Sin(angle));
|
||||||
|
|
||||||
|
Vector2 tri_polys[3] = {
|
||||||
|
origin->Point(),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
J2D::FillTriangle(line_color);
|
||||||
|
|
||||||
|
//J2D::FillTriangle();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
Anchor* origin;
|
||||||
|
Anchor* goal;
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
@@ -41,7 +41,6 @@ namespace JUI
|
|||||||
auto* rect = new JUI::TextRect(file_layout);
|
auto* rect = new JUI::TextRect(file_layout);
|
||||||
rect->Size({100_percent, 20_px});
|
rect->Size({100_percent, 20_px});
|
||||||
|
|
||||||
|
|
||||||
std::string entry_type = entry.is_directory() ? "directory" : "file";
|
std::string entry_type = entry.is_directory() ? "directory" : "file";
|
||||||
std::string perms = stringify(entry.status().permissions());
|
std::string perms = stringify(entry.status().permissions());
|
||||||
std::string type = stringify(entry.status().type());
|
std::string type = stringify(entry.status().type());
|
||||||
|
24
main.cpp
24
main.cpp
@@ -34,6 +34,7 @@
|
|||||||
#include <JUI/Widgets/Collapsible.hpp>
|
#include <JUI/Widgets/Collapsible.hpp>
|
||||||
#include <JUI/Widgets/CommandLine.hpp>
|
#include <JUI/Widgets/CommandLine.hpp>
|
||||||
|
|
||||||
|
#include "JUI/Widgets/Anchor.hpp"
|
||||||
#include "JUI/Widgets/ColorPicker.hpp"
|
#include "JUI/Widgets/ColorPicker.hpp"
|
||||||
#include "JUI/Widgets/FileDialog.hpp"
|
#include "JUI/Widgets/FileDialog.hpp"
|
||||||
#include "JUI/Widgets/FpsGraph.hpp"
|
#include "JUI/Widgets/FpsGraph.hpp"
|
||||||
@@ -160,7 +161,9 @@ JUI::UtilityBar* CreateUtilityBar(JUI::Widget* root) {
|
|||||||
|
|
||||||
demos->AddButton("Scroll Widget Demo", [&] {});
|
demos->AddButton("Scroll Widget Demo", [&] {});
|
||||||
|
|
||||||
demos->AddButton("Command Line", [&]{ console->Toggle();});
|
demos->AddButton("Command Line", [&] {
|
||||||
|
console->Toggle();
|
||||||
|
});
|
||||||
|
|
||||||
demos->AddButton("File Dialog", [&] {CreateFileDialog();});
|
demos->AddButton("File Dialog", [&] {CreateFileDialog();});
|
||||||
|
|
||||||
@@ -176,6 +179,13 @@ JUI::UtilityBar* CreateUtilityBar(JUI::Widget* root) {
|
|||||||
berries->AddButton("Blueberries");
|
berries->AddButton("Blueberries");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* ptA = new JUI::Anchor(topbar, {10_px, 20_px});
|
||||||
|
|
||||||
|
auto* ptB = new JUI::Anchor(demos, UDim2::Center);
|
||||||
|
|
||||||
|
auto* line = new JUI::ArrowDecorator(topbar, ptA, ptB);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* edit = topbar->AddButton("Edit");
|
auto* edit = topbar->AddButton("Edit");
|
||||||
@@ -552,18 +562,6 @@ JUI::Scene* CreateScene() {
|
|||||||
auto* widget_list = CreateWidgetList(root);
|
auto* widget_list = CreateWidgetList(root);
|
||||||
|
|
||||||
|
|
||||||
//auto* horizontal = new HorizontalListLayout(root);
|
|
||||||
//horizontal->ZIndex(1);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//auto* separator_a = new Rect(radio_btn_set_layout());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//nineslice_demo_window->Padding(1_px);
|
|
||||||
// End Window //
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
root->SetViewportSize({800, 600});
|
root->SetViewportSize({800, 600});
|
||||||
|
@@ -147,6 +147,10 @@ float Widget::GetAbsoluteRotation() const {
|
|||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2 Widget::GetAbsoluteCentroid() const {
|
||||||
|
return GetAbsolutePosition() + (GetAbsoluteSize() / 2.f);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Widget *> Widget::GetChildren() { return children; }
|
std::vector<Widget *> Widget::GetChildren() { return children; }
|
||||||
|
|
||||||
std::vector<Widget *> Widget::GetDescendants() {
|
std::vector<Widget *> Widget::GetDescendants() {
|
||||||
|
3
src/JUI/Mixins/Focusable.cpp
Normal file
3
src/JUI/Mixins/Focusable.cpp
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#include <JUI/Mixins/Focusable.hpp>
|
||||||
|
|
||||||
|
bool JUI::Focusable::Focused() const { return focused; }
|
@@ -1,5 +1,18 @@
|
|||||||
#include <JUI/UDim2.hpp>
|
#include <JUI/UDim2.hpp>
|
||||||
|
|
||||||
|
const JUI::UDim2 JUI::UDim2::Center {50_percent, 50_percent};
|
||||||
|
|
||||||
|
const JUI::UDim2 JUI::UDim2::TopLeft {0_percent, 0_percent};
|
||||||
|
const JUI::UDim2 JUI::UDim2::BottomRight {100_percent, 100_percent};
|
||||||
|
const JUI::UDim2 JUI::UDim2::BottomLeft {0_percent, 100_percent};
|
||||||
|
const JUI::UDim2 JUI::UDim2::TopRight {100_percent, 0_percent};
|
||||||
|
|
||||||
|
const JUI::UDim2 JUI::UDim2::TopCenter {50_percent, 0_percent};
|
||||||
|
const JUI::UDim2 JUI::UDim2::LeftCenter {0_percent, 50_percent};
|
||||||
|
const JUI::UDim2 JUI::UDim2::BottomCenter {50_percent, 100_percent};
|
||||||
|
|
||||||
|
const JUI::UDim2 JUI::UDim2::RightCenter {100_percent, 50_percent};
|
||||||
|
|
||||||
JUI::UDim2::UDim2() {
|
JUI::UDim2::UDim2() {
|
||||||
//X = {0, 0.f};
|
//X = {0, 0.f};
|
||||||
//Y = {0, 0.f};
|
//Y = {0, 0.f};
|
||||||
|
Reference in New Issue
Block a user