add history to layer create, delete, move, rename, and merge
This commit is contained in:
@@ -131,20 +131,22 @@ void NodePanelLayer::init()
|
||||
next = tmp;
|
||||
}
|
||||
int source_index = m_layers_container->get_child_index(m_current_layer);
|
||||
add_layer(next.c_str());
|
||||
auto l = add_layer(next.c_str(), false, false, nullptr, nullptr, source_index + 1);
|
||||
if (on_layer_duplicate)
|
||||
on_layer_duplicate(this, source_index);
|
||||
if (on_layer_change)
|
||||
on_layer_change(this, -1, m_layers_container->get_child_index(m_current_layer));
|
||||
update_attributes();
|
||||
|
||||
auto a = new ActionLayerAdd;
|
||||
a->m_panel = this;
|
||||
a->m_layer_node = l->shared_from_this();
|
||||
a->m_layer_order = m_layers_container->get_child_index(l);
|
||||
a->m_layer_id = Canvas::I->m_layers[a->m_layer_order]->id;
|
||||
ActionManager::add(a);
|
||||
};
|
||||
btn_add->on_click = [this](Node*) {
|
||||
add_layer();
|
||||
if (on_layer_add)
|
||||
on_layer_add(this, nullptr, 0);
|
||||
if (on_layer_change)
|
||||
on_layer_change(this, -1, m_layers_container->get_child_index(m_current_layer));
|
||||
update_attributes();
|
||||
add_layer(true, true);
|
||||
};
|
||||
btn_remove->on_click = [this](Node*) {
|
||||
if (m_layers.size() == 1)
|
||||
@@ -159,6 +161,11 @@ void NodePanelLayer::init()
|
||||
{
|
||||
on_layer_order(this, old_idx, new_idx);
|
||||
}
|
||||
auto a = new ActionLayerMove;
|
||||
a->m_panel = this;
|
||||
a->m_layer_node = m_current_layer->shared_from_this();
|
||||
a->m_offset = -1;
|
||||
ActionManager::add(a);
|
||||
};
|
||||
btn_down->on_click = [this](Node*) {
|
||||
int old_idx = m_layers_container->get_child_index(m_current_layer);
|
||||
@@ -168,6 +175,11 @@ void NodePanelLayer::init()
|
||||
{
|
||||
on_layer_order(this, old_idx, new_idx);
|
||||
}
|
||||
auto a = new ActionLayerMove;
|
||||
a->m_panel = this;
|
||||
a->m_layer_node = m_current_layer->shared_from_this();
|
||||
a->m_offset = +1;
|
||||
ActionManager::add(a);
|
||||
};
|
||||
m_opacity = find<NodeSliderH>("opacity");
|
||||
m_opacity->on_value_changed = [this](Node*, float value) {
|
||||
@@ -183,13 +195,13 @@ void NodePanelLayer::init()
|
||||
};
|
||||
}
|
||||
|
||||
NodeLayer* NodePanelLayer::add_layer(const char* name, bool add_history /*= true*/, std::unique_ptr<class Layer> layer /*= nullptr*/, int index /*= 0*/)
|
||||
NodeLayer* NodePanelLayer::add_layer(const char* name, bool add_history /*= true*/, bool create_events /*= false*/,
|
||||
std::shared_ptr<Layer> layer /*= nullptr*/, std::shared_ptr<NodeLayer> layer_node /*= nullptr*/, int index /*= 0*/)
|
||||
{
|
||||
NodeLayer* l = new NodeLayer;
|
||||
if (layer)
|
||||
m_layers_container->add_child(l, index);
|
||||
else
|
||||
m_layers_container->add_child(l);
|
||||
if (index == -1)
|
||||
index = m_layers_container->m_children.size();
|
||||
auto l = layer_node ? layer_node : std::make_shared<NodeLayer>();
|
||||
m_layers_container->add_child(l, index);
|
||||
l->init();
|
||||
l->create();
|
||||
l->loaded();
|
||||
@@ -200,36 +212,45 @@ NodeLayer* NodePanelLayer::add_layer(const char* name, bool add_history /*= true
|
||||
l->on_highlight = std::bind(&NodePanelLayer::handle_layer_highlight, this, std::placeholders::_1, std::placeholders::_2);
|
||||
if (m_current_layer)
|
||||
m_current_layer->m_selected = false;
|
||||
m_current_layer = l;
|
||||
m_current_layer = l.get();
|
||||
m_current_layer->m_selected = true;
|
||||
m_layers.push_back(l);
|
||||
m_layers.push_back(l.get());
|
||||
|
||||
if (add_history)
|
||||
{
|
||||
if (create_events)
|
||||
{
|
||||
if (on_layer_add)
|
||||
on_layer_add(this, nullptr, m_layers_container->get_child_index(m_current_layer));
|
||||
if (on_layer_change)
|
||||
on_layer_change(this, -1, m_layers_container->get_child_index(m_current_layer));
|
||||
update_attributes();
|
||||
}
|
||||
|
||||
auto a = new ActionLayerAdd;
|
||||
a->m_panel = this;
|
||||
a->m_layer_node = l->shared_from_this();
|
||||
a->m_layer_order = m_layers_container->get_child_index(l);
|
||||
a->m_layer_order = m_layers_container->get_child_index(l.get());
|
||||
a->m_layer_id = Canvas::I->m_layers[a->m_layer_order]->id;
|
||||
ActionManager::add(a);
|
||||
update_attributes();
|
||||
}
|
||||
else
|
||||
else if (create_events)
|
||||
{
|
||||
if (on_layer_add)
|
||||
on_layer_add(this, std::move(layer), index);
|
||||
on_layer_add(this, layer, index);
|
||||
if (on_layer_change)
|
||||
on_layer_change(this, -1, m_layers_container->get_child_index(m_current_layer));
|
||||
update_attributes();
|
||||
}
|
||||
|
||||
return l;
|
||||
return l.get();
|
||||
}
|
||||
|
||||
void NodePanelLayer::add_layer()
|
||||
void NodePanelLayer::add_layer(bool add_history /*= true*/, bool create_events /*= false*/)
|
||||
{
|
||||
static char s[64];
|
||||
sprintf(s, "Layer-%d", id_counter++);
|
||||
add_layer(s);
|
||||
add_layer(s, add_history, create_events);
|
||||
}
|
||||
|
||||
NodeLayer* NodePanelLayer::get_layer_at(int index)
|
||||
@@ -239,11 +260,12 @@ NodeLayer* NodePanelLayer::get_layer_at(int index)
|
||||
|
||||
void NodePanelLayer::remove_layer(NodeLayer* layer, bool add_history /*= true*/)
|
||||
{
|
||||
auto it = std::find(m_layers.begin(), m_layers.end(), m_current_layer);
|
||||
auto i = m_layers_container->get_child_index(m_current_layer);
|
||||
auto it = std::find(m_layers.begin(), m_layers.end(), layer);
|
||||
auto i = m_layers_container->get_child_index(layer);
|
||||
int old_idx = i;// (int)std::distance(m_layers.begin(), it);
|
||||
(*it)->m_selected = false;
|
||||
auto copy = (*it)->shared_from_this();
|
||||
m_layers_container->remove_child(m_current_layer);
|
||||
m_layers_container->remove_child(layer);
|
||||
m_layers.erase(it);
|
||||
i = std::min<int>(i, (int)m_layers.size() - 1);
|
||||
m_current_layer = (NodeLayer*)m_layers_container->get_child_at(i);
|
||||
@@ -254,7 +276,7 @@ void NodePanelLayer::remove_layer(NodeLayer* layer, bool add_history /*= true*/)
|
||||
auto a = new ActionLayerRemove;
|
||||
a->m_panel = this;
|
||||
a->m_layer_node = copy;
|
||||
a->m_layer = std::move(Canvas::I->m_layers[Canvas::I->m_order[old_idx]]);
|
||||
a->m_layer = Canvas::I->m_layers[old_idx];
|
||||
a->m_layer_order = old_idx;
|
||||
ActionManager::add(a);
|
||||
}
|
||||
@@ -342,6 +364,31 @@ kEventResult NodePanelLayer::handle_event(Event* e)
|
||||
return kEventResult::Available;
|
||||
}
|
||||
|
||||
void NodePanelLayer::merge(int src_index, int dst_index, bool create_history)
|
||||
{
|
||||
if (create_history)
|
||||
{
|
||||
auto a = new ActionLayerMerge;
|
||||
a->m_direction = ActionLayerMerge::Direction::Undo;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
a->m_dirty_box[i] = Canvas::I->m_layers[dst_index]->m_dirty_box[i];
|
||||
a->m_dirty_face[i] = Canvas::I->m_layers[dst_index]->m_dirty_face[i];
|
||||
}
|
||||
a->m_snap = Canvas::I->m_layers[dst_index]->snapshot(
|
||||
Canvas::I->m_layers[src_index]->m_dirty_box, Canvas::I->m_layers[src_index]->m_dirty_face);
|
||||
a->m_layer = Canvas::I->m_layers[src_index];
|
||||
a->m_layer_node = std::static_pointer_cast<NodeLayer>(m_layers_container->m_children[src_index]);
|
||||
a->m_layer_node->m_selected = false;
|
||||
a->m_panel = std::static_pointer_cast<NodePanelLayer>(shared_from_this());
|
||||
a->m_src_index = src_index;
|
||||
a->m_dst_index = dst_index;
|
||||
ActionManager::add(a);
|
||||
}
|
||||
Canvas::I->layer_merge(Canvas::I->m_current_layer_idx, dst_index);
|
||||
remove_layer((NodeLayer*)m_layers_container->m_children[src_index].get(), false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Action* ActionLayerAdd::get_redo()
|
||||
@@ -349,8 +396,10 @@ Action* ActionLayerAdd::get_redo()
|
||||
auto a = new ActionLayerRemove;
|
||||
a->m_panel = m_panel;
|
||||
a->m_layer_node = m_layer_node;
|
||||
a->m_layer = std::move(Canvas::I->m_layers[Canvas::I->m_order[m_layer_order]]);
|
||||
a->m_layer = *std::find_if(Canvas::I->m_layers.begin(), Canvas::I->m_layers.end(),
|
||||
[id=m_layer_id](const auto& x){ return x->id == id; });
|
||||
a->m_layer_order = m_layer_order;
|
||||
LOG("ActionLayerAdd::get_redo %s", a->m_layer->m_name.c_str());
|
||||
return a;
|
||||
}
|
||||
|
||||
@@ -372,13 +421,17 @@ Action* ActionLayerRemove::get_redo()
|
||||
a->m_panel = m_panel;
|
||||
a->m_layer_node = m_layer_node;
|
||||
a->m_layer_order = m_layer_order;
|
||||
a->m_layer_id = m_layer->id;
|
||||
LOG("ActionLayerRemove::get_redo %s", ((NodeLayer*)m_layer_node.get())->m_label_text.c_str());
|
||||
return a;
|
||||
}
|
||||
|
||||
void ActionLayerRemove::undo()
|
||||
{
|
||||
std::string name = m_layer->m_name;
|
||||
m_panel->add_layer(name.c_str(), false, std::move(m_layer), m_layer_order);
|
||||
m_panel->add_layer(name.c_str(), false, true, m_layer,
|
||||
std::dynamic_pointer_cast<NodeLayer>(m_layer_node), m_layer_order);
|
||||
LOG("ActionLayerRemove::undo %s", name.c_str());
|
||||
}
|
||||
|
||||
size_t ActionLayerRemove::memory()
|
||||
@@ -390,15 +443,61 @@ size_t ActionLayerRemove::memory()
|
||||
|
||||
Action* ActionLayerMove::get_redo()
|
||||
{
|
||||
return nullptr;
|
||||
auto a = new ActionLayerMove;
|
||||
a->m_panel = m_panel;
|
||||
a->m_layer_node = m_layer_node;
|
||||
a->m_offset = -m_offset;
|
||||
return a;
|
||||
}
|
||||
|
||||
void ActionLayerMove::undo()
|
||||
{
|
||||
|
||||
int old_idx = m_panel->m_layers_container->get_child_index(m_layer_node.get());
|
||||
m_panel->m_layers_container->move_child_offset(m_layer_node.get(), -m_offset);
|
||||
int new_idx = m_panel->m_layers_container->get_child_index(m_layer_node.get());
|
||||
if (m_panel->on_layer_order && old_idx != new_idx)
|
||||
{
|
||||
m_panel->on_layer_order(m_panel, old_idx, new_idx);
|
||||
}
|
||||
}
|
||||
|
||||
size_t ActionLayerMove::memory()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ActionLayerMerge::undo()
|
||||
{
|
||||
if (m_direction == Direction::Undo)
|
||||
{
|
||||
Canvas::I->m_layers[m_dst_index]->restore(m_snap);
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Canvas::I->m_layers[m_dst_index]->m_dirty_box[i] = m_dirty_box[i];
|
||||
Canvas::I->m_layers[m_dst_index]->m_dirty_face[i] = m_dirty_face[i];
|
||||
}
|
||||
auto name = m_layer->m_name;
|
||||
m_panel->add_layer(name.c_str(), false, true, m_layer, m_layer_node, m_src_index);
|
||||
}
|
||||
else if (m_direction == Direction::Redo)
|
||||
{
|
||||
m_panel->merge(m_src_index, m_dst_index, false);
|
||||
}
|
||||
}
|
||||
|
||||
Action* ActionLayerMerge::get_redo()
|
||||
{
|
||||
auto a = new ActionLayerMerge;
|
||||
a->m_dirty_box = m_dirty_box;
|
||||
a->m_dirty_face = m_dirty_face;
|
||||
a->m_dst_index = m_dst_index;
|
||||
a->m_src_index = m_src_index;
|
||||
a->m_layer = m_layer;
|
||||
a->m_layer_node = m_layer_node;
|
||||
a->m_panel = m_panel;
|
||||
a->m_snap = m_snap;
|
||||
a->m_direction = m_direction == Direction::Undo ? Direction::Redo : Direction::Undo;
|
||||
return a;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user