1 /**
2 Helper to manage UndoRedo in the editor or custom tools.
3 
4 Copyright:
5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.  
6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)  
7 Copyright (c) 2017-2018 Godot-D contributors  
8 
9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License)
10 
11 
12 */
13 module godot.undoredo;
14 import std.meta : AliasSeq, staticIndexOf;
15 import std.traits : Unqual;
16 import godot.d.meta;
17 import godot.core;
18 import godot.c;
19 import godot.d.bind;
20 import godot.d.reference;
21 import godot.object;
22 import godot.classdb;
23 /**
24 Helper to manage UndoRedo in the editor or custom tools.
25 
26 It works by registering methods and property changes inside 'actions'.
27 Common behavior is to create an action, then add do/undo calls to functions or property changes, then committing the action.
28 Here's an example on how to add an action to Godot editor's own 'undoredo':
29 
30 
31 var undoredo = get_undo_redo() # method of EditorPlugin
32 
33 func do_something():
34     pass # put your code here
35 
36 func undo_something():
37     pass # put here the code that reverts what's done by "do_something()"
38 
39 func _on_MyButton_pressed():
40     var node = get_node("MyNode2D")
41     undoredo.create_action("Move the node")
42     undoredo.add_do_method(self, "do_something")
43     undoredo.add_undo_method(self, "undo_something")
44     undoredo.add_do_property(node, "position", Vector2(100,100))
45     undoredo.add_undo_property(node, "position", node.position)
46     undoredo.commit_action()
47 
48 
49 $(D createAction), $(D addDoMethod), $(D addUndoMethod), $(D addDoProperty), $(D addUndoProperty), and $(D commitAction) should be called one after the other, like in the example. Not doing so could lead to crashes.
50 If you don't need to register a method you can leave $(D addDoMethod) and $(D addUndoMethod) out, and so it goes for properties. You can register more than one method/property.
51 */
52 @GodotBaseClass struct UndoRedo
53 {
54 	enum string _GODOT_internal_name = "UndoRedo";
55 public:
56 @nogc nothrow:
57 	union { godot_object _godot_object; GodotObject _GODOT_base; }
58 	alias _GODOT_base this;
59 	alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses);
60 	package(godot) __gshared bool _classBindingInitialized = false;
61 	package(godot) static struct _classBinding
62 	{
63 		__gshared:
64 		@GodotName("create_action") GodotMethod!(void, String, long) createAction;
65 		@GodotName("commit_action") GodotMethod!(void) commitAction;
66 		@GodotName("add_do_method") GodotMethod!(Variant, GodotObject, String, GodotVarArgs) addDoMethod;
67 		@GodotName("add_undo_method") GodotMethod!(Variant, GodotObject, String, GodotVarArgs) addUndoMethod;
68 		@GodotName("add_do_property") GodotMethod!(void, GodotObject, String, Variant) addDoProperty;
69 		@GodotName("add_undo_property") GodotMethod!(void, GodotObject, String, Variant) addUndoProperty;
70 		@GodotName("add_do_reference") GodotMethod!(void, GodotObject) addDoReference;
71 		@GodotName("add_undo_reference") GodotMethod!(void, GodotObject) addUndoReference;
72 		@GodotName("clear_history") GodotMethod!(void) clearHistory;
73 		@GodotName("get_current_action_name") GodotMethod!(String) getCurrentActionName;
74 		@GodotName("get_version") GodotMethod!(long) getVersion;
75 		@GodotName("redo") GodotMethod!(bool) redo;
76 		@GodotName("undo") GodotMethod!(bool) undo;
77 	}
78 	bool opEquals(in UndoRedo other) const { return _godot_object.ptr is other._godot_object.ptr; }
79 	UndoRedo opAssign(T : typeof(null))(T n) { _godot_object.ptr = null; }
80 	bool opEquals(typeof(null) n) const { return _godot_object.ptr is null; }
81 	mixin baseCasts;
82 	static UndoRedo _new()
83 	{
84 		static godot_class_constructor constructor;
85 		if(constructor is null) constructor = _godot_api.godot_get_class_constructor("UndoRedo");
86 		if(constructor is null) return typeof(this).init;
87 		return cast(UndoRedo)(constructor());
88 	}
89 	@disable new(size_t s);
90 	/// 
91 	enum MergeMode : int
92 	{
93 		/**
94 		
95 		*/
96 		mergeDisable = 0,
97 		/**
98 		
99 		*/
100 		mergeEnds = 1,
101 		/**
102 		
103 		*/
104 		mergeAll = 2,
105 	}
106 	/// 
107 	enum Constants : int
108 	{
109 		mergeDisable = 0,
110 		mergeEnds = 1,
111 		mergeAll = 2,
112 	}
113 	/**
114 	Create a new action. After this is called, do all your calls to $(D addDoMethod), $(D addUndoMethod), $(D addDoProperty), and $(D addUndoProperty), then commit the action with $(D commitAction).
115 	*/
116 	void createAction(StringArg0)(in StringArg0 name, in long merge_mode = 0)
117 	{
118 		checkClassBinding!(typeof(this))();
119 		ptrcall!(void)(_classBinding.createAction, _godot_object, name, merge_mode);
120 	}
121 	/**
122 	Commit the action. All 'do' methods/properties are called/set when this function is called.
123 	*/
124 	void commitAction()
125 	{
126 		checkClassBinding!(typeof(this))();
127 		ptrcall!(void)(_classBinding.commitAction, _godot_object);
128 	}
129 	/**
130 	Register a method that will be called when the action is committed.
131 	*/
132 	Variant addDoMethod(StringArg1, VarArgs...)(GodotObject object, in StringArg1 method, VarArgs varArgs)
133 	{
134 		Array _GODOT_args = Array.empty_array;
135 		_GODOT_args.append(object);
136 		_GODOT_args.append(method);
137 		foreach(vai, VA; VarArgs)
138 		{
139 			_GODOT_args.append(varArgs[vai]);
140 		}
141 		String _GODOT_method_name = String("add_do_method");
142 		return this.callv(_GODOT_method_name, _GODOT_args);
143 	}
144 	/**
145 	Register a method that will be called when the action is undone.
146 	*/
147 	Variant addUndoMethod(StringArg1, VarArgs...)(GodotObject object, in StringArg1 method, VarArgs varArgs)
148 	{
149 		Array _GODOT_args = Array.empty_array;
150 		_GODOT_args.append(object);
151 		_GODOT_args.append(method);
152 		foreach(vai, VA; VarArgs)
153 		{
154 			_GODOT_args.append(varArgs[vai]);
155 		}
156 		String _GODOT_method_name = String("add_undo_method");
157 		return this.callv(_GODOT_method_name, _GODOT_args);
158 	}
159 	/**
160 	Register a property value change for 'do'.
161 	*/
162 	void addDoProperty(StringArg1, VariantArg2)(GodotObject object, in StringArg1 property, in VariantArg2 value)
163 	{
164 		checkClassBinding!(typeof(this))();
165 		ptrcall!(void)(_classBinding.addDoProperty, _godot_object, object, property, value);
166 	}
167 	/**
168 	Register a property value change for 'undo'.
169 	*/
170 	void addUndoProperty(StringArg1, VariantArg2)(GodotObject object, in StringArg1 property, in VariantArg2 value)
171 	{
172 		checkClassBinding!(typeof(this))();
173 		ptrcall!(void)(_classBinding.addUndoProperty, _godot_object, object, property, value);
174 	}
175 	/**
176 	Register a reference for 'do' that will be erased if the 'do' history is lost. This is useful mostly for new nodes created for the 'do' call. Do not use for resources.
177 	*/
178 	void addDoReference(GodotObject object)
179 	{
180 		checkClassBinding!(typeof(this))();
181 		ptrcall!(void)(_classBinding.addDoReference, _godot_object, object);
182 	}
183 	/**
184 	Register a reference for 'undo' that will be erased if the 'undo' history is lost. This is useful mostly for nodes removed with the 'do' call (not the 'undo' call!).
185 	*/
186 	void addUndoReference(GodotObject object)
187 	{
188 		checkClassBinding!(typeof(this))();
189 		ptrcall!(void)(_classBinding.addUndoReference, _godot_object, object);
190 	}
191 	/**
192 	Clear the undo/redo history and associated references.
193 	*/
194 	void clearHistory()
195 	{
196 		checkClassBinding!(typeof(this))();
197 		ptrcall!(void)(_classBinding.clearHistory, _godot_object);
198 	}
199 	/**
200 	Get the name of the current action.
201 	*/
202 	String getCurrentActionName() const
203 	{
204 		checkClassBinding!(typeof(this))();
205 		return ptrcall!(String)(_classBinding.getCurrentActionName, _godot_object);
206 	}
207 	/**
208 	Get the version, each time a new action is committed, the version number of the UndoRedo is increased automatically.
209 	This is useful mostly to check if something changed from a saved version.
210 	*/
211 	long getVersion() const
212 	{
213 		checkClassBinding!(typeof(this))();
214 		return ptrcall!(long)(_classBinding.getVersion, _godot_object);
215 	}
216 	/**
217 	Redo last action.
218 	*/
219 	bool redo()
220 	{
221 		checkClassBinding!(typeof(this))();
222 		return ptrcall!(bool)(_classBinding.redo, _godot_object);
223 	}
224 	/**
225 	Undo last action.
226 	*/
227 	bool undo()
228 	{
229 		checkClassBinding!(typeof(this))();
230 		return ptrcall!(bool)(_classBinding.undo, _godot_object);
231 	}
232 }