Parcourir la source

Merge pull request #5287 from marcelofg55/master

Added popup menu for animation key right-click
Juan Linietsky il y a 9 ans
Parent
commit
8462127aa9
2 fichiers modifiés avec 244 ajouts et 122 suppressions
  1. 235 122
      tools/editor/animation_editor.cpp
  2. 9 0
      tools/editor/animation_editor.h

+ 235 - 122
tools/editor/animation_editor.cpp

@@ -693,11 +693,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) {
 
@@ -765,108 +857,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:
@@ -1618,9 +1609,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());
 
@@ -1628,6 +1617,16 @@ void AnimationKeyEditor::_track_menu_selected(int p_idx) {
 		undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",cont_editing,p_idx);
 		undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",cont_editing,animation->value_track_get_update_mode(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;
+		}
 	}
 
 }
@@ -1789,6 +1788,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;
@@ -1859,22 +1877,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"))) {
@@ -1934,6 +1937,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)) {
 
 

+ 9 - 0
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: