Files
panopainter/src/app_core/main_toolbar.h

212 lines
7.4 KiB
C++

#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 <string>
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<MainToolbarPlan> 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<MainToolbarPlan>::success(plan);
case MainToolbarCommand::save_document:
plan.action = MainToolbarAction::show_save_dialog;
plan.label = "Save";
return pp::foundation::Result<MainToolbarPlan>::success(plan);
case MainToolbarCommand::undo:
{
const auto history = plan_history_undo(undo_count);
if (!history) {
return pp::foundation::Result<MainToolbarPlan>::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<MainToolbarPlan>::success(plan);
}
case MainToolbarCommand::redo:
{
const auto history = plan_history_redo(redo_count);
if (!history) {
return pp::foundation::Result<MainToolbarPlan>::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<MainToolbarPlan>::success(plan);
}
case MainToolbarCommand::clear_history:
{
const auto history = plan_history_clear(undo_count, redo_count, memory_bytes);
if (!history) {
return pp::foundation::Result<MainToolbarPlan>::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<MainToolbarPlan>::success(plan);
}
case MainToolbarCommand::clear_canvas:
{
const auto clear = plan_document_canvas_clear(has_canvas);
if (!clear) {
return pp::foundation::Result<MainToolbarPlan>::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<MainToolbarPlan>::success(plan);
}
case MainToolbarCommand::show_message_box:
plan.action = MainToolbarAction::show_message_box;
plan.label = "Show Message Box";
return pp::foundation::Result<MainToolbarPlan>::success(plan);
case MainToolbarCommand::show_settings:
plan.action = MainToolbarAction::show_settings_dialog;
plan.label = "Settings";
return pp::foundation::Result<MainToolbarPlan>::success(plan);
}
return pp::foundation::Result<MainToolbarPlan>::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