Files
panopainter/engine/node_panel_layer.cpp

227 lines
6.5 KiB
C++

#include "pch.h"
#include "log.h"
#include "node_panel_layer.h"
Node* NodeLayer::clone_instantiate() const
{
return new NodeLayer();
}
void NodeLayer::clone_children(Node* dest) const
{
NodeBorder::clone_children(dest);
NodeLayer* n = static_cast<NodeLayer*>(dest);
n->m_label = n->find<NodeText>("label");
n->m_visibility = n->find<NodeCheckBox>("cb");
}
void NodeLayer::clone_copy(Node* dest) const
{
NodeBorder::clone_copy(dest);
NodeLayer* n = (NodeLayer*)dest;
n->m_selected = m_selected;
n->m_label_text = m_label_text;
}
void NodeLayer::init()
{
const auto& m_template = (NodeBorder*)init_template("tpl-layer");
m_color = m_template->m_color;
m_border_color = m_template->m_border_color;
m_thinkness = m_template->m_thinkness;
m_label = find<NodeText>("label");
m_visibility = find<NodeCheckBox>("cb");
m_opacity = find<NodeSliderH>("sl-opacity");
}
void NodeLayer::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
{
NodeBorder::parse_attributes(ka, attr);
switch (ka)
{
case kAttribute::Text:
m_label_text = attr->Value();
break;
case kAttribute::Selected:
m_selected = attr->BoolValue();
default:
break;
}
}
void NodeLayer::loaded()
{
NodeBorder::loaded();
if (!m_label_text.empty())
m_label->set_text(m_label_text.c_str());
m_opacity->on_value_changed = [this](Node*, float value) {
if (on_opacity_changed)
on_opacity_changed(this, value);
};
m_visibility->on_value_changed = [this](Node*, bool checked) {
if (on_visibility_changed)
on_visibility_changed(this, checked);
};
}
kEventResult NodeLayer::handle_event(Event* e)
{
NodeBorder::handle_event(e);
switch (e->m_type)
{
case kEventType::MouseEnter:
break;
case kEventType::MouseLeave:
break;
case kEventType::MouseDownL:
m_selected = true;
if (on_selected)
on_selected(this);
break;
case kEventType::MouseUpL:
break;
default:
return kEventResult::Available;
break;
}
return kEventResult::Consumed;
}
void NodeLayer::draw()
{
auto c = m_selected ? m_color_selected : m_color_normal;
m_thinkness = m_selected ? 1.f : 0.f;
m_color = m_mouse_inside ? m_color_hover : c;
NodeBorder::draw();
}
void NodeLayer::set_name(const char* s)
{
m_label_text = s;
m_label->set_text(s);
}
Node* NodePanelLayer::clone_instantiate() const
{
return new NodePanelLayer();
}
void NodePanelLayer::init()
{
LOG("NodePanelLayer::init");
init_template("tpl-panel-layers");
LOG("template initted");
m_layers_container = find<NodeBorder>("layers-container");
LOG("template container found");
// for (int i = 0; i < 1; i++)
// {
// LOG("add layer");
// add_layer();
// }
LOG("find components");
// m_current_layer = m_layers[0];
// m_layers[0]->m_selected = true;
btn_add = find<NodeButtonCustom>("btn-add");
btn_remove = find<NodeButtonCustom>("btn-remove");
btn_up = find<NodeButtonCustom>("btn-up");
btn_down = find<NodeButtonCustom>("btn-down");
LOG("attach events");
btn_add->on_click = [this](Node*) {
add_layer();
if (on_layer_add)
on_layer_add(this);
};
btn_remove->on_click = [this](Node*) {
if (m_layers.size() == 1)
return; // dont' delete the last layer
remove_layer(m_current_layer);
};
btn_up->on_click = [this](Node*) {
int old_idx = m_layers_container->get_child_index(m_current_layer);
m_layers_container->move_child_offset(m_current_layer, -1);
int new_idx = m_layers_container->get_child_index(m_current_layer);
if (on_layer_order && old_idx != new_idx)
{
on_layer_order(this, old_idx, new_idx);
}
};
btn_down->on_click = [this](Node*) {
int old_idx = m_layers_container->get_child_index(m_current_layer);
m_layers_container->move_child_offset(m_current_layer, +1);
int new_idx = m_layers_container->get_child_index(m_current_layer);
if (on_layer_order && old_idx != new_idx)
{
on_layer_order(this, old_idx, new_idx);
}
};
LOG("done init");
}
void NodePanelLayer::add_layer(const char* name)
{
NodeLayer* l = new NodeLayer;
m_layers_container->add_child(l);
l->init();
l->create();
l->loaded();
l->set_name(name);
l->on_selected = std::bind(&NodePanelLayer::handle_layer_selected, this, std::placeholders::_1);
l->on_opacity_changed = std::bind(&NodePanelLayer::handle_layer_opacity, this, std::placeholders::_1, std::placeholders::_2);
l->on_visibility_changed = std::bind(&NodePanelLayer::handle_layer_visibility, this, std::placeholders::_1, std::placeholders::_2);
m_layers.push_back(l);
}
void NodePanelLayer::add_layer()
{
static char s[64];
sprintf(s, "Layer-%d", id_counter++);
add_layer(s);
}
NodeLayer* NodePanelLayer::get_layer_at(int index)
{
return static_cast<NodeLayer*>(m_layers_container->get_child_at(index));
}
void NodePanelLayer::remove_layer(NodeLayer* layer)
{
auto it = std::find(m_layers.begin(), m_layers.end(), m_current_layer);
auto i = m_layers_container->get_child_index(m_current_layer);
m_layers_container->remove_child(m_current_layer);
m_layers.erase(it);
i = std::min<int>(i, (int)m_layers.size() - 1);
m_current_layer = m_layers[i];
m_current_layer->m_selected = true;
if (on_layer_delete)
on_layer_delete(this, (int)std::distance(m_layers.begin(), it));
if (on_layer_change)
on_layer_change(this, -1, i);
}
void NodePanelLayer::handle_layer_opacity(NodeLayer* target, float value)
{
if (on_layer_opacity_changed)
on_layer_opacity_changed(this, m_layers_container->get_child_index(target), value);
}
void NodePanelLayer::handle_layer_visibility(NodeLayer* target, bool visible)
{
if (on_layer_visibility_changed)
on_layer_visibility_changed(this, m_layers_container->get_child_index(target), visible);
}
void NodePanelLayer::handle_layer_selected(NodeLayer* target)
{
if (m_current_layer)
m_current_layer->m_selected = false;
m_current_layer = target;
m_current_layer->m_selected = true;
if (on_layer_change)
on_layer_change(this, -1, m_layers_container->get_child_index(m_current_layer));
}
void NodePanelLayer::clear()
{
m_layers_container->remove_all_children();
m_layers.clear();
}