Route animation panel view through app core

This commit is contained in:
2026-06-05 00:37:11 +02:00
parent a9e12f2219
commit bd6cdc20c5
8 changed files with 469 additions and 28 deletions

View File

@@ -36,8 +36,8 @@ void NodePanelAnimation::execute_animation_plan(const pp::app::DocumentAnimation
pp::app::DocumentAnimationPanelState NodePanelAnimation::animation_panel_state() const
{
return pp::app::DocumentAnimationPanelState {
.total_duration = Canvas::I->anim_duration(),
.current_frame = Canvas::I->m_anim_frame,
.total_duration = m_timeline ? m_timeline->m_frames_count : 0,
.current_frame = m_timeline ? m_timeline->m_frame : 0,
.playback_active = btn_play->is_active(),
};
}
@@ -195,50 +195,91 @@ void NodePanelAnimation::load_layers()
return;
m_layers_container->remove_all_children();
m_frames_container->remove_all_children();
if (!Canvas::I)
return;
auto& layers = Canvas::I->m_layers;
m_selected_frame = nullptr;
std::vector<pp::app::DocumentAnimationLayerInput> layer_inputs;
layer_inputs.reserve(layers.size());
for (int i = 0; i < layers.size(); i++)
{
auto l = m_layers_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);
auto film = m_frames_container->add_child_ref<NodeAnimationFilm>();
pp::app::DocumentAnimationLayerInput input;
input.layer_index = i;
input.layer_id = layers[i]->id;
input.name = layers[i]->m_name;
input.visible = layers[i]->m_visible;
input.frame_durations.reserve(layers[i]->frames_count());
for (int fi = 0; fi < layers[i]->frames_count(); fi++)
{
auto b = film->add_frame(layers[i]->frame_duration(fi));
input.frame_durations.push_back(layers[i]->frame_duration(fi));
layer_inputs.push_back(std::move(input));
}
if (m_selected_frame_layer_id == layers[i]->id && m_selected_frame_index == fi)
const auto view_result = pp::app::plan_animation_panel_view(
layer_inputs,
Canvas::I->anim_duration(),
Canvas::I->m_current_layer_idx,
Canvas::I->m_anim_frame,
m_selected_frame_layer_id,
m_selected_frame_index,
m_onion->get_int());
if (!view_result)
{
LOG("Animation panel view failed: %s", view_result.status().message);
return;
}
const auto& view = view_result.value();
for (const auto& layer_view : view.layers)
{
auto l = m_layers_container->add_child<NodeAnimationLayer>();
l->set_text(layer_view.name);
l->set_selected(layer_view.current);
l->set_chekcbox(layer_view.visible);
auto film = m_frames_container->add_child_ref<NodeAnimationFilm>();
const int frame_count = static_cast<int>(layer_view.frames.size());
for (const auto& frame_view : layer_view.frames)
{
auto b = film->add_frame(frame_view.duration);
if (frame_view.selected)
{
b->set_active(true);
m_selected_frame = b.get();
}
b->on_click = [this, fi, lid=layers[i]->id, i] (Node* target) {
b->on_click = [this,
frame_index = frame_view.frame_index,
frame_count,
layer_id = layer_view.layer_id,
layer_index = layer_view.layer_index] (Node* target) {
auto frame = static_cast<NodeAnimationFrame*>(target);
if (m_selected_frame)
m_selected_frame->set_active(false);
frame->set_active(true);
m_selected_frame = frame;
const auto plan = pp::app::plan_animation_select_frame(
Canvas::I->m_layers[i]->frames_count(),
i,
lid,
fi);
if (plan)
execute_animation_plan(plan.value(), Canvas::I->m_layers[i].get());
frame_count,
layer_index,
layer_id,
frame_index);
if (plan && Canvas::I && layer_index >= 0 && layer_index < static_cast<int>(Canvas::I->m_layers.size()))
execute_animation_plan(plan.value(), Canvas::I->m_layers[layer_index].get());
};
}
}
m_timeline->m_frame = Canvas::I->m_anim_frame;
m_timeline->m_onion_size = m_onion->get_int();
m_timeline->m_frame = view.current_frame;
m_timeline->m_frames_count = view.total_duration;
m_timeline->m_onion_size = view.onion_size;
update_frames();
}
void NodePanelAnimation::update_frames()
{
int total_frames = Canvas::I->anim_duration();
if (!m_timeline || !m_frame_label)
return;
int total_frames = m_timeline ? m_timeline->m_frames_count : 1;
int digits = (int)floor(glm::log(total_frames));
m_frame_label->set_text_format("%0*d/%d", digits, m_timeline->m_frame + 1, total_frames);
}
@@ -349,8 +390,7 @@ kEventResult NodeAnimationTimeline::handle_event(Event* e)
auto me = static_cast<MouseEvent*>(e);
auto update = [&](){
auto loc = me->m_pos - m_pos;
const int total_duration = Canvas::I ? Canvas::I->anim_duration() : 0;
const auto scrub = pp::app::plan_animation_timeline_scrub(total_duration, loc.x);
const auto scrub = pp::app::plan_animation_timeline_scrub(m_frames_count, loc.x);
if (!scrub)
return;
m_frame = scrub.value().target_frame;