Add history command service boundary
This commit is contained in:
@@ -23,6 +23,15 @@ struct HistoryUiPlan {
|
||||
bool no_op = false;
|
||||
};
|
||||
|
||||
class HistoryUiServices {
|
||||
public:
|
||||
virtual ~HistoryUiServices() = default;
|
||||
|
||||
virtual void invoke_undo() = 0;
|
||||
virtual void invoke_redo() = 0;
|
||||
virtual void clear_history() = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Status validate_history_metric(int value, const char* message) noexcept
|
||||
{
|
||||
if (value < 0) {
|
||||
@@ -107,4 +116,46 @@ struct HistoryUiPlan {
|
||||
return pp::foundation::Result<HistoryUiPlan>::success(plan);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Status execute_history_ui_plan(
|
||||
const HistoryUiPlan& plan,
|
||||
HistoryUiServices& services)
|
||||
{
|
||||
const auto undo_status = validate_history_metric(plan.undo_count, "undo action count must not be negative");
|
||||
if (!undo_status.ok()) {
|
||||
return undo_status;
|
||||
}
|
||||
const auto redo_status = validate_history_metric(plan.redo_count, "redo action count must not be negative");
|
||||
if (!redo_status.ok()) {
|
||||
return redo_status;
|
||||
}
|
||||
const auto memory_status = validate_history_metric(plan.memory_bytes, "history memory bytes must not be negative");
|
||||
if (!memory_status.ok()) {
|
||||
return memory_status;
|
||||
}
|
||||
|
||||
if (plan.no_op) {
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
switch (plan.operation) {
|
||||
case HistoryUiOperation::undo:
|
||||
if (plan.invokes_undo) {
|
||||
services.invoke_undo();
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
case HistoryUiOperation::redo:
|
||||
if (plan.invokes_redo) {
|
||||
services.invoke_redo();
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
case HistoryUiOperation::clear:
|
||||
if (plan.clears_history) {
|
||||
services.clear_history();
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
return pp::foundation::Status::invalid_argument("unknown history operation");
|
||||
}
|
||||
|
||||
} // namespace pp::app
|
||||
|
||||
@@ -41,6 +41,7 @@ struct MainToolbarPlan {
|
||||
bool records_undo = false;
|
||||
bool marks_unsaved = false;
|
||||
bool no_op = false;
|
||||
HistoryUiPlan history;
|
||||
DocumentCanvasClearPlan canvas_clear;
|
||||
};
|
||||
|
||||
@@ -50,9 +51,9 @@ public:
|
||||
|
||||
virtual void show_open_dialog() = 0;
|
||||
virtual void show_save_dialog() = 0;
|
||||
virtual void invoke_undo() = 0;
|
||||
virtual void invoke_redo() = 0;
|
||||
virtual void clear_history() = 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;
|
||||
@@ -92,6 +93,7 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -108,6 +110,7 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -123,6 +126,7 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -171,13 +175,13 @@ public:
|
||||
services.show_save_dialog();
|
||||
return pp::foundation::Status::success();
|
||||
case MainToolbarAction::invoke_undo:
|
||||
services.invoke_undo();
|
||||
services.invoke_undo(plan.history);
|
||||
return pp::foundation::Status::success();
|
||||
case MainToolbarAction::invoke_redo:
|
||||
services.invoke_redo();
|
||||
services.invoke_redo(plan.history);
|
||||
return pp::foundation::Status::success();
|
||||
case MainToolbarAction::clear_history:
|
||||
services.clear_history();
|
||||
services.clear_history(plan.history);
|
||||
return pp::foundation::Status::success();
|
||||
case MainToolbarAction::clear_canvas:
|
||||
services.clear_canvas(plan.canvas_clear);
|
||||
|
||||
@@ -317,19 +317,19 @@ public:
|
||||
app_.dialog_save();
|
||||
}
|
||||
|
||||
void invoke_undo() override
|
||||
void invoke_undo(const pp::app::HistoryUiPlan& plan) override
|
||||
{
|
||||
ActionManager::undo();
|
||||
execute_history_plan(plan);
|
||||
}
|
||||
|
||||
void invoke_redo() override
|
||||
void invoke_redo(const pp::app::HistoryUiPlan& plan) override
|
||||
{
|
||||
ActionManager::redo();
|
||||
execute_history_plan(plan);
|
||||
}
|
||||
|
||||
void clear_history() override
|
||||
void clear_history(const pp::app::HistoryUiPlan& plan) override
|
||||
{
|
||||
ActionManager::clear();
|
||||
execute_history_plan(plan);
|
||||
}
|
||||
|
||||
void clear_canvas(const pp::app::DocumentCanvasClearPlan& plan) override
|
||||
@@ -376,6 +376,32 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
class LegacyHistoryUiServices final : public pp::app::HistoryUiServices {
|
||||
public:
|
||||
void invoke_undo() override
|
||||
{
|
||||
ActionManager::undo();
|
||||
}
|
||||
|
||||
void invoke_redo() override
|
||||
{
|
||||
ActionManager::redo();
|
||||
}
|
||||
|
||||
void clear_history() override
|
||||
{
|
||||
ActionManager::clear();
|
||||
}
|
||||
};
|
||||
|
||||
void execute_history_plan(const pp::app::HistoryUiPlan& plan)
|
||||
{
|
||||
LegacyHistoryUiServices services;
|
||||
const auto status = pp::app::execute_history_ui_plan(plan, services);
|
||||
if (!status.ok())
|
||||
LOG("History action failed: %s", status.message);
|
||||
}
|
||||
|
||||
App& app_;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user