#pragma once #include "app_core/app_dialog.h" #include "app_core/document_canvas.h" #include "app_core/history_ui.h" #include "foundation/result.h" #include namespace pp::app { enum class MainToolbarCommand { open_document, save_document, undo, redo, clear_history, clear_canvas, show_message_box, show_settings, }; enum class MainToolbarAction { show_open_dialog, show_save_dialog, invoke_undo, invoke_redo, clear_history, clear_canvas, show_message_box, show_settings_dialog, no_op_unavailable, }; struct MainToolbarPlan { MainToolbarCommand command = MainToolbarCommand::open_document; MainToolbarAction action = MainToolbarAction::show_open_dialog; std::string label; bool requires_canvas = false; bool updates_memory_label = false; bool updates_title = false; bool records_undo = false; bool marks_unsaved = false; bool no_op = false; HistoryUiPlan history; DocumentCanvasClearPlan canvas_clear; }; class MainToolbarServices { public: virtual ~MainToolbarServices() = default; virtual void show_open_dialog() = 0; virtual void show_save_dialog() = 0; virtual void invoke_undo(const HistoryUiPlan& plan) = 0; virtual void invoke_redo(const HistoryUiPlan& plan) = 0; virtual void clear_history(const HistoryUiPlan& plan) = 0; virtual void clear_canvas(const DocumentCanvasClearPlan& plan) = 0; virtual void show_message_box() = 0; virtual void show_settings_dialog() = 0; }; [[nodiscard]] inline AppMessageDialogPlan plan_main_toolbar_message_dialog() { return plan_app_message_dialog( "Just a test message", "Longer description for the error or the message.", true); } [[nodiscard]] inline pp::foundation::Result plan_main_toolbar_command( MainToolbarCommand command, int undo_count = 0, int redo_count = 0, int memory_bytes = 0, bool has_canvas = true) { MainToolbarPlan plan; plan.command = command; switch (command) { case MainToolbarCommand::open_document: plan.action = MainToolbarAction::show_open_dialog; plan.label = "Open"; return pp::foundation::Result::success(plan); case MainToolbarCommand::save_document: plan.action = MainToolbarAction::show_save_dialog; plan.label = "Save"; return pp::foundation::Result::success(plan); case MainToolbarCommand::undo: { const auto history = plan_history_undo(undo_count); if (!history) { return pp::foundation::Result::failure(history.status()); } plan.action = history.value().invokes_undo ? MainToolbarAction::invoke_undo : MainToolbarAction::no_op_unavailable; plan.label = history.value().invokes_undo ? "Undo" : "Undo (No history)"; plan.updates_memory_label = history.value().updates_memory_label; plan.updates_title = history.value().updates_title; plan.no_op = history.value().no_op; plan.history = history.value(); return pp::foundation::Result::success(plan); } case MainToolbarCommand::redo: { const auto history = plan_history_redo(redo_count); if (!history) { return pp::foundation::Result::failure(history.status()); } plan.action = history.value().invokes_redo ? MainToolbarAction::invoke_redo : MainToolbarAction::no_op_unavailable; plan.label = history.value().invokes_redo ? "Redo" : "Redo (No history)"; plan.updates_memory_label = history.value().updates_memory_label; plan.updates_title = history.value().updates_title; plan.no_op = history.value().no_op; plan.history = history.value(); return pp::foundation::Result::success(plan); } case MainToolbarCommand::clear_history: { const auto history = plan_history_clear(undo_count, redo_count, memory_bytes); if (!history) { return pp::foundation::Result::failure(history.status()); } plan.action = history.value().clears_history ? MainToolbarAction::clear_history : MainToolbarAction::no_op_unavailable; plan.label = history.value().clears_history ? "Clear History" : "Clear History (Empty)"; plan.updates_memory_label = history.value().updates_memory_label; plan.no_op = history.value().no_op; plan.history = history.value(); return pp::foundation::Result::success(plan); } case MainToolbarCommand::clear_canvas: { const auto clear = plan_document_canvas_clear(has_canvas); if (!clear) { return pp::foundation::Result::failure(clear.status()); } plan.action = clear.value().clears_canvas ? MainToolbarAction::clear_canvas : MainToolbarAction::no_op_unavailable; plan.label = clear.value().clears_canvas ? "Clear Canvas" : "Clear Canvas (No canvas)"; plan.requires_canvas = true; plan.records_undo = clear.value().records_undo; plan.marks_unsaved = clear.value().marks_unsaved; plan.no_op = clear.value().no_op; plan.canvas_clear = clear.value(); return pp::foundation::Result::success(plan); } case MainToolbarCommand::show_message_box: plan.action = MainToolbarAction::show_message_box; plan.label = "Show Message Box"; return pp::foundation::Result::success(plan); case MainToolbarCommand::show_settings: plan.action = MainToolbarAction::show_settings_dialog; plan.label = "Settings"; return pp::foundation::Result::success(plan); } return pp::foundation::Result::failure( pp::foundation::Status::invalid_argument("unknown main toolbar command")); } [[nodiscard]] inline pp::foundation::Status execute_main_toolbar_plan( const MainToolbarPlan& plan, MainToolbarServices& services) { switch (plan.action) { case MainToolbarAction::show_open_dialog: services.show_open_dialog(); return pp::foundation::Status::success(); case MainToolbarAction::show_save_dialog: services.show_save_dialog(); return pp::foundation::Status::success(); case MainToolbarAction::invoke_undo: services.invoke_undo(plan.history); return pp::foundation::Status::success(); case MainToolbarAction::invoke_redo: services.invoke_redo(plan.history); return pp::foundation::Status::success(); case MainToolbarAction::clear_history: services.clear_history(plan.history); return pp::foundation::Status::success(); case MainToolbarAction::clear_canvas: services.clear_canvas(plan.canvas_clear); return pp::foundation::Status::success(); case MainToolbarAction::show_message_box: services.show_message_box(); return pp::foundation::Status::success(); case MainToolbarAction::show_settings_dialog: services.show_settings_dialog(); return pp::foundation::Status::success(); case MainToolbarAction::no_op_unavailable: return pp::foundation::Status::success(); } return pp::foundation::Status::invalid_argument("unknown main toolbar action"); } } // namespace pp::app