Route layer panel view through app core

This commit is contained in:
2026-06-05 00:50:37 +02:00
parent bd6cdc20c5
commit 75fd7faeb0
8 changed files with 368 additions and 7 deletions

View File

@@ -1172,6 +1172,24 @@ if(TARGET pano_cli)
LABELS "app;document;integration;desktop-fast;fuzz"
WILL_FAIL TRUE)
add_test(NAME pano_cli_plan_layer_panel_view_smoke
COMMAND pano_cli plan-layer-panel-view --layer-count 3 --current-index 1 --hidden-index 2 --locked-index 1 --current-opacity 0.25 --current-blend-mode 4)
set_tests_properties(pano_cli_plan_layer_panel_view_smoke PROPERTIES
LABELS "app;document;ui;integration;desktop-fast"
PASS_REGULAR_EXPRESSION "\"command\":\"plan-layer-panel-view\".*\"layers\":3.*\"currentIndex\":1.*\"currentName\":\"Layer 1\".*\"currentOpacity\":0.25.*\"currentAlphaLocked\":true.*\"currentBlendMode\":4.*\"visibleLayers\":2.*\"lockedLayers\":1")
add_test(NAME pano_cli_plan_layer_panel_view_rejects_bad_opacity
COMMAND pano_cli plan-layer-panel-view --layer-count 2 --current-index 1 --current-opacity 1.5)
set_tests_properties(pano_cli_plan_layer_panel_view_rejects_bad_opacity PROPERTIES
LABELS "app;document;ui;integration;desktop-fast;fuzz"
WILL_FAIL TRUE)
add_test(NAME pano_cli_plan_layer_panel_view_rejects_bad_current
COMMAND pano_cli plan-layer-panel-view --layer-count 2 --current-index 2)
set_tests_properties(pano_cli_plan_layer_panel_view_rejects_bad_current PROPERTIES
LABELS "app;document;ui;integration;desktop-fast;fuzz"
WILL_FAIL TRUE)
add_test(NAME pano_cli_plan_layer_merge_smoke
COMMAND pano_cli plan-layer-merge --layer-count 3 --from-index 2 --to-index 1)
set_tests_properties(pano_cli_plan_layer_merge_smoke PROPERTIES

View File

@@ -3,6 +3,7 @@
#include <cmath>
#include <string>
#include <vector>
namespace {
@@ -383,6 +384,96 @@ void layer_highlight_is_transient(pp::tests::Harness& harness)
PP_EXPECT(harness, !pp::app::plan_document_layer_highlight(2, 2, true));
}
void layer_panel_view_projects_current_controls_and_visibility(pp::tests::Harness& harness)
{
const std::vector<pp::app::DocumentLayerPanelInput> layers {
pp::app::DocumentLayerPanelInput {
.layer_index = 0,
.name = "Base",
.opacity = 1.0F,
.visible = true,
.alpha_locked = false,
.blend_mode = 0,
},
pp::app::DocumentLayerPanelInput {
.layer_index = 1,
.name = "Ink",
.opacity = 0.25F,
.visible = false,
.alpha_locked = true,
.blend_mode = 4,
},
};
const auto view = pp::app::plan_document_layer_panel_view(layers, 1);
PP_EXPECT(harness, view);
if (view) {
PP_EXPECT(harness, view.value().current_index == 1);
PP_EXPECT(harness, view.value().current_opacity == 0.25F);
PP_EXPECT(harness, view.value().current_alpha_locked);
PP_EXPECT(harness, view.value().current_blend_mode == 4);
PP_EXPECT(harness, view.value().layers.size() == 2);
PP_EXPECT(harness, !view.value().layers[0].current);
PP_EXPECT(harness, view.value().layers[1].current);
PP_EXPECT(harness, view.value().layers[0].name == "Base");
PP_EXPECT(harness, view.value().layers[1].name == "Ink");
PP_EXPECT(harness, view.value().layers[0].visible);
PP_EXPECT(harness, !view.value().layers[1].visible);
PP_EXPECT(harness, view.value().layers[1].alpha_locked);
}
}
void layer_panel_view_rejects_invalid_document_state(pp::tests::Harness& harness)
{
const std::vector<pp::app::DocumentLayerPanelInput> valid_layers {
pp::app::DocumentLayerPanelInput {
.layer_index = 0,
.name = "Base",
.opacity = 1.0F,
.visible = true,
.alpha_locked = false,
.blend_mode = 0,
},
};
const std::vector<pp::app::DocumentLayerPanelInput> bad_index {
pp::app::DocumentLayerPanelInput {
.layer_index = 2,
.name = "Base",
.opacity = 1.0F,
.visible = true,
.alpha_locked = false,
.blend_mode = 0,
},
};
const std::vector<pp::app::DocumentLayerPanelInput> bad_opacity {
pp::app::DocumentLayerPanelInput {
.layer_index = 0,
.name = "Base",
.opacity = std::nanf(""),
.visible = true,
.alpha_locked = false,
.blend_mode = 0,
},
};
const std::vector<pp::app::DocumentLayerPanelInput> bad_blend {
pp::app::DocumentLayerPanelInput {
.layer_index = 0,
.name = "Base",
.opacity = 1.0F,
.visible = true,
.alpha_locked = false,
.blend_mode = pp::app::document_layer_legacy_blend_mode_count,
},
};
PP_EXPECT(harness, !pp::app::plan_document_layer_panel_view({}, 0));
PP_EXPECT(harness, !pp::app::plan_document_layer_panel_view(valid_layers, -1));
PP_EXPECT(harness, !pp::app::plan_document_layer_panel_view(valid_layers, 1));
PP_EXPECT(harness, !pp::app::plan_document_layer_panel_view(bad_index, 0));
PP_EXPECT(harness, !pp::app::plan_document_layer_panel_view(bad_opacity, 0));
PP_EXPECT(harness, !pp::app::plan_document_layer_panel_view(bad_blend, 0));
}
void layer_operation_executor_dispatches_document_mutations(pp::tests::Harness& harness)
{
FakeDocumentLayerOperationServices services;
@@ -814,6 +905,8 @@ int main()
harness.run("layer remove keeps at least one layer", layer_remove_keeps_at_least_one_layer);
harness.run("layer metadata plans validate values", layer_metadata_plans_validate_values);
harness.run("layer highlight is transient", layer_highlight_is_transient);
harness.run("layer panel view projects current controls and visibility", layer_panel_view_projects_current_controls_and_visibility);
harness.run("layer panel view rejects invalid document state", layer_panel_view_rejects_invalid_document_state);
harness.run("layer operation executor dispatches document mutations", layer_operation_executor_dispatches_document_mutations);
harness.run("layer operation executor dispatches selection and metadata", layer_operation_executor_dispatches_selection_and_metadata);
harness.run("layer operation executor preserves no op and transient actions", layer_operation_executor_preserves_no_op_and_transient_actions);