Working on ContextMenu & UtilityBar
This commit is contained in:
@@ -93,13 +93,13 @@ namespace JUI {
|
||||
auto* btn = AddButton(name);
|
||||
|
||||
// TODO: Is this memory safe at all?
|
||||
btn->OnClickEvent += [&] (auto a, auto b) mutable {
|
||||
btn->OnClickEvent += [&, callback] (auto a, auto b) mutable {
|
||||
callback();
|
||||
};
|
||||
return btn;
|
||||
}
|
||||
|
||||
std::pair<TextButton*, ContextMenu*> AddSubmenu(const std::string& name);
|
||||
ContextMenu* AddSubmenu(const std::string& name);
|
||||
|
||||
|
||||
/// Sets whether the widget will automatically hide itself when the mouse leaves its bounding box.
|
||||
|
@@ -16,6 +16,9 @@ namespace JUI
|
||||
{
|
||||
class UtilityBar;
|
||||
|
||||
|
||||
// TODO: Automatically adjust to make this widget's width that of the widest subcomponent button.
|
||||
|
||||
/// 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
|
||||
@@ -31,6 +34,12 @@ namespace JUI
|
||||
|
||||
|
||||
TextButton* AddButton(const std::string& name);
|
||||
TextButton* AddButton(const std::string& name, const std::function<void()>& callback) {
|
||||
auto* button = AddButton(name);
|
||||
|
||||
button->OnClickEvent += [&, callback] (auto a, auto b) mutable { callback();};
|
||||
return button;
|
||||
}
|
||||
|
||||
protected:
|
||||
//std::vector<TextButton*> buttons;
|
||||
|
270
main.cpp
270
main.cpp
@@ -30,111 +30,135 @@
|
||||
#include <JUI/Widgets/Collapsible.hpp>
|
||||
#include <JUI/Widgets/CommandLine.hpp>
|
||||
|
||||
using namespace JUI;
|
||||
|
||||
|
||||
float ui_scale = 1.f;
|
||||
float accum = 0;
|
||||
int iter = 0;
|
||||
|
||||
JUI::Scene* scene;
|
||||
JGL::Texture* sample_texture;
|
||||
JGL::Texture* slicer;
|
||||
JUI::VerticalListLayout* list;
|
||||
JUI::Window* scroller_window;
|
||||
JUI::ScrollingRect* scroller;
|
||||
JUI::TextRect* widget_count;
|
||||
JUI::CommandLine* console;
|
||||
JUI::Window* nineslice_demo_window;
|
||||
JUI::UtilityBar* topbar;
|
||||
|
||||
int count_descendants(JUI::Widget* w) {
|
||||
return w->GetDescendants().size();
|
||||
}
|
||||
|
||||
JUI::Scene* CreateScene() {
|
||||
using namespace JUI;
|
||||
JUI::Window* CreateInfoboxWindow(JUI::Widget* root) {
|
||||
|
||||
auto *root = new Scene();
|
||||
}
|
||||
|
||||
/*root->DescendantAdded += [&] (auto* node) {
|
||||
widget_count->SetContent("Widgets: " + count_descendants(root));
|
||||
};
|
||||
|
||||
root->DescendantRemoved += [&] (auto* node) {
|
||||
widget_count->SetContent("Widgets: " + count_descendants(root));
|
||||
};*/
|
||||
|
||||
auto* nineslice_demo_window = new JUI::Window(root);
|
||||
/// Constructs, applies layout, and returns, a JUI::Window which demonstrates the NineSliceRect capability.
|
||||
/// @param root The Widget to parent the NineSliceRect to.
|
||||
JUI::Window* CreateNinesliceWindow(JUI::Widget* root) {
|
||||
nineslice_demo_window = new JUI::Window(root);
|
||||
nineslice_demo_window->Name("NineSlice Demo Window");
|
||||
nineslice_demo_window->CornerRounding(10);
|
||||
nineslice_demo_window->Size({50_percent, 50_percent});
|
||||
nineslice_demo_window->SetTitle("9-Slice Demo");
|
||||
nineslice_demo_window->Visible(false);
|
||||
nineslice_demo_window->TitlebarHeight(12);
|
||||
nineslice_demo_window->Close();
|
||||
nineslice_demo_window->TitlebarHeight(12); {
|
||||
auto* nineslice = new JUI::NineSliceRect(nineslice_demo_window);
|
||||
nineslice->Content(slicer);
|
||||
nineslice->Size({100_percent, 100_percent});
|
||||
nineslice->BGColor(Colors::Transparent);
|
||||
nineslice->TopLeftQuad({{0,0},{96,96}});
|
||||
nineslice->TopRightQuad({{384-96,0},{96,96}});
|
||||
nineslice->BottomLeftQuad({ {0, 378-96}, {96, 96}});
|
||||
nineslice->BottomRightQuad({ {384-96, 378-96}, {96, 96}});
|
||||
nineslice->TopQuad({ {96, 0}, {192, 96} });
|
||||
nineslice->BottomQuad({ {96, 378-96}, {192, 96} });
|
||||
nineslice->RightQuad({{384-(96), 96}, {96, 378-(96*2)}});
|
||||
nineslice->LeftQuad({{0, 96}, {96, 378-(96*2)}});
|
||||
nineslice->CenterQuad({{96, 96}, {384-(96*2), 378-(96*2)}});
|
||||
auto* darkie = new JUI::Image(nineslice_demo_window->ViewportInstance(), sample_texture); {
|
||||
darkie->FitImageToParent(true);
|
||||
darkie->Color({255,255,255,128});
|
||||
auto* list = new VerticalListLayout(nineslice_demo_window->ViewportInstance()); {
|
||||
list->Padding(10_px);
|
||||
TextRect* a = new TextRect(list); {
|
||||
a->SetTextSize(16); a->Size({0, 20, 1, 0}); a->Center();
|
||||
a->SetContent("This is a virtual window.");
|
||||
}
|
||||
TextRect* b = new TextRect(list); {
|
||||
b->SetTextSize(16); b->Size({0, 20, 1, 0}); b->Center();
|
||||
b->SetContent("You can drag it around via left-click, and resize via right-click. Isn't that cool??");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nineslice_demo_window;
|
||||
}
|
||||
|
||||
console = new JUI::CommandLine(root);
|
||||
console->Close();
|
||||
JUI::UtilityBar* CreateUtilityBar(JUI::Widget* root) {
|
||||
auto* topbar = new UtilityBar(root); {
|
||||
topbar->ZIndex(3);
|
||||
|
||||
JUI::UILogs.OnLog += [&] (const std::string& msg, Color4 c){ console->Log(msg, c);};
|
||||
// TODO: Make it so that when you mouse over another option in the *parent* menu, it closes any open submenus.
|
||||
auto* demos = topbar->AddSubmenu("Demos");
|
||||
{
|
||||
demos->AddButton("9-Slice Widget Demo",
|
||||
[&] mutable { nineslice_demo_window->Toggle(); });
|
||||
|
||||
auto* topbar = new UtilityBar(root);
|
||||
topbar->ZIndex(3);
|
||||
demos->AddButton("Scroll Widget Demo", [&] mutable {});
|
||||
|
||||
auto* demos = topbar->AddSubmenu("Demos");
|
||||
demos->AddButton("Command Line",
|
||||
[&] mutable{ console->Toggle();});
|
||||
|
||||
demos->AddButton("9-Slice Widget Demo",
|
||||
[&] mutable { nineslice_demo_window->Toggle(); });
|
||||
auto* test_sub = demos->AddSubmenu("Submenu"); {
|
||||
test_sub->AddButton("Apples");
|
||||
test_sub->AddButton("Bananas");
|
||||
test_sub->AddButton("Oranges");
|
||||
}
|
||||
}
|
||||
|
||||
demos->AddButton("Scroll Widget Demo", [&] mutable {});
|
||||
|
||||
demos->AddButton("Command Line",
|
||||
[&] mutable{ console->Toggle();});
|
||||
auto* edit = topbar->AddButton("Edit");
|
||||
auto* view = topbar->AddSubmenu("View"); {
|
||||
view->AddButton("Increase UI Scale 5%", [&]mutable {
|
||||
ui_scale += 0.05f;
|
||||
});
|
||||
view->AddButton("Decrease UI Scale 5%", [&] mutable{
|
||||
ui_scale -= 0.05f;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//auto* file_tt = new JUI::Tooltip(file);
|
||||
//file_tt->SetContent("Tooltip");
|
||||
auto* help = topbar->AddButton("About", [&] mutable {
|
||||
|
||||
/*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));
|
||||
auto* open_nineslice = ctx_menu->AddItem("9-Slice Widget Demo");
|
||||
});
|
||||
|
||||
open_nineslice->OnClickEvent += [&, nineslice_demo_window] (Vector2 pos, JUI::MouseButton btn) {
|
||||
nineslice_demo_window->Visible(true);
|
||||
};
|
||||
widget_count = new JUI::TextRect(topbar);
|
||||
widget_count->Size(UDim2(100,20,0,0));
|
||||
widget_count->AnchorPoint({1, 0});
|
||||
widget_count->Position({100_percent, 0_percent});
|
||||
widget_count->BGColor(Colors::Transparent);
|
||||
widget_count->SetTextColor(Colors::Black);
|
||||
widget_count->BorderColor(Colors::Transparent);
|
||||
widget_count->BorderWidth(0);
|
||||
widget_count->Center();
|
||||
widget_count->AlignRight();
|
||||
|
||||
auto* open_scroll = ctx_menu->AddItem("Scroll Widget Demo");
|
||||
}
|
||||
return topbar;
|
||||
}
|
||||
|
||||
open_scroll->OnClickEvent += [&] (Vector2 pos, JUI::MouseButton btn) {};
|
||||
//ctx_menu->AddItem("");
|
||||
|
||||
|
||||
auto* open_console = ctx_menu->AddItem("Command Line");
|
||||
open_console->OnClickEvent += [&] (Vector2 pos, JUI::MouseButton btn)mutable {
|
||||
console->Open();
|
||||
};
|
||||
|
||||
ctx_menu->ZIndex(3);
|
||||
};*/
|
||||
|
||||
topbar->AddButton("Edit");
|
||||
auto* view = topbar->AddButton("View");
|
||||
|
||||
topbar->AddButton("Help");
|
||||
|
||||
widget_count = new JUI::TextRect(topbar);
|
||||
widget_count->Size(UDim2(100,20,0,0));
|
||||
widget_count->AnchorPoint({1, 0});
|
||||
widget_count->Position({100_percent, 0_percent});
|
||||
widget_count->BGColor(Colors::Transparent);
|
||||
widget_count->SetTextColor(Colors::Black);
|
||||
widget_count->BorderColor(Colors::Transparent);
|
||||
widget_count->BorderWidth(0);
|
||||
widget_count->Center();
|
||||
widget_count->AlignRight();
|
||||
|
||||
//auto* horizontal = new HorizontalListLayout(root);
|
||||
//horizontal->ZIndex(1);
|
||||
|
||||
auto* column_rect = new Rect(root);
|
||||
/// Constructs, styles, and returns a JUI::Rect which contains a sample of each widget in action.
|
||||
JUI::Rect* CreateWidgetList(JUI::Widget* root) {
|
||||
auto* widget_list = new Rect(root);
|
||||
//column_rect->ZIndex(4);
|
||||
column_rect->Size({0, -24, 0.2f, 1.f});
|
||||
column_rect->Position({0, 24, 0, 0});
|
||||
column_rect->BGColor(Colors::Grays::Gainsboro);
|
||||
widget_list->Size({0, -24, 0.2f, 1.f});
|
||||
widget_list->Position({0, 24, 0, 0});
|
||||
widget_list->BGColor(Colors::Grays::Gainsboro);
|
||||
|
||||
auto* column_layout = new VerticalListLayout(column_rect);
|
||||
auto* column_layout = new VerticalListLayout(widget_list);
|
||||
|
||||
auto* btn_container1 = new Rect(column_layout);
|
||||
btn_container1->Size({100_percent, 24_px});
|
||||
@@ -264,73 +288,75 @@ JUI::Scene* CreateScene() {
|
||||
radio_c_label->SetContent("C ");
|
||||
radio_c_label->SetTextSize(12);
|
||||
|
||||
//auto* separator_a = new Rect(radio_btn_set_layout());
|
||||
return widget_list;
|
||||
}
|
||||
|
||||
auto* other_window = new JUI::Window(root);
|
||||
other_window->Position({10_percent, 10_percent});
|
||||
other_window->Size({30_percent, 25_percent});
|
||||
other_window->SetTitle("Another Window");
|
||||
JUI::Window* CreateScrollDemoWindow(Widget* root) {
|
||||
auto* scroller_demo = new JUI::Window(root);
|
||||
scroller_demo->Position({10_percent, 10_percent});
|
||||
scroller_demo->Size({30_percent, 25_percent});
|
||||
scroller_demo->SetTitle("ScrollingRect Demonstration");
|
||||
|
||||
Tween* t = other_window->TweenPosition({50_percent, 50_percent}, {.time = 5});
|
||||
Tween* t = scroller_demo->TweenPosition({50_percent, 50_percent}, {.time = 5});
|
||||
|
||||
t->Completed += [] () { std::cout << "Tween type test!!" << std::endl; };
|
||||
|
||||
scroller = new JUI::ScrollingRect(other_window->ViewportInstance());
|
||||
scroller = new JUI::ScrollingRect(scroller_demo->ViewportInstance());
|
||||
scroller->Size({100_percent, 100_percent});
|
||||
scroller->BGColor(Colors::Reds::LightCoral);
|
||||
|
||||
list = new JUI::VerticalListLayout(scroller);
|
||||
list->LayoutOrder(JUI::LayoutOrder::V::BOTTOM);
|
||||
|
||||
return scroller_demo;
|
||||
}
|
||||
|
||||
JUI::Window* CreateAnimationDemoWindow() {
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JUI::Scene* CreateScene() {
|
||||
|
||||
auto *root = new Scene();
|
||||
|
||||
topbar = CreateUtilityBar(root);
|
||||
|
||||
nineslice_demo_window = CreateNinesliceWindow(root);
|
||||
scroller_window = CreateScrollDemoWindow(root);
|
||||
|
||||
|
||||
console = new JUI::CommandLine(root); {
|
||||
console->Close();
|
||||
JUI::UILogs.OnLog += [&] (const std::string& msg, Color4 c){ console->Log(msg, c);};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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 //
|
||||
|
||||
auto* nineslice = new JUI::NineSliceRect(nineslice_demo_window);
|
||||
nineslice->Content(slicer);
|
||||
nineslice->Size({100_percent, 100_percent});
|
||||
nineslice->BGColor(Colors::Transparent);
|
||||
nineslice->TopLeftQuad({{0,0},{96,96}});
|
||||
nineslice->TopRightQuad({{384-96,0},{96,96}});
|
||||
nineslice->BottomLeftQuad({ {0, 378-96}, {96, 96}});
|
||||
nineslice->BottomRightQuad({ {384-96, 378-96}, {96, 96}});
|
||||
|
||||
nineslice->TopQuad({ {96, 0}, {192, 96} });
|
||||
nineslice->BottomQuad({ {96, 378-96}, {192, 96} });
|
||||
nineslice->RightQuad({{384-(96), 96}, {96, 378-(96*2)}});
|
||||
nineslice->LeftQuad({{0, 96}, {96, 378-(96*2)}});
|
||||
|
||||
nineslice->CenterQuad({{96, 96}, {384-(96*2), 378-(96*2)}});
|
||||
|
||||
auto darkie = new JUI::Image(nineslice_demo_window->ViewportInstance(), sample_texture);
|
||||
darkie->FitImageToParent(true);
|
||||
darkie->Color({255,255,255,128});
|
||||
|
||||
auto list = new VerticalListLayout(nineslice_demo_window->ViewportInstance());
|
||||
list->Padding(10_px);
|
||||
|
||||
TextRect* a = new TextRect(list);
|
||||
a->SetTextSize(16);
|
||||
a->Size({0, 20, 1, 0});
|
||||
//a->FitText(true);
|
||||
a->Center();
|
||||
a->SetContent("This is a virtual window.");
|
||||
|
||||
|
||||
TextRect* b = new TextRect(list);
|
||||
b->SetTextSize(16);
|
||||
b->SetContent("You can drag it around via left-click, and resize via right-click. Isn't that cool??");
|
||||
//b->FitText(true);
|
||||
b->Size({0, 20, 1, 0});
|
||||
b->Center();
|
||||
|
||||
root->SetViewportSize({800, 600});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
float scale = 1.f;
|
||||
float accum = 0;
|
||||
int iter = 0;
|
||||
|
||||
|
||||
class JUIDevelopmentTestWindow : public ReWindow::OpenGLWindow {
|
||||
public:
|
||||
@@ -356,6 +382,8 @@ public:
|
||||
accum += elapsed;
|
||||
|
||||
scene->Update(elapsed);
|
||||
/// As a demo, change the scene's UI scale.
|
||||
scene->GlobalUIScale({ui_scale, ui_scale});
|
||||
|
||||
if (accum > 1.f) {
|
||||
iter--;
|
||||
@@ -425,13 +453,13 @@ public:
|
||||
}
|
||||
|
||||
void OnMouseWheel(const ReWindow::MouseWheelEvent &w) override {
|
||||
scale += w.WheelMovement * 0.125f;
|
||||
ui_scale += w.WheelMovement * 0.125f;
|
||||
|
||||
if (scene->ObserveMouseWheel(w.WheelMovement))
|
||||
return;
|
||||
|
||||
/// As a demo, change the scene's UI scale.
|
||||
scene->GlobalUIScale({scale, scale});
|
||||
scene->GlobalUIScale({ui_scale, ui_scale});
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -38,12 +38,20 @@ namespace JUI {
|
||||
return line_item;
|
||||
}
|
||||
|
||||
std::pair<TextButton *, ContextMenu *> ContextMenu::AddSubmenu(const std::string &name) {
|
||||
ContextMenu * ContextMenu::AddSubmenu(const std::string &name) {
|
||||
auto* btn = AddButton(name);
|
||||
|
||||
// TODO: For auto-hiding, check if the widget is over a submenu as well.
|
||||
// TODO: Duplicated code with UtilityBar.cpp
|
||||
auto* submenu = new JUI::ContextMenu(this);
|
||||
submenu->AnchorPoint({1, 0});
|
||||
auto* submenu = new JUI::ContextMenu(btn);
|
||||
submenu->AnchorPoint({0, 0});
|
||||
submenu->Position({100_percent, 0_percent});
|
||||
|
||||
btn->OnClickEvent += [submenu] (auto a, auto b) mutable {
|
||||
submenu->Visible(true);
|
||||
};
|
||||
|
||||
return submenu;
|
||||
}
|
||||
|
||||
void ContextMenu::CloseOnHoverLoss(bool value) { close_on_hover_loss = value;}
|
||||
|
@@ -25,29 +25,16 @@ namespace JUI {
|
||||
ContextMenu * UtilityBar::AddSubmenu(const std::string &name) {
|
||||
auto* btn = AddButton(name);
|
||||
|
||||
//buttons.push_back(btn);
|
||||
|
||||
auto* submenu = new JUI::ContextMenu(this);
|
||||
//submenu->AnchorPoint({0, 1});
|
||||
// TODO: Fix AnchorPoint behavior!!
|
||||
submenu->Position({0_percent, 100_percent});
|
||||
submenu->Visible(true);
|
||||
|
||||
//submenus.push_back(submenu);
|
||||
|
||||
btn->OnClickEvent += [submenu] (auto a, auto b) mutable {
|
||||
submenu->Visible(true);
|
||||
};
|
||||
|
||||
//conn.Invoke({}, MouseButton::Left);
|
||||
|
||||
// TODO: We seem to have duplicate events
|
||||
// Hoverable::OnExitEvent
|
||||
// RectBase::MouseExit
|
||||
//submenu->MouseExit += [&] (auto) mutable {
|
||||
// submenu->Visible(false);
|
||||
//};
|
||||
|
||||
|
||||
return submenu;
|
||||
}
|
||||
|
@@ -226,8 +226,8 @@ namespace JUI {
|
||||
RectBase::Draw(this->GetAbsolutePosition(), this->GetAbsoluteSize());
|
||||
Widget::Draw();
|
||||
|
||||
J2D::DrawString(Colors::Black, std::format("hover: {}", hovered), this->GetAbsolutePosition().x, this->GetAbsolutePosition().y, 1.f, 10);
|
||||
J2D::DrawString(Colors::Black, std::format("mbutton: {}", mb_state), this->GetAbsolutePosition().x, this->GetAbsolutePosition().y+10, 1.f, 10);
|
||||
//J2D::DrawString(Colors::Black, std::format("hover: {}", hovered), this->GetAbsolutePosition().x, this->GetAbsolutePosition().y, 1.f, 10);
|
||||
//J2D::DrawString(Colors::Black, std::format("mbutton: {}", mb_state), this->GetAbsolutePosition().x, this->GetAbsolutePosition().y+10, 1.f, 10);
|
||||
}
|
||||
|
||||
void Window::SetTitle(const std::string &title) {
|
||||
|
Reference in New Issue
Block a user