1 /*
2  * This file is part of d-dazzle.
3  *
4  * d-dazzle is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * d-dazzle is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with d-dazzle; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 module dazzle.ShortcutController;
20 
21 private import dazzle.ShortcutChord;
22 private import dazzle.ShortcutContext;
23 private import dazzle.ShortcutManager;
24 private import dazzle.c.functions;
25 public  import dazzle.c.types;
26 private import glib.ConstructionException;
27 private import glib.Str;
28 private import gobject.ObjectG;
29 private import gobject.Signals;
30 private import gtk.Widget;
31 private import std.algorithm;
32 
33 
34 /** */
35 public class ShortcutController : ObjectG
36 {
37 	/** the main Gtk struct */
38 	protected DzlShortcutController* dzlShortcutController;
39 
40 	/** Get the main Gtk struct */
41 	public DzlShortcutController* getShortcutControllerStruct(bool transferOwnership = false)
42 	{
43 		if (transferOwnership)
44 			ownedRef = false;
45 		return dzlShortcutController;
46 	}
47 
48 	/** the main Gtk struct as a void* */
49 	protected override void* getStruct()
50 	{
51 		return cast(void*)dzlShortcutController;
52 	}
53 
54 	/**
55 	 * Sets our main struct and passes it to the parent class.
56 	 */
57 	public this (DzlShortcutController* dzlShortcutController, bool ownedRef = false)
58 	{
59 		this.dzlShortcutController = dzlShortcutController;
60 		super(cast(GObject*)dzlShortcutController, ownedRef);
61 	}
62 
63 
64 	/** */
65 	public static GType getType()
66 	{
67 		return dzl_shortcut_controller_get_type();
68 	}
69 
70 	/** */
71 	public this(Widget widget)
72 	{
73 		auto p = dzl_shortcut_controller_new((widget is null) ? null : widget.getWidgetStruct());
74 
75 		if(p is null)
76 		{
77 			throw new ConstructionException("null returned by new");
78 		}
79 
80 		this(cast(DzlShortcutController*) p, true);
81 	}
82 
83 	/**
84 	 * Finds the registered #DzlShortcutController for a widget.
85 	 *
86 	 * The controller is created if it does not already exist.
87 	 *
88 	 * Returns: An #DzlShortcutController or %NULL.
89 	 */
90 	public static ShortcutController find(Widget widget)
91 	{
92 		auto p = dzl_shortcut_controller_find((widget is null) ? null : widget.getWidgetStruct());
93 
94 		if(p is null)
95 		{
96 			return null;
97 		}
98 
99 		return ObjectG.getDObject!(ShortcutController)(cast(DzlShortcutController*) p);
100 	}
101 
102 	/**
103 	 * Finds the registered #DzlShortcutController for a widget.
104 	 *
105 	 * If no controller is found, %NULL is returned.
106 	 *
107 	 * Returns: An #DzlShortcutController or %NULL.
108 	 */
109 	public static ShortcutController tryFind(Widget widget)
110 	{
111 		auto p = dzl_shortcut_controller_try_find((widget is null) ? null : widget.getWidgetStruct());
112 
113 		if(p is null)
114 		{
115 			return null;
116 		}
117 
118 		return ObjectG.getDObject!(ShortcutController)(cast(DzlShortcutController*) p);
119 	}
120 
121 	/** */
122 	public void addCommandAction(string commandId, string defaultAccel, DzlShortcutPhase phase, string action)
123 	{
124 		dzl_shortcut_controller_add_command_action(dzlShortcutController, Str.toStringz(commandId), Str.toStringz(defaultAccel), phase, Str.toStringz(action));
125 	}
126 
127 	/** */
128 	public void addCommandCallback(string commandId, string defaultAccel, DzlShortcutPhase phase, GtkCallback callback, void* callbackData, GDestroyNotify callbackDataDestroy)
129 	{
130 		dzl_shortcut_controller_add_command_callback(dzlShortcutController, Str.toStringz(commandId), Str.toStringz(defaultAccel), phase, callback, callbackData, callbackDataDestroy);
131 	}
132 
133 	/**
134 	 * This method will locate and execute the command matching the id @command.
135 	 *
136 	 * If the command is not found, %FALSE is returned.
137 	 *
138 	 * Params:
139 	 *     command = the id of the command
140 	 *
141 	 * Returns: %TRUE if the command was found and executed.
142 	 */
143 	public bool executeCommand(string command)
144 	{
145 		return dzl_shortcut_controller_execute_command(dzlShortcutController, Str.toStringz(command)) != 0;
146 	}
147 
148 	/**
149 	 * This function gets the #DzlShortcutController:context property, which
150 	 * is the current context to dispatch events to. An #DzlShortcutContext
151 	 * is a group of keybindings that may be activated in response to a
152 	 * single or series of #GdkEventKey.
153 	 *
154 	 * Returns: A #DzlShortcutContext or %NULL.
155 	 *
156 	 * Since: 3.26
157 	 */
158 	public ShortcutContext getContext()
159 	{
160 		auto p = dzl_shortcut_controller_get_context(dzlShortcutController);
161 
162 		if(p is null)
163 		{
164 			return null;
165 		}
166 
167 		return ObjectG.getDObject!(ShortcutContext)(cast(DzlShortcutContext*) p);
168 	}
169 
170 	/**
171 	 * Controllers can have a different context for a particular phase, which allows
172 	 * them to activate different keybindings depending if the event in capture,
173 	 * bubble, or dispatch.
174 	 *
175 	 * Params:
176 	 *     phase = the phase for the shorcut delivery
177 	 *
178 	 * Returns: A #DzlShortcutContext or %NULL.
179 	 *
180 	 * Since: 3.26
181 	 */
182 	public ShortcutContext getContextForPhase(DzlShortcutPhase phase)
183 	{
184 		auto p = dzl_shortcut_controller_get_context_for_phase(dzlShortcutController, phase);
185 
186 		if(p is null)
187 		{
188 			return null;
189 		}
190 
191 		return ObjectG.getDObject!(ShortcutContext)(cast(DzlShortcutContext*) p);
192 	}
193 
194 	/**
195 	 * This method gets the #DzlShortcutController:current-chord property.
196 	 * This is useful if you want to monitor in-progress chord building.
197 	 *
198 	 * Note that this value will only be valid on the controller for the
199 	 * toplevel widget (a #GtkWindow). Chords are not tracked at the
200 	 * individual widget controller level.
201 	 *
202 	 * Returns: A #DzlShortcutChord or %NULL.
203 	 */
204 	public ShortcutChord getCurrentChord()
205 	{
206 		auto p = dzl_shortcut_controller_get_current_chord(dzlShortcutController);
207 
208 		if(p is null)
209 		{
210 			return null;
211 		}
212 
213 		return ObjectG.getDObject!(ShortcutChord)(cast(DzlShortcutChord*) p);
214 	}
215 
216 	/**
217 	 * Gets the #DzlShortcutManager associated with this controller.
218 	 *
219 	 * Generally, this will look for the root controller's manager as mixing and
220 	 * matching managers in a single window hierarchy is not supported.
221 	 *
222 	 * Returns: A #DzlShortcutManager.
223 	 */
224 	public ShortcutManager getManager()
225 	{
226 		auto p = dzl_shortcut_controller_get_manager(dzlShortcutController);
227 
228 		if(p is null)
229 		{
230 			return null;
231 		}
232 
233 		return ObjectG.getDObject!(ShortcutManager)(cast(DzlShortcutManager*) p);
234 	}
235 
236 	/**
237 	 * Returns: the widget for the controller
238 	 *
239 	 * Since: 3.34
240 	 */
241 	public Widget getWidget()
242 	{
243 		auto p = dzl_shortcut_controller_get_widget(dzlShortcutController);
244 
245 		if(p is null)
246 		{
247 			return null;
248 		}
249 
250 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
251 	}
252 
253 	/** */
254 	public void removeAccel(string accel, DzlShortcutPhase phase)
255 	{
256 		dzl_shortcut_controller_remove_accel(dzlShortcutController, Str.toStringz(accel), phase);
257 	}
258 
259 	/**
260 	 * Changes the context for the controller to the context matching @name.
261 	 *
262 	 * Contexts are resolved at runtime through the current theme (and possibly
263 	 * a parent theme if it inherits from one).
264 	 *
265 	 * Params:
266 	 *     name = The name of the context
267 	 *
268 	 * Since: 3.26
269 	 */
270 	public void setContextByName(string name)
271 	{
272 		dzl_shortcut_controller_set_context_by_name(dzlShortcutController, Str.toStringz(name));
273 	}
274 
275 	/**
276 	 * Sets the #DzlShortcutController:manager property.
277 	 *
278 	 * If you set this to %NULL, it will revert to the default #DzlShortcutManager
279 	 * for the process.
280 	 *
281 	 * Params:
282 	 *     manager = A #DzlShortcutManager or %NULL
283 	 */
284 	public void setManager(ShortcutManager manager)
285 	{
286 		dzl_shortcut_controller_set_manager(dzlShortcutController, (manager is null) ? null : manager.getShortcutManagerStruct());
287 	}
288 
289 	/**
290 	 * This signal is emitted when the shortcut controller is requesting
291 	 * the widget to reset any state it may have regarding the shortcut
292 	 * controller. Such an example might be a modal system that lives
293 	 * outside the controller whose state should be cleared in response
294 	 * to the controller changing modes.
295 	 */
296 	gulong addOnReset(void delegate(ShortcutController) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
297 	{
298 		return Signals.connect(this, "reset", dlg, connectFlags ^ ConnectFlags.SWAPPED);
299 	}
300 
301 	/**
302 	 * This changes the current context on the #DzlShortcutController to be the
303 	 * context matching @name. This is found by looking up the context by name
304 	 * in the active #DzlShortcutTheme.
305 	 *
306 	 * Params:
307 	 *     name = The name of the context
308 	 */
309 	gulong addOnSetContextNamed(void delegate(string, ShortcutController) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
310 	{
311 		return Signals.connect(this, "set-context-named", dlg, connectFlags ^ ConnectFlags.SWAPPED);
312 	}
313 }