#pragma once #include "foundation/result.h" #include namespace pp::app { enum class ToolsMenuCommand { panels, options, clear_grids, reset_camera, shortcuts, sonarpen, }; enum class ToolsMenuAction { show_panels_submenu, show_options_submenu, clear_grid_overlays, reset_camera, show_shortcuts_dialog, start_sonarpen, no_op_unavailable, }; enum class ToolsPanel { presets, color, color_advanced, layers, brush, grids, animation, }; enum class ToolsPanelAction { open_floating_panel, no_op_already_visible, }; struct ToolsMenuPlan { ToolsMenuCommand command = ToolsMenuCommand::panels; ToolsMenuAction action = ToolsMenuAction::show_panels_submenu; std::string_view label; bool closes_root_popup = false; }; struct ToolsPanelPlan { ToolsPanel panel = ToolsPanel::presets; ToolsPanelAction action = ToolsPanelAction::open_floating_panel; std::string_view title; int width = 0; int height = 0; int min_width = 0; int min_height = 0; bool droppable = true; bool hides_embedded_title = false; }; class ToolsMenuServices { public: virtual ~ToolsMenuServices() = default; virtual void show_panels_submenu() = 0; virtual void show_options_submenu() = 0; virtual void clear_grid_overlays() = 0; virtual void reset_camera() = 0; virtual void show_shortcuts_dialog() = 0; virtual void start_sonarpen() = 0; }; [[nodiscard]] constexpr ToolsMenuPlan plan_tools_menu_command( ToolsMenuCommand command, bool sonarpen_available = false) noexcept { switch (command) { case ToolsMenuCommand::panels: return { command, ToolsMenuAction::show_panels_submenu, "Panels", false }; case ToolsMenuCommand::options: return { command, ToolsMenuAction::show_options_submenu, "Options", false }; case ToolsMenuCommand::clear_grids: return { command, ToolsMenuAction::clear_grid_overlays, "Clear Grids", true }; case ToolsMenuCommand::reset_camera: return { command, ToolsMenuAction::reset_camera, "Reset Camera", true }; case ToolsMenuCommand::shortcuts: return { command, ToolsMenuAction::show_shortcuts_dialog, "Shortcuts", true }; case ToolsMenuCommand::sonarpen: return { command, sonarpen_available ? ToolsMenuAction::start_sonarpen : ToolsMenuAction::no_op_unavailable, "SonarPen", sonarpen_available, }; } return { command, ToolsMenuAction::no_op_unavailable, "", false }; } [[nodiscard]] constexpr ToolsPanelPlan plan_tools_panel( ToolsPanel panel, bool already_visible) noexcept { ToolsPanelPlan plan; plan.panel = panel; plan.action = already_visible ? ToolsPanelAction::no_op_already_visible : ToolsPanelAction::open_floating_panel; switch (panel) { case ToolsPanel::presets: plan.title = "Brushes"; plan.height = 300; plan.min_height = 300; plan.min_width = 100; break; case ToolsPanel::color: plan.title = "Color Picker"; plan.height = 300; plan.hides_embedded_title = true; break; case ToolsPanel::color_advanced: plan.title = "Color Picker"; plan.width = 300; plan.height = 300; break; case ToolsPanel::layers: plan.title = "Layers"; plan.height = 300; plan.min_height = 100; plan.hides_embedded_title = true; break; case ToolsPanel::brush: plan.title = "Brush Settings"; plan.height = 300; plan.hides_embedded_title = true; break; case ToolsPanel::grids: plan.title = "Grid"; plan.height = 300; plan.hides_embedded_title = true; break; case ToolsPanel::animation: plan.title = "Animation"; plan.width = 500; plan.height = 300; plan.droppable = false; break; } return plan; } [[nodiscard]] inline pp::foundation::Status execute_tools_menu_plan( const ToolsMenuPlan& plan, ToolsMenuServices& services) { switch (plan.action) { case ToolsMenuAction::show_panels_submenu: services.show_panels_submenu(); return pp::foundation::Status::success(); case ToolsMenuAction::show_options_submenu: services.show_options_submenu(); return pp::foundation::Status::success(); case ToolsMenuAction::clear_grid_overlays: services.clear_grid_overlays(); return pp::foundation::Status::success(); case ToolsMenuAction::reset_camera: services.reset_camera(); return pp::foundation::Status::success(); case ToolsMenuAction::show_shortcuts_dialog: services.show_shortcuts_dialog(); return pp::foundation::Status::success(); case ToolsMenuAction::start_sonarpen: services.start_sonarpen(); return pp::foundation::Status::success(); case ToolsMenuAction::no_op_unavailable: return pp::foundation::Status::success(); } return pp::foundation::Status::invalid_argument("unknown tools menu action"); } }