Browse Source

Implemented UndoRedo mergeable modes

Franklin Sobrinho 9 years ago
parent
commit
debf574df3

+ 48 - 13
core/undo_redo.cpp

@@ -52,26 +52,46 @@ void UndoRedo::_discard_redo() {
 
 }
 
-
-void UndoRedo::create_action(const String& p_name,bool p_mergeable) {
+void UndoRedo::create_action(const String& p_name,MergeMode p_mode) {
 
 	if (action_level==0) {
 
 		_discard_redo();
-		if (p_mergeable && actions.size() && actions[actions.size()-1].name==p_name) {
 
-			//old will replace new (it's mergeable after all)
-			// should check references though!
+		// Check if the merge operation is valid
+		if (p_mode!=MERGE_DISABLE && actions.size() && actions[actions.size()-1].name==p_name) {
+
 			current_action=actions.size()-2;
-			actions[current_action+1].do_ops.clear();
-			//actions[current_action+1].undo_ops.clear(); - no, this is kept
-			merging=true;
+
+			if (p_mode==MERGE_ENDS) {
+
+				// Clear all do ops from last action, and delete all object references
+				List<Operation>::Element *E=actions[current_action+1].do_ops.front();
+
+				while (E) {
+
+					if (E->get().type==Operation::TYPE_REFERENCE) {
+
+						Object *obj=ObjectDB::get_instance(E->get().object);
+
+						if (obj)
+							memdelete(obj);
+					}
+
+					E=E->next();
+					actions[current_action+1].do_ops.pop_front();
+				}
+			}
+
+			merge_mode=p_mode;
 
 		} else {
+
 			Action new_action;
 			new_action.name=p_name;
 			actions.push_back(new_action);
-			merging=false;
+
+			merge_mode=MERGE_DISABLE;
 		}
 	}
 
@@ -102,8 +122,10 @@ void UndoRedo::add_undo_method(Object *p_object,const String& p_method,VARIANT_A
 	VARIANT_ARGPTRS
 	ERR_FAIL_COND(action_level<=0);
 	ERR_FAIL_COND((current_action+1)>=actions.size());
-	if (merging)
-		return; //- no undo if merging
+
+	// No undo if the merge mode is MERGE_ENDS
+	if (merge_mode==MERGE_ENDS)
+		return;
 
 	Operation undo_op;
 	undo_op.object=p_object->get_instance_ID();
@@ -139,6 +161,10 @@ void UndoRedo::add_undo_property(Object *p_object,const String& p_property,const
 	ERR_FAIL_COND(action_level<=0);
 	ERR_FAIL_COND((current_action+1)>=actions.size());
 
+	// No undo if the merge mode is MERGE_ENDS
+	if (merge_mode==MERGE_ENDS)
+		return;
+
 	Operation undo_op;
 	undo_op.object=p_object->get_instance_ID();
 	if (p_object->cast_to<Resource>())
@@ -167,6 +193,11 @@ void UndoRedo::add_undo_reference(Object *p_object) {
 
 	ERR_FAIL_COND(action_level<=0);
 	ERR_FAIL_COND((current_action+1)>=actions.size());
+
+	// No undo if the merge mode is MERGE_ENDS
+	if (merge_mode==MERGE_ENDS)
+		return;
+
 	Operation undo_op;
 	undo_op.object=p_object->get_instance_ID();
 	if (p_object->cast_to<Resource>())
@@ -352,7 +383,7 @@ UndoRedo::UndoRedo() {
 	action_level=0;
 	current_action=-1;
 	max_steps=-1;
-	merging=true;
+	merge_mode=MERGE_DISABLE;
 	callback=NULL;
 	callback_ud=NULL;
 
@@ -448,7 +479,7 @@ Variant UndoRedo::_add_undo_method(const Variant** p_args, int p_argcount, Varia
 
 void UndoRedo::_bind_methods() {
 
-	ObjectTypeDB::bind_method(_MD("create_action","name","mergeable"),&UndoRedo::create_action, DEFVAL(false) );
+	ObjectTypeDB::bind_method(_MD("create_action","name","merge_mode"),&UndoRedo::create_action, DEFVAL(MERGE_DISABLE) );
 	ObjectTypeDB::bind_method(_MD("commit_action"),&UndoRedo::commit_action);
 
 	//ObjectTypeDB::bind_method(_MD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method);
@@ -489,4 +520,8 @@ void UndoRedo::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("clear_history"),&UndoRedo::clear_history);
 	ObjectTypeDB::bind_method(_MD("get_current_action_name"),&UndoRedo::get_current_action_name);
 	ObjectTypeDB::bind_method(_MD("get_version"),&UndoRedo::get_version);
+
+	BIND_CONSTANT(MERGE_DISABLE);
+	BIND_CONSTANT(MERGE_ENDS);
+	BIND_CONSTANT(MERGE_ALL);
 }

+ 10 - 2
core/undo_redo.h

@@ -41,6 +41,12 @@ class UndoRedo : public Object {
 	OBJ_SAVE_TYPE( UndoRedo );
 public:
 
+	enum MergeMode {
+		MERGE_DISABLE,
+		MERGE_ENDS,
+		MERGE_ALL
+	};
+
 	typedef void (*CommitNotifyCallback)(void *p_ud,const String& p_name);
 	Variant _add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
 	Variant _add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
@@ -76,7 +82,7 @@ private:
 	int current_action;
 	int action_level;
 	int max_steps;
-	bool merging;
+	MergeMode merge_mode;
 	uint64_t version;
 
 	void _pop_history_tail();
@@ -98,7 +104,7 @@ protected:
 
 public:
 
-	void create_action(const String& p_name="",bool p_mergeable=false);
+	void create_action(const String& p_name="",MergeMode p_mode=MERGE_DISABLE);
 
 	void add_do_method(Object *p_object,const String& p_method,VARIANT_ARG_LIST);
 	void add_undo_method(Object *p_object,const String& p_method,VARIANT_ARG_LIST);
@@ -128,4 +134,6 @@ public:
 	~UndoRedo();
 };
 
+VARIANT_ENUM_CAST( UndoRedo::MergeMode );
+
 #endif // UNDO_REDO_H

+ 10 - 6
tools/editor/animation_editor.cpp

@@ -316,7 +316,7 @@ public:
 			int existing = animation->track_find_key(track,new_time,true);
 
 			setting=true;
-			undo_redo->create_action(TTR("Move Add Key"),false);
+			undo_redo->create_action(TTR("Move Add Key"),UndoRedo::MERGE_ENDS);
 
 			Variant val = animation->track_get_key_value(track,key);
 			float trans = animation->track_get_key_transition(track,key);
@@ -344,7 +344,7 @@ public:
 			float val = p_value;
 			float prev_val = animation->track_get_key_transition(track,key);
 			setting=true;
-			undo_redo->create_action(TTR("Anim Change Transition"),true);
+			undo_redo->create_action(TTR("Anim Change Transition"),UndoRedo::MERGE_ENDS);
 			undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",track,key,val);
 			undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",track,key,prev_val);
 			undo_redo->add_do_method(this,"_update_obj",animation);
@@ -387,7 +387,7 @@ public:
 					}
 
 					setting=true;
-					undo_redo->create_action(TTR("Anim Change Value"),true);
+					undo_redo->create_action(TTR("Anim Change Value"),UndoRedo::MERGE_ENDS);
 					Variant prev =  animation->track_get_key_value(track,key);
 					undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,value);
 					undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,prev);
@@ -463,7 +463,11 @@ public:
 					}
 				}
 
-				undo_redo->create_action(TTR("Anim Change Call"),mergeable);
+				if (mergeable)
+					undo_redo->create_action(TTR("Anim Change Call"),UndoRedo::MERGE_ENDS);
+				else
+					undo_redo->create_action(TTR("Anim Change Call"));
+
 				Variant prev =  animation->track_get_key_value(track,key);
 				setting=true;
 				undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,d_new);
@@ -1715,9 +1719,9 @@ void AnimationKeyEditor::_curve_transition_changed(float p_what) {
 	if (selection.size()==0)
 		return;
 	if (selection.size()==1)
-		undo_redo->create_action(TTR("Edit Node Curve"),true);
+		undo_redo->create_action(TTR("Edit Node Curve"),UndoRedo::MERGE_ENDS);
 	else
-		undo_redo->create_action(TTR("Edit Selection Curve"),true);
+		undo_redo->create_action(TTR("Edit Selection Curve"),UndoRedo::MERGE_ENDS);
 
 	for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) {
 

+ 1 - 1
tools/editor/plugins/canvas_item_editor_plugin.cpp

@@ -648,7 +648,7 @@ void CanvasItemEditor::_key_move(const Vector2& p_dir, bool p_snap, KeyMoveMODE
 	if (editor_selection->get_selected_node_list().empty())
 		return;
 
-	undo_redo->create_action(TTR("Move Action"),true);
+	undo_redo->create_action(TTR("Move Action"),UndoRedo::MERGE_ENDS);
 
 	List<Node*> &selection = editor_selection->get_selected_node_list();
 

+ 1 - 1
tools/editor/plugins/color_ramp_editor_plugin.cpp

@@ -84,7 +84,7 @@ void ColorRampEditorPlugin::_ramp_changed() {
 		if (old_offsets.size()!=new_offsets.size())
 			ur->create_action(TTR("Add/Remove Color Ramp Point"));
 		else
-			ur->create_action(TTR("Modify Color Ramp"),true);
+			ur->create_action(TTR("Modify Color Ramp"),UndoRedo::MERGE_ENDS);
 		ur->add_do_method(this,"undo_redo_color_ramp",new_offsets,new_colors);
 		ur->add_undo_method(this,"undo_redo_color_ramp",old_offsets,old_colors);
 		ur->commit_action();

+ 9 - 9
tools/editor/plugins/shader_graph_editor_plugin.cpp

@@ -675,7 +675,7 @@ GraphCurveMapEdit::GraphCurveMapEdit(){
 void ShaderGraphView::_scalar_const_changed(double p_value,int p_id) {
 
 	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
-	ur->create_action(TTR("Change Scalar Constant"),true);
+	ur->create_action(TTR("Change Scalar Constant"),UndoRedo::MERGE_ENDS);
 	ur->add_do_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,p_value);
 	ur->add_undo_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,graph->scalar_const_node_get_value(type,p_id));
 	ur->add_do_method(this,"_update_graph");
@@ -693,7 +693,7 @@ void ShaderGraphView::_vec_const_changed(double p_value, int p_id,Array p_arr){
 	}
 
 	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
-	ur->create_action(TTR("Change Vec Constant"),true);
+	ur->create_action(TTR("Change Vec Constant"),UndoRedo::MERGE_ENDS);
 	ur->add_do_method(graph.ptr(),"vec_const_node_set_value",type,p_id,val);
 	ur->add_undo_method(graph.ptr(),"vec_const_node_set_value",type,p_id,graph->vec_const_node_get_value(type,p_id));
 	ur->add_do_method(this,"_update_graph");
@@ -706,7 +706,7 @@ void ShaderGraphView::_vec_const_changed(double p_value, int p_id,Array p_arr){
 void ShaderGraphView::_rgb_const_changed(const Color& p_color, int p_id){
 
 	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
-	ur->create_action(TTR("Change RGB Constant"),true);
+	ur->create_action(TTR("Change RGB Constant"),UndoRedo::MERGE_ENDS);
 	ur->add_do_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,p_color);
 	ur->add_undo_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,graph->rgb_const_node_get_value(type,p_id));
 	ur->add_do_method(this,"_update_graph");
@@ -807,7 +807,7 @@ void ShaderGraphView::_vec_func_changed(int p_func, int p_id){
 void ShaderGraphView::_scalar_input_changed(double p_value,int p_id){
 
 	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
-	ur->create_action(TTR("Change Scalar Uniform"),true);
+	ur->create_action(TTR("Change Scalar Uniform"),UndoRedo::MERGE_ENDS);
 	ur->add_do_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,p_value);
 	ur->add_undo_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,graph->scalar_input_node_get_value(type,p_id));
 	ur->add_do_method(this,"_update_graph");
@@ -825,7 +825,7 @@ void ShaderGraphView::_vec_input_changed(double p_value, int p_id,Array p_arr){
 	}
 
 	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
-	ur->create_action(TTR("Change Vec Uniform"),true);
+	ur->create_action(TTR("Change Vec Uniform"),UndoRedo::MERGE_ENDS);
 	ur->add_do_method(graph.ptr(),"vec_input_node_set_value",type,p_id,val);
 	ur->add_undo_method(graph.ptr(),"vec_input_node_set_value",type,p_id,graph->vec_input_node_get_value(type,p_id));
 	ur->add_do_method(this,"_update_graph");
@@ -863,7 +863,7 @@ void ShaderGraphView::_rgb_input_changed(const Color& p_color, int p_id){
 
 
 	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
-	ur->create_action(TTR("Change RGB Uniform"),true);
+	ur->create_action(TTR("Change RGB Uniform"),UndoRedo::MERGE_ENDS);
 	ur->add_do_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,p_color);
 	ur->add_undo_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,graph->rgb_input_node_get_value(type,p_id));
 	ur->add_do_method(this,"_update_graph");
@@ -963,7 +963,7 @@ void ShaderGraphView::_comment_edited(int p_id,Node* p_button) {
 
 	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
 	TextEdit *te=p_button->cast_to<TextEdit>();
-	ur->create_action(TTR("Change Comment"),true);
+	ur->create_action(TTR("Change Comment"),UndoRedo::MERGE_ENDS);
 	ur->add_do_method(graph.ptr(),"comment_node_set_text",type,p_id,te->get_text());
 	ur->add_undo_method(graph.ptr(),"comment_node_set_text",type,p_id,graph->comment_node_get_text(type,p_id));
 	ur->add_do_method(this,"_update_graph");
@@ -1005,7 +1005,7 @@ void ShaderGraphView::_color_ramp_changed(int p_id,Node* p_ramp) {
 	if (old_offsets.size()!=new_offsets.size())
 		ur->create_action(TTR("Add/Remove to Color Ramp"));
 	else
-		ur->create_action(TTR("Modify Color Ramp"),true);
+		ur->create_action(TTR("Modify Color Ramp"),UndoRedo::MERGE_ENDS);
 
 	ur->add_do_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,new_colors,new_offsets);
 	ur->add_undo_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,old_colors,old_offsets);
@@ -1041,7 +1041,7 @@ void ShaderGraphView::_curve_changed(int p_id,Node* p_curve) {
 	if (old_points.size()!=new_points.size())
 		ur->create_action(TTR("Add/Remove to Curve Map"));
 	else
-		ur->create_action(TTR("Modify Curve Map"),true);
+		ur->create_action(TTR("Modify Curve Map"),UndoRedo::MERGE_ENDS);
 
 	ur->add_do_method(graph.ptr(),"curve_map_node_set_points",type,p_id,new_points);
 	ur->add_undo_method(graph.ptr(),"curve_map_node_set_points",type,p_id,old_points);

+ 1 - 1
tools/editor/plugins/sprite_frames_editor_plugin.cpp

@@ -524,7 +524,7 @@ void SpriteFramesEditor::_animation_fps_changed(double p_value) {
 	if (updating)
 		return;
 
-	undo_redo->create_action(TTR("Change Animation FPS"),true);
+	undo_redo->create_action(TTR("Change Animation FPS"),UndoRedo::MERGE_ENDS);
 	undo_redo->add_do_method(frames,"set_animation_speed",edited_anim,p_value);
 	undo_redo->add_undo_method(frames,"set_animation_speed",edited_anim,frames->get_animation_speed(edited_anim));
 	undo_redo->add_do_method(this,"_update_library",true);

+ 1 - 1
tools/editor/property_editor.cpp

@@ -3564,7 +3564,7 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
 	} else {
 
 
-		undo_redo->create_action(TTR("Set")+" "+p_name,true);
+		undo_redo->create_action(TTR("Set")+" "+p_name,UndoRedo::MERGE_ENDS);
 		undo_redo->add_do_property(obj,p_name,p_value);
 		undo_redo->add_undo_property(obj,p_name,obj->get(p_name));
 		undo_redo->add_do_method(this,"_changed_callback",obj,p_name);