Extract layer menu action planning
This commit is contained in:
@@ -32,6 +32,21 @@ enum class DocumentLayerOperation {
|
||||
set_highlight,
|
||||
};
|
||||
|
||||
enum class DocumentLayerMenuCommand {
|
||||
clear,
|
||||
rename,
|
||||
merge_down,
|
||||
};
|
||||
|
||||
enum class DocumentLayerMenuAction {
|
||||
clear_current_layer,
|
||||
show_rename_dialog,
|
||||
merge_with_lower_layer,
|
||||
show_merge_animated_not_supported,
|
||||
no_op_select_layer,
|
||||
no_op_select_upper_layer,
|
||||
};
|
||||
|
||||
struct DocumentLayerRenamePlan {
|
||||
std::string old_name;
|
||||
std::string new_name;
|
||||
@@ -55,6 +70,14 @@ struct DocumentLayerOperationPlan {
|
||||
bool updates_title = false;
|
||||
};
|
||||
|
||||
struct DocumentLayerMenuPlan {
|
||||
DocumentLayerMenuCommand command = DocumentLayerMenuCommand::clear;
|
||||
DocumentLayerMenuAction action = DocumentLayerMenuAction::clear_current_layer;
|
||||
std::string label;
|
||||
int from_index = 0;
|
||||
int to_index = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Status validate_layer_index(
|
||||
int layer_count,
|
||||
int index) noexcept
|
||||
@@ -328,4 +351,63 @@ struct DocumentLayerOperationPlan {
|
||||
return pp::foundation::Result<DocumentLayerOperationPlan>::success(plan);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Result<DocumentLayerMenuPlan> plan_document_layer_menu(
|
||||
DocumentLayerMenuCommand command,
|
||||
bool has_current_layer,
|
||||
int current_index,
|
||||
int animation_duration,
|
||||
std::string_view current_layer_name,
|
||||
std::string_view lower_layer_name)
|
||||
{
|
||||
if (current_index < 0) {
|
||||
return pp::foundation::Result<DocumentLayerMenuPlan>::failure(
|
||||
pp::foundation::Status::out_of_range("current layer index must not be negative"));
|
||||
}
|
||||
if (animation_duration < 0) {
|
||||
return pp::foundation::Result<DocumentLayerMenuPlan>::failure(
|
||||
pp::foundation::Status::out_of_range("animation duration must not be negative"));
|
||||
}
|
||||
|
||||
DocumentLayerMenuPlan plan;
|
||||
plan.command = command;
|
||||
plan.from_index = current_index;
|
||||
plan.to_index = current_index > 0 ? current_index - 1 : 0;
|
||||
|
||||
switch (command) {
|
||||
case DocumentLayerMenuCommand::clear:
|
||||
plan.action = has_current_layer
|
||||
? DocumentLayerMenuAction::clear_current_layer
|
||||
: DocumentLayerMenuAction::no_op_select_layer;
|
||||
plan.label = has_current_layer
|
||||
? "Clear Layer " + std::string(current_layer_name)
|
||||
: "Clear Layer (Select a layer)";
|
||||
break;
|
||||
case DocumentLayerMenuCommand::rename:
|
||||
plan.action = has_current_layer
|
||||
? DocumentLayerMenuAction::show_rename_dialog
|
||||
: DocumentLayerMenuAction::no_op_select_layer;
|
||||
plan.label = has_current_layer
|
||||
? "Rename Layer " + std::string(current_layer_name)
|
||||
: "Rename Layer (Select a layer)";
|
||||
break;
|
||||
case DocumentLayerMenuCommand::merge_down:
|
||||
if (!has_current_layer) {
|
||||
plan.action = DocumentLayerMenuAction::no_op_select_layer;
|
||||
plan.label = "Merge Layer (Select a layer)";
|
||||
} else if (animation_duration > 1) {
|
||||
plan.action = DocumentLayerMenuAction::show_merge_animated_not_supported;
|
||||
plan.label = "Merge Layer (Animation not supported)";
|
||||
} else if (current_index <= 0) {
|
||||
plan.action = DocumentLayerMenuAction::no_op_select_upper_layer;
|
||||
plan.label = "Merge Layer (Select upper layers)";
|
||||
} else {
|
||||
plan.action = DocumentLayerMenuAction::merge_with_lower_layer;
|
||||
plan.label = "Merge with " + std::string(lower_layer_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return pp::foundation::Result<DocumentLayerMenuPlan>::success(std::move(plan));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -190,6 +190,39 @@ void apply_file_menu_plan(App& app, pp::app::FileMenuCommand command)
|
||||
}
|
||||
}
|
||||
|
||||
pp::app::DocumentLayerMenuPlan make_layer_menu_plan(
|
||||
pp::app::DocumentLayerMenuCommand command,
|
||||
App& app)
|
||||
{
|
||||
const bool has_current_layer = app.layers && app.layers->m_current_layer;
|
||||
const int current_index = app.canvas && app.canvas->m_canvas
|
||||
? app.canvas->m_canvas->m_current_layer_idx
|
||||
: 0;
|
||||
const int animation_duration = Canvas::I
|
||||
? Canvas::I->anim_duration()
|
||||
: 0;
|
||||
const std::string current_name = has_current_layer
|
||||
? app.layers->m_current_layer->m_label_text
|
||||
: std::string {};
|
||||
std::string lower_name;
|
||||
if (app.canvas && app.canvas->m_canvas && current_index > 0
|
||||
&& current_index - 1 < static_cast<int>(app.canvas->m_canvas->m_layers.size()))
|
||||
{
|
||||
lower_name = app.canvas->m_canvas->m_layers[current_index - 1]->m_name;
|
||||
}
|
||||
|
||||
const auto plan = pp::app::plan_document_layer_menu(
|
||||
command,
|
||||
has_current_layer,
|
||||
current_index,
|
||||
animation_duration,
|
||||
current_name,
|
||||
lower_name);
|
||||
if (plan)
|
||||
return plan.value();
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void App::title_update()
|
||||
@@ -1513,67 +1546,52 @@ void App::init_menu_layer()
|
||||
layout[main_id]->add_child(popup);
|
||||
|
||||
popup->find<NodeButtonCustom>("layer-clear")->on_click = [this, popup](Node*) {
|
||||
canvas->m_canvas->clear();
|
||||
const auto plan = make_layer_menu_plan(pp::app::DocumentLayerMenuCommand::clear, *this);
|
||||
if (plan.action == pp::app::DocumentLayerMenuAction::clear_current_layer)
|
||||
canvas->m_canvas->clear();
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
if (layers->m_current_layer)
|
||||
{
|
||||
const auto plan = make_layer_menu_plan(pp::app::DocumentLayerMenuCommand::clear, *this);
|
||||
popup->find<NodeButtonCustom>("layer-clear")->
|
||||
find<NodeText>("menu-label")->
|
||||
set_text(("Clear Layer " + layers->m_current_layer->m_label_text).c_str());
|
||||
set_text(plan.label.c_str());
|
||||
}
|
||||
|
||||
popup->find<NodeButtonCustom>("layer-rename")->on_click = [this, popup](Node*) {
|
||||
dialog_layer_rename();
|
||||
const auto plan = make_layer_menu_plan(pp::app::DocumentLayerMenuCommand::rename, *this);
|
||||
if (plan.action == pp::app::DocumentLayerMenuAction::show_rename_dialog)
|
||||
dialog_layer_rename();
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
if (layers->m_current_layer)
|
||||
{
|
||||
const auto plan = make_layer_menu_plan(pp::app::DocumentLayerMenuCommand::rename, *this);
|
||||
popup->find<NodeButtonCustom>("layer-rename")->
|
||||
find<NodeText>("menu-label")->
|
||||
set_text(("Rename Layer " + layers->m_current_layer->m_label_text).c_str());
|
||||
else
|
||||
popup->find<NodeButtonCustom>("layer-rename")->
|
||||
find<NodeText>("menu-label")->
|
||||
set_text("Rename Layer (Select a layer)");
|
||||
set_text(plan.label.c_str());
|
||||
}
|
||||
|
||||
popup->find<NodeButtonCustom>("layer-merge")->on_click = [this, popup](Node*) {
|
||||
//layers->get_child_index(layers->)
|
||||
if (Canvas::I->anim_duration() > 1)
|
||||
const auto plan = make_layer_menu_plan(pp::app::DocumentLayerMenuCommand::merge_down, *this);
|
||||
if (plan.action == pp::app::DocumentLayerMenuAction::show_merge_animated_not_supported)
|
||||
{
|
||||
message_box("Not supported", "Merging animated layers is not supported yet.");
|
||||
}
|
||||
else
|
||||
else if (plan.action == pp::app::DocumentLayerMenuAction::merge_with_lower_layer)
|
||||
{
|
||||
int current_idx_order = Canvas::I->m_current_layer_idx;
|
||||
if (current_idx_order > 0)
|
||||
{
|
||||
layers->merge(current_idx_order, current_idx_order - 1, true);
|
||||
}
|
||||
layers->merge(plan.from_index, plan.to_index, true);
|
||||
}
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
if (layers->m_current_layer)
|
||||
{
|
||||
int current_idx_order = canvas->m_canvas->m_current_layer_idx;
|
||||
if (current_idx_order > 0)
|
||||
{
|
||||
int down_layer_idx = current_idx_order - 1;
|
||||
popup->find<NodeButtonCustom>("layer-merge")->
|
||||
find<NodeText>("menu-label")->
|
||||
set_text(("Merge with " + canvas->m_canvas->m_layers[down_layer_idx]->m_name).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
popup->find<NodeButtonCustom>("layer-merge")->
|
||||
find<NodeText>("menu-label")->
|
||||
set_text("Merge Layer (Select upper layers)");
|
||||
}
|
||||
}
|
||||
else
|
||||
const auto plan = make_layer_menu_plan(pp::app::DocumentLayerMenuCommand::merge_down, *this);
|
||||
popup->find<NodeButtonCustom>("layer-merge")->
|
||||
find<NodeText>("menu-label")->
|
||||
set_text("Merge Layer (Select a layer)");
|
||||
find<NodeText>("menu-label")->
|
||||
set_text(plan.label.c_str());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user