Refactoring for organization.

This commit is contained in:
2025-05-13 14:28:02 -05:00
parent 0ff787fd95
commit 21fee89e77
4 changed files with 120 additions and 49 deletions

View File

@@ -50,40 +50,37 @@ namespace JUI {
/// A vertically-descending list menu of button objects, which supports sub-menus much like class UtilityBar.
/// @see UtilityBar
class ContextMenu : public Rect, public Pinnable, public NestableMenu {
class ContextMenu : public Rect, public Pinnable, public NestableMenu, public TextStyler {
public:
Event<> PresumeMouseFocusLost;
// TODO: Work in progress.
void PropogateTextSize(int value) {
for (auto* child : children) {
TextStyler* textual = dynamic_cast<TextStyler *>(child);
if (textual)
textual->TextSize(value);
}
}
/// Sets the TextSize property for the child elements of this widget.
void TextSize(int value) {
// 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);
}
/// The default constructor initializes base state of the widget.
ContextMenu();
/// Constructs this object by explicitly specifying the parent element.
explicit ContextMenu(Widget* parent);
void SetFont(const JGL::Font& use_my_font);
public:
Event<> PresumeMouseFocusLost;
public:
/// Adds a new button to this ContextMenu.
/// @param name The label to apply to the new button.
TextButton* AddButton(const std::string &name) override;
/// Adds a new button to this ContextMenu.
/// @param name The label to apply to the new button.
/// @param callback The function to run when the button is clicked.
TextButton* AddButton(const std::string& name, const std::function<void()> &callback) override;
/// Adds a separator to this ContextMenu.
/// @param size The height of this separator.
Separator* AddSeparator(const UDim& size = 5_px) override;
/// Adds a button, which opens a submenu, to this ContextMenu. Only the submenu is returned.
ContextMenu* AddSubmenu(const std::string& name) override;
/// Sets the text size of the buttons and sub-menus managed by this object.
void TextSize(int value) override;
/// Sets the text color of the buttons and sub-menus managed by this object.
void TextColor(const Color4& color) override;
/// Sets the font of the buttons and sub-menus managed by this object.
void Font(const JGL::Font& value) override;
/// Sets whether the widget will automatically hide itself when the mouse leaves its bounding box.
void CloseOnHoverLoss(bool value);
@@ -92,26 +89,19 @@ namespace JUI {
[[nodiscard]] bool CloseOnHoverLoss() const;
void Update(float delta) override {
Rect::Update(delta);
if (parent->IsMouseInside() || IsMouseInside() || IsMouseInsideDescendants())
mouse_outside_tests = 0;
else
mouse_outside_tests++;
if (mouse_outside_tests >= 3)
PresumeMouseFocusLost();
}
void Update(float delta) override;
protected:
VerticalListLayout* layout;
JGL::Font font;
bool close_on_hover_loss = true;
float aggregate_height = 0;
float estimated_width = 0;
float mouse_outside_tests = 0;
// TODO: This is handled the same way as in UtilityBar, proposed to abstract it away into NestableMenu.
std::vector<TextButton*> buttons;
std::vector<ContextMenu*> submenus;
private:
};

View File

@@ -17,15 +17,13 @@ namespace JUI
class UtilityBar;
/// 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 NestableMenu
class UtilityBar : public Rect, public NestableMenu, public TextStyler
{
public:
UtilityBar();
explicit UtilityBar(Widget* parent);
@@ -33,15 +31,22 @@ namespace JUI
/// Adds a new 'Submenu', which consists of a labeled button, which opens a contextual-submenu
ContextMenu* AddSubmenu(const std::string& name) override;
TextButton* AddButton(const std::string& name) override;
TextButton* AddButton(const std::string& name, const std::function<void()>& callback) override;
Separator* AddSeparator(const UDim& size = 5_px) override;
std::vector<TextButton*> GetButtons() { return buttons;}
std::vector<ContextMenu*> GetSubmenus() { return submenus;}
void Font(const JGL::Font &value) override;
void TextSize(int value) override;
void TextColor(const Color4 &color) override;
protected:
//std::vector<TextButton*> buttons;
//std::vector<ContextMenu*> submenus;
std::vector<TextButton*> buttons;
std::vector<ContextMenu*> submenus;
HorizontalListLayout* layout = nullptr;
private:

View File

@@ -18,8 +18,31 @@ namespace JUI {
this->Parent(parent);
}
void ContextMenu::SetFont(const JGL::Font &use_my_font) {
font = use_my_font;
void ContextMenu::TextSize(int value) {
TextStyler::TextSize(value);
for (auto* btn : buttons)
btn->TextSize(value);
for (auto* submenu: submenus)
submenu->TextSize(value);
}
void ContextMenu::TextColor(const Color4 &color) {
TextStyler::TextColor(color);
for (auto* btn : buttons)
btn->TextColor(color);
for (auto* submenu: submenus)
submenu->TextColor(color);
}
void ContextMenu::Font(const JGL::Font &value) {
TextStyler::Font(value);
for (auto* btn : buttons)
btn->Font(value);
for (auto* submenu: submenus)
submenu->Font(value);
}
float GuesstimateTextWidth(const std::string& text, int ptSize) {
@@ -46,6 +69,9 @@ namespace JUI {
this->size.X.Pixels = estimated_width;
this->size.Y.Pixels = aggregate_height;
buttons.push_back(line_item);
return line_item;
}
@@ -64,6 +90,12 @@ namespace JUI {
Separator * ContextMenu::AddSeparator(const UDim& size) {
auto* separator = new Separator(layout);
separator->Size({100_percent, size});
// TODO: Temp Hack: Implement Auto-size.
aggregate_height += separator->GetAbsoluteSize().y;
this->size.X.Pixels = estimated_width;
this->size.Y.Pixels = aggregate_height;
return separator;
}
@@ -90,10 +122,25 @@ namespace JUI {
this->Unpin();
};
submenus.push_back(submenu);
return submenu;
}
void ContextMenu::CloseOnHoverLoss(bool value) { close_on_hover_loss = value;}
bool ContextMenu::CloseOnHoverLoss() const { return close_on_hover_loss; }
void ContextMenu::Update(float delta) {
Rect::Update(delta);
if (parent->IsMouseInside() || IsMouseInside() || IsMouseInsideDescendants())
mouse_outside_tests = 0;
else
mouse_outside_tests++;
if (mouse_outside_tests >= 3)
PresumeMouseFocusLost();
}
}

View File

@@ -25,7 +25,8 @@ namespace JUI {
ContextMenu * UtilityBar::AddSubmenu(const std::string &name) {
auto* btn = AddButton(name);
auto* submenu = new JUI::ContextMenu(this);
auto* submenu = new JUI::ContextMenu(btn);
//submenu->AnchorPoint({0, 1});
// TODO: Fix AnchorPoint behavior!!
submenu->Position({0_percent, 100_percent});
@@ -36,6 +37,7 @@ namespace JUI {
submenu->Visible(true);
};
submenus.push_back(submenu);
return submenu;
}
@@ -52,7 +54,7 @@ namespace JUI {
btn->BorderWidth(0.f);
btn->Content(name);
//buttons.push_back(btn);
buttons.push_back(btn);
return btn;
}
@@ -75,4 +77,31 @@ namespace JUI {
return new Separator(layout);
}
void UtilityBar::Font(const JGL::Font &value) {
TextStyler::Font(value);
for (auto* btn : buttons)
btn->Font(value);
for (auto* submenu : submenus)
submenu->Font(value);
}
void UtilityBar::TextSize(int value) {
TextStyler::TextSize(value);
for (auto* btn : buttons)
btn->TextSize(value);
for (auto* submenu : submenus)
submenu->TextSize(value);
}
void UtilityBar::TextColor(const Color4 &color) {
TextStyler::TextColor(color);
for (auto* btn : buttons)
btn->TextColor(color);
for (auto* submenu : submenus)
submenu->TextColor(color);
}
}