From c90c09b1694f37a6aad9b1f35cade933a717e4bf Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Thu, 30 Apr 2026 12:09:03 +0300 Subject: [PATCH] Added phone tool settings --- src/DrawingProgram/DrawingProgram.cpp | 30 --- src/DrawingProgram/DrawingProgram.hpp | 4 +- .../DrawingProgramSelection.cpp | 15 ++ .../DrawingProgramSelection.hpp | 2 + src/DrawingProgram/Tools/BrushTool.cpp | 12 ++ src/DrawingProgram/Tools/BrushTool.hpp | 1 + .../Tools/DrawingProgramToolBase.hpp | 2 + src/DrawingProgram/Tools/EditTool.cpp | 11 ++ src/DrawingProgram/Tools/EditTool.hpp | 1 + src/DrawingProgram/Tools/EllipseDrawTool.cpp | 18 ++ src/DrawingProgram/Tools/EllipseDrawTool.hpp | 1 + src/DrawingProgram/Tools/EraserTool.cpp | 16 ++ src/DrawingProgram/Tools/EraserTool.hpp | 1 + src/DrawingProgram/Tools/EyeDropperTool.cpp | 14 ++ src/DrawingProgram/Tools/EyeDropperTool.hpp | 1 + src/DrawingProgram/Tools/GridModifyTool.cpp | 45 +++++ src/DrawingProgram/Tools/GridModifyTool.hpp | 1 + src/DrawingProgram/Tools/LassoSelectTool.cpp | 7 + src/DrawingProgram/Tools/LassoSelectTool.hpp | 1 + src/DrawingProgram/Tools/LineDrawTool.cpp | 11 ++ src/DrawingProgram/Tools/LineDrawTool.hpp | 1 + src/DrawingProgram/Tools/PanCanvasTool.cpp | 7 + src/DrawingProgram/Tools/PanCanvasTool.hpp | 1 + src/DrawingProgram/Tools/RectDrawTool.cpp | 20 ++ src/DrawingProgram/Tools/RectDrawTool.hpp | 1 + src/DrawingProgram/Tools/RectSelectTool.cpp | 7 + src/DrawingProgram/Tools/RectSelectTool.hpp | 1 + src/DrawingProgram/Tools/ScreenshotTool.cpp | 10 + src/DrawingProgram/Tools/ScreenshotTool.hpp | 1 + src/DrawingProgram/Tools/TextBoxTool.cpp | 7 + src/DrawingProgram/Tools/TextBoxTool.hpp | 1 + src/DrawingProgram/Tools/ZoomCanvasTool.cpp | 7 + src/DrawingProgram/Tools/ZoomCanvasTool.hpp | 1 + src/GUIStuff/Elements/CheckBox.cpp | 23 ++- src/GUIStuff/Elements/CheckBox.hpp | 3 + src/GUIStuff/Elements/NumberSlider.hpp | 20 +- src/GUIStuff/Elements/RadioButton.cpp | 23 ++- src/GUIStuff/Elements/RadioButton.hpp | 3 + src/GUIStuff/GUIManager.cpp | 9 + src/GUIStuff/GUIManager.hpp | 3 + src/Screens/PhoneDrawingProgramScreen.cpp | 184 ++++++++++++++++-- src/Screens/PhoneDrawingProgramScreen.hpp | 9 + 42 files changed, 479 insertions(+), 57 deletions(-) diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index 6159191..511fa73 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -398,36 +398,6 @@ void DrawingProgram::toolbar_gui(Toolbar& t) { }); } -void DrawingProgram::phone_bottom_toolbar_gui(PhoneDrawingProgramScreen& t) { - using namespace GUIStuff; - using namespace ElementHelpers; - - GUIManager& gui = world.main.g.gui; - - auto tool_button = [&](const char* id, const std::string& svgPath, DrawingProgramToolType toolType) { - svg_icon_button(gui, id, svgPath, { - .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, - .isSelected = drawTool->get_type() == toolType, - .onClick = [&, toolType] { - switch_to_tool(toolType); - } - }); - }; - - tool_button("Brush Toolbar Button", "data/icons/brush.svg", DrawingProgramToolType::BRUSH); - tool_button("Eraser Toolbar Button", "data/icons/eraser.svg", DrawingProgramToolType::ERASER); - tool_button("Line Toolbar Button", "data/icons/line.svg", DrawingProgramToolType::LINE); - tool_button("Text Toolbar Button", "data/icons/text.svg", DrawingProgramToolType::TEXTBOX); - tool_button("Ellipse Toolbar Button", "data/icons/circle.svg", DrawingProgramToolType::ELLIPSE); - tool_button("Rect Toolbar Button", "data/icons/rectangle.svg", DrawingProgramToolType::RECTANGLE); - tool_button("RectSelect Toolbar Button", "data/icons/rectselect.svg", DrawingProgramToolType::RECTSELECT); - tool_button("LassoSelect Toolbar Button", "data/icons/lassoselect.svg", DrawingProgramToolType::LASSOSELECT); - tool_button("Edit Toolbar Button", "data/icons/cursor.svg", DrawingProgramToolType::EDIT); - tool_button("Eyedropper Toolbar Button", "data/icons/eyedropper.svg", DrawingProgramToolType::EYEDROPPER); - tool_button("Zoom Canvas Toolbar Button", "data/icons/zoom.svg", DrawingProgramToolType::ZOOM); - tool_button("Pan Canvas Toolbar Button", "data/icons/hand.svg", DrawingProgramToolType::PAN); -} - void DrawingProgram::right_click_popup_gui(Toolbar& t) { if(rightClickPopupLocation.has_value()) drawTool->right_click_popup_gui(t, rightClickPopupLocation.value()); diff --git a/src/DrawingProgram/DrawingProgram.hpp b/src/DrawingProgram/DrawingProgram.hpp index bb3bd33..722cd74 100644 --- a/src/DrawingProgram/DrawingProgram.hpp +++ b/src/DrawingProgram/DrawingProgram.hpp @@ -29,7 +29,6 @@ class DrawingProgram { void toolbar_gui(Toolbar& t); void tool_options_gui(Toolbar& t); void right_click_popup_gui(Toolbar& t); - void phone_bottom_toolbar_gui(PhoneDrawingProgramScreen& t); void update(); void scale_up(const WorldScalar& scaleUpAmount); void draw(SkCanvas* canvas, const DrawData& drawData); @@ -78,6 +77,8 @@ class DrawingProgram { void set_right_click_popup_location(const Vector2f& newLoc); void clear_right_click_popup(); + + std::unique_ptr drawTool; private: void process_transform_message(const std::vector>& transforms); @@ -129,7 +130,6 @@ class DrawingProgram { }; std::vector droppedDownloadingFiles; - std::unique_ptr drawTool; std::optional rightClickPopupLocation; diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index 2bbf2f1..60f36a4 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -60,6 +60,21 @@ void DrawingProgramSelection::selection_gui(Toolbar& t) { }); } +void DrawingProgramSelection::phone_selection_gui(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + + gui.new_id("general selection gui", [&] { + text_label(gui, "Select from:"); + radio_button_selector(gui, "layer selector", &drawP.controls.layerSelector, { + {"Layer being edited", DrawingProgramLayerManager::LayerSelector::LAYER_BEING_EDITED}, + {"All visible layers", DrawingProgramLayerManager::LayerSelector::ALL_VISIBLE_LAYERS} + }); + }); +} + void DrawingProgramSelection::update_selection_stroke_color() { if(strokeColorChangeData.oldColor != strokeColorChangeData.newColor) { for(auto& c : selectedSet) { diff --git a/src/DrawingProgram/DrawingProgramSelection.hpp b/src/DrawingProgram/DrawingProgramSelection.hpp index dea0ab3..112a589 100644 --- a/src/DrawingProgram/DrawingProgramSelection.hpp +++ b/src/DrawingProgram/DrawingProgramSelection.hpp @@ -5,11 +5,13 @@ #include "../InputManager.hpp" class DrawingProgram; +class PhoneDrawingProgramScreen; class DrawingProgramSelection { public: DrawingProgramSelection(DrawingProgram& initDrawP); void selection_gui(Toolbar& t); + void phone_selection_gui(PhoneDrawingProgramScreen& t); void add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, DrawingProgramLayerManager::LayerSelector layerSelector, bool frontObjectOnly); void remove_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, DrawingProgramLayerManager::LayerSelector layerSelector, bool frontObjectOnly); void erase_component(CanvasComponentContainer::ObjInfo* objToCheck); diff --git a/src/DrawingProgram/Tools/BrushTool.cpp b/src/DrawingProgram/Tools/BrushTool.cpp index 121bd29..c56cf34 100644 --- a/src/DrawingProgram/Tools/BrushTool.cpp +++ b/src/DrawingProgram/Tools/BrushTool.cpp @@ -183,6 +183,18 @@ void BrushTool::gui_toolbox(Toolbar& t) { }); } +void BrushTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + + gui.new_id("brush tool", [&] { + checkbox_boolean_field(gui, "hasroundcaps", "Round Caps", &drawP.world.main.toolConfig.brush.hasRoundCaps); + drawP.world.main.toolConfig.relative_width_gui(drawP, "Size"); + }); +} + void BrushTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) { t.paint_popup(popupPos); } diff --git a/src/DrawingProgram/Tools/BrushTool.hpp b/src/DrawingProgram/Tools/BrushTool.hpp index e7a7c3f..bb9f088 100644 --- a/src/DrawingProgram/Tools/BrushTool.hpp +++ b/src/DrawingProgram/Tools/BrushTool.hpp @@ -17,6 +17,7 @@ class BrushTool : public DrawingProgramToolBase { BrushTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void tool_update() override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; diff --git a/src/DrawingProgram/Tools/DrawingProgramToolBase.hpp b/src/DrawingProgram/Tools/DrawingProgramToolBase.hpp index 0da1db3..3e06aaa 100644 --- a/src/DrawingProgram/Tools/DrawingProgramToolBase.hpp +++ b/src/DrawingProgram/Tools/DrawingProgramToolBase.hpp @@ -5,6 +5,7 @@ #include "../../InputManager.hpp" class DrawingProgram; +class PhoneDrawingProgramScreen; #define MINIMUM_DISTANCE_BETWEEN_BOUNDS 10.0f @@ -30,6 +31,7 @@ class DrawingProgramToolBase { DrawingProgramToolBase(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() = 0; virtual void gui_toolbox(Toolbar& t) = 0; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) = 0; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) = 0; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) = 0; virtual void tool_update() = 0; diff --git a/src/DrawingProgram/Tools/EditTool.cpp b/src/DrawingProgram/Tools/EditTool.cpp index 72b7450..151b598 100644 --- a/src/DrawingProgram/Tools/EditTool.cpp +++ b/src/DrawingProgram/Tools/EditTool.cpp @@ -39,6 +39,17 @@ void EditTool::gui_toolbox(Toolbar& t) { } } +void EditTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + + gui.new_id("edit tool", [&] { + text_label_centered(gui, "Edit"); + }); +} + void EditTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) { if(erasedComp == objInfoBeingEdited) switch_tool(get_type()); diff --git a/src/DrawingProgram/Tools/EditTool.hpp b/src/DrawingProgram/Tools/EditTool.hpp index 1381e08..32538d9 100644 --- a/src/DrawingProgram/Tools/EditTool.hpp +++ b/src/DrawingProgram/Tools/EditTool.hpp @@ -20,6 +20,7 @@ class EditTool : public DrawingProgramToolBase { EditTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void tool_update() override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; diff --git a/src/DrawingProgram/Tools/EllipseDrawTool.cpp b/src/DrawingProgram/Tools/EllipseDrawTool.cpp index 23a84aa..633443a 100644 --- a/src/DrawingProgram/Tools/EllipseDrawTool.cpp +++ b/src/DrawingProgram/Tools/EllipseDrawTool.cpp @@ -39,6 +39,24 @@ void EllipseDrawTool::gui_toolbox(Toolbar& t) { }); } +void EllipseDrawTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + auto& toolConfig = drawP.world.main.toolConfig; + auto& fillStrokeMode = toolConfig.ellipseDraw.fillStrokeMode; + gui.new_id("ellipse draw tool", [&] { + radio_button_selector(gui, "fill type", &fillStrokeMode, { + {"Fill only", 0}, + {"Outline only", 1}, + {"Fill and Outline", 2} + }); + if(fillStrokeMode == 1 || fillStrokeMode == 2) + toolConfig.relative_width_gui(drawP, "Outline Size"); + }); +} + void EllipseDrawTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { if(button.button == InputManager::MouseButton::LEFT) { if(button.down && drawP.layerMan.is_a_layer_being_edited() && !objInfoBeingEdited && !drawP.world.main.g.gui.cursor_obstructed()) { diff --git a/src/DrawingProgram/Tools/EllipseDrawTool.hpp b/src/DrawingProgram/Tools/EllipseDrawTool.hpp index c324a53..8be5a01 100644 --- a/src/DrawingProgram/Tools/EllipseDrawTool.hpp +++ b/src/DrawingProgram/Tools/EllipseDrawTool.hpp @@ -11,6 +11,7 @@ class EllipseDrawTool : public DrawingProgramToolBase { EllipseDrawTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/EraserTool.cpp b/src/DrawingProgram/Tools/EraserTool.cpp index ebff085..e7c65e0 100644 --- a/src/DrawingProgram/Tools/EraserTool.cpp +++ b/src/DrawingProgram/Tools/EraserTool.cpp @@ -32,6 +32,22 @@ void EraserTool::gui_toolbox(Toolbar& t) { }); } +void EraserTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + + gui.new_id("eraser tool", [&] { + drawP.world.main.toolConfig.relative_width_gui(drawP, "Size"); + text_label(gui, "Erase from:"); + radio_button_selector(gui, "layer selector", &drawP.controls.layerSelector, { + {"Layer being edited", DrawingProgramLayerManager::LayerSelector::LAYER_BEING_EDITED}, + {"All visible layers", DrawingProgramLayerManager::LayerSelector::ALL_VISIBLE_LAYERS} + }); + }); +} + void EraserTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) { t.paint_popup(popupPos); } diff --git a/src/DrawingProgram/Tools/EraserTool.hpp b/src/DrawingProgram/Tools/EraserTool.hpp index 54614d4..2fad49c 100644 --- a/src/DrawingProgram/Tools/EraserTool.hpp +++ b/src/DrawingProgram/Tools/EraserTool.hpp @@ -10,6 +10,7 @@ class EraserTool : public DrawingProgramToolBase { EraserTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/EyeDropperTool.cpp b/src/DrawingProgram/Tools/EyeDropperTool.cpp index ad6238b..9372c24 100644 --- a/src/DrawingProgram/Tools/EyeDropperTool.cpp +++ b/src/DrawingProgram/Tools/EyeDropperTool.cpp @@ -42,6 +42,20 @@ void EyeDropperTool::gui_toolbox(Toolbar& t) { }); } +void EyeDropperTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + auto& selectingStrokeColor = drawP.world.main.toolConfig.eyeDropper.selectingStrokeColor; + gui.new_id("Color select tool", [&] { + radio_button_selector(gui, "Stroke type", &selectingStrokeColor, { + {"Stroke Color", true}, + {"Fill Color", false} + }); + }); +} + void EyeDropperTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) { t.paint_popup(popupPos); } diff --git a/src/DrawingProgram/Tools/EyeDropperTool.hpp b/src/DrawingProgram/Tools/EyeDropperTool.hpp index 4ee3915..64e8edb 100644 --- a/src/DrawingProgram/Tools/EyeDropperTool.hpp +++ b/src/DrawingProgram/Tools/EyeDropperTool.hpp @@ -8,6 +8,7 @@ class EyeDropperTool : public DrawingProgramToolBase { EyeDropperTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void tool_update() override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; diff --git a/src/DrawingProgram/Tools/GridModifyTool.cpp b/src/DrawingProgram/Tools/GridModifyTool.cpp index 011e877..4f46e0a 100644 --- a/src/DrawingProgram/Tools/GridModifyTool.cpp +++ b/src/DrawingProgram/Tools/GridModifyTool.cpp @@ -161,6 +161,51 @@ void GridModifyTool::gui_toolbox(Toolbar& t) { }); } +void GridModifyTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + + gui.new_id("Grid modify tool", [&] { + NetworkingObjects::NetObjTemporaryPtr gLock = grid.lock(); + if(gLock) { + WorldGrid& g = *gLock; + 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); + std::vector listOfGridTypes = { + "Circle Points", + "Square Points", + "Square Lines", + "Horizontal Lines" + }; + left_to_right_line_layout(gui, [&]() { + text_label(gui, "Type"); + 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); + }); + 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); + } + }); +} + void GridModifyTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) { t.paint_popup(popupPos); } diff --git a/src/DrawingProgram/Tools/GridModifyTool.hpp b/src/DrawingProgram/Tools/GridModifyTool.hpp index 728aa71..08a2c93 100644 --- a/src/DrawingProgram/Tools/GridModifyTool.hpp +++ b/src/DrawingProgram/Tools/GridModifyTool.hpp @@ -10,6 +10,7 @@ class GridModifyTool : public DrawingProgramToolBase { GridModifyTool(DrawingProgram& initDrawP); void set_grid(const NetworkingObjects::NetObjWeakPtr& newGrid); virtual DrawingProgramToolType get_type() override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void gui_toolbox(Toolbar& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/LassoSelectTool.cpp b/src/DrawingProgram/Tools/LassoSelectTool.cpp index 4e74caa..b323149 100644 --- a/src/DrawingProgram/Tools/LassoSelectTool.cpp +++ b/src/DrawingProgram/Tools/LassoSelectTool.cpp @@ -47,6 +47,13 @@ void LassoSelectTool::gui_toolbox(Toolbar& t) { }); } +void LassoSelectTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + auto& gui = drawP.world.main.g.gui; + gui.new_id("lasso select tool", [&] { + drawP.selection.phone_selection_gui(t); + }); +} + void LassoSelectTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) { drawP.selection_action_menu(popupPos); } diff --git a/src/DrawingProgram/Tools/LassoSelectTool.hpp b/src/DrawingProgram/Tools/LassoSelectTool.hpp index aebaf0f..bc6dc58 100644 --- a/src/DrawingProgram/Tools/LassoSelectTool.hpp +++ b/src/DrawingProgram/Tools/LassoSelectTool.hpp @@ -12,6 +12,7 @@ class LassoSelectTool : public DrawingProgramToolBase { LassoSelectTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/LineDrawTool.cpp b/src/DrawingProgram/Tools/LineDrawTool.cpp index a88ab74..743c237 100644 --- a/src/DrawingProgram/Tools/LineDrawTool.cpp +++ b/src/DrawingProgram/Tools/LineDrawTool.cpp @@ -30,6 +30,17 @@ void LineDrawTool::gui_toolbox(Toolbar& t) { }); } +void LineDrawTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + auto& gui = drawP.world.main.g.gui; + auto& toolConfig = drawP.world.main.toolConfig; + gui.new_id("rect draw tool", [&] { + toolConfig.relative_width_gui(drawP, "Size"); + checkbox_boolean_field(gui, "hasroundcaps", "Round Caps", &toolConfig.lineDraw.hasRoundCaps); + }); +} + void LineDrawTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { if(button.button == InputManager::MouseButton::LEFT) { auto& toolConfig = drawP.world.main.toolConfig; diff --git a/src/DrawingProgram/Tools/LineDrawTool.hpp b/src/DrawingProgram/Tools/LineDrawTool.hpp index 5a47dae..33c0bde 100644 --- a/src/DrawingProgram/Tools/LineDrawTool.hpp +++ b/src/DrawingProgram/Tools/LineDrawTool.hpp @@ -10,6 +10,7 @@ class LineDrawTool : public DrawingProgramToolBase { LineDrawTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/PanCanvasTool.cpp b/src/DrawingProgram/Tools/PanCanvasTool.cpp index 8a96c01..d00e5ae 100644 --- a/src/DrawingProgram/Tools/PanCanvasTool.cpp +++ b/src/DrawingProgram/Tools/PanCanvasTool.cpp @@ -23,6 +23,13 @@ void PanCanvasTool::gui_toolbox(Toolbar& t) { }); } +void PanCanvasTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + auto& gui = drawP.world.main.g.gui; + gui.new_id("Pan canvas tool", [&] { + GUIStuff::ElementHelpers::text_label_centered(gui, "Pan tool"); + }); +} + void PanCanvasTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) { drawP.selection_action_menu(popupPos); } diff --git a/src/DrawingProgram/Tools/PanCanvasTool.hpp b/src/DrawingProgram/Tools/PanCanvasTool.hpp index b55881f..ec82d96 100644 --- a/src/DrawingProgram/Tools/PanCanvasTool.hpp +++ b/src/DrawingProgram/Tools/PanCanvasTool.hpp @@ -8,6 +8,7 @@ class PanCanvasTool : public DrawingProgramToolBase { PanCanvasTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/RectDrawTool.cpp b/src/DrawingProgram/Tools/RectDrawTool.cpp index 37e21f5..0b40f9a 100644 --- a/src/DrawingProgram/Tools/RectDrawTool.cpp +++ b/src/DrawingProgram/Tools/RectDrawTool.cpp @@ -39,6 +39,26 @@ void RectDrawTool::gui_toolbox(Toolbar& t) { }); } +void RectDrawTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + auto& toolConfig = drawP.world.main.toolConfig; + auto& fillStrokeMode = toolConfig.rectDraw.fillStrokeMode; + auto& relativeRadiusWidth = toolConfig.rectDraw.relativeRadiusWidth; + gui.new_id("rect draw tool", [&] { + slider_scalar_field(gui, "relradiuswidth", "Corner Radius", &relativeRadiusWidth, 0.0f, 40.0f); + radio_button_selector(gui, "fill type", &fillStrokeMode, { + {"Fill only", 0}, + {"Outline only", 1}, + {"Fill and Outline", 2} + }); + if(fillStrokeMode == 1 || fillStrokeMode == 2) + toolConfig.relative_width_gui(drawP, "Outline Size"); + }); +} + void RectDrawTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { if(button.button == InputManager::MouseButton::LEFT) { if(button.down && drawP.layerMan.is_a_layer_being_edited() && !objInfoBeingEdited && !drawP.world.main.g.gui.cursor_obstructed()) { diff --git a/src/DrawingProgram/Tools/RectDrawTool.hpp b/src/DrawingProgram/Tools/RectDrawTool.hpp index 000c2d8..b469125 100644 --- a/src/DrawingProgram/Tools/RectDrawTool.hpp +++ b/src/DrawingProgram/Tools/RectDrawTool.hpp @@ -10,6 +10,7 @@ class RectDrawTool : public DrawingProgramToolBase { RectDrawTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/RectSelectTool.cpp b/src/DrawingProgram/Tools/RectSelectTool.cpp index 2097609..80a6307 100644 --- a/src/DrawingProgram/Tools/RectSelectTool.cpp +++ b/src/DrawingProgram/Tools/RectSelectTool.cpp @@ -26,6 +26,13 @@ void RectSelectTool::gui_toolbox(Toolbar& t) { }); } +void RectSelectTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + auto& gui = drawP.world.main.g.gui; + gui.new_id("rect select tool", [&] { + drawP.selection.phone_selection_gui(t); + }); +} + void RectSelectTool::input_key_callback(const InputManager::KeyCallbackArgs& key) { drawP.selection.input_key_callback_modify_selection(key); } diff --git a/src/DrawingProgram/Tools/RectSelectTool.hpp b/src/DrawingProgram/Tools/RectSelectTool.hpp index a5a29a7..d220e5e 100644 --- a/src/DrawingProgram/Tools/RectSelectTool.hpp +++ b/src/DrawingProgram/Tools/RectSelectTool.hpp @@ -10,6 +10,7 @@ class RectSelectTool : public DrawingProgramToolBase { RectSelectTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/ScreenshotTool.cpp b/src/DrawingProgram/Tools/ScreenshotTool.cpp index 1a580f6..7a8c62d 100644 --- a/src/DrawingProgram/Tools/ScreenshotTool.cpp +++ b/src/DrawingProgram/Tools/ScreenshotTool.cpp @@ -106,6 +106,16 @@ void ScreenshotTool::gui_toolbox(Toolbar& t) { }); } +void ScreenshotTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + using namespace GUIStuff; + using namespace ElementHelpers; + + auto& gui = drawP.world.main.g.gui; + gui.new_id("screenshot tool", [&] { + text_label_centered(gui, "Screenshot"); + }); +} + void ScreenshotTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) { t.paint_popup(popupPos); } diff --git a/src/DrawingProgram/Tools/ScreenshotTool.hpp b/src/DrawingProgram/Tools/ScreenshotTool.hpp index d6a8366..7c2d6b0 100644 --- a/src/DrawingProgram/Tools/ScreenshotTool.hpp +++ b/src/DrawingProgram/Tools/ScreenshotTool.hpp @@ -13,6 +13,7 @@ class ScreenshotTool : public DrawingProgramToolBase { ScreenshotTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/TextBoxTool.cpp b/src/DrawingProgram/Tools/TextBoxTool.cpp index 99b3010..b52b46d 100644 --- a/src/DrawingProgram/Tools/TextBoxTool.cpp +++ b/src/DrawingProgram/Tools/TextBoxTool.cpp @@ -26,6 +26,13 @@ void TextBoxTool::gui_toolbox(Toolbar& t) { }); } +void TextBoxTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + auto& gui = drawP.world.main.g.gui; + gui.new_id("textbox tool", [&] { + GUIStuff::ElementHelpers::text_label_centered(gui, "Place textbox"); + }); +} + void TextBoxTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { if(button.button == InputManager::MouseButton::LEFT) { if(button.down && drawP.layerMan.is_a_layer_being_edited() && !objInfoBeingEdited && !drawP.world.main.g.gui.cursor_obstructed()) { diff --git a/src/DrawingProgram/Tools/TextBoxTool.hpp b/src/DrawingProgram/Tools/TextBoxTool.hpp index 0ed7ba7..5ab5197 100644 --- a/src/DrawingProgram/Tools/TextBoxTool.hpp +++ b/src/DrawingProgram/Tools/TextBoxTool.hpp @@ -10,6 +10,7 @@ class TextBoxTool : public DrawingProgramToolBase { TextBoxTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/DrawingProgram/Tools/ZoomCanvasTool.cpp b/src/DrawingProgram/Tools/ZoomCanvasTool.cpp index d70c0f9..31678ed 100644 --- a/src/DrawingProgram/Tools/ZoomCanvasTool.cpp +++ b/src/DrawingProgram/Tools/ZoomCanvasTool.cpp @@ -23,6 +23,13 @@ void ZoomCanvasTool::gui_toolbox(Toolbar& t) { }); } +void ZoomCanvasTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) { + auto& gui = drawP.world.main.g.gui; + gui.new_id("Zoom canvas tool", [&] { + GUIStuff::ElementHelpers::text_label_centered(gui, "Zoom tool"); + }); +} + void ZoomCanvasTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) { drawP.selection_action_menu(popupPos); } diff --git a/src/DrawingProgram/Tools/ZoomCanvasTool.hpp b/src/DrawingProgram/Tools/ZoomCanvasTool.hpp index 693a853..4dc3a36 100644 --- a/src/DrawingProgram/Tools/ZoomCanvasTool.hpp +++ b/src/DrawingProgram/Tools/ZoomCanvasTool.hpp @@ -8,6 +8,7 @@ class ZoomCanvasTool : public DrawingProgramToolBase { ZoomCanvasTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox(Toolbar& t) override; + virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override; virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override; virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override; virtual void tool_update() override; diff --git a/src/GUIStuff/Elements/CheckBox.cpp b/src/GUIStuff/Elements/CheckBox.cpp index cd396d0..64234e3 100644 --- a/src/GUIStuff/Elements/CheckBox.cpp +++ b/src/GUIStuff/Elements/CheckBox.cpp @@ -22,7 +22,7 @@ void CheckBox::layout(const Clay_ElementId& id, const std::function& isT } void CheckBox::update() { - if(smooth_two_way_animation_time_check_for_change(hoverAnimation, gui.io.deltaTime, mouseHovering, CHECKBOX_ANIMATION_TIME)) + if(smooth_two_way_animation_time_check_for_change(hoverAnimation, gui.io.deltaTime, is_hovering_animation(), CHECKBOX_ANIMATION_TIME)) gui.invalidate_draw_element(this); if(oldIsTicked != isTicked()) { gui.invalidate_draw_element(this); @@ -30,9 +30,26 @@ void CheckBox::update() { } } +bool CheckBox::is_hovering_animation() { + return mouseHovering && (!gui.last_interaction_is_touch() || isHeld); +} + void CheckBox::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { - if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) + if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) { gui.set_post_callback_func([&](){if(onClick) onClick();}); + isHeld = true; + } + else + isHeld = false; +} + +void CheckBox::input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) { + if(mouseHovering && touch.down) { + gui.set_post_callback_func([&](){if(onClick) onClick();}); + isHeld = true; + } + else + isHeld = false; } void CheckBox::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) { @@ -53,7 +70,7 @@ void CheckBox::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderComma } else { SkRect checkBox = SkRect::MakeLTRB(-0.45f, -0.45f, 0.45f, 0.45f); - p.setColor4f(convert_vec4(mouseHovering ? io.theme->fillColor1 : io.theme->fillColor2)); + p.setColor4f(convert_vec4(is_hovering_animation() ? io.theme->fillColor1 : io.theme->fillColor2)); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(0.15f); canvas->drawRoundRect(checkBox, 0.25f, 0.25f, p); diff --git a/src/GUIStuff/Elements/CheckBox.hpp b/src/GUIStuff/Elements/CheckBox.hpp index 4771772..b8747ea 100644 --- a/src/GUIStuff/Elements/CheckBox.hpp +++ b/src/GUIStuff/Elements/CheckBox.hpp @@ -9,6 +9,7 @@ class CheckBox : public Element { virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override; virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override; + virtual void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) override; virtual void update() override; void layout(const Clay_ElementId& id, const std::function& isTicked, const std::function& onClick); @@ -16,6 +17,8 @@ class CheckBox : public Element { static constexpr float CHECKBOX_ANIMATION_TIME = 0.3; float hoverAnimation = 0.0; bool oldIsTicked = false; + bool isHeld = false; + bool is_hovering_animation(); std::function isTicked; std::function onClick; }; diff --git a/src/GUIStuff/Elements/NumberSlider.hpp b/src/GUIStuff/Elements/NumberSlider.hpp index fbeff8c..9d9ed90 100644 --- a/src/GUIStuff/Elements/NumberSlider.hpp +++ b/src/GUIStuff/Elements/NumberSlider.hpp @@ -1,6 +1,7 @@ #pragma once #include "Element.hpp" #include "../GUIManager.hpp" +#include "../../TimePoint.hpp" namespace GUIStuff { @@ -35,7 +36,7 @@ template class NumberSlider : public Element { virtual void update() override { smooth_two_way_animation_time(dd.holdAnimation, gui.io.deltaTime, dd.isHeld, HOLD_ANIMATION_TIME); - smooth_two_way_animation_time(dd.hoverAnimation, gui.io.deltaTime, mouseHovering, gui.io.theme->hoverExpandTime); + smooth_two_way_animation_time(dd.hoverAnimation, gui.io.deltaTime, mouseHovering && !gui.last_interaction_is_touch(), gui.io.theme->hoverExpandTime); if(oldDD != dd) { gui.invalidate_draw_element(this, { .top = 10.0f, @@ -113,6 +114,23 @@ template class NumberSlider : public Element { update_slider_pos(motion.pos, false); } + virtual void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) override { + bool oldIsHeld = dd.isHeld; + dd.isHeld = mouseHovering && touch.down; + if(oldIsHeld && !dd.isHeld) { + gui.set_post_callback_func([&] { + if(config.onRelease) config.onRelease(); + }); + } + else if(dd.isHeld && boundingBox.has_value()) + update_slider_pos(touch.pos, true); + } + + virtual void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) override { + if(dd.isHeld && boundingBox.has_value()) + update_slider_pos(motion.pos, false); + } + private: void update_slider_pos(const Vector2f& p, bool justHeld) { gui.set_post_callback_func([&, p, justHeld] { diff --git a/src/GUIStuff/Elements/RadioButton.cpp b/src/GUIStuff/Elements/RadioButton.cpp index 3c55a92..1de0a80 100644 --- a/src/GUIStuff/Elements/RadioButton.cpp +++ b/src/GUIStuff/Elements/RadioButton.cpp @@ -20,7 +20,7 @@ void RadioButton::layout(const Clay_ElementId& id, const std::function& } void RadioButton::update() { - if(smooth_two_way_animation_time_check_for_change(hoverAnimation, gui.io.deltaTime, mouseHovering, RADIOBUTTON_ANIMATION_TIME)) + if(smooth_two_way_animation_time_check_for_change(hoverAnimation, gui.io.deltaTime, is_hovering_animation(), RADIOBUTTON_ANIMATION_TIME)) gui.invalidate_draw_element(this); if(oldIsTicked != isTicked()) { gui.invalidate_draw_element(this); @@ -28,9 +28,26 @@ void RadioButton::update() { } } +bool RadioButton::is_hovering_animation() { + return mouseHovering && (!gui.last_interaction_is_touch() || isHeld); +} + void RadioButton::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { - if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) + if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) { gui.set_post_callback_func([&] { if(onClick) onClick(); }); + isHeld = true; + } + else + isHeld = false; +} + +void RadioButton::input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) { + if(mouseHovering && touch.down) { + gui.set_post_callback_func([&] { if(onClick) onClick(); }); + isHeld = true; + } + else + isHeld = false; } void RadioButton::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) { @@ -62,7 +79,7 @@ void RadioButton::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCo else { SkPaint p; p.setAntiAlias(skiaAA); - p.setColor4f(convert_vec4(mouseHovering ? io.theme->fillColor1 : io.theme->backColor2)); + p.setColor4f(convert_vec4(is_hovering_animation() ? io.theme->fillColor1 : io.theme->backColor2)); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(0.15f); canvas->drawCircle(0.0f, 0.0f, 0.5f, p); diff --git a/src/GUIStuff/Elements/RadioButton.hpp b/src/GUIStuff/Elements/RadioButton.hpp index 8300827..cabfd4f 100644 --- a/src/GUIStuff/Elements/RadioButton.hpp +++ b/src/GUIStuff/Elements/RadioButton.hpp @@ -8,12 +8,15 @@ class RadioButton : public Element { RadioButton(GUIManager& gui); virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override; virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override; + virtual void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) override; virtual void update() override; void layout(const Clay_ElementId& id, const std::function& isTicked, const std::function& onClick); private: static constexpr float RADIOBUTTON_ANIMATION_TIME = 0.3; bool oldIsTicked = false; + bool isHeld = false; + bool is_hovering_animation(); float hoverAnimation = 0.0; std::function isTicked; std::function onClick; diff --git a/src/GUIStuff/GUIManager.cpp b/src/GUIStuff/GUIManager.cpp index c7965b3..08d23a1 100644 --- a/src/GUIStuff/GUIManager.cpp +++ b/src/GUIStuff/GUIManager.cpp @@ -27,6 +27,7 @@ GUIManager::GUIManager() Clay_SetMeasureTextFunction(clay_skia_measure_text, this); setToLayout = true; postCallbackFuncIsHighPriority = false; + lastInteractionIsTouch = false; } Clay_Dimensions GUIManager::clay_skia_measure_text(Clay_StringSlice str, Clay_TextElementConfig* config, void* userData) { @@ -671,6 +672,10 @@ void GUIManager::invalidate_draw_in_area(const SCollision::AABB& bb) { invalidDrawBB = bb; } +bool GUIManager::last_interaction_is_touch() { + return lastInteractionIsTouch; +} + bool GUIManager::cursor_obstructed() const { return cursorObstructed; } @@ -702,6 +707,7 @@ void GUIManager::input_key_callback(const InputManager::KeyCallbackArgs& key) { void GUIManager::input_mouse_button_callback(InputManager::MouseButtonCallbackArgs button) { if(button.deviceType != InputManager::MouseDeviceType::TOUCH) { + lastInteractionIsTouch = false; button.pos /= io.guiScaleMultiplier; mouse_callback(button.pos, [&button] (ElementContainer* e) { e->elem->input_mouse_button_callback(button); }); } @@ -709,6 +715,7 @@ void GUIManager::input_mouse_button_callback(InputManager::MouseButtonCallbackAr void GUIManager::input_mouse_motion_callback(InputManager::MouseMotionCallbackArgs motion) { if(motion.deviceType != InputManager::MouseDeviceType::TOUCH) { + lastInteractionIsTouch = false; motion.pos /= io.guiScaleMultiplier; motion.move /= io.guiScaleMultiplier; mouse_callback(motion.pos, [&motion] (ElementContainer* e) { e->elem->input_mouse_motion_callback(motion); }); @@ -721,11 +728,13 @@ void GUIManager::input_mouse_wheel_callback(InputManager::MouseWheelCallbackArgs } void GUIManager::input_finger_touch_callback(InputManager::FingerTouchCallbackArgs touch) { + lastInteractionIsTouch = true; touch.pos /= io.guiScaleMultiplier; mouse_callback(touch.pos, [&touch] (ElementContainer* e) { e->elem->input_finger_touch_callback(touch); }); } void GUIManager::input_finger_motion_callback(InputManager::FingerMotionCallbackArgs motion) { + lastInteractionIsTouch = true; motion.pos /= io.guiScaleMultiplier; motion.move /= io.guiScaleMultiplier; mouse_callback(motion.pos, [&motion] (ElementContainer* e) { e->elem->input_finger_motion_callback(motion); }); diff --git a/src/GUIStuff/GUIManager.hpp b/src/GUIStuff/GUIManager.hpp index 1a5a003..43d7ce7 100644 --- a/src/GUIStuff/GUIManager.hpp +++ b/src/GUIStuff/GUIManager.hpp @@ -47,6 +47,8 @@ class GUIManager { void invalidate_draw_element(Element* element, const BorderData& extraPadding = {}); void invalidate_draw_in_area(const SCollision::AABB& bb); + bool last_interaction_is_touch(); + template ElementType* element(const char* id, const Args&... a) { push_id(id); @@ -161,6 +163,7 @@ class GUIManager { void calculate_new_clip_rect(std::vector>& clipRectStack, std::optional>& clipRect, bool& clipNoDraw); void clip_rect_transform(SkCanvas* canvas, std::vector>& clipRectStack, std::optional>& clipRect, bool& clipNoDraw); + bool lastInteractionIsTouch; bool setToLayout; bool setToUpdateInvalidateDrawAreaFromLayout; bool cursorObstructed; diff --git a/src/Screens/PhoneDrawingProgramScreen.cpp b/src/Screens/PhoneDrawingProgramScreen.cpp index 17649ca..6a9c69e 100644 --- a/src/Screens/PhoneDrawingProgramScreen.cpp +++ b/src/Screens/PhoneDrawingProgramScreen.cpp @@ -27,6 +27,8 @@ void PhoneDrawingProgramScreen::main_display() { CLAY_AUTO_ID({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }, + .childGap = main.g.gui.io.theme->childGap1, + .childAlignment = {.x = CLAY_ALIGN_X_CENTER}, .layoutDirection = CLAY_TOP_TO_BOTTOM }, }) { @@ -77,42 +79,188 @@ void PhoneDrawingProgramScreen::top_toolbar() { void PhoneDrawingProgramScreen::bottom_toolbar() { auto& gui = main.g.gui; auto& io = gui.io; - auto& drawProg = main.world->drawProg; window_fill_side_bar(gui, { .dir = WindowFillSideBarConfig::Direction::BOTTOM, }, [&] { CLAY_AUTO_ID({ .layout = { .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0) }, - .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, - .layoutDirection = CLAY_LEFT_TO_RIGHT + .childGap = io.theme->childGap1, + .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER} } }) { - gui.element("bottom toolbar", [&](LayoutElement*, const Clay_ElementId& lId) { - CLAY(lId, { + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0) }, + .childGap = io.theme->childGap1, + .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_BOTTOM}, + .layoutDirection = CLAY_TOP_TO_BOTTOM + } + }) { + CLAY_AUTO_ID({ .layout = { - .sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0) }, - }, - .backgroundColor = convert_vec4(io.theme->backColor1), - .cornerRadius = CLAY_CORNER_RADIUS(io.theme->windowCorners1) + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0) }, + .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_BOTTOM}, + .layoutDirection = CLAY_LEFT_TO_RIGHT + } }) { - gui.clipping_element("tools scroll", ScrollArea::Options{ - .scrollHorizontal = true, - .clipHorizontal = true, - .scrollbarX = ScrollArea::ScrollbarType::NONE, - .layoutDirection = CLAY_LEFT_TO_RIGHT, - .xAlign = CLAY_ALIGN_X_LEFT, - .yAlign = CLAY_ALIGN_Y_CENTER, - .innerContent = [&](auto&) { - drawProg.phone_bottom_toolbar_gui(*this); + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0) }, + } + }) {} + switch(settingsMenuPopup) { + case SettingsMenuPopup::NONE: + break; + case SettingsMenuPopup::SETTINGS: + tool_settings_popup(); + break; + case SettingsMenuPopup::FG_COLOR: + break; + case SettingsMenuPopup::BG_COLOR: + break; + } + } + + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0) }, + .childGap = io.theme->childGap1, + .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, + .layoutDirection = CLAY_LEFT_TO_RIGHT + } + }) { + gui.element("bottom toolbar", [&](LayoutElement*, const Clay_ElementId& lId) { + CLAY(lId, { + .layout = { + .sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0)} + }, + .backgroundColor = convert_vec4(io.theme->backColor1), + .cornerRadius = CLAY_CORNER_RADIUS(io.theme->windowCorners1) + }) { + gui.clipping_element("tools scroll", ScrollArea::Options{ + .scrollHorizontal = true, + .clipHorizontal = true, + .scrollbarX = ScrollArea::ScrollbarType::NONE, + .layoutDirection = CLAY_LEFT_TO_RIGHT, + .xAlign = CLAY_ALIGN_X_LEFT, + .yAlign = CLAY_ALIGN_Y_CENTER, + .innerContent = [&](auto&) { + bottom_toolbar_gui(); + } + }); + } + }); + gui.element("bottom extra toolbar", [&](LayoutElement*, const Clay_ElementId& lId) { + CLAY(lId, { + .layout = { + .sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0)}, + .layoutDirection = CLAY_LEFT_TO_RIGHT + }, + .backgroundColor = convert_vec4(io.theme->backColor1), + .cornerRadius = CLAY_CORNER_RADIUS(io.theme->windowCorners1) + }) { + bottom_extra_toolbar_gui(); } }); } + } + } + }); +} + +void PhoneDrawingProgramScreen::bottom_toolbar_gui() { + GUIManager& gui = main.g.gui; + auto& drawP = main.world->drawProg; + + auto tool_button = [&](const char* id, const std::string& svgPath, DrawingProgramToolType toolType) { + svg_icon_button(gui, id, svgPath, { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, + .isSelected = drawP.drawTool->get_type() == toolType, + .onClick = [&, toolType] { + drawP.switch_to_tool(toolType); + } + }); + }; + + tool_button("Brush Toolbar Button", "data/icons/brush.svg", DrawingProgramToolType::BRUSH); + tool_button("Eraser Toolbar Button", "data/icons/eraser.svg", DrawingProgramToolType::ERASER); + tool_button("Line Toolbar Button", "data/icons/line.svg", DrawingProgramToolType::LINE); + tool_button("Text Toolbar Button", "data/icons/text.svg", DrawingProgramToolType::TEXTBOX); + tool_button("Ellipse Toolbar Button", "data/icons/circle.svg", DrawingProgramToolType::ELLIPSE); + tool_button("Rect Toolbar Button", "data/icons/rectangle.svg", DrawingProgramToolType::RECTANGLE); + tool_button("RectSelect Toolbar Button", "data/icons/rectselect.svg", DrawingProgramToolType::RECTSELECT); + tool_button("LassoSelect Toolbar Button", "data/icons/lassoselect.svg", DrawingProgramToolType::LASSOSELECT); + tool_button("Edit Toolbar Button", "data/icons/cursor.svg", DrawingProgramToolType::EDIT); + tool_button("Eyedropper Toolbar Button", "data/icons/eyedropper.svg", DrawingProgramToolType::EYEDROPPER); + tool_button("Zoom Canvas Toolbar Button", "data/icons/zoom.svg", DrawingProgramToolType::ZOOM); + tool_button("Pan Canvas Toolbar Button", "data/icons/hand.svg", DrawingProgramToolType::PAN); +} + +void PhoneDrawingProgramScreen::tool_settings_popup() { + GUIManager& gui = main.g.gui; + auto& drawP = main.world->drawProg; + auto& io = gui.io; + + gui.element("tool settings popup", [&] (LayoutElement*, const Clay_ElementId& lId) { + CLAY(lId, { + .layout = { + .sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0)}, + }, + .backgroundColor = convert_vec4(io.theme->backColor1), + .cornerRadius = CLAY_CORNER_RADIUS(io.theme->windowCorners1) + }) { + gui.element("toolbox scroll area", ScrollArea::Options{ + .scrollVertical = true, + .clipVertical = true, + .scrollbarY = ScrollArea::ScrollbarType::NORMAL, + .innerContent = [&](auto&) { + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + .padding = CLAY_PADDING_ALL(io.theme->padding1), + .childGap = io.theme->childGap1, + .layoutDirection = CLAY_TOP_TO_BOTTOM + }, + }) { + drawP.drawTool->gui_phone_toolbox(*this); + } + } }); } }); } +void PhoneDrawingProgramScreen::bottom_extra_toolbar_gui() { + GUIManager& gui = main.g.gui; + + svg_icon_button(gui, "tool settings", "data/icons/RemixIcon/settings-3-line.svg", { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, + .isSelected = settingsMenuPopup == SettingsMenuPopup::SETTINGS, + .onClick = [&] { + settingsMenuPopup = (settingsMenuPopup == SettingsMenuPopup::SETTINGS) ? SettingsMenuPopup::NONE : SettingsMenuPopup::SETTINGS; + } + }); + + color_button(gui, "foreground color", &main.toolConfig.globalConf.foregroundColor, { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, + .isSelected = settingsMenuPopup == SettingsMenuPopup::FG_COLOR, + .hasAlpha = true, + .onClick = [&] { + settingsMenuPopup = (settingsMenuPopup == SettingsMenuPopup::FG_COLOR) ? SettingsMenuPopup::NONE : SettingsMenuPopup::FG_COLOR; + } + }); + + color_button(gui, "background color", &main.toolConfig.globalConf.backgroundColor, { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, + .isSelected = settingsMenuPopup == SettingsMenuPopup::BG_COLOR, + .hasAlpha = true, + .onClick = [&] { + settingsMenuPopup = (settingsMenuPopup == SettingsMenuPopup::BG_COLOR) ? SettingsMenuPopup::NONE : SettingsMenuPopup::BG_COLOR; + } + }); +} + void PhoneDrawingProgramScreen::input_global_back_button_callback() { main.world->save_to_file(main.world->filePath); main.set_tab_to_close(main.world.get()); diff --git a/src/Screens/PhoneDrawingProgramScreen.hpp b/src/Screens/PhoneDrawingProgramScreen.hpp index e172058..4c4f2aa 100644 --- a/src/Screens/PhoneDrawingProgramScreen.hpp +++ b/src/Screens/PhoneDrawingProgramScreen.hpp @@ -10,8 +10,17 @@ class PhoneDrawingProgramScreen : public DrawingProgramScreen { virtual void input_global_back_button_callback() override; virtual void input_app_about_to_go_to_background_callback() override; private: + void bottom_toolbar_gui(); + void bottom_extra_toolbar_gui(); void save_files(); void top_toolbar(); void bottom_toolbar(); void main_display(); + void tool_settings_popup(); + enum class SettingsMenuPopup { + NONE, + SETTINGS, + FG_COLOR, + BG_COLOR + } settingsMenuPopup = SettingsMenuPopup::NONE; };