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.SearchEntry; 26 27 private import gdk.Event; 28 private import glib.ConstructionException; 29 private import gobject.ObjectG; 30 private import gobject.Signals; 31 private import gtk.Entry; 32 private import gtk.Widget; 33 public import gtkc.gdktypes; 34 private import gtkc.gtk; 35 public import gtkc.gtktypes; 36 private import std.algorithm; 37 38 39 /** 40 * #GtkSearchEntry is a subclass of #GtkEntry that has been 41 * tailored for use as a search entry. 42 * 43 * It will show an inactive symbolic “find” icon when the search 44 * entry is empty, and a symbolic “clear” icon when there is text. 45 * Clicking on the “clear” icon will empty the search entry. 46 * 47 * Note that the search/clear icon is shown using a secondary 48 * icon, and thus does not work if you are using the secondary 49 * icon position for some other purpose. 50 * 51 * To make filtering appear more reactive, it is a good idea to 52 * not react to every change in the entry text immediately, but 53 * only after a short delay. To support this, #GtkSearchEntry 54 * emits the #GtkSearchEntry::search-changed signal which can 55 * be used instead of the #GtkEditable::changed signal. 56 * 57 * The #GtkSearchEntry::previous-match, #GtkSearchEntry::next-match 58 * and #GtkSearchEntry::stop-search signals can be uesd to implement 59 * moving between search results and ending the search. 60 * 61 * Often, GtkSearchEntry will be fed events by means of being 62 * placed inside a #GtkSearchBar. If that is not the case, 63 * you can use gtk_search_entry_handle_event() to pass events. 64 */ 65 public class SearchEntry : Entry 66 { 67 /** the main Gtk struct */ 68 protected GtkSearchEntry* gtkSearchEntry; 69 70 /** Get the main Gtk struct */ 71 public GtkSearchEntry* getSearchEntryStruct() 72 { 73 return gtkSearchEntry; 74 } 75 76 /** the main Gtk struct as a void* */ 77 protected override void* getStruct() 78 { 79 return cast(void*)gtkSearchEntry; 80 } 81 82 protected override void setStruct(GObject* obj) 83 { 84 gtkSearchEntry = cast(GtkSearchEntry*)obj; 85 super.setStruct(obj); 86 } 87 88 /** 89 * Sets our main struct and passes it to the parent class. 90 */ 91 public this (GtkSearchEntry* gtkSearchEntry, bool ownedRef = false) 92 { 93 this.gtkSearchEntry = gtkSearchEntry; 94 super(cast(GtkEntry*)gtkSearchEntry, ownedRef); 95 } 96 97 98 /** */ 99 public static GType getType() 100 { 101 return gtk_search_entry_get_type(); 102 } 103 104 /** 105 * Creates a #GtkSearchEntry, with a find icon when the search field is 106 * empty, and a clear icon when it isn't. 107 * 108 * Return: a new #GtkSearchEntry 109 * 110 * Since: 3.6 111 * 112 * Throws: ConstructionException GTK+ fails to create the object. 113 */ 114 public this() 115 { 116 auto p = gtk_search_entry_new(); 117 118 if(p is null) 119 { 120 throw new ConstructionException("null returned by new"); 121 } 122 123 this(cast(GtkSearchEntry*) p); 124 } 125 126 /** 127 * This function should be called when the top-level window 128 * which contains the search entry received a key event. If 129 * the entry is part of a #GtkSearchBar, it is preferable 130 * to call gtk_search_bar_handle_event() instead, which will 131 * reveal the entry in addition to passing the event to this 132 * function. 133 * 134 * If the key event is handled by the search entry and starts 135 * or continues a search, %GDK_EVENT_STOP will be returned. 136 * The caller should ensure that the entry is shown in this 137 * case, and not propagate the event further. 138 * 139 * Params: 140 * event = a key event 141 * 142 * Return: %GDK_EVENT_STOP if the key press event resulted 143 * in a search beginning or continuing, %GDK_EVENT_PROPAGATE 144 * otherwise. 145 * 146 * Since: 3.16 147 */ 148 public bool handleEvent(Event event) 149 { 150 return gtk_search_entry_handle_event(gtkSearchEntry, (event is null) ? null : event.getEventStruct()) != 0; 151 } 152 153 protected class OnNextMatchDelegateWrapper 154 { 155 void delegate(SearchEntry) dlg; 156 gulong handlerId; 157 ConnectFlags flags; 158 this(void delegate(SearchEntry) dlg, gulong handlerId, ConnectFlags flags) 159 { 160 this.dlg = dlg; 161 this.handlerId = handlerId; 162 this.flags = flags; 163 } 164 } 165 protected OnNextMatchDelegateWrapper[] onNextMatchListeners; 166 167 /** 168 * The ::next-match signal is a [keybinding signal][GtkBindingSignal] 169 * which gets emitted when the user initiates a move to the next match 170 * for the current search string. 171 * 172 * Applications should connect to it, to implement moving between 173 * matches. 174 * 175 * The default bindings for this signal is Ctrl-g. 176 * 177 * Since: 3.16 178 */ 179 gulong addOnNextMatch(void delegate(SearchEntry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 180 { 181 onNextMatchListeners ~= new OnNextMatchDelegateWrapper(dlg, 0, connectFlags); 182 onNextMatchListeners[onNextMatchListeners.length - 1].handlerId = Signals.connectData( 183 this, 184 "next-match", 185 cast(GCallback)&callBackNextMatch, 186 cast(void*)onNextMatchListeners[onNextMatchListeners.length - 1], 187 cast(GClosureNotify)&callBackNextMatchDestroy, 188 connectFlags); 189 return onNextMatchListeners[onNextMatchListeners.length - 1].handlerId; 190 } 191 192 extern(C) static void callBackNextMatch(GtkSearchEntry* searchentryStruct,OnNextMatchDelegateWrapper wrapper) 193 { 194 wrapper.dlg(wrapper.outer); 195 } 196 197 extern(C) static void callBackNextMatchDestroy(OnNextMatchDelegateWrapper wrapper, GClosure* closure) 198 { 199 wrapper.outer.internalRemoveOnNextMatch(wrapper); 200 } 201 202 protected void internalRemoveOnNextMatch(OnNextMatchDelegateWrapper source) 203 { 204 foreach(index, wrapper; onNextMatchListeners) 205 { 206 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 207 { 208 onNextMatchListeners[index] = null; 209 onNextMatchListeners = std.algorithm.remove(onNextMatchListeners, index); 210 break; 211 } 212 } 213 } 214 215 216 protected class OnPreviousMatchDelegateWrapper 217 { 218 void delegate(SearchEntry) dlg; 219 gulong handlerId; 220 ConnectFlags flags; 221 this(void delegate(SearchEntry) dlg, gulong handlerId, ConnectFlags flags) 222 { 223 this.dlg = dlg; 224 this.handlerId = handlerId; 225 this.flags = flags; 226 } 227 } 228 protected OnPreviousMatchDelegateWrapper[] onPreviousMatchListeners; 229 230 /** 231 * The ::previous-match signal is a [keybinding signal][GtkBindingSignal] 232 * which gets emitted when the user initiates a move to the previous match 233 * for the current search string. 234 * 235 * Applications should connect to it, to implement moving between 236 * matches. 237 * 238 * The default bindings for this signal is Ctrl-Shift-g. 239 * 240 * Since: 3.16 241 */ 242 gulong addOnPreviousMatch(void delegate(SearchEntry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 243 { 244 onPreviousMatchListeners ~= new OnPreviousMatchDelegateWrapper(dlg, 0, connectFlags); 245 onPreviousMatchListeners[onPreviousMatchListeners.length - 1].handlerId = Signals.connectData( 246 this, 247 "previous-match", 248 cast(GCallback)&callBackPreviousMatch, 249 cast(void*)onPreviousMatchListeners[onPreviousMatchListeners.length - 1], 250 cast(GClosureNotify)&callBackPreviousMatchDestroy, 251 connectFlags); 252 return onPreviousMatchListeners[onPreviousMatchListeners.length - 1].handlerId; 253 } 254 255 extern(C) static void callBackPreviousMatch(GtkSearchEntry* searchentryStruct,OnPreviousMatchDelegateWrapper wrapper) 256 { 257 wrapper.dlg(wrapper.outer); 258 } 259 260 extern(C) static void callBackPreviousMatchDestroy(OnPreviousMatchDelegateWrapper wrapper, GClosure* closure) 261 { 262 wrapper.outer.internalRemoveOnPreviousMatch(wrapper); 263 } 264 265 protected void internalRemoveOnPreviousMatch(OnPreviousMatchDelegateWrapper source) 266 { 267 foreach(index, wrapper; onPreviousMatchListeners) 268 { 269 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 270 { 271 onPreviousMatchListeners[index] = null; 272 onPreviousMatchListeners = std.algorithm.remove(onPreviousMatchListeners, index); 273 break; 274 } 275 } 276 } 277 278 279 protected class OnSearchChangedDelegateWrapper 280 { 281 void delegate(SearchEntry) dlg; 282 gulong handlerId; 283 ConnectFlags flags; 284 this(void delegate(SearchEntry) dlg, gulong handlerId, ConnectFlags flags) 285 { 286 this.dlg = dlg; 287 this.handlerId = handlerId; 288 this.flags = flags; 289 } 290 } 291 protected OnSearchChangedDelegateWrapper[] onSearchChangedListeners; 292 293 /** 294 * The #GtkSearchEntry::search-changed signal is emitted with a short 295 * delay of 150 milliseconds after the last change to the entry text. 296 * 297 * Since: 3.10 298 */ 299 gulong addOnSearchChanged(void delegate(SearchEntry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 300 { 301 onSearchChangedListeners ~= new OnSearchChangedDelegateWrapper(dlg, 0, connectFlags); 302 onSearchChangedListeners[onSearchChangedListeners.length - 1].handlerId = Signals.connectData( 303 this, 304 "search-changed", 305 cast(GCallback)&callBackSearchChanged, 306 cast(void*)onSearchChangedListeners[onSearchChangedListeners.length - 1], 307 cast(GClosureNotify)&callBackSearchChangedDestroy, 308 connectFlags); 309 return onSearchChangedListeners[onSearchChangedListeners.length - 1].handlerId; 310 } 311 312 extern(C) static void callBackSearchChanged(GtkSearchEntry* searchentryStruct,OnSearchChangedDelegateWrapper wrapper) 313 { 314 wrapper.dlg(wrapper.outer); 315 } 316 317 extern(C) static void callBackSearchChangedDestroy(OnSearchChangedDelegateWrapper wrapper, GClosure* closure) 318 { 319 wrapper.outer.internalRemoveOnSearchChanged(wrapper); 320 } 321 322 protected void internalRemoveOnSearchChanged(OnSearchChangedDelegateWrapper source) 323 { 324 foreach(index, wrapper; onSearchChangedListeners) 325 { 326 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 327 { 328 onSearchChangedListeners[index] = null; 329 onSearchChangedListeners = std.algorithm.remove(onSearchChangedListeners, index); 330 break; 331 } 332 } 333 } 334 335 336 protected class OnStopSearchDelegateWrapper 337 { 338 void delegate(SearchEntry) dlg; 339 gulong handlerId; 340 ConnectFlags flags; 341 this(void delegate(SearchEntry) dlg, gulong handlerId, ConnectFlags flags) 342 { 343 this.dlg = dlg; 344 this.handlerId = handlerId; 345 this.flags = flags; 346 } 347 } 348 protected OnStopSearchDelegateWrapper[] onStopSearchListeners; 349 350 /** 351 * The ::stop-search signal is a [keybinding signal][GtkBindingSignal] 352 * which gets emitted when the user stops a search via keyboard input. 353 * 354 * Applications should connect to it, to implement hiding the search 355 * entry in this case. 356 * 357 * The default bindings for this signal is Escape. 358 * 359 * Since: 3.16 360 */ 361 gulong addOnStopSearch(void delegate(SearchEntry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 362 { 363 onStopSearchListeners ~= new OnStopSearchDelegateWrapper(dlg, 0, connectFlags); 364 onStopSearchListeners[onStopSearchListeners.length - 1].handlerId = Signals.connectData( 365 this, 366 "stop-search", 367 cast(GCallback)&callBackStopSearch, 368 cast(void*)onStopSearchListeners[onStopSearchListeners.length - 1], 369 cast(GClosureNotify)&callBackStopSearchDestroy, 370 connectFlags); 371 return onStopSearchListeners[onStopSearchListeners.length - 1].handlerId; 372 } 373 374 extern(C) static void callBackStopSearch(GtkSearchEntry* searchentryStruct,OnStopSearchDelegateWrapper wrapper) 375 { 376 wrapper.dlg(wrapper.outer); 377 } 378 379 extern(C) static void callBackStopSearchDestroy(OnStopSearchDelegateWrapper wrapper, GClosure* closure) 380 { 381 wrapper.outer.internalRemoveOnStopSearch(wrapper); 382 } 383 384 protected void internalRemoveOnStopSearch(OnStopSearchDelegateWrapper source) 385 { 386 foreach(index, wrapper; onStopSearchListeners) 387 { 388 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 389 { 390 onStopSearchListeners[index] = null; 391 onStopSearchListeners = std.algorithm.remove(onStopSearchListeners, index); 392 break; 393 } 394 } 395 } 396 397 }