Added popup menu for animation key right-click
This commit is contained in:
parent
bd79aa52ab
commit
e71391e7cc
2 changed files with 244 additions and 122 deletions
|
@ -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)) {
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
Loading…
Reference in a new issue