From b7bd2efc718c89949be87a1fb07740c14a7b8098 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Mon, 6 Apr 2026 12:23:46 +0300 Subject: [PATCH] Readded grid menu and fixed grid modify tool --- src/DrawingProgram/Tools/GridModifyTool.cpp | 41 ++- src/GUIStuff/ElementHelpers/ButtonHelpers.hpp | 10 +- .../Elements/ColorRectangleDisplay.cpp | 2 +- src/GUIStuff/Elements/DropDown.hpp | 4 +- src/GUIStuff/Elements/SelectableButton.cpp | 12 +- src/GUIStuff/Elements/SelectableButton.hpp | 1 + src/GUIStuff/GUIManager.cpp | 6 +- src/GUIStuff/GUIManager.hpp | 1 + src/Toolbar.cpp | 249 +++++++++--------- src/Toolbar.hpp | 15 +- 10 files changed, 180 insertions(+), 161 deletions(-) diff --git a/src/DrawingProgram/Tools/GridModifyTool.cpp b/src/DrawingProgram/Tools/GridModifyTool.cpp index 90d4eb4..25150bd 100644 --- a/src/DrawingProgram/Tools/GridModifyTool.cpp +++ b/src/DrawingProgram/Tools/GridModifyTool.cpp @@ -128,7 +128,6 @@ void GridModifyTool::gui_toolbox() { input_text_field(gui, "grid name", "Name", &g.name); checkbox_boolean_field(gui, "Visible", "Visible", &g.visible); checkbox_boolean_field(gui, "Display in Front", "Display in front of canvas", &g.displayInFront); - size_t typeSelected = static_cast(g.gridType); std::vector listOfGridTypes = { "Circle Points", "Square Points", @@ -137,31 +136,29 @@ void GridModifyTool::gui_toolbox() { }; left_to_right_line_layout(gui, [&]() { text_label(gui, "Type"); - gui.element>("filepicker select type", &typeSelected, listOfGridTypes); + gui.element>("filepicker select type", &g.gridType, listOfGridTypes); + }); + input_scalar_field(gui, "Subdivisions", "Subdivisions", &g.subdivisions, 1, 10, { + .onEdit = [&] { g.set_subdivisions(g.subdivisions); } + }); + checkbox_boolean_field(gui, "Subdivide outwards", "Subdivide when zooming out", &g.removeDivisionsOutwards, [&] { + g.set_remove_divisions_outwards(g.removeDivisionsOutwards); }); - g.gridType = static_cast(typeSelected); - uint32_t sDiv = g.subdivisions; - input_scalar_field(gui, "Subdivisions", "Subdivisions", &sDiv, 1, 10); - g.set_subdivisions(sDiv); - bool divOut = g.removeDivisionsOutwards; - checkbox_boolean_field(gui, "Subdivide outwards", "Subdivide when zooming out", &divOut); - g.set_remove_divisions_outwards(divOut); left_to_right_line_layout(gui, [&]() { - //if(gui.color_button_big("Grid Color", &g.color, &g.color == t.colorRight)) - // t.color_selector_right(&g.color == t.colorRight ? nullptr : &g.color); + t.color_button_right("Grid Color", &g.color); text_label(gui, "Grid Color"); }); - bool bounded = g.bounds.has_value(); - bool prevBoundedValue = bounded; - checkbox_boolean_field(gui, "Bounded", "Bounded", &bounded); - if(bounded && !prevBoundedValue) { - SCollision::AABB newBounds; - newBounds.min = g.offset - drawP.world.drawData.cam.c.dir_from_space(drawP.world.main.window.size.cast() * 0.3f); - newBounds.max = g.offset + drawP.world.drawData.cam.c.dir_from_space(drawP.world.main.window.size.cast() * 0.3f); - g.bounds = newBounds; - } - else if(!bounded && prevBoundedValue) - g.bounds = std::nullopt; + auto bounded = std::make_shared(g.bounds.has_value()); + checkbox_boolean_field(gui, "Bounded", "Bounded", bounded.get(), [&, bounded] { + if(*bounded) { + SCollision::AABB newBounds; + newBounds.min = g.offset - drawP.world.drawData.cam.c.dir_from_space(drawP.world.main.window.size.cast() * 0.3f); + newBounds.max = g.offset + drawP.world.drawData.cam.c.dir_from_space(drawP.world.main.window.size.cast() * 0.3f); + g.bounds = newBounds; + } + else + g.bounds = std::nullopt; + }); checkbox_boolean_field(gui, "Show Coordinates", "Show Coordinates (visible\nwhen canvas isn't rotated)", &g.showCoordinates); } }); diff --git a/src/GUIStuff/ElementHelpers/ButtonHelpers.hpp b/src/GUIStuff/ElementHelpers/ButtonHelpers.hpp index abdbc51..ed76f77 100644 --- a/src/GUIStuff/ElementHelpers/ButtonHelpers.hpp +++ b/src/GUIStuff/ElementHelpers/ButtonHelpers.hpp @@ -13,6 +13,7 @@ template SelectableButton::Data selectable_button_options_to_dat toRet.onClick = options.onClick; toRet.isSelected = options.isSelected; toRet.drawType = options.drawType; + toRet.onClickButton = options.onClickButton; return toRet; } @@ -23,6 +24,7 @@ struct TextButtonOptions { bool centered = true; std::function onClick; + std::function onClickButton; }; struct SVGButtonOptions { @@ -31,6 +33,7 @@ struct SVGButtonOptions { float size = BIG_BUTTON_SIZE; std::function onClick; + std::function onClickButton; }; struct FixedSizeColorButtonOptions { @@ -40,13 +43,15 @@ struct FixedSizeColorButtonOptions { float size = BIG_BUTTON_SIZE; std::function onClick; + std::function onClickButton; }; void text_button(GUIManager& gui, const char* id, std::string_view text, const TextButtonOptions& options = {}); void text_button_sized(GUIManager& gui, const char* id, std::string_view text, Clay_SizingAxis x, Clay_SizingAxis y, const TextButtonOptions& options = {}); SelectableButton* svg_icon_button(GUIManager& gui, const char* id, const std::string& svgPath, const SVGButtonOptions& options = {}); -template void color_button(GUIManager& gui, const char* id, T* val, const FixedSizeColorButtonOptions& options = {}) { +template SelectableButton* color_button(GUIManager& gui, const char* id, T* val, const FixedSizeColorButtonOptions& options = {}) { + SelectableButton* toRet; gui.new_id(id, [&] { SelectableButton::Data d = selectable_button_options_to_data(options); d.innerContent = [&] (const SelectableButton::InnerContentCallbackParameters&) { @@ -58,9 +63,10 @@ template void color_button(GUIManager& gui, const char* id, T* val, }); }; CLAY_AUTO_ID({.layout = {.sizing = {.width = CLAY_SIZING_FIXED(options.size), .height = CLAY_SIZING_FIXED(options.size) } } }) { - gui.element("button", d); + toRet = gui.element("button", d); } }); + return toRet; } }} diff --git a/src/GUIStuff/Elements/ColorRectangleDisplay.cpp b/src/GUIStuff/Elements/ColorRectangleDisplay.cpp index f0132b1..e784336 100644 --- a/src/GUIStuff/Elements/ColorRectangleDisplay.cpp +++ b/src/GUIStuff/Elements/ColorRectangleDisplay.cpp @@ -32,7 +32,7 @@ void ColorRectangleDisplay::clay_draw(SkCanvas* canvas, UpdateInputData& io, Cla SkPaint alphaPaint; alphaPaint.setShader(get_alpha_background_shader()); canvas->drawPaint(alphaPaint); - canvas->drawPaint(SkPaint{color}); + canvas->drawPaint(SkPaint{SkColor4f(color.fR, color.fG, color.fB, std::sqrt(color.fA))}); // Square root for alpha to keep color visible canvas->restore(); } } diff --git a/src/GUIStuff/Elements/DropDown.hpp b/src/GUIStuff/Elements/DropDown.hpp index c0f042b..d1e59e1 100644 --- a/src/GUIStuff/Elements/DropDown.hpp +++ b/src/GUIStuff/Elements/DropDown.hpp @@ -38,7 +38,7 @@ template class DropDown : public Element { .layoutDirection = CLAY_LEFT_TO_RIGHT, } }) { - ElementHelpers::text_label(gui, selections[*data]); + ElementHelpers::text_label(gui, selections[static_cast(*data)]); CLAY_AUTO_ID({.layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}}}) {} CLAY_AUTO_ID({ .layout = { @@ -121,7 +121,7 @@ template class DropDown : public Element { update_hovering_over(i, l->mouseHovering); if(l->mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) { gui.set_post_callback_func([&, i] { - *d = i; + *d = static_cast(i); isOpen = false; if(opts.onClick) opts.onClick(); }); diff --git a/src/GUIStuff/Elements/SelectableButton.cpp b/src/GUIStuff/Elements/SelectableButton.cpp index 7c321dc..ec7f14c 100644 --- a/src/GUIStuff/Elements/SelectableButton.cpp +++ b/src/GUIStuff/Elements/SelectableButton.cpp @@ -14,7 +14,11 @@ void SelectableButton::layout(const Clay_ElementId& id, const Data& d) { SkColor4f backgroundColorHighlight; SkColor4f backgroundColor; - onClick = d.onClick; + onClick = [&, this, d] { + if(d.onClickButton) + d.onClickButton(this); + else if(d.onClick) d.onClick(); + }; if(isHeld || ((d.isSelected || mouseHovering) && d.drawType == DrawType::TRANSPARENT_BORDER)) borderColor = io.theme->fillColor1; @@ -66,8 +70,10 @@ void SelectableButton::layout(const Clay_ElementId& id, const Data& d) { void SelectableButton::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { bool oldIsHeld = isHeld; isHeld = mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down; - if(isHeld) { - gui.set_post_callback_func([&]{ if(onClick) onClick(); }); + if(isHeld) + gui.set_to_layout(); + else if(mouseHovering && oldIsHeld && button.button == InputManager::MouseButton::LEFT && !button.down) { + gui.set_post_callback_func(onClick); gui.set_to_layout(); } else if(mouseHovering != oldIsHovering || isHeld != oldIsHeld) diff --git a/src/GUIStuff/Elements/SelectableButton.hpp b/src/GUIStuff/Elements/SelectableButton.hpp index 06b4777..9745345 100644 --- a/src/GUIStuff/Elements/SelectableButton.hpp +++ b/src/GUIStuff/Elements/SelectableButton.hpp @@ -22,6 +22,7 @@ class SelectableButton : public Element { DrawType drawType = DrawType::TRANSPARENT_ALL; bool isSelected = false; std::function onClick; + std::function onClickButton; std::function innerContent; }; diff --git a/src/GUIStuff/GUIManager.cpp b/src/GUIStuff/GUIManager.cpp index 1d744c0..6245e49 100644 --- a/src/GUIStuff/GUIManager.cpp +++ b/src/GUIStuff/GUIManager.cpp @@ -299,11 +299,15 @@ void GUIManager::new_id(int64_t id, const std::function& f) { void GUIManager::set_z_index(int16_t z, const std::function& f) { auto oldClippingRegion = clippingRegion; clippingRegion = std::nullopt; + set_z_index_keep_clipping_region(z, f); + clippingRegion = oldClippingRegion; +} + +void GUIManager::set_z_index_keep_clipping_region(int16_t z, const std::function& f) { int16_t oldZIndex = zIndex; zIndex = z; f(); zIndex = oldZIndex; - clippingRegion = oldClippingRegion; } int16_t GUIManager::get_z_index() { diff --git a/src/GUIStuff/GUIManager.hpp b/src/GUIStuff/GUIManager.hpp index e1e830d..b865ddc 100644 --- a/src/GUIStuff/GUIManager.hpp +++ b/src/GUIStuff/GUIManager.hpp @@ -29,6 +29,7 @@ class GUIManager { void new_id(int64_t id, const std::function& f); void set_z_index(int16_t z, const std::function& f); + void set_z_index_keep_clipping_region(int16_t z, const std::function& f); int16_t get_z_index(); void set_post_callback_func(const std::function& f); diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index 9e0bfdd..f51bb67 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -166,9 +166,9 @@ void Toolbar::color_button_left(const char* id, Vector4f* color, const ColorSele auto& gui = main.g.gui; color_button(gui, id, color, { .isSelected = colorLeft == color, - .onClick = [&, colorSelectorData, color] { + .onClickButton = [&, colorSelectorData, color] (SelectableButton* b) { if(colorSelectorData.onSelectorButtonClick) colorSelectorData.onSelectorButtonClick(); - color_selector_left(color, { + color_selector_left(b, color, { .onChange = colorSelectorData.onChange, .onSelect = colorSelectorData.onSelect, .onDeselect = colorSelectorData.onDeselect, @@ -181,9 +181,9 @@ void Toolbar::color_button_right(const char* id, Vector4f* color, const ColorSel auto& gui = main.g.gui; color_button(gui, id, color, { .isSelected = colorRight == color, - .onClick = [&, colorSelectorData, color] { + .onClickButton = [&, colorSelectorData, color] (SelectableButton* b) { if(colorSelectorData.onSelectorButtonClick) colorSelectorData.onSelectorButtonClick(); - color_selector_right(color, { + color_selector_right(b, color, { .onChange = colorSelectorData.onChange, .onSelect = colorSelectorData.onSelect, .onDeselect = colorSelectorData.onDeselect, @@ -192,23 +192,25 @@ void Toolbar::color_button_right(const char* id, Vector4f* color, const ColorSel }); } -void Toolbar::color_selector_left(Vector4f* color, const ColorSelectorData& colorSelectorData) { +void Toolbar::color_selector_left(Element* button, Vector4f* color, const ColorSelectorData& colorSelectorData) { if(colorLeft != color) { - colorLeftJustEnabled = color; + colorLeft = color; colorLeftData = colorSelectorData; + colorLeftButton = button; } else - colorLeftJustDisabled = true; + colorLeft = nullptr; main.g.gui.set_to_layout(); } -void Toolbar::color_selector_right(Vector4f* color, const ColorSelectorData& colorSelectorData) { +void Toolbar::color_selector_right(Element* button, Vector4f* color, const ColorSelectorData& colorSelectorData) { if(colorRight != color) { - colorRightJustEnabled = color; + colorRight = color; colorRightData = colorSelectorData; + colorRightButton = button; } else - colorRightJustDisabled = true; + colorRight = nullptr; main.g.gui.set_to_layout(); } @@ -310,12 +312,6 @@ void Toolbar::layout_run() { if(!main.world->clientStillConnecting) main.world->drawProg.right_click_popup_gui(); - - // Make sure theyre set to null in case drawing_program_gui wasn't called - colorLeftJustEnabled = nullptr; - colorLeftJustDisabled = false; - colorRightJustEnabled = nullptr; - colorRightJustDisabled = false; } bool Toolbar::app_close_requested() { @@ -497,7 +493,6 @@ void Toolbar::top_toolbar() { }) { global_log(); bool bookmarkMenuPopUpJustOpen = false; - bool gridMenuPopUpJustOpen = false; bool layerMenuPopUpJustOpen = false; auto icon_button_top_toolbar = [&](const char* id, const std::string& svgPath, bool isSelected, const std::function& onClick) { @@ -545,13 +540,11 @@ void Toolbar::top_toolbar() { icon_button_top_toolbar("Menu Redo Button", "data/icons/redo.svg", false, [&] { main.world->redo_with_checks(); }); - icon_button_top_toolbar("Grids Button", "data/icons/grid.svg", gridMenu.popupOpen, [&] { + Element* gridMenuButton = icon_button_top_toolbar("Grids Button", "data/icons/grid.svg", gridMenu.popupOpen, [&] { if(gridMenu.popupOpen) stop_displaying_grid_menu(); - else { + else gridMenu.popupOpen = true; - gridMenuPopUpJustOpen = true; - } }); icon_button_top_toolbar("Layer Menu Button", "data/icons/layer.svg", layerMenuPopupOpen, [&] { if(layerMenuPopupOpen) { @@ -575,7 +568,7 @@ void Toolbar::top_toolbar() { }); if(gridMenu.popupOpen) - grid_menu(gridMenuPopUpJustOpen); + grid_menu(gridMenuButton); if(bookmarkMenuPopupOpen) bookmark_menu(bookmarkMenuPopUpJustOpen); if(layerMenuPopupOpen) @@ -845,102 +838,124 @@ void Toolbar::update_notification_gui() { } #endif -void Toolbar::grid_menu(bool justOpened) { +void Toolbar::grid_menu(Element* gridMenuButton) { auto& gui = main.g.gui; auto& io = gui.io; if(main.world->gridMan.grids) { - gui.new_id("grid menu", [&] { - //CLAY(localId, { - // .layout = { - // .sizing = {.width = CLAY_SIZING_FIT(300), .height = CLAY_SIZING_FIT(0, 600) }, - // .padding = CLAY_PADDING_ALL(io.theme->padding1), - // .childGap = io.theme->childGap1, - // .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP}, - // .layoutDirection = CLAY_TOP_TO_BOTTOM - // }, - // .backgroundColor = convert_vec4(io.theme->backColor1), - // .cornerRadius = CLAY_CORNER_RADIUS(io.theme->windowCorners1), - // .floating = {.offset = {.x = 0, .y = static_cast(io.theme->padding1)}, .attachPoints = {.element = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_BOTTOM}, .attachTo = CLAY_ATTACH_TO_PARENT} - //}) { - // gui.obstructing_window(localId); - // text_label_centered(gui, "Grids"); - // float entryHeight = 25.0f; - // if(main.world->gridMan.grids->empty()) - // text_label_centered(gui, "No grids yet..."); - // uint32_t toDelete = std::numeric_limits::max(); - // gui.scroll_bar_many_entries_area("grid menu entries", entryHeight, main.world->gridMan.grids->size(), true, [&](size_t i, bool isListHovered) { - // auto& grid = main.world->gridMan.grids->at(i)->obj; - // bool selectedEntry = gridMenu.selectedGrid == i; - // CLAY_AUTO_ID({ - // .layout = { - // .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(entryHeight)}, - // .childGap = 2, - // .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}, - // .layoutDirection = CLAY_LEFT_TO_RIGHT - // }, - // .backgroundColor = selectedEntry ? convert_vec4(io.theme->backColor1) : convert_vec4(io.theme->backColor2) - // }) { - // text_label(gui, grid->get_display_name()); - // bool miniButtonClicked = false; - // CLAY_AUTO_ID({ - // .layout = { - // .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, - // .childGap = 1, - // .childAlignment = {.x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER}, - // .layoutDirection = CLAY_LEFT_TO_RIGHT - // } - // }) { - // if(gui.svg_icon_button_transparent("visibility eye", grid->visible ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", false, entryHeight, false)) { - // miniButtonClicked = true; - // grid->visible = !grid->visible; - // NetworkingObjects::generic_serialized_class_send_update_to_all(grid); - // } - // if(gui.svg_icon_button_transparent("edit pencil", "data/icons/pencil.svg", false, entryHeight, false)) { - // miniButtonClicked = true; - // main.world->drawProg.modify_grid(grid); - // stop_displaying_grid_menu(); - // } - // if(gui.svg_icon_button_transparent("delete trash", "data/icons/trash.svg", false, entryHeight, false)) { - // miniButtonClicked = true; - // toDelete = i; - // } - // } - // if(Clay_Hovered() && io.mouse.leftClick && isListHovered && !miniButtonClicked) { - // gridMenu.selectedGrid = i; - // if(io.mouse.leftClick >= 2) { - // main.world->drawProg.modify_grid(grid); - // stop_displaying_grid_menu(); - // } - // } - // } - // }); - // if(toDelete != std::numeric_limits::max()) - // main.world->gridMan.remove_grid(toDelete); - // gui.left_to_right_line_layout([&]() { - // bool addByEnter = false; - // gui.input_text("grid text input", &gridMenu.newName, true, [&](GUIStuff::SelectionHelper& s) { - // addByEnter = s.selected && io.key.enter; - // }); - // if(gui.svg_icon_button("grid add button", "data/icons/plusbold.svg", false, GUIStuff::GUIManager::SMALL_BUTTON_SIZE) || (addByEnter && !gridMenu.newName.empty())) { - // main.world->gridMan.add_default_grid(gridMenu.newName); - // main.world->drawProg.modify_grid(main.world->gridMan.grids->at(main.world->gridMan.grids->size() - 1)->obj); - // stop_displaying_grid_menu(); - // } - // }); - - // bool dropdownHover = false; - // if(io.mouse.leftClick && !Clay_Hovered() && !justOpened && !dropdownHover) - // stop_displaying_grid_menu(); - //} + gui.set_z_index(gui.get_z_index() + 1, [&] { + gui.element("grid menu", [&] (LayoutElement*, const Clay_ElementId& lId) { + CLAY(lId, { + .layout = { + .sizing = {.width = CLAY_SIZING_FIT(300), .height = CLAY_SIZING_FIT(0, 600) }, + .padding = CLAY_PADDING_ALL(io.theme->padding1), + .childGap = io.theme->childGap1, + .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP}, + .layoutDirection = CLAY_TOP_TO_BOTTOM + }, + .backgroundColor = convert_vec4(io.theme->backColor1), + .cornerRadius = CLAY_CORNER_RADIUS(io.theme->windowCorners1), + .floating = {.offset = {.x = 0, .y = static_cast(io.theme->padding1)}, .attachPoints = {.element = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_BOTTOM}, .attachTo = CLAY_ATTACH_TO_PARENT} + }) { + text_label_centered(gui, "Grids"); + float ENTRY_HEIGHT = 25.0f; + if(main.world->gridMan.grids->empty()) + text_label_centered(gui, "No grids yet..."); + scroll_area_many_entries(gui, "grid menu entries", { + .entryHeight = ENTRY_HEIGHT, + .entryCount = main.world->gridMan.grids->size(), + .clipHorizontal = true, + .elementContent = [&](size_t i) { + auto& grid = main.world->gridMan.grids->at(i)->obj; + bool selectedEntry = gridMenu.selectedGrid == i; + gui.element("elem", [&] (LayoutElement*, const Clay_ElementId& lId2) { + CLAY(lId2, { + .layout = { + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT)}, + .childGap = 2, + .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}, + .layoutDirection = CLAY_LEFT_TO_RIGHT + }, + .backgroundColor = selectedEntry ? convert_vec4(io.theme->backColor1) : convert_vec4(io.theme->backColor2) + }) { + text_label(gui, grid->get_display_name()); + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + .childGap = 1, + .childAlignment = {.x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER}, + .layoutDirection = CLAY_LEFT_TO_RIGHT + } + }) { + auto list_button = [&](const char* id, const char* svgPath, const std::function& onClick) { + gui.set_z_index_keep_clipping_region(gui.get_z_index() + 1, [&] { + svg_icon_button(gui, id, svgPath, { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, + .size = ENTRY_HEIGHT, + .onClick = onClick + }); + }); + }; + list_button("visibility eye", grid->visible ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", [&] { + grid->visible = !grid->visible; + NetworkingObjects::generic_serialized_class_send_update_to_all(grid); + }); + list_button("edit pencil", "data/icons/pencil.svg", [&] { + main.world->drawProg.modify_grid(grid); + stop_displaying_grid_menu(); + }); + list_button("delete trash", "data/icons/trash.svg", [&, i] { + main.world->gridMan.remove_grid(i); + }); + } + } + }, LayoutElement::Callbacks { + .mouseButton = [&, i] (LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) { + if(l->mouseHovering && button.down && button.button == InputManager::MouseButton::LEFT) { + gridMenu.selectedGrid = i; + if(button.clicks == 2) { + main.world->drawProg.modify_grid(grid); + stop_displaying_grid_menu(); + } + gui.set_to_layout(); + } + } + }); + } + }); + left_to_right_line_layout(gui, [&]() { + input_text(gui, "grid text input", &gridMenu.newName, { + .onEnter = [&]() { add_grid(); } + }); + svg_icon_button(gui, "grid add button", "data/icons/plusbold.svg", { + .size = SMALL_BUTTON_SIZE, + .onClick = [&] { add_grid(); } + }); + }); + } + }, LayoutElement::Callbacks { + .mouseButton = [&, gridMenuButton] (LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) { + if(!l->mouseHovering && !l->childMouseHovering && !gridMenuButton->mouseHovering && button.down) + stop_displaying_grid_menu(); + } + }); }); } } +void Toolbar::add_grid() { + if(!gridMenu.newName.empty()) { + main.world->gridMan.add_default_grid(gridMenu.newName); + main.world->drawProg.modify_grid(main.world->gridMan.grids->at(main.world->gridMan.grids->size() - 1)->obj); + stop_displaying_grid_menu(); + } +} + void Toolbar::stop_displaying_grid_menu() { gridMenu.newName.clear(); gridMenu.popupOpen = false; gridMenu.selectedGrid = std::numeric_limits::max(); + main.g.gui.set_to_layout(); } void Toolbar::bookmark_menu(bool justOpened) { @@ -1212,31 +1227,21 @@ void Toolbar::drawing_program_gui() { }) { main.world->drawProg.toolbar_gui(); - if(colorLeftJustEnabled) - colorLeft = colorLeftJustEnabled; - else if(colorLeftJustDisabled) - colorLeft = nullptr; - - if(colorRightJustEnabled) - colorRight = colorRightJustEnabled; - else if(colorRightJustDisabled) - colorRight = nullptr; - if(colorLeft) - color_picker_window("Drawing program gui color picker left", &colorLeft, &colorLeftJustDisabled, colorLeftData); + color_picker_window("Drawing program gui color picker left", &colorLeft, colorLeftButton, colorLeftData); CLAY_AUTO_ID({ .layout = { .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)} } }) {} if(colorRight) - color_picker_window("Drawing program gui color picker right", &colorRight, &colorRightJustDisabled, colorRightData); + color_picker_window("Drawing program gui color picker right", &colorRight, colorRightButton, colorRightData); main.world->drawProg.tool_options_gui(); } } -void Toolbar::color_picker_window(const char* id, Vector4f** color, bool* colorJustDisabled, const ColorSelectorData& colorSelectorData) { +void Toolbar::color_picker_window(const char* id, Vector4f** color, GUIStuff::Element* b, const ColorSelectorData& colorSelectorData) { auto& gui = main.g.gui; CLAY_AUTO_ID({ @@ -1268,9 +1273,9 @@ void Toolbar::color_picker_window(const char* id, Vector4f** color, bool* colorJ }); } }, LayoutElement::Callbacks{ - .mouseButton = [&, colorJustDisabled](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) { - if(!l->mouseHovering && !l->childMouseHovering && button.down) { - *colorJustDisabled = true; + .mouseButton = [&, b, color](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) { + if(!l->mouseHovering && !l->childMouseHovering && !b->mouseHovering && button.down) { + *color = nullptr; main.g.gui.set_to_layout(); } } diff --git a/src/Toolbar.hpp b/src/Toolbar.hpp index e05a63f..7389556 100644 --- a/src/Toolbar.hpp +++ b/src/Toolbar.hpp @@ -56,8 +56,8 @@ class Toolbar { std::function onSelect; std::function onDeselect; }; - void color_selector_left(Vector4f* color, const ColorSelectorData& colorSelectorData = {}); - void color_selector_right(Vector4f* color, const ColorSelectorData& colorSelectorData = {}); + void color_selector_left(GUIStuff::Element* button, Vector4f* color, const ColorSelectorData& colorSelectorData = {}); + void color_selector_right(GUIStuff::Element* button, Vector4f* color, const ColorSelectorData& colorSelectorData = {}); void color_button_left(const char* id, Vector4f* color, const ColorSelectorButtonData& colorSelectorData = {}); void color_button_right(const char* id, Vector4f* color, const ColorSelectorButtonData& colorSelectorData = {}); @@ -73,14 +73,12 @@ class Toolbar { void load_palettes(); void load_licenses(); + GUIStuff::Element* colorLeftButton; Vector4f* colorLeft = nullptr; - bool colorLeftJustDisabled = false; - Vector4f* colorLeftJustEnabled = nullptr; ColorSelectorData colorLeftData; + GUIStuff::Element* colorRightButton; Vector4f* colorRight = nullptr; - bool colorRightJustDisabled = false; - Vector4f* colorRightJustEnabled = nullptr; ColorSelectorData colorRightData; bool app_close_requested(); @@ -93,7 +91,8 @@ class Toolbar { void chat_box(); void global_log(); void top_toolbar(); - void grid_menu(bool justOpened); + void grid_menu(GUIStuff::Element* gridMenuButton); + void add_grid(); void stop_displaying_grid_menu(); void bookmark_menu(bool justOpened); void layer_menu(bool justOpened); @@ -103,7 +102,7 @@ class Toolbar { void file_picker_gui_done(); void file_picker_gui(); void performance_metrics(); - void color_picker_window(const char* id, Vector4f** color, bool* colorJustDisabled, const ColorSelectorData& colorSelectorData); + void color_picker_window(const char* id, Vector4f** color, GUIStuff::Element* b, const ColorSelectorData& colorSelectorData); void color_palette(const char* id, Vector4f* color, const std::function& onChange); void open_world_file(bool isClient, const std::string& netSource, const std::string& serverLocalID); void load_default_palette();