Route layer panel view through app core
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace pp::app {
|
||||
|
||||
@@ -84,6 +85,33 @@ struct DocumentLayerMergePlan {
|
||||
bool create_history = true;
|
||||
};
|
||||
|
||||
struct DocumentLayerPanelInput {
|
||||
int layer_index = 0;
|
||||
std::string name;
|
||||
float opacity = 1.0F;
|
||||
bool visible = true;
|
||||
bool alpha_locked = false;
|
||||
int blend_mode = 0;
|
||||
};
|
||||
|
||||
struct DocumentLayerPanelLayerView {
|
||||
int layer_index = 0;
|
||||
std::string name;
|
||||
float opacity = 1.0F;
|
||||
bool visible = true;
|
||||
bool alpha_locked = false;
|
||||
int blend_mode = 0;
|
||||
bool current = false;
|
||||
};
|
||||
|
||||
struct DocumentLayerPanelView {
|
||||
int current_index = 0;
|
||||
float current_opacity = 1.0F;
|
||||
bool current_alpha_locked = false;
|
||||
int current_blend_mode = 0;
|
||||
std::vector<DocumentLayerPanelLayerView> layers;
|
||||
};
|
||||
|
||||
class DocumentLayerMenuServices {
|
||||
public:
|
||||
virtual ~DocumentLayerMenuServices() = default;
|
||||
@@ -158,6 +186,60 @@ public:
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Result<DocumentLayerPanelView> plan_document_layer_panel_view(
|
||||
const std::vector<DocumentLayerPanelInput>& layers,
|
||||
int current_index)
|
||||
{
|
||||
if (layers.empty()) {
|
||||
return pp::foundation::Result<DocumentLayerPanelView>::failure(
|
||||
pp::foundation::Status::invalid_argument("layer panel requires at least one layer"));
|
||||
}
|
||||
|
||||
const auto current_status = validate_layer_index(static_cast<int>(layers.size()), current_index);
|
||||
if (!current_status.ok()) {
|
||||
return pp::foundation::Result<DocumentLayerPanelView>::failure(current_status);
|
||||
}
|
||||
|
||||
DocumentLayerPanelView view;
|
||||
view.current_index = current_index;
|
||||
view.layers.reserve(layers.size());
|
||||
|
||||
for (const auto& input : layers) {
|
||||
const auto index_status = validate_layer_index(static_cast<int>(layers.size()), input.layer_index);
|
||||
if (!index_status.ok()) {
|
||||
return pp::foundation::Result<DocumentLayerPanelView>::failure(index_status);
|
||||
}
|
||||
|
||||
if (!std::isfinite(input.opacity) || input.opacity < 0.0F || input.opacity > 1.0F) {
|
||||
return pp::foundation::Result<DocumentLayerPanelView>::failure(
|
||||
pp::foundation::Status::out_of_range("layer opacity must be finite and within 0..1"));
|
||||
}
|
||||
|
||||
if (input.blend_mode < 0 || input.blend_mode >= document_layer_legacy_blend_mode_count) {
|
||||
return pp::foundation::Result<DocumentLayerPanelView>::failure(
|
||||
pp::foundation::Status::out_of_range("layer blend mode is outside the supported range"));
|
||||
}
|
||||
|
||||
const bool current = input.layer_index == current_index;
|
||||
DocumentLayerPanelLayerView layer;
|
||||
layer.layer_index = input.layer_index;
|
||||
layer.name = input.name;
|
||||
layer.opacity = input.opacity;
|
||||
layer.visible = input.visible;
|
||||
layer.alpha_locked = input.alpha_locked;
|
||||
layer.blend_mode = input.blend_mode;
|
||||
layer.current = current;
|
||||
if (current) {
|
||||
view.current_opacity = input.opacity;
|
||||
view.current_alpha_locked = input.alpha_locked;
|
||||
view.current_blend_mode = input.blend_mode;
|
||||
}
|
||||
view.layers.push_back(std::move(layer));
|
||||
}
|
||||
|
||||
return pp::foundation::Result<DocumentLayerPanelView>::success(std::move(view));
|
||||
}
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Result<DocumentLayerRenamePlan> plan_document_layer_rename(
|
||||
std::string_view old_name,
|
||||
std::string_view requested_name)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "pch.h"
|
||||
#include "app_core/document_layer.h"
|
||||
#include "log.h"
|
||||
#include "node_panel_layer.h"
|
||||
#include "canvas.h"
|
||||
@@ -367,13 +368,38 @@ void NodePanelLayer::clear()
|
||||
|
||||
void NodePanelLayer::update_attributes()
|
||||
{
|
||||
auto& l = Canvas::I->m_layers[Canvas::I->m_current_layer_idx];
|
||||
m_opacity->set_value(l->m_opacity);
|
||||
m_alpha_lock->set_value(l->m_alpha_locked);
|
||||
m_blend_mode->set_index(l->m_blend_mode);
|
||||
for (int i = 0; i < Canvas::I->m_layers.size(); i++)
|
||||
if (!Canvas::I)
|
||||
return;
|
||||
|
||||
std::vector<pp::app::DocumentLayerPanelInput> layer_inputs;
|
||||
layer_inputs.reserve(Canvas::I->m_layers.size());
|
||||
for (int i = 0; i < static_cast<int>(Canvas::I->m_layers.size()); i++)
|
||||
{
|
||||
m_layers[i]->m_visibility->set_value(Canvas::I->m_layers[i]->m_visible);
|
||||
const auto& layer = Canvas::I->m_layers[i];
|
||||
layer_inputs.push_back(pp::app::DocumentLayerPanelInput {
|
||||
.layer_index = i,
|
||||
.name = layer->m_name,
|
||||
.opacity = layer->m_opacity,
|
||||
.visible = layer->m_visible,
|
||||
.alpha_locked = layer->m_alpha_locked,
|
||||
.blend_mode = layer->m_blend_mode,
|
||||
});
|
||||
}
|
||||
|
||||
const auto view = pp::app::plan_document_layer_panel_view(layer_inputs, Canvas::I->m_current_layer_idx);
|
||||
if (!view)
|
||||
{
|
||||
LOG("Layer panel view failed: %s", view.status().message);
|
||||
return;
|
||||
}
|
||||
|
||||
m_opacity->set_value(view.value().current_opacity);
|
||||
m_alpha_lock->set_value(view.value().current_alpha_locked);
|
||||
m_blend_mode->set_index(view.value().current_blend_mode);
|
||||
for (const auto& layer : view.value().layers)
|
||||
{
|
||||
if (layer.layer_index >= 0 && layer.layer_index < static_cast<int>(m_layers.size()))
|
||||
m_layers[layer.layer_index]->m_visibility->set_value(layer.visible);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user