1 /**
2  * Bind module.
3  *
4  * License:
5  *     MIT. See LICENSE for full details.
6  */
7 module tkd.widget.common.canvas.bind;
8 
9 /**
10  * These are common commands that apply to all widgets that have them injected.
11  */
12 mixin template Bind()
13 {
14 	import std.regex : match;
15 
16 	/**
17 	 * The bindings.
18 	 */
19 	private CommandCallback[string] _bindings;
20 
21 	/**
22 	 * Bind a callback to a particular event triggered by this item.
23 	 * This command is identical to $(LINK2 
24 	 * ../../../element/uielement.html#UiElement, UiElement)'s bind method.
25 	 *
26 	 * If bindings have been created for a canvas widget they are invoked in 
27 	 * addition to bindings created for the canvas's items. The bindings for 
28 	 * items will be invoked before any of the bindings for the window as a 
29 	 * whole.
30 	 *
31 	 * Params:
32 	 *     binding = The binding that triggers this event. See below.
33 	 *     callback = The delegate callback to execute when the event triggers.
34 	 *
35 	 * Returns:
36 	 *     This item to aid method chaining.
37 	 *
38 	 * Bindings:
39 	 *     The only events for which bindings may be specified are those 
40 	 *     related to the mouse and keyboard (such as Enter, Leave, 
41 	 *     ButtonPress, Motion, and KeyPress) or virtual events.
42 	 *
43 	 * Callback_Arguments:
44 	 *     These are the fields within the callback's $(LINK2 
45 	 *     ../../../element/element.html#CommandArgs, CommandArgs) parameter which 
46 	 *     are populated by this method when the callback is executed. 
47 	 *     $(P
48 	 *         $(PARAM_TABLE
49 	 *             $(PARAM_ROW CommandArgs.element, The item that executed the callback.)
50 	 *             $(PARAM_ROW CommandArgs.uniqueData, The binding that was responded to.)
51 	 *             $(PARAM_ROW CommandArgs.callback, The callback which was executed.)
52 	 *             $(PARAM_ROW CommandArgs.event.button, The number of any button that was pressed.)
53 	 *             $(PARAM_ROW CommandArgs.event.keyCode, The key code of any key pressed.)
54 	 *             $(PARAM_ROW CommandArgs.event.x, The horizontal position of the mouse relative to the widget.)
55 	 *             $(PARAM_ROW CommandArgs.event.y, The vertical position of the mouse relative to the widget.)
56 	 *             $(PARAM_ROW CommandArgs.event.wheel, Mouse wheel delta.)
57 	 *             $(PARAM_ROW CommandArgs.event.key, Key symbol of any key pressed.)
58 	 *             $(PARAM_ROW CommandArgs.event.screenX, The horizontal position of the mouse relative to the screen.)
59 	 *             $(PARAM_ROW CommandArgs.event.screenY, The vertical position of the mouse relative to the screen.)
60 	 *         )
61 	 *     )
62 	 *
63 	 * See_Also:
64 	 *     $(LINK2 ../../../element/element.html#CommandCallback, tkd.element.element.CommandCallback) $(BR)
65 	 *     $(LINK2 ../../../element/uielement.html#UiElement, tkd.element.uielement.UiElement) $(BR)
66 	 */
67 	public auto bind(this T)(string binding, CommandCallback callback)
68 	{
69 		assert(!match(binding, r"^<.*?>$").empty, "Binding must take the form of <binding>");
70 
71 		this._bindings[binding] = callback;
72 
73 		if (this._parent)
74 		{
75 			string command = this.createCommand(callback, binding);
76 			this._tk.eval("%s bind %s {%s} {%s %%b %%k %%x %%y %%D %%K %%X %%Y}", this._parent.id, this.id, binding, command);
77 		}
78 
79 		return cast(T) this;
80 	}
81 
82 	/**
83 	 * Unbind a previous event binding.
84 	 *
85 	 * Params:
86 	 *     binding = The binding to remove.
87 	 *
88 	 * Returns:
89 	 *     This item to aid method chaining.
90 	 */
91 	public auto unbind(this T)(string binding)
92 	{
93 		this._bindings.remove(binding);
94 
95 		if (this._parent)
96 		{
97 			this._tk.deleteCommand(this.getCommandName(binding));
98 			this._tk.eval("%s bind %s {%s} {}", this._parent.id, this.id, binding);
99 		}
100 
101 		return cast(T) this;
102 	}
103 }