Skip to content

Commit 6512551

Browse files
committed
Animation Window improvements
1 parent da310a9 commit 6512551

1 file changed

Lines changed: 120 additions & 27 deletions

File tree

editor/window/AnimationWindow.cpp

Lines changed: 120 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "command/CommandHandle.h"
99
#include "command/type/PropertyCmd.h"
1010
#include "command/type/MultiPropertyCmd.h"
11+
#include "command/type/CreateEntityCmd.h"
1112

1213
#include "component/ActionComponent.h"
1314
#include "component/AnimationComponent.h"
@@ -20,6 +21,11 @@
2021
#include "component/TranslateTracksComponent.h"
2122
#include "component/SpriteAnimationComponent.h"
2223
#include "component/TimedActionComponent.h"
24+
#include "component/PositionActionComponent.h"
25+
#include "component/RotationActionComponent.h"
26+
#include "component/ScaleActionComponent.h"
27+
#include "component/ColorActionComponent.h"
28+
#include "component/AlphaActionComponent.h"
2329
#include "subsystem/ActionSystem.h"
2430
#include "subsystem/MeshSystem.h"
2531

@@ -112,6 +118,16 @@ std::string editor::AnimationWindow::getActionLabel(Entity actionEntity, Scene*
112118
}
113119

114120
if (sig.test(scene->getComponentId<TimedActionComponent>())) {
121+
if (sig.test(scene->getComponentId<PositionActionComponent>()))
122+
return "PositionAction";
123+
if (sig.test(scene->getComponentId<RotationActionComponent>()))
124+
return "RotationAction";
125+
if (sig.test(scene->getComponentId<ScaleActionComponent>()))
126+
return "ScaleAction";
127+
if (sig.test(scene->getComponentId<ColorActionComponent>()))
128+
return "ColorAction";
129+
if (sig.test(scene->getComponentId<AlphaActionComponent>()))
130+
return "AlphaAction";
115131
return "TimedAction";
116132
}
117133

@@ -379,36 +395,96 @@ void editor::AnimationWindow::drawToolbar(float width, AnimationComponent& anim,
379395
// Add Action
380396
ImGui::BeginDisabled(isPreviewing);
381397
if (ImGui::Button(ICON_FA_PLUS " Add Action")) {
382-
// If a frame is selected, add to the same track, otherwise track 0
383-
uint32_t targetTrack = 0;
384-
if (selectedFrameIndex >= 0 && selectedFrameIndex < (int)anim.actions.size()) {
385-
targetTrack = anim.actions[selectedFrameIndex].track;
398+
ImGui::OpenPopup("##add_action_popup");
399+
}
400+
if (ImGui::BeginPopup("##add_action_popup")) {
401+
EntityCreationType selectedType = EntityCreationType::EMPTY;
402+
std::string entityName;
403+
bool selected = false;
404+
405+
if (ImGui::MenuItem(ICON_FA_PLUS " Empty Action")) {
406+
selected = true;
407+
}
408+
ImGui::Separator();
409+
if (ImGui::MenuItem(ICON_FA_FILM " Animation")) {
410+
selectedType = EntityCreationType::ANIMATION;
411+
entityName = "Animation";
412+
selected = true;
413+
}
414+
if (ImGui::MenuItem(ICON_FA_PLAY " Sprite Animation")) {
415+
selectedType = EntityCreationType::SPRITE_ANIMATION;
416+
entityName = "SpriteAnimation";
417+
selected = true;
418+
}
419+
if (ImGui::MenuItem(ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT " Position Action")) {
420+
selectedType = EntityCreationType::POSITION_ACTION;
421+
entityName = "PositionAction";
422+
selected = true;
423+
}
424+
if (ImGui::MenuItem(ICON_FA_ROTATE " Rotation Action")) {
425+
selectedType = EntityCreationType::ROTATION_ACTION;
426+
entityName = "RotationAction";
427+
selected = true;
428+
}
429+
if (ImGui::MenuItem(ICON_FA_UP_RIGHT_AND_DOWN_LEFT_FROM_CENTER " Scale Action")) {
430+
selectedType = EntityCreationType::SCALE_ACTION;
431+
entityName = "ScaleAction";
432+
selected = true;
433+
}
434+
if (ImGui::MenuItem(ICON_FA_PALETTE " Color Action")) {
435+
selectedType = EntityCreationType::COLOR_ACTION;
436+
entityName = "ColorAction";
437+
selected = true;
438+
}
439+
if (ImGui::MenuItem(ICON_FA_EYE " Alpha Action")) {
440+
selectedType = EntityCreationType::ALPHA_ACTION;
441+
entityName = "AlphaAction";
442+
selected = true;
386443
}
387444

388-
ActionFrame newFrame = {0.0f, 1.0f, NULL_ENTITY, targetTrack};
389-
390-
// Find non-overlapping track
391-
bool overlap;
392-
do {
393-
overlap = false;
394-
for (const auto& a : anim.actions) {
395-
if (a.track == newFrame.track) {
396-
float startA = a.startTime;
397-
float endA = a.startTime + a.duration;
398-
float startB = newFrame.startTime;
399-
float endB = newFrame.startTime + newFrame.duration;
400-
// Strict less-than for overlap means adjoining frames (e.g. 0-1 and 1-2) are OK
401-
if (std::max(startA, startB) < std::min(endA, endB)) {
402-
overlap = true;
403-
newFrame.track++;
404-
break;
445+
if (selected) {
446+
// If a frame is selected, add to the same track, otherwise track 0
447+
uint32_t targetTrack = 0;
448+
if (selectedFrameIndex >= 0 && selectedFrameIndex < (int)anim.actions.size()) {
449+
targetTrack = anim.actions[selectedFrameIndex].track;
450+
}
451+
452+
Entity actionEntity = NULL_ENTITY;
453+
if (selectedType != EntityCreationType::EMPTY) {
454+
Entity target = scene->findComponent<ActionComponent>(selectedEntity)
455+
? scene->getComponent<ActionComponent>(selectedEntity).target
456+
: NULL_ENTITY;
457+
auto* cmd = new CreateEntityCmd(project, selectedSceneId, entityName, selectedType, target);
458+
CommandHandle::get(selectedSceneId)->addCommandNoMerge(cmd);
459+
actionEntity = cmd->getEntity();
460+
}
461+
462+
ActionFrame newFrame = {0.0f, 1.0f, actionEntity, targetTrack};
463+
464+
// Find non-overlapping track
465+
bool overlap;
466+
do {
467+
overlap = false;
468+
for (const auto& a : anim.actions) {
469+
if (a.track == newFrame.track) {
470+
float startA = a.startTime;
471+
float endA = a.startTime + a.duration;
472+
float startB = newFrame.startTime;
473+
float endB = newFrame.startTime + newFrame.duration;
474+
if (std::max(startA, startB) < std::min(endA, endB)) {
475+
overlap = true;
476+
newFrame.track++;
477+
break;
478+
}
405479
}
406480
}
407-
}
408-
} while (overlap);
481+
} while (overlap);
482+
483+
anim.actions.push_back(newFrame);
484+
selectedFrameIndex = anim.actions.size() - 1;
485+
}
409486

410-
anim.actions.push_back(newFrame);
411-
selectedFrameIndex = anim.actions.size() - 1;
487+
ImGui::EndPopup();
412488
}
413489
ImGui::EndDisabled();
414490
ImGui::SameLine();
@@ -602,8 +678,19 @@ bool editor::AnimationWindow::drawTracks(ImVec2 canvasPos, ImVec2 canvasSize, fl
602678
return IM_COL32(80, 190, 190, 200); // Teal: MorphTracks
603679
if (sig.test(scene->getComponentId<KeyframeTracksComponent>()))
604680
return IM_COL32(70, 130, 180, 200); // Steel blue: KeyframeTracks
605-
if (sig.test(scene->getComponentId<TimedActionComponent>()))
606-
return IM_COL32(180, 100, 70, 200); // Warm red: TimedAction
681+
if (sig.test(scene->getComponentId<TimedActionComponent>())) {
682+
if (sig.test(scene->getComponentId<PositionActionComponent>()))
683+
return IM_COL32(100, 180, 220, 200); // Light blue: PositionAction
684+
if (sig.test(scene->getComponentId<RotationActionComponent>()))
685+
return IM_COL32(220, 160, 70, 200); // Amber: RotationAction
686+
if (sig.test(scene->getComponentId<ScaleActionComponent>()))
687+
return IM_COL32(180, 100, 200, 200); // Violet: ScaleAction
688+
if (sig.test(scene->getComponentId<ColorActionComponent>()))
689+
return IM_COL32(220, 120, 160, 200); // Pink: ColorAction
690+
if (sig.test(scene->getComponentId<AlphaActionComponent>()))
691+
return IM_COL32(160, 200, 120, 200); // Lime: AlphaAction
692+
return IM_COL32(180, 100, 70, 200); // Warm red: generic TimedAction
693+
}
607694
if (sig.test(scene->getComponentId<AnimationComponent>()))
608695
return IM_COL32(180, 170, 70, 200); // Gold: Animation
609696

@@ -745,6 +832,12 @@ bool editor::AnimationWindow::drawTracks(ImVec2 canvasPos, ImVec2 canvasSize, fl
745832
}
746833
}
747834
}
835+
836+
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && hovered) {
837+
if (frame.action != NULL_ENTITY && scene->isEntityCreated(frame.action)) {
838+
project->setSelectedEntity(selectedSceneId, frame.action);
839+
}
840+
}
748841
}
749842
}
750843

0 commit comments

Comments
 (0)