Extract layer operation planning

This commit is contained in:
2026-06-03 10:20:37 +02:00
parent 07ed23c2d1
commit fdc1defaba
7 changed files with 752 additions and 38 deletions

View File

@@ -7,6 +7,7 @@
#include "node_dialog_picker.h"
#include "node_panel_floating.h"
#include "app_core/app_preferences.h"
#include "app_core/document_layer.h"
#include "app_core/app_status.h"
#include "settings.h"
#include "serializer.h"
@@ -182,17 +183,30 @@ void App::init_sidebar()
};
layers->on_layer_add = [this](Node*, std::shared_ptr<class Layer> layer, int index) {
Canvas::I->layer_add(layers->m_layers.back()->m_label_text.c_str(), layer, index);
Canvas::I->m_unsaved = true;
const auto plan = pp::app::plan_document_layer_add(
static_cast<int>(Canvas::I->m_layers.size()),
index,
layers->m_layers.back()->m_label_text);
if (!plan)
return;
Canvas::I->layer_add(plan.value().name, layer, plan.value().insert_index);
Canvas::I->m_unsaved = plan.value().marks_unsaved;
Canvas::I->anim_update();
animation->load_layers();
title_update();
if (plan.value().reloads_animation_layers)
animation->load_layers();
if (plan.value().updates_title)
title_update();
};
layers->on_layer_duplicate = [this](Node*, int source_index) {
Canvas::I->layer_add(layers->m_layers.back()->m_label_text.c_str(), nullptr, source_index + 1);
auto& dst = Canvas::I->m_layers[source_index + 1];
auto& src = Canvas::I->m_layers[source_index];
const auto plan = pp::app::plan_document_layer_duplicate(
static_cast<int>(Canvas::I->m_layers.size()),
source_index);
if (!plan)
return;
Canvas::I->layer_add(layers->m_layers.back()->m_label_text.c_str(), nullptr, plan.value().insert_index);
auto& dst = Canvas::I->m_layers[plan.value().insert_index];
auto& src = Canvas::I->m_layers[plan.value().source_index];
for (int i = 1; i < src->frames_count(); i++)
dst->add_frame();
Canvas::I->anim_update();
@@ -217,57 +231,115 @@ void App::init_sidebar()
dst->m_opacity = src->m_opacity;
dst->m_blend_mode = src->m_blend_mode;
dst->m_alpha_locked = src->m_alpha_locked;
Canvas::I->m_unsaved = true;
animation->load_layers();
title_update();
Canvas::I->m_unsaved = plan.value().marks_unsaved;
if (plan.value().reloads_animation_layers)
animation->load_layers();
if (plan.value().updates_title)
title_update();
};
layers->on_layer_change = [this](Node*, int old_idx, int new_idx) {
canvas->m_canvas->m_current_layer_idx = new_idx;
animation->load_layers();
const auto plan = pp::app::plan_document_layer_select(
static_cast<int>(canvas->m_canvas->m_layers.size()),
new_idx);
if (!plan)
return;
canvas->m_canvas->m_current_layer_idx = plan.value().index;
if (plan.value().reloads_animation_layers)
animation->load_layers();
};
layers->on_layer_order = [this](Node*, int old_idx, int new_idx) {
canvas->m_canvas->layer_order(old_idx, new_idx);
canvas->m_canvas->m_unsaved = true;
animation->load_layers();
title_update();
const auto plan = pp::app::plan_document_layer_reorder(
static_cast<int>(canvas->m_canvas->m_layers.size()),
old_idx,
new_idx);
if (!plan || !plan.value().mutates_document)
return;
canvas->m_canvas->layer_order(plan.value().from_index, plan.value().to_index);
canvas->m_canvas->m_unsaved = plan.value().marks_unsaved;
if (plan.value().reloads_animation_layers)
animation->load_layers();
if (plan.value().updates_title)
title_update();
};
layers->on_layer_delete = [this](Node*, int idx) {
canvas->m_canvas->layer_remove(idx);
canvas->m_canvas->m_unsaved = true;
animation->load_layers();
title_update();
const auto plan = pp::app::plan_document_layer_remove(
static_cast<int>(canvas->m_canvas->m_layers.size()),
idx);
if (!plan)
return;
canvas->m_canvas->layer_remove(plan.value().index);
canvas->m_canvas->m_unsaved = plan.value().marks_unsaved;
if (plan.value().reloads_animation_layers)
animation->load_layers();
if (plan.value().updates_title)
title_update();
};
layers->on_layer_opacity_changed = [this](Node*, int idx, float value) {
canvas->m_canvas->m_layers[idx]->m_opacity = value;
canvas->m_canvas->m_unsaved = true;
title_update();
const auto plan = pp::app::plan_document_layer_opacity(
static_cast<int>(canvas->m_canvas->m_layers.size()),
idx,
value);
if (!plan)
return;
canvas->m_canvas->m_layers[plan.value().index]->m_opacity = plan.value().opacity;
canvas->m_canvas->m_unsaved = plan.value().marks_unsaved;
if (plan.value().updates_title)
title_update();
};
layers->on_layer_visibility_changed = [this](Node*, int idx, bool visible) {
canvas->m_canvas->m_layers[idx]->m_visible = visible;
canvas->m_canvas->m_unsaved = true;
animation->load_layers();
title_update();
const auto plan = pp::app::plan_document_layer_visibility(
static_cast<int>(canvas->m_canvas->m_layers.size()),
idx,
visible);
if (!plan)
return;
canvas->m_canvas->m_layers[plan.value().index]->m_visible = plan.value().flag;
canvas->m_canvas->m_unsaved = plan.value().marks_unsaved;
if (plan.value().reloads_animation_layers)
animation->load_layers();
if (plan.value().updates_title)
title_update();
};
layers->on_layer_alpha_lock_changed = [this](Node*, int idx, bool locked) {
canvas->m_canvas->m_layers[idx]->m_alpha_locked = locked;
canvas->m_canvas->m_unsaved = true;
title_update();
const auto plan = pp::app::plan_document_layer_alpha_lock(
static_cast<int>(canvas->m_canvas->m_layers.size()),
idx,
locked);
if (!plan)
return;
canvas->m_canvas->m_layers[plan.value().index]->m_alpha_locked = plan.value().flag;
canvas->m_canvas->m_unsaved = plan.value().marks_unsaved;
if (plan.value().updates_title)
title_update();
};
layers->on_layer_blend_mode_changed = [this](Node*, int idx, int mode) {
canvas->m_canvas->m_layers[idx]->m_blend_mode = mode;
canvas->m_canvas->m_unsaved = true;
title_update();
const auto plan = pp::app::plan_document_layer_blend_mode(
static_cast<int>(canvas->m_canvas->m_layers.size()),
idx,
mode);
if (!plan)
return;
canvas->m_canvas->m_layers[plan.value().index]->m_blend_mode = plan.value().blend_mode;
canvas->m_canvas->m_unsaved = plan.value().marks_unsaved;
if (plan.value().updates_title)
title_update();
};
layers->on_layer_highlight_changed = [this](Node*, int idx, bool highlight) {
canvas->m_canvas->m_layers[idx]->m_hightlight = highlight;
const auto plan = pp::app::plan_document_layer_highlight(
static_cast<int>(canvas->m_canvas->m_layers.size()),
idx,
highlight);
if (!plan)
return;
canvas->m_canvas->m_layers[plan.value().index]->m_hightlight = plan.value().flag;
};
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-stroke"))
{