Add brush preset list executor bridge
This commit is contained in:
@@ -201,6 +201,23 @@ public:
|
||||
virtual void save_texture_list() = 0;
|
||||
};
|
||||
|
||||
class BrushPresetListServices {
|
||||
public:
|
||||
virtual ~BrushPresetListServices() = default;
|
||||
|
||||
virtual pp::foundation::Status add_current_brush_preset(int target_index) = 0;
|
||||
virtual void remove_brush_preset(
|
||||
int current_index,
|
||||
int target_index,
|
||||
bool selects_target,
|
||||
bool clears_selection) = 0;
|
||||
virtual void move_brush_preset(int from_index, int to_index) = 0;
|
||||
virtual void select_brush_preset(int index, bool notify_brush_changed) = 0;
|
||||
virtual void clear_brush_presets(bool clears_selection) = 0;
|
||||
virtual void update_preset_empty_notification() = 0;
|
||||
virtual void save_preset_list() = 0;
|
||||
};
|
||||
|
||||
class BrushStrokeControlServices {
|
||||
public:
|
||||
virtual ~BrushStrokeControlServices() = default;
|
||||
@@ -763,4 +780,83 @@ public:
|
||||
return pp::foundation::Status::invalid_argument("unknown brush texture list operation");
|
||||
}
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Status execute_brush_preset_list_plan(
|
||||
const BrushPresetListPlan& plan,
|
||||
BrushPresetListServices& services)
|
||||
{
|
||||
switch (plan.operation) {
|
||||
case BrushPresetListOperation::add_current_brush:
|
||||
{
|
||||
if (plan.item_count < 0 || plan.target_index != plan.item_count) {
|
||||
return pp::foundation::Status::out_of_range("brush preset add plan has invalid target");
|
||||
}
|
||||
|
||||
const auto add_status = services.add_current_brush_preset(plan.target_index);
|
||||
if (!add_status.ok()) {
|
||||
return add_status;
|
||||
}
|
||||
if (plan.updates_empty_notification) {
|
||||
services.update_preset_empty_notification();
|
||||
}
|
||||
if (plan.saves_list) {
|
||||
services.save_preset_list();
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
case BrushPresetListOperation::remove_preset:
|
||||
if (plan.item_count <= 0 || plan.current_index < 0 || plan.current_index >= plan.item_count) {
|
||||
return pp::foundation::Status::out_of_range("brush preset remove plan has invalid selection");
|
||||
}
|
||||
if (plan.selects_target && (plan.target_index < 0 || plan.target_index >= plan.item_count - 1)) {
|
||||
return pp::foundation::Status::out_of_range("brush preset remove plan has invalid target");
|
||||
}
|
||||
services.remove_brush_preset(
|
||||
plan.current_index,
|
||||
plan.target_index,
|
||||
plan.selects_target,
|
||||
plan.clears_selection);
|
||||
if (plan.updates_empty_notification) {
|
||||
services.update_preset_empty_notification();
|
||||
}
|
||||
if (plan.saves_list) {
|
||||
services.save_preset_list();
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
|
||||
case BrushPresetListOperation::move_preset:
|
||||
if (plan.item_count <= 0 || plan.current_index < 0 || plan.current_index >= plan.item_count
|
||||
|| plan.target_index < 0 || plan.target_index >= plan.item_count) {
|
||||
return pp::foundation::Status::out_of_range("brush preset move plan has invalid indices");
|
||||
}
|
||||
services.move_brush_preset(plan.current_index, plan.target_index);
|
||||
if (plan.saves_list) {
|
||||
services.save_preset_list();
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
|
||||
case BrushPresetListOperation::select_preset:
|
||||
if (plan.item_count <= 0 || plan.target_index < 0 || plan.target_index >= plan.item_count) {
|
||||
return pp::foundation::Status::out_of_range("brush preset select plan has invalid target");
|
||||
}
|
||||
services.select_brush_preset(plan.target_index, plan.notifies_brush_changed);
|
||||
return pp::foundation::Status::success();
|
||||
|
||||
case BrushPresetListOperation::clear_presets:
|
||||
if (plan.item_count < 0) {
|
||||
return pp::foundation::Status::out_of_range("brush preset clear plan has invalid item count");
|
||||
}
|
||||
services.clear_brush_presets(plan.clears_selection);
|
||||
if (plan.updates_empty_notification) {
|
||||
services.update_preset_empty_notification();
|
||||
}
|
||||
if (plan.saves_list) {
|
||||
services.save_preset_list();
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
return pp::foundation::Status::invalid_argument("unknown brush preset list operation");
|
||||
}
|
||||
|
||||
} // namespace pp::app
|
||||
|
||||
@@ -407,70 +407,111 @@ Node* NodePanelBrushPreset::clone_instantiate() const
|
||||
return new NodePanelBrushPreset();
|
||||
}
|
||||
|
||||
void NodePanelBrushPreset::execute_preset_list_plan(const pp::app::BrushPresetListPlan& plan)
|
||||
{
|
||||
switch (plan.operation)
|
||||
namespace pp::panopainter {
|
||||
|
||||
class LegacyBrushPresetListServices final : public pp::app::BrushPresetListServices {
|
||||
public:
|
||||
explicit LegacyBrushPresetListServices(NodePanelBrushPreset& owner)
|
||||
: owner_(owner)
|
||||
{
|
||||
case pp::app::BrushPresetListOperation::add_current_brush:
|
||||
if (!Canvas::I || !Canvas::I->m_current_brush)
|
||||
return;
|
||||
for (auto p : s_panels)
|
||||
p->add_brush(std::make_shared<Brush>(*Canvas::I->m_current_brush));
|
||||
break;
|
||||
}
|
||||
|
||||
case pp::app::BrushPresetListOperation::move_preset:
|
||||
for (auto p : s_panels)
|
||||
{
|
||||
if (plan.current_index >= 0 && plan.current_index < static_cast<int>(p->m_container->m_children.size()))
|
||||
p->m_container->move_child(p->m_container->m_children[plan.current_index].get(), plan.target_index);
|
||||
pp::foundation::Status add_current_brush_preset(int target_index) override
|
||||
{
|
||||
if (target_index < 0) {
|
||||
return pp::foundation::Status::out_of_range("brush preset add target is invalid");
|
||||
}
|
||||
if (!Canvas::I || !Canvas::I->m_current_brush) {
|
||||
return pp::foundation::Status::invalid_argument("current brush must be available to add a preset");
|
||||
}
|
||||
break;
|
||||
|
||||
case pp::app::BrushPresetListOperation::remove_preset:
|
||||
for (auto p : s_panels)
|
||||
{
|
||||
if (plan.current_index < 0 || plan.current_index >= static_cast<int>(p->m_container->m_children.size()))
|
||||
for (auto p : NodePanelBrushPreset::s_panels) {
|
||||
p->add_brush(std::make_shared<Brush>(*Canvas::I->m_current_brush));
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
void remove_brush_preset(
|
||||
int current_index,
|
||||
int target_index,
|
||||
bool selects_target,
|
||||
bool clears_selection) override
|
||||
{
|
||||
for (auto p : NodePanelBrushPreset::s_panels) {
|
||||
if (current_index < 0 || current_index >= static_cast<int>(p->m_container->m_children.size())) {
|
||||
continue;
|
||||
bool new_current = !p->m_current || p->m_container->get_child_index(p->m_current) == plan.current_index;
|
||||
p->m_container->m_children[plan.current_index]->destroy();
|
||||
if (plan.clears_selection)
|
||||
{
|
||||
p->m_current = nullptr;
|
||||
}
|
||||
else if (new_current && plan.selects_target)
|
||||
{
|
||||
p->m_current = static_cast<NodeBrushPresetItem*>(p->m_container->m_children[plan.target_index].get());
|
||||
|
||||
const bool new_current = !p->m_current || p->m_container->get_child_index(p->m_current) == current_index;
|
||||
p->m_container->m_children[current_index]->destroy();
|
||||
if (clears_selection) {
|
||||
p->m_current = nullptr;
|
||||
} else if (new_current && selects_target) {
|
||||
p->m_current = static_cast<NodeBrushPresetItem*>(p->m_container->m_children[target_index].get());
|
||||
p->m_current->m_selected = true;
|
||||
}
|
||||
p->m_notification->SetVisibility(p->m_container->m_children.size() == 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case pp::app::BrushPresetListOperation::select_preset:
|
||||
for (auto p : s_panels)
|
||||
{
|
||||
if (p->m_current)
|
||||
void move_brush_preset(int from_index, int to_index) override
|
||||
{
|
||||
for (auto p : NodePanelBrushPreset::s_panels) {
|
||||
if (from_index >= 0 && from_index < static_cast<int>(p->m_container->m_children.size())) {
|
||||
p->m_container->move_child(p->m_container->m_children[from_index].get(), to_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void select_brush_preset(int index, bool notify_brush_changed) override
|
||||
{
|
||||
for (auto p : NodePanelBrushPreset::s_panels) {
|
||||
if (p->m_current) {
|
||||
p->m_current->m_selected = false;
|
||||
p->m_current = static_cast<NodeBrushPresetItem*>(p->m_container->get_child_at(plan.target_index));
|
||||
}
|
||||
p->m_current = static_cast<NodeBrushPresetItem*>(p->m_container->get_child_at(index));
|
||||
p->m_current->m_selected = true;
|
||||
p->m_interacted = true;
|
||||
}
|
||||
if (plan.notifies_brush_changed && on_brush_changed)
|
||||
on_brush_changed(this, m_current->m_brush);
|
||||
break;
|
||||
|
||||
case pp::app::BrushPresetListOperation::clear_presets:
|
||||
for (auto p : s_panels)
|
||||
{
|
||||
p->m_container->remove_all_children();
|
||||
p->m_current = nullptr;
|
||||
p->m_notification->SetVisibility(p->m_container->m_children.size() == 0);
|
||||
if (notify_brush_changed && owner_.on_brush_changed) {
|
||||
owner_.on_brush_changed(&owner_, owner_.m_current->m_brush);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (plan.saves_list)
|
||||
save();
|
||||
void clear_brush_presets(bool clears_selection) override
|
||||
{
|
||||
for (auto p : NodePanelBrushPreset::s_panels) {
|
||||
p->m_container->remove_all_children();
|
||||
if (clears_selection) {
|
||||
p->m_current = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_preset_empty_notification() override
|
||||
{
|
||||
for (auto p : NodePanelBrushPreset::s_panels) {
|
||||
p->m_notification->SetVisibility(p->m_container->m_children.size() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void save_preset_list() override
|
||||
{
|
||||
owner_.save();
|
||||
}
|
||||
|
||||
private:
|
||||
NodePanelBrushPreset& owner_;
|
||||
};
|
||||
|
||||
} // namespace pp::panopainter
|
||||
|
||||
void NodePanelBrushPreset::execute_preset_list_plan(const pp::app::BrushPresetListPlan& plan)
|
||||
{
|
||||
pp::panopainter::LegacyBrushPresetListServices services(*this);
|
||||
const auto status = pp::app::execute_brush_preset_list_plan(plan, services);
|
||||
if (!status.ok()) {
|
||||
LOG("Brush preset list action failed: %s", status.message);
|
||||
}
|
||||
}
|
||||
|
||||
void NodePanelBrushPreset::init()
|
||||
|
||||
@@ -15,6 +15,7 @@ struct BrushPresetListPlan;
|
||||
}
|
||||
namespace pp::panopainter {
|
||||
class LegacyBrushTextureListServices;
|
||||
class LegacyBrushPresetListServices;
|
||||
}
|
||||
|
||||
class NodeButtonBrush : public NodeButtonCustom, public Serializer::Type
|
||||
@@ -88,6 +89,8 @@ public:
|
||||
|
||||
class NodePanelBrushPreset : public Node
|
||||
{
|
||||
friend class pp::panopainter::LegacyBrushPresetListServices;
|
||||
|
||||
static std::vector<NodePanelBrushPreset*> s_panels;
|
||||
bool m_interacted = false;
|
||||
NodeBrushPresetItem* m_current = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user