1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD 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 * gtkD 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 gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gtk.GestureMultiPress; 26 27 private import glib.ConstructionException; 28 private import gobject.ObjectG; 29 private import gobject.Signals; 30 private import gtk.Gesture; 31 private import gtk.GestureSingle; 32 private import gtk.Widget; 33 private import gtk.c.functions; 34 public import gtk.c.types; 35 public import gtkc.gtktypes; 36 private import std.algorithm; 37 38 39 /** 40 * #GtkGestureMultiPress is a #GtkGesture implementation able to recognize 41 * multiple clicks on a nearby zone, which can be listened for through the 42 * #GtkGestureMultiPress::pressed signal. Whenever time or distance between 43 * clicks exceed the GTK+ defaults, #GtkGestureMultiPress::stopped is emitted, 44 * and the click counter is reset. 45 * 46 * Callers may also restrict the area that is considered valid for a >1 47 * touch/button press through gtk_gesture_multi_press_set_area(), so any 48 * click happening outside that area is considered to be a first click of 49 * its own. 50 */ 51 public class GestureMultiPress : GestureSingle 52 { 53 /** the main Gtk struct */ 54 protected GtkGestureMultiPress* gtkGestureMultiPress; 55 56 /** Get the main Gtk struct */ 57 public GtkGestureMultiPress* getGestureMultiPressStruct(bool transferOwnership = false) 58 { 59 if (transferOwnership) 60 ownedRef = false; 61 return gtkGestureMultiPress; 62 } 63 64 /** the main Gtk struct as a void* */ 65 protected override void* getStruct() 66 { 67 return cast(void*)gtkGestureMultiPress; 68 } 69 70 /** 71 * Sets our main struct and passes it to the parent class. 72 */ 73 public this (GtkGestureMultiPress* gtkGestureMultiPress, bool ownedRef = false) 74 { 75 this.gtkGestureMultiPress = gtkGestureMultiPress; 76 super(cast(GtkGestureSingle*)gtkGestureMultiPress, ownedRef); 77 } 78 79 80 /** */ 81 public static GType getType() 82 { 83 return gtk_gesture_multi_press_get_type(); 84 } 85 86 /** 87 * Returns a newly created #GtkGesture that recognizes single and multiple 88 * presses. 89 * 90 * Params: 91 * widget = a #GtkWidget 92 * 93 * Returns: a newly created #GtkGestureMultiPress 94 * 95 * Since: 3.14 96 * 97 * Throws: ConstructionException GTK+ fails to create the object. 98 */ 99 public this(Widget widget) 100 { 101 auto p = gtk_gesture_multi_press_new((widget is null) ? null : widget.getWidgetStruct()); 102 103 if(p is null) 104 { 105 throw new ConstructionException("null returned by new"); 106 } 107 108 this(cast(GtkGestureMultiPress*) p, true); 109 } 110 111 /** 112 * If an area was set through gtk_gesture_multi_press_set_area(), 113 * this function will return %TRUE and fill in @rect with the 114 * press area. See gtk_gesture_multi_press_set_area() for more 115 * details on what the press area represents. 116 * 117 * Params: 118 * rect = return location for the press area 119 * 120 * Returns: %TRUE if @rect was filled with the press area 121 * 122 * Since: 3.14 123 */ 124 public bool getArea(out GdkRectangle rect) 125 { 126 return gtk_gesture_multi_press_get_area(gtkGestureMultiPress, &rect) != 0; 127 } 128 129 /** 130 * If @rect is non-%NULL, the press area will be checked to be 131 * confined within the rectangle, otherwise the button count 132 * will be reset so the press is seen as being the first one. 133 * If @rect is #NULL, the area will be reset to an unrestricted 134 * state. 135 * 136 * Note: The rectangle is only used to determine whether any 137 * non-first click falls within the expected area. This is not 138 * akin to an input shape. 139 * 140 * Params: 141 * rect = rectangle to receive coordinates on 142 * 143 * Since: 3.14 144 */ 145 public void setArea(GdkRectangle* rect) 146 { 147 gtk_gesture_multi_press_set_area(gtkGestureMultiPress, rect); 148 } 149 150 protected class OnPressedDelegateWrapper 151 { 152 void delegate(int, double, double, GestureMultiPress) dlg; 153 gulong handlerId; 154 155 this(void delegate(int, double, double, GestureMultiPress) dlg) 156 { 157 this.dlg = dlg; 158 onPressedListeners ~= this; 159 } 160 161 void remove(OnPressedDelegateWrapper source) 162 { 163 foreach(index, wrapper; onPressedListeners) 164 { 165 if (wrapper.handlerId == source.handlerId) 166 { 167 onPressedListeners[index] = null; 168 onPressedListeners = std.algorithm.remove(onPressedListeners, index); 169 break; 170 } 171 } 172 } 173 } 174 OnPressedDelegateWrapper[] onPressedListeners; 175 176 /** 177 * This signal is emitted whenever a button or touch press happens. 178 * 179 * Params: 180 * nPress = how many touch/button presses happened with this one 181 * x = The X coordinate, in widget allocation coordinates 182 * y = The Y coordinate, in widget allocation coordinates 183 * 184 * Since: 3.14 185 */ 186 gulong addOnPressed(void delegate(int, double, double, GestureMultiPress) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 187 { 188 auto wrapper = new OnPressedDelegateWrapper(dlg); 189 wrapper.handlerId = Signals.connectData( 190 this, 191 "pressed", 192 cast(GCallback)&callBackPressed, 193 cast(void*)wrapper, 194 cast(GClosureNotify)&callBackPressedDestroy, 195 connectFlags); 196 return wrapper.handlerId; 197 } 198 199 extern(C) static void callBackPressed(GtkGestureMultiPress* gesturemultipressStruct, int nPress, double x, double y, OnPressedDelegateWrapper wrapper) 200 { 201 wrapper.dlg(nPress, x, y, wrapper.outer); 202 } 203 204 extern(C) static void callBackPressedDestroy(OnPressedDelegateWrapper wrapper, GClosure* closure) 205 { 206 wrapper.remove(wrapper); 207 } 208 209 protected class OnReleasedDelegateWrapper 210 { 211 void delegate(int, double, double, GestureMultiPress) dlg; 212 gulong handlerId; 213 214 this(void delegate(int, double, double, GestureMultiPress) dlg) 215 { 216 this.dlg = dlg; 217 onReleasedListeners ~= this; 218 } 219 220 void remove(OnReleasedDelegateWrapper source) 221 { 222 foreach(index, wrapper; onReleasedListeners) 223 { 224 if (wrapper.handlerId == source.handlerId) 225 { 226 onReleasedListeners[index] = null; 227 onReleasedListeners = std.algorithm.remove(onReleasedListeners, index); 228 break; 229 } 230 } 231 } 232 } 233 OnReleasedDelegateWrapper[] onReleasedListeners; 234 235 /** 236 * This signal is emitted when a button or touch is released. @n_press 237 * will report the number of press that is paired to this event, note 238 * that #GtkGestureMultiPress::stopped may have been emitted between the 239 * press and its release, @n_press will only start over at the next press. 240 * 241 * Params: 242 * nPress = number of press that is paired with this release 243 * x = The X coordinate, in widget allocation coordinates 244 * y = The Y coordinate, in widget allocation coordinates 245 * 246 * Since: 3.14 247 */ 248 gulong addOnReleased(void delegate(int, double, double, GestureMultiPress) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 249 { 250 auto wrapper = new OnReleasedDelegateWrapper(dlg); 251 wrapper.handlerId = Signals.connectData( 252 this, 253 "released", 254 cast(GCallback)&callBackReleased, 255 cast(void*)wrapper, 256 cast(GClosureNotify)&callBackReleasedDestroy, 257 connectFlags); 258 return wrapper.handlerId; 259 } 260 261 extern(C) static void callBackReleased(GtkGestureMultiPress* gesturemultipressStruct, int nPress, double x, double y, OnReleasedDelegateWrapper wrapper) 262 { 263 wrapper.dlg(nPress, x, y, wrapper.outer); 264 } 265 266 extern(C) static void callBackReleasedDestroy(OnReleasedDelegateWrapper wrapper, GClosure* closure) 267 { 268 wrapper.remove(wrapper); 269 } 270 271 protected class OnStoppedDelegateWrapper 272 { 273 void delegate(GestureMultiPress) dlg; 274 gulong handlerId; 275 276 this(void delegate(GestureMultiPress) dlg) 277 { 278 this.dlg = dlg; 279 onStoppedListeners ~= this; 280 } 281 282 void remove(OnStoppedDelegateWrapper source) 283 { 284 foreach(index, wrapper; onStoppedListeners) 285 { 286 if (wrapper.handlerId == source.handlerId) 287 { 288 onStoppedListeners[index] = null; 289 onStoppedListeners = std.algorithm.remove(onStoppedListeners, index); 290 break; 291 } 292 } 293 } 294 } 295 OnStoppedDelegateWrapper[] onStoppedListeners; 296 297 /** 298 * This signal is emitted whenever any time/distance threshold has 299 * been exceeded. 300 * 301 * Since: 3.14 302 */ 303 gulong addOnStopped(void delegate(GestureMultiPress) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 304 { 305 auto wrapper = new OnStoppedDelegateWrapper(dlg); 306 wrapper.handlerId = Signals.connectData( 307 this, 308 "stopped", 309 cast(GCallback)&callBackStopped, 310 cast(void*)wrapper, 311 cast(GClosureNotify)&callBackStoppedDestroy, 312 connectFlags); 313 return wrapper.handlerId; 314 } 315 316 extern(C) static void callBackStopped(GtkGestureMultiPress* gesturemultipressStruct, OnStoppedDelegateWrapper wrapper) 317 { 318 wrapper.dlg(wrapper.outer); 319 } 320 321 extern(C) static void callBackStoppedDestroy(OnStoppedDelegateWrapper wrapper, GClosure* closure) 322 { 323 wrapper.remove(wrapper); 324 } 325 }