Added popup menu for animation key right-click

This commit is contained in:
marcelofg55 2016-06-18 22:22:03 -03:00
parent bd79aa52ab
commit e71391e7cc
2 changed files with 244 additions and 122 deletions

View file

@ -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)) {

View file

@ -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: