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 protected override void setStruct(GObject* obj) 71 { 72 gtkGestureMultiPress = cast(GtkGestureMultiPress*)obj; 73 super.setStruct(obj); 74 } 75 76 /** 77 * Sets our main struct and passes it to the parent class. 78 */ 79 public this (GtkGestureMultiPress* gtkGestureMultiPress, bool ownedRef = false) 80 { 81 this.gtkGestureMultiPress = gtkGestureMultiPress; 82 super(cast(GtkGestureSingle*)gtkGestureMultiPress, ownedRef); 83 } 84 85 86 /** */ 87 public static GType getType() 88 { 89 return gtk_gesture_multi_press_get_type(); 90 } 91 92 /** 93 * Returns a newly created #GtkGesture that recognizes single and multiple 94 * presses. 95 * 96 * Params: 97 * widget = a #GtkWidget 98 * 99 * Returns: a newly created #GtkGestureMultiPress 100 * 101 * Since: 3.14 102 * 103 * Throws: ConstructionException GTK+ fails to create the object. 104 */ 105 public this(Widget widget) 106 { 107 auto p = gtk_gesture_multi_press_new((widget is null) ? null : widget.getWidgetStruct()); 108 109 if(p is null) 110 { 111 throw new ConstructionException("null returned by new"); 112 } 113 114 this(cast(GtkGestureMultiPress*) p, true); 115 } 116 117 /** 118 * If an area was set through gtk_gesture_multi_press_set_area(), 119 * this function will return %TRUE and fill in @rect with the 120 * press area. See gtk_gesture_multi_press_set_area() for more 121 * details on what the press area represents. 122 * 123 * Params: 124 * rect = return location for the press area 125 * 126 * Returns: %TRUE if @rect was filled with the press area 127 * 128 * Since: 3.14 129 */ 130 public bool getArea(out GdkRectangle rect) 131 { 132 return gtk_gesture_multi_press_get_area(gtkGestureMultiPress, &rect) != 0; 133 } 134 135 /** 136 * If @rect is non-%NULL, the press area will be checked to be 137 * confined within the rectangle, otherwise the button count 138 * will be reset so the press is seen as being the first one. 139 * If @rect is #NULL, the area will be reset to an unrestricted 140 * state. 141 * 142 * Note: The rectangle is only used to determine whether any 143 * non-first click falls within the expected area. This is not 144 * akin to an input shape. 145 * 146 * Params: 147 * rect = rectangle to receive coordinates on 148 * 149 * Since: 3.14 150 */ 151 public void setArea(GdkRectangle* rect) 152 { 153 gtk_gesture_multi_press_set_area(gtkGestureMultiPress, rect); 154 } 155 156 protected class OnPressedDelegateWrapper 157 { 158 void delegate(int, double, double, GestureMultiPress) dlg; 159 gulong handlerId; 160 161 this(void delegate(int, double, double, GestureMultiPress) dlg) 162 { 163 this.dlg = dlg; 164 onPressedListeners ~= this; 165 } 166 167 void remove(OnPressedDelegateWrapper source) 168 { 169 foreach(index, wrapper; onPressedListeners) 170 { 171 if (wrapper.handlerId == source.handlerId) 172 { 173 onPressedListeners[index] = null; 174 onPressedListeners = std.algorithm.remove(onPressedListeners, index); 175 break; 176 } 177 } 178 } 179 } 180 OnPressedDelegateWrapper[] onPressedListeners; 181 182 /** 183 * This signal is emitted whenever a button or touch press happens. 184 * 185 * Params: 186 * nPress = how many touch/button presses happened with this one 187 * x = The X coordinate, in widget allocation coordinates 188 * y = The Y coordinate, in widget allocation coordinates 189 * 190 * Since: 3.14 191 */ 192 gulong addOnPressed(void delegate(int, double, double, GestureMultiPress) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 193 { 194 auto wrapper = new OnPressedDelegateWrapper(dlg); 195 wrapper.handlerId = Signals.connectData( 196 this, 197 "pressed", 198 cast(GCallback)&callBackPressed, 199 cast(void*)wrapper, 200 cast(GClosureNotify)&callBackPressedDestroy, 201 connectFlags); 202 return wrapper.handlerId; 203 } 204 205 extern(C) static void callBackPressed(GtkGestureMultiPress* gesturemultipressStruct, int nPress, double x, double y, OnPressedDelegateWrapper wrapper) 206 { 207 wrapper.dlg(nPress, x, y, wrapper.outer); 208 } 209 210 extern(C) static void callBackPressedDestroy(OnPressedDelegateWrapper wrapper, GClosure* closure) 211 { 212 wrapper.remove(wrapper); 213 } 214 215 protected class OnReleasedDelegateWrapper 216 { 217 void delegate(int, double, double, GestureMultiPress) dlg; 218 gulong handlerId; 219 220 this(void delegate(int, double, double, GestureMultiPress) dlg) 221 { 222 this.dlg = dlg; 223 onReleasedListeners ~= this; 224 } 225 226 void remove(OnReleasedDelegateWrapper source) 227 { 228 foreach(index, wrapper; onReleasedListeners) 229 { 230 if (wrapper.handlerId == source.handlerId) 231 { 232 onReleasedListeners[index] = null; 233 onReleasedListeners = std.algorithm.remove(onReleasedListeners, index); 234 break; 235 } 236 } 237 } 238 } 239 OnReleasedDelegateWrapper[] onReleasedListeners; 240 241 /** 242 * This signal is emitted when a button or touch is released. @n_press 243 * will report the number of press that is paired to this event, note 244 * that #GtkGestureMultiPress::stopped may have been emitted between the 245 * press and its release, @n_press will only start over at the next press. 246 * 247 * Params: 248 * nPress = number of press that is paired with this release 249 * x = The X coordinate, in widget allocation coordinates 250 * y = The Y coordinate, in widget allocation coordinates 251 * 252 * Since: 3.14 253 */ 254 gulong addOnReleased(void delegate(int, double, double, GestureMultiPress) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 255 { 256 auto wrapper = new OnReleasedDelegateWrapper(dlg); 257 wrapper.handlerId = Signals.connectData( 258 this, 259 "released", 260 cast(GCallback)&callBackReleased, 261 cast(void*)wrapper, 262 cast(GClosureNotify)&callBackReleasedDestroy, 263 connectFlags); 264 return wrapper.handlerId; 265 } 266 267 extern(C) static void callBackReleased(GtkGestureMultiPress* gesturemultipressStruct, int nPress, double x, double y, OnReleasedDelegateWrapper wrapper) 268 { 269 wrapper.dlg(nPress, x, y, wrapper.outer); 270 } 271 272 extern(C) static void callBackReleasedDestroy(OnReleasedDelegateWrapper wrapper, GClosure* closure) 273 { 274 wrapper.remove(wrapper); 275 } 276 277 protected class OnStoppedDelegateWrapper 278 { 279 void delegate(GestureMultiPress) dlg; 280 gulong handlerId; 281 282 this(void delegate(GestureMultiPress) dlg) 283 { 284 this.dlg = dlg; 285 onStoppedListeners ~= this; 286 } 287 288 void remove(OnStoppedDelegateWrapper source) 289 { 290 foreach(index, wrapper; onStoppedListeners) 291 { 292 if (wrapper.handlerId == source.handlerId) 293 { 294 onStoppedListeners[index] = null; 295 onStoppedListeners = std.algorithm.remove(onStoppedListeners, index); 296 break; 297 } 298 } 299 } 300 } 301 OnStoppedDelegateWrapper[] onStoppedListeners; 302 303 /** 304 * This signal is emitted whenever any time/distance threshold has 305 * been exceeded. 306 * 307 * Since: 3.14 308 */ 309 gulong addOnStopped(void delegate(GestureMultiPress) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 310 { 311 auto wrapper = new OnStoppedDelegateWrapper(dlg); 312 wrapper.handlerId = Signals.connectData( 313 this, 314 "stopped", 315 cast(GCallback)&callBackStopped, 316 cast(void*)wrapper, 317 cast(GClosureNotify)&callBackStoppedDestroy, 318 connectFlags); 319 return wrapper.handlerId; 320 } 321 322 extern(C) static void callBackStopped(GtkGestureMultiPress* gesturemultipressStruct, OnStoppedDelegateWrapper wrapper) 323 { 324 wrapper.dlg(wrapper.outer); 325 } 326 327 extern(C) static void callBackStoppedDestroy(OnStoppedDelegateWrapper wrapper, GClosure* closure) 328 { 329 wrapper.remove(wrapper); 330 } 331 }