implement animation panel interaction
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
#include "pch.h"
|
||||
#include "node_panel_animation.h"
|
||||
#include "node_button.h"
|
||||
#include "node_button_custom.h"
|
||||
#include "canvas.h"
|
||||
|
||||
Node* NodePanelAnimation::clone_instantiate() const
|
||||
{
|
||||
@@ -22,4 +25,197 @@ void NodePanelAnimation::init()
|
||||
|
||||
void NodePanelAnimation::init_controls()
|
||||
{
|
||||
m_container = find<NodeScroll>("container");
|
||||
m_timeline = find<NodeAnimationTimeline>("timeline");
|
||||
btn_add = find<NodeButtonCustom>("btn-add");
|
||||
btn_remove = find<NodeButtonCustom>("btn-remove");
|
||||
btn_up = find<NodeButtonCustom>("btn-up");
|
||||
btn_down = find<NodeButtonCustom>("btn-down");
|
||||
btn_duplicate = find<NodeButtonCustom>("btn-duplicate");
|
||||
|
||||
btn_add->on_click = [this](Node*) {
|
||||
Canvas::I->layer().add_frame();
|
||||
load_layers();
|
||||
};
|
||||
btn_up->on_click = [this](Node*) {
|
||||
auto& layers = Canvas::I->m_layers;
|
||||
auto layer = std::find_if(layers.begin(), layers.end(),
|
||||
[id = m_selected_frame_layer_id](const auto& l) { return l->id == id; });
|
||||
if (layer != layers.end())
|
||||
(*layer)->m_frames[m_selected_frame_index].m_duration++;
|
||||
};
|
||||
btn_up->on_click = [this](Node*) {
|
||||
if (auto layer = Canvas::I->layer_with_id(m_selected_frame_layer_id))
|
||||
layer->m_frames[m_selected_frame_index].m_duration++;
|
||||
load_layers();
|
||||
};
|
||||
btn_down->on_click = [this](Node*) {
|
||||
if (auto layer = Canvas::I->layer_with_id(m_selected_frame_layer_id))
|
||||
layer->m_frames[m_selected_frame_index].m_duration--;
|
||||
load_layers();
|
||||
};
|
||||
|
||||
m_timeline->on_frame_changed = [this] (NodeAnimationTimeline* target, int frame) {
|
||||
LOG("goto frame %d", frame);
|
||||
Canvas::I->anim_goto_frame(frame);
|
||||
load_layers();
|
||||
};
|
||||
}
|
||||
|
||||
void NodePanelAnimation::load_layers()
|
||||
{
|
||||
if (!added_to_root())
|
||||
return;
|
||||
m_container->remove_all_children();
|
||||
auto& layers = Canvas::I->m_layers;
|
||||
m_selected_frame = nullptr;
|
||||
for (int i = 0; i < layers.size(); i++)
|
||||
{
|
||||
auto l = m_container->add_child<NodeAnimationLayer>();
|
||||
l->set_text(layers[i]->m_name);
|
||||
l->set_selected(Canvas::I->m_current_layer_idx == i);
|
||||
l->set_chekcbox(layers[i]->m_visible);
|
||||
for (int fi = 0; fi < layers[i]->m_frames.size(); fi++)
|
||||
{
|
||||
auto b = l->add_frame(layers[i]->m_frames[fi].m_duration);
|
||||
if (m_selected_frame_layer_id == layers[i]->id && m_selected_frame_index == fi)
|
||||
{
|
||||
b->set_active(true);
|
||||
m_selected_frame = b.get();
|
||||
}
|
||||
b->on_click = [this, fi, lid=layers[i]->id] (Node* target) {
|
||||
auto frame = static_cast<NodeAnimationFrame*>(target);
|
||||
frame->set_active(true);
|
||||
if (m_selected_frame)
|
||||
m_selected_frame->set_active(false);
|
||||
m_selected_frame = frame;
|
||||
m_selected_frame_layer_id = lid;
|
||||
m_selected_frame_index = fi;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodePanelAnimation::added(Node* parent)
|
||||
{
|
||||
parent::added(parent);
|
||||
load_layers();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Node* NodeAnimationLayer::clone_instantiate() const
|
||||
{
|
||||
return new this_class;
|
||||
}
|
||||
|
||||
void NodeAnimationLayer::clone_finalize(Node* dest) const
|
||||
{
|
||||
parent::clone_finalize(dest);
|
||||
auto n = static_cast<this_class*>(dest);
|
||||
n->init_controls();
|
||||
}
|
||||
|
||||
void NodeAnimationLayer::init()
|
||||
{
|
||||
parent::init();
|
||||
init_template_file("data/dialogs/panel-animation.xml", "tpl-layer");
|
||||
init_controls();
|
||||
}
|
||||
|
||||
void NodeAnimationLayer::init_controls()
|
||||
{
|
||||
m_label = find<NodeText>("label");
|
||||
m_visibility = find<NodeCheckBox>("cb");
|
||||
m_container = find<NodeScroll>("container");
|
||||
}
|
||||
|
||||
void NodeAnimationLayer::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;
|
||||
parent::draw();
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeAnimationFrame> NodeAnimationLayer::add_frame(int duration)
|
||||
{
|
||||
auto b = m_container->add_child_ref<NodeAnimationFrame>();
|
||||
b->SetWidth(30 * duration + 5 * (duration - 1));
|
||||
//b->SetFlexGrow(duration);
|
||||
b->SetHeightP(100);
|
||||
b->SetMargin(0, 5, 0, 0);
|
||||
return b;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void NodeAnimationTimeline::draw()
|
||||
{
|
||||
parent::draw();
|
||||
ShaderManager::use(kShader::Color);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, m_cursor_color);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
float step = 35.f;
|
||||
glm::vec2 cur_pos = {
|
||||
m_pos.x + step * m_frame + step * 0.5f,
|
||||
m_pos.y + m_size.y * 0.5f
|
||||
};
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, m_proj
|
||||
* glm::translate(glm::vec3(cur_pos, 0))
|
||||
* glm::scale(glm::vec3(step * 0.25f, m_size.y * 0.5f, 1))
|
||||
);
|
||||
m_plane.draw_fill();
|
||||
|
||||
//bool scissor = glIsEnabled(GL_SCISSOR_TEST);
|
||||
//glDisable(GL_SCISSOR_TEST);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, m_proj
|
||||
* glm::translate(glm::vec3(cur_pos, 0))
|
||||
* glm::scale(glm::vec3(step * 0.15f, m_size.y * 0.5f, 1))
|
||||
* glm::translate(glm::vec3(0, .5, 0))
|
||||
);
|
||||
m_plane.draw_fill();
|
||||
//scissor ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
kEventResult NodeAnimationTimeline::handle_event(Event* e)
|
||||
{
|
||||
parent::handle_event(e);
|
||||
static int signaled_frame = -1;
|
||||
auto me = static_cast<MouseEvent*>(e);
|
||||
auto ge = static_cast<GestureEvent*>(e);
|
||||
auto update = [&](){
|
||||
auto loc = me->m_pos - m_pos;
|
||||
m_frame = glm::clamp((int)glm::floor(loc.x / 35.f), 0, Canvas::I->anim_duration() - 1);
|
||||
if (on_frame_changed && signaled_frame != m_frame)
|
||||
on_frame_changed(this, m_frame);
|
||||
signaled_frame = m_frame;
|
||||
};
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
mouse_capture();
|
||||
m_dragging = true;
|
||||
m_drag_start_frame = m_frame;
|
||||
update();
|
||||
break;
|
||||
case kEventType::MouseMove:
|
||||
if (m_dragging)
|
||||
update();
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
m_dragging = false;
|
||||
mouse_release();
|
||||
break;
|
||||
case kEventType::MouseCancel:
|
||||
m_dragging = false;
|
||||
m_frame = m_drag_start_frame;
|
||||
mouse_release();
|
||||
break;
|
||||
default:
|
||||
return kEventResult::Available;
|
||||
break;
|
||||
}
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user