summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/editor/animation_editor.cpp357
-rw-r--r--tools/editor/animation_editor.h9
2 files changed, 244 insertions, 122 deletions
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp
index 08b90b5408..0dcd088976 100644
--- a/tools/editor/animation_editor.cpp
+++ b/tools/editor/animation_editor.cpp
@@ -694,11 +694,103 @@ void AnimationKeyEditor::_menu_add_track(int p_type) {
}
}
+void AnimationKeyEditor::_anim_duplicate_keys(bool transpose) {
+ //duplicait!
+ if (selection.size() && animation.is_valid() && selected_track>=0 && selected_track<animation->get_track_count()) {
+
+ int top_track=0x7FFFFFFF;
+ float top_time = 1e10;
+ for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) {
+
+ const SelectedKey &sk = E->key();
+
+ float t = animation->track_get_key_time(sk.track,sk.key);
+ if (t<top_time)
+ top_time=t;
+ if (sk.track<top_track)
+ top_track=sk.track;
+
+ }
+ ERR_FAIL_COND( top_track == 0x7FFFFFFF || top_time==1e10 );
+
+ //
+
+ int start_track = transpose ? selected_track : top_track;
+
+ undo_redo->create_action(TTR("Anim Duplicate Keys"));
+
+ List<Pair<int,float> > new_selection_values;
+
+ for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) {
+
+ const SelectedKey &sk = E->key();
+
+ float t = animation->track_get_key_time(sk.track,sk.key);
+
+ float dst_time = t+(timeline_pos - top_time);
+ int dst_track = sk.track + (start_track - top_track);
+
+ if (dst_track < 0 || dst_track>= animation->get_track_count())
+ continue;
+
+ if (animation->track_get_type(dst_track) != animation->track_get_type(sk.track))
+ continue;
+
+ int existing_idx = animation->track_find_key(dst_track,dst_time,true);
+
+ undo_redo->add_do_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key));
+ undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",dst_track,dst_time);
+
+ Pair<int,float> p;
+ p.first=dst_track;
+ p.second=dst_time;
+ new_selection_values.push_back( p );
+
+ if (existing_idx!=-1) {
+
+ undo_redo->add_undo_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(dst_track,existing_idx),animation->track_get_key_transition(dst_track,existing_idx));
+
+ }
+
+ }
+
+ undo_redo->commit_action();
+
+ //reselect duplicated
+
+ Map<SelectedKey,KeyInfo> new_selection;
+ for (List<Pair<int,float> >::Element *E=new_selection_values.front();E;E=E->next()) {
+
+ int track=E->get().first;
+ float time = E->get().second;
+
+ int existing_idx = animation->track_find_key(track,time,true);
+
+ if (existing_idx==-1)
+ continue;
+ SelectedKey sk2;
+ sk2.track=track;
+ sk2.key=existing_idx;
+
+ KeyInfo ki;
+ ki.pos=time;
+
+ new_selection[sk2]=ki;
+
+ }
+
+
+ selection=new_selection;
+ track_editor->update();
+ _edit_if_single_selection();
+
+ }
+}
+
void AnimationKeyEditor::_menu_track(int p_type) {
ERR_FAIL_COND(!animation.is_valid());
-
last_menu_track_opt=p_type;
switch(p_type) {
@@ -766,108 +858,7 @@ void AnimationKeyEditor::_menu_track(int p_type) {
case TRACK_MENU_DUPLICATE:
case TRACK_MENU_DUPLICATE_TRANSPOSE: {
-
- //duplicait!
- if (selection.size() && animation.is_valid() && selected_track>=0 && selected_track<animation->get_track_count()) {
-
-
- int top_track=0x7FFFFFFF;
- float top_time = 1e10;
- for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) {
-
- const SelectedKey &sk = E->key();
-
- float t = animation->track_get_key_time(sk.track,sk.key);
- if (t<top_time)
- top_time=t;
- if (sk.track<top_track)
- top_track=sk.track;
-
-
- }
- ERR_FAIL_COND( top_track == 0x7FFFFFFF || top_time==1e10 );
-
- //
-
- int start_track = p_type==TRACK_MENU_DUPLICATE_TRANSPOSE ? selected_track : top_track;
-
-
- undo_redo->create_action(TTR("Anim Duplicate Keys"));
-
- List<Pair<int,float> > new_selection_values;
-
- for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) {
-
- const SelectedKey &sk = E->key();
-
- float t = animation->track_get_key_time(sk.track,sk.key);
-
- float dst_time = t+(timeline_pos - top_time);
- int dst_track = sk.track + (start_track - top_track);
-
- if (dst_track < 0 || dst_track>= animation->get_track_count())
- continue;
-
- if (animation->track_get_type(dst_track) != animation->track_get_type(sk.track))
- continue;
-
- int existing_idx = animation->track_find_key(dst_track,dst_time,true);
-
- undo_redo->add_do_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key));
- undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",dst_track,dst_time);
-
- Pair<int,float> p;
- p.first=dst_track;
- p.second=dst_time;
- new_selection_values.push_back( p );
-
- if (existing_idx!=-1) {
-
- undo_redo->add_undo_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(dst_track,existing_idx),animation->track_get_key_transition(dst_track,existing_idx));
-
- }
-
-
-
- }
-
- undo_redo->commit_action();
-
- //reselect duplicated
-
- Map<SelectedKey,KeyInfo> new_selection;
- for (List<Pair<int,float> >::Element *E=new_selection_values.front();E;E=E->next()) {
-
-
- int track=E->get().first;
- float time = E->get().second;
-
- int existing_idx = animation->track_find_key(track,time,true);
-
- if (existing_idx==-1)
- continue;
- SelectedKey sk2;
- sk2.track=track;
- sk2.key=existing_idx;
-
- KeyInfo ki;
- ki.pos=time;
-
-
- new_selection[sk2]=ki;
-
-
- }
-
-
- selection=new_selection;
- track_editor->update();
- _edit_if_single_selection();
-
-
- }
-
-
+ _anim_duplicate_keys(p_type==TRACK_MENU_DUPLICATE_TRANSPOSE);
} break;
case TRACK_MENU_SET_ALL_TRANS_LINEAR:
case TRACK_MENU_SET_ALL_TRANS_CONSTANT:
@@ -1619,9 +1610,7 @@ void AnimationKeyEditor::_track_menu_selected(int p_idx) {
undo_redo->add_do_method(animation.ptr(),"track_set_interpolation_type",interp_editing,p_idx);
undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",interp_editing,animation->track_get_interpolation_type(interp_editing));
undo_redo->commit_action();
- }
-
- if (cont_editing!=-1) {
+ } else if (cont_editing!=-1) {
ERR_FAIL_INDEX(cont_editing,animation->get_track_count());
@@ -1629,6 +1618,16 @@ void AnimationKeyEditor::_track_menu_selected(int p_idx) {
undo_redo->add_do_method(animation.ptr(),"value_track_set_continuous",cont_editing,p_idx);
undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",cont_editing,animation->value_track_is_continuous(cont_editing));
undo_redo->commit_action();
+ } else {
+ switch (p_idx) {
+
+ case RIGHT_MENU_DUPLICATE:
+ _anim_duplicate_keys(); break;
+ case RIGHT_MENU_DUPLICATE_TRANSPOSE:
+ _anim_duplicate_keys(true); break;
+ case RIGHT_MENU_REMOVE:
+ _anim_delete_keys(); break;
+ }
}
}
@@ -1790,6 +1789,25 @@ bool AnimationKeyEditor::_edit_if_single_selection() {
}
+void AnimationKeyEditor::_anim_delete_keys() {
+ if (selection.size()) {
+ undo_redo->create_action(TTR("Anim Delete Keys"));
+
+ for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) {
+
+ undo_redo->add_do_method(animation.ptr(),"track_remove_key",E->key().track,E->key().key);
+ undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key));
+
+ }
+ undo_redo->add_do_method(this,"_clear_selection_for_anim",animation);
+ undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation);
+ undo_redo->commit_action();
+ //selection.clear();
+ accept_event();
+ _edit_if_single_selection();
+ }
+}
+
void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
Control *te=track_editor;
@@ -1861,22 +1879,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
} else if (p_input.key.scancode==KEY_DELETE && p_input.key.pressed && click.click==ClickOver::CLICK_NONE) {
- if (selection.size()) {
- undo_redo->create_action(TTR("Anim Delete Keys"));
-
- for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) {
-
- undo_redo->add_do_method(animation.ptr(),"track_remove_key",E->key().track,E->key().key);
- undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key));
-
- }
- undo_redo->add_do_method(this,"_clear_selection_for_anim",animation);
- undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation);
- undo_redo->commit_action();
- //selection.clear();
- accept_event();
- _edit_if_single_selection();
- }
+ _anim_delete_keys();
} else if (animation.is_valid() && animation->get_track_count()>0) {
if (p_input.is_pressed() && (p_input.is_action("ui_up") || p_input.is_action("ui_page_up"))) {
@@ -1936,6 +1939,116 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
v_scroll->set_val( v_scroll->get_val() + v_scroll->get_page() / 8 );
}
+ if (mb.button_index==BUTTON_RIGHT && mb.pressed) {
+
+ Point2 mpos = Point2(mb.x,mb.y)-ofs;
+
+ if (selection.size() == 0) {
+ // Auto-select on right-click if nothing is selected
+ // Note: This code is pretty much duplicated from the left click code,
+ // both codes could be moved into a function to avoid the duplicated code.
+ Point2 mpos = Point2(mb.x,mb.y)-ofs;
+
+ if (mpos.y < h ) {
+ return;
+ }
+
+ mpos.y -= h;
+
+ int idx = mpos.y / h;
+ idx+=v_scroll->get_val();
+ if (idx <0 || idx>=animation->get_track_count())
+ break;
+
+ if (mpos.x < name_limit) {
+ } else if (mpos.x < settings_limit) {
+ float pos = mpos.x - name_limit;
+ pos/=_get_zoom_scale();
+ pos+=h_scroll->get_val();
+ float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0;
+
+ int kidx = animation->track_find_key(idx,pos);
+ int kidx_n = kidx+1;
+ int key=-1;
+
+ if (kidx>=0 && kidx<animation->track_get_key_count(idx)) {
+
+ float kpos = animation->track_get_key_time(idx,kidx);
+ if (ABS(pos-kpos)<=w_time) {
+
+ key=kidx;
+ }
+ }
+
+ if (key==-1 && kidx_n>=0 && kidx_n<animation->track_get_key_count(idx)) {
+
+ float kpos = animation->track_get_key_time(idx,kidx_n);
+ if (ABS(pos-kpos)<=w_time) {
+
+ key=kidx_n;
+ }
+ }
+
+ if (key==-1) {
+
+ click.click=ClickOver::CLICK_SELECT_KEYS;
+ click.at=Point2(mb.x,mb.y);
+ click.to=click.at;
+ click.shift=mb.mod.shift;
+ selected_track=idx;
+ track_editor->update();
+ //drag select region
+ return;
+
+ }
+
+
+
+ SelectedKey sk;
+ sk.track=idx;
+ sk.key=key;
+ KeyInfo ki;
+ ki.pos= animation->track_get_key_time(idx,key);
+ click.shift=mb.mod.shift;
+ click.selk=sk;
+
+
+ if (!mb.mod.shift && !selection.has(sk))
+ _clear_selection();
+
+ selection.insert(sk,ki);
+
+ click.click=ClickOver::CLICK_MOVE_KEYS;
+ click.at=Point2(mb.x,mb.y);
+ click.to=click.at;
+ update();
+ selected_track=idx;
+ track_editor->update();
+
+ if (_edit_if_single_selection() && mb.mod.command) {
+ edit_button->set_pressed(true);
+ key_editor_tab->show();
+ }
+ }
+ }
+
+ if (selection.size()) {
+ // User has right clicked and we have a selection, show a popup menu with options
+ track_menu->clear();
+ track_menu->set_size(Point2(1,1));
+ track_menu->add_item(TTR("Duplicate Selection"), RIGHT_MENU_DUPLICATE);
+ track_menu->add_item(TTR("Duplicate Transposed"), RIGHT_MENU_DUPLICATE_TRANSPOSE);
+ track_menu->add_item(TTR("Remove Selection"), RIGHT_MENU_REMOVE);
+
+ track_menu->set_pos(te->get_global_pos()+mpos);
+
+ interp_editing=-1;
+ cont_editing=-1;
+
+ track_menu->popup();
+ }
+ }
+
if (mb.button_index==BUTTON_LEFT && !(mb.button_mask&~BUTTON_MASK_LEFT)) {
diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h
index 413c73b4b9..131100a205 100644
--- a/tools/editor/animation_editor.h
+++ b/tools/editor/animation_editor.h
@@ -99,6 +99,12 @@ class AnimationKeyEditor : public VBoxContainer {
CURVE_SET_CONSTANT
};
+ enum {
+ RIGHT_MENU_DUPLICATE,
+ RIGHT_MENU_DUPLICATE_TRANSPOSE,
+ RIGHT_MENU_REMOVE
+ };
+
struct MouseOver {
enum Over {
@@ -313,6 +319,9 @@ class AnimationKeyEditor : public VBoxContainer {
void _add_call_track(const NodePath& p_base);
+ void _anim_duplicate_keys(bool transpose = false);
+ void _anim_delete_keys();
+
void _root_removed();
protected: