Spitball Redesigns
This commit is contained in:
@@ -28,7 +28,9 @@ endif()
|
||||
if (WIN32)
|
||||
add_library(JUI STATIC ${JUI_SRC}
|
||||
include/JUI/Mixins/DragAndDropReceiver.hpp
|
||||
include/JUI/Widgets/RadioButtonSet.hpp)
|
||||
include/JUI/Widgets/RadioButtonSet.hpp
|
||||
src/JUI/Widgets/UtilityBar.cpp
|
||||
include/JUI/Widgets/ContextMenu.hpp)
|
||||
endif()
|
||||
|
||||
set_target_properties(JUI PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
119
include/JUI/Widgets/ContextMenu.hpp
Normal file
119
include/JUI/Widgets/ContextMenu.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/// 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 Widget.hpp
|
||||
/// @desc Base Widget Class - All JUI widgets extend their behavior from this class.
|
||||
/// @edit 2024-10-11
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <JUI/Widgets/TextButton.hpp>
|
||||
|
||||
#include "ListLayout.hpp"
|
||||
|
||||
namespace JUI {
|
||||
|
||||
/// TODO: Observe and design all the base interfaces for various style categories.
|
||||
class TextStyleInterface {
|
||||
public:
|
||||
virtual ~TextStyleInterface() = default;
|
||||
|
||||
virtual JGL::Font Font() const = 0;
|
||||
virtual int TextSize() const = 0;
|
||||
virtual Color4 TextColor() const = 0;
|
||||
virtual bool WordWrap() const = 0;
|
||||
|
||||
|
||||
|
||||
virtual void Font(const JGL::Font& value) = 0;
|
||||
virtual void TextSize(int value) = 0;
|
||||
virtual void TextColor(const Color4& color) = 0;
|
||||
};
|
||||
|
||||
class RectStyleInterface {
|
||||
public:
|
||||
virtual Color4 BGColor() const = 0;
|
||||
virtual Color4 BorderColor() const = 0;
|
||||
virtual enum BorderMode BorderMode() const = 0;
|
||||
virtual float BorderWidth() const = 0;
|
||||
virtual float CornerRounding() const = 0;
|
||||
|
||||
virtual void BGColor(const Color4& color) = 0;
|
||||
virtual void BorderColor(const Color4& color) = 0;
|
||||
virtual void BorderMode(const enum BorderMode& borderMode) = 0;
|
||||
|
||||
};
|
||||
|
||||
class PaddingStyleInterface {
|
||||
|
||||
};
|
||||
|
||||
class MarginStyleInterface {
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// A vertically-descending list menu of button objects, which supports sub-menus much like class UtilityBar.
|
||||
/// @see UtilityBar
|
||||
class ContextMenu : public Rect, public TextStyleInterface {
|
||||
public:
|
||||
|
||||
void PropogateTextSize(int value) {
|
||||
for (auto* child : children) {
|
||||
TextStyleInterface* textual = dynamic_cast<TextStyleInterface *>(child);
|
||||
|
||||
if (textual)
|
||||
textual->TextSize(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the TextSize property for the child elements of this widget.
|
||||
void TextSize(int value) override {
|
||||
// TODO: This works fine for the ContextMenu, where children are assuemed to only by submenus and buttons.
|
||||
// Some widgets will need to be handled specially, because only some of their children are logically bound to it.
|
||||
PropogateTextSize(value);
|
||||
}
|
||||
|
||||
ContextMenu();
|
||||
|
||||
explicit ContextMenu(Widget* parent);
|
||||
|
||||
|
||||
void SetFont(const JGL::Font& use_my_font);
|
||||
|
||||
TextButton* AddButton(const std::string &name);
|
||||
|
||||
TextButton* AddButton(const std::string& name, const std::function<void()> &callback) {
|
||||
|
||||
auto* btn = AddButton(name);
|
||||
|
||||
// TODO: Is this memory safe at all?
|
||||
btn->OnClickEvent += [&] (auto a, auto b) mutable {
|
||||
callback();
|
||||
};
|
||||
return btn;
|
||||
}
|
||||
|
||||
std::pair<TextButton*, ContextMenu*> AddSubmenu(const std::string& name);
|
||||
|
||||
|
||||
/// Sets whether the widget will automatically hide itself when the mouse leaves its bounding box.
|
||||
void CloseOnHoverLoss(bool value);
|
||||
|
||||
/// @return Whether the widget will automatically hide itself when the mouse leaves its bounding box.
|
||||
[[nodiscard]] bool CloseOnHoverLoss() const;
|
||||
|
||||
protected:
|
||||
VerticalListLayout* layout;
|
||||
JGL::Font font;
|
||||
bool close_on_hover_loss = true;;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
@@ -1,100 +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 Widget.hpp
|
||||
/// @desc Base Widget Class - All JUI widgets extend their behavior from this class.
|
||||
/// @edit 2024-10-11
|
||||
|
||||
#pragma once
|
||||
#include "ContextMenu.hpp"
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
class UtilityBar;
|
||||
|
||||
class ContextMenu : public Rect {
|
||||
public:
|
||||
ContextMenu() : Rect() {
|
||||
Name("ContextMenu");
|
||||
this->BGColor(Colors::White);
|
||||
this->Margin(2_px);
|
||||
this->Size({200, 200, 0, 0});
|
||||
layout = new VerticalListLayout(this);
|
||||
|
||||
MouseExit += [this] (Vector2 _)
|
||||
{
|
||||
this->Visible(false);
|
||||
this->Parent(nullptr);
|
||||
// TODO: Collect
|
||||
};
|
||||
}
|
||||
|
||||
explicit ContextMenu(Widget* parent) : ContextMenu()
|
||||
{
|
||||
this->Parent(parent);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SetFont(const JGL::Font& use_my_font)
|
||||
{
|
||||
font = use_my_font;
|
||||
}
|
||||
TextButton* AddItem(const std::string &name)
|
||||
{
|
||||
auto* line_item = new TextButton(layout);
|
||||
line_item->SetFont(font);
|
||||
line_item->SetContent(name);
|
||||
line_item->SetTextSize(16);
|
||||
line_item->SetTextColor(Colors::Black);
|
||||
line_item->Size({0, 20, 1, 0});
|
||||
return line_item;
|
||||
}
|
||||
protected:
|
||||
VerticalListLayout* layout;
|
||||
JGL::Font font;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
/// A horizontal toolbar widget that is designed to be used at the top of windows, and subwindow widgets.
|
||||
/// Convenience functions are provided for adding tool buttons and sub-menus.
|
||||
/// @see class ContextMenu
|
||||
class UtilityBar : public Rect
|
||||
{
|
||||
public:
|
||||
UtilityBar() : Rect()
|
||||
{
|
||||
// TODO: Make a note that all JGL::Font members on widgets need to be initialized to JGL::Fonts::Jupiteroid inside the constructor.
|
||||
font = JGL::Fonts::Jupiteroid;
|
||||
UtilityBar();
|
||||
|
||||
this->Size({0, 20, 1, 0});
|
||||
this->Position({0,0,0,0});
|
||||
this->BGColor(Colors::White);
|
||||
this->BorderColor(Colors::Blues::CornflowerBlue);
|
||||
this->BorderWidth(2);
|
||||
this->Margin(2_px);
|
||||
this->BorderMode(BorderMode::Outline);
|
||||
layout = new HorizontalListLayout(this);
|
||||
//layout->PaddingLeft(2_px);
|
||||
layout->PaddingRight(2_px);
|
||||
//layout->PaddingRight(2_px);
|
||||
}
|
||||
explicit UtilityBar(Widget* parent);
|
||||
|
||||
explicit UtilityBar(Widget* parent) : UtilityBar() {
|
||||
this->Parent(parent);
|
||||
}
|
||||
|
||||
TextButton* AddSubmenu(const std::string& name)
|
||||
{
|
||||
auto btn = AddButton(name);
|
||||
/// Adds a new 'Submenu', which consists of a labeled button, which opens a contextual-submenu
|
||||
std::pair<TextButton*, ContextMenu*> AddSubmenu(const std::string& name);
|
||||
|
||||
|
||||
return btn;
|
||||
}
|
||||
TextButton* AddButton(const std::string& name);
|
||||
|
||||
|
||||
TextButton* AddButton(const std::string& name)
|
||||
{
|
||||
auto str_width = font.MeasureString(name, 14);
|
||||
|
||||
auto* btn = new TextButton(layout);
|
||||
btn->SetFont(font);
|
||||
btn->SetTextSize(14);
|
||||
btn->SetTextColor(Colors::Black);
|
||||
btn->Size({static_cast<int>(str_width.x)+16, 0, 0, 1});
|
||||
btn->BorderWidth(0.f);
|
||||
btn->SetContent(name);
|
||||
return btn;
|
||||
}
|
||||
void SetFont(const JGL::Font& use_my_font)
|
||||
{
|
||||
font = use_my_font;
|
||||
@@ -104,4 +41,4 @@ namespace JUI
|
||||
JGL::Font font;
|
||||
private:
|
||||
};
|
||||
}
|
||||
}
|
||||
|
19
main.cpp
19
main.cpp
@@ -70,12 +70,21 @@ JUI::Scene* CreateScene() {
|
||||
|
||||
auto* topbar = new UtilityBar(root);
|
||||
topbar->ZIndex(3);
|
||||
auto* file = topbar->AddButton("Demos");
|
||||
auto [demo_btn, demos] = topbar->AddSubmenu("Demos");
|
||||
|
||||
auto* file_tt = new JUI::Tooltip(file);
|
||||
file_tt->SetContent("Tooltip");
|
||||
demos->AddButton("9-Slice Widget Demo",
|
||||
[&] mutable { nineslice_demo_window->Toggle(); });
|
||||
|
||||
file->OnClickEvent += [&, root, nineslice_demo_window] (Vector2 pos, JUI::MouseButton btn)
|
||||
demos->AddButton("Scroll Widget Demo", [&] mutable {});
|
||||
|
||||
demos->AddButton("Command Line",
|
||||
[&] mutable{ console->Toggle();});
|
||||
|
||||
|
||||
//auto* file_tt = new JUI::Tooltip(file);
|
||||
//file_tt->SetContent("Tooltip");
|
||||
|
||||
/*file->OnClickEvent += [&, root, nineslice_demo_window] (Vector2 pos, JUI::MouseButton btn)
|
||||
{
|
||||
auto* ctx_menu = new ContextMenu(root);
|
||||
ctx_menu->Position(UDim2(0,20,0,0));
|
||||
@@ -97,7 +106,7 @@ JUI::Scene* CreateScene() {
|
||||
};
|
||||
|
||||
ctx_menu->ZIndex(3);
|
||||
};
|
||||
};*/
|
||||
|
||||
topbar->AddButton("Edit");
|
||||
auto* view = topbar->AddButton("View");
|
||||
|
49
src/JUI/Widgets/ContextMenu.cpp
Normal file
49
src/JUI/Widgets/ContextMenu.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <JUI/Widgets/ContextMenu.hpp>
|
||||
|
||||
namespace JUI {
|
||||
ContextMenu::ContextMenu(): Rect() {
|
||||
Name("ContextMenu");
|
||||
this->BGColor(Colors::White);
|
||||
this->Margin(2_px);
|
||||
this->Size({200, 200, 0, 0});
|
||||
layout = new VerticalListLayout(this);
|
||||
|
||||
MouseExit += [this] (Vector2 _)
|
||||
{
|
||||
this->Visible(false);
|
||||
this->Parent(nullptr);
|
||||
// TODO: Collect
|
||||
};
|
||||
}
|
||||
|
||||
ContextMenu::ContextMenu(Widget *parent): ContextMenu() {
|
||||
this->Parent(parent);
|
||||
|
||||
}
|
||||
|
||||
void ContextMenu::SetFont(const JGL::Font &use_my_font) {
|
||||
font = use_my_font;
|
||||
}
|
||||
|
||||
TextButton * ContextMenu::AddButton(const std::string &name) {
|
||||
auto* line_item = new TextButton(layout);
|
||||
line_item->SetFont(font);
|
||||
line_item->SetContent(name);
|
||||
line_item->SetTextSize(16);
|
||||
line_item->SetTextColor(Colors::Black);
|
||||
line_item->Size({0, 20, 1, 0});
|
||||
return line_item;
|
||||
}
|
||||
|
||||
std::pair<TextButton *, ContextMenu *> ContextMenu::AddSubmenu(const std::string &name) {
|
||||
auto* btn = AddButton(name);
|
||||
|
||||
// TODO: Duplicated code with UtilityBar.cpp
|
||||
auto* submenu = new JUI::ContextMenu(this);
|
||||
submenu->AnchorPoint({1, 0});
|
||||
}
|
||||
|
||||
void ContextMenu::CloseOnHoverLoss(bool value) { close_on_hover_loss = value;}
|
||||
|
||||
bool ContextMenu::CloseOnHoverLoss() const { return close_on_hover_loss; }
|
||||
}
|
60
src/JUI/Widgets/UtilityBar.cpp
Normal file
60
src/JUI/Widgets/UtilityBar.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <JUI/Widgets/UtilityBar.hpp>
|
||||
|
||||
namespace JUI {
|
||||
UtilityBar::UtilityBar(): Rect() {
|
||||
// TODO: Make a note that all JGL::Font members on widgets need to be initialized to JGL::Fonts::Jupiteroid inside the constructor.
|
||||
font = JGL::Fonts::Jupiteroid;
|
||||
|
||||
this->Size({0, 20, 1, 0});
|
||||
this->Position({0,0,0,0});
|
||||
this->BGColor(Colors::White);
|
||||
this->BorderColor(Colors::Blues::CornflowerBlue);
|
||||
this->BorderWidth(2);
|
||||
this->Margin(2_px);
|
||||
this->BorderMode(BorderMode::Outline);
|
||||
layout = new HorizontalListLayout(this);
|
||||
//layout->PaddingLeft(2_px);
|
||||
layout->PaddingRight(2_px);
|
||||
//layout->PaddingRight(2_px);
|
||||
}
|
||||
|
||||
UtilityBar::UtilityBar(Widget *parent): UtilityBar() {
|
||||
this->Parent(parent);
|
||||
}
|
||||
|
||||
std::pair<TextButton *, ContextMenu *> UtilityBar::AddSubmenu(const std::string &name) {
|
||||
auto btn = AddButton(name);
|
||||
|
||||
|
||||
auto* submenu = new JUI::ContextMenu(this);
|
||||
submenu->AnchorPoint({1, 0});
|
||||
submenu->Position({0_percent, 0_percent});
|
||||
|
||||
btn->OnClickEvent += [&] (auto a, auto b) mutable {
|
||||
submenu->Visible(true);
|
||||
};
|
||||
|
||||
// TODO: We seem to have duplicate events
|
||||
// Hoverable::OnExitEvent
|
||||
// RectBase::MouseExit
|
||||
//submenu->MouseExit += [&] (auto) mutable {
|
||||
// submenu->Visible(false);
|
||||
//};
|
||||
|
||||
|
||||
return {btn, submenu};
|
||||
}
|
||||
|
||||
TextButton * UtilityBar::AddButton(const std::string &name) {
|
||||
auto str_width = font.MeasureString(name, 14);
|
||||
|
||||
auto* btn = new TextButton(layout);
|
||||
btn->SetFont(font);
|
||||
btn->SetTextSize(14);
|
||||
btn->SetTextColor(Colors::Black);
|
||||
btn->Size({static_cast<int>(str_width.x)+16, 0, 0, 1});
|
||||
btn->BorderWidth(0.f);
|
||||
btn->SetContent(name);
|
||||
return btn;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user