Merge pull request #6188 from TheHX/undo-redo
Implemented UndoRedo mergeable modes
This commit is contained in:
commit
e51d59ed98
8 changed files with 81 additions and 34 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -3738,7 +3738,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);
|
||||
|
|
Loading…
Reference in a new issue