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.Popover; 26 27 private import gio.MenuModel; 28 private import glib.ConstructionException; 29 private import glib.Str; 30 private import gobject.ObjectG; 31 private import gobject.Signals; 32 private import gtk.Bin; 33 private import gtk.Widget; 34 public import gtkc.gdktypes; 35 private import gtkc.gtk; 36 public import gtkc.gtktypes; 37 private import std.algorithm; 38 39 40 /** 41 * GtkPopover is a bubble-like context window, primarily meant to 42 * provide context-dependent information or options. Popovers are 43 * attached to a widget, passed at construction time on gtk_popover_new(), 44 * or updated afterwards through gtk_popover_set_relative_to(), by 45 * default they will point to the whole widget area, although this 46 * behavior can be changed through gtk_popover_set_pointing_to(). 47 * 48 * The position of a popover relative to the widget it is attached to 49 * can also be changed through gtk_popover_set_position(). 50 * 51 * By default, #GtkPopover performs a GTK+ grab, in order to ensure 52 * input events get redirected to it while it is shown, and also so 53 * the popover is dismissed in the expected situations (clicks outside 54 * the popover, or the Esc key being pressed). If no such modal behavior 55 * is desired on a popover, gtk_popover_set_modal() may be called on it 56 * to tweak its behavior. 57 * 58 * ## GtkPopover as menu replacement 59 * 60 * GtkPopover is often used to replace menus. To facilitate this, it 61 * supports being populated from a #GMenuModel, using 62 * gtk_popover_new_from_model(). In addition to all the regular menu 63 * model features, this function supports rendering sections in the 64 * model in a more compact form, as a row of icon buttons instead of 65 * menu items. 66 * 67 * To use this rendering, set the ”display-hint” attribute of the 68 * section to ”horizontal-buttons” and set the icons of your items 69 * with the ”verb-icon” attribute. 70 * 71 * |[ 72 * <section> 73 * <attribute name="display-hint">horizontal-buttons</attribute> 74 * <item> 75 * <attribute name="label">Cut</attribute> 76 * <attribute name="action">app.cut</attribute> 77 * <attribute name="verb-icon">edit-cut-symbolic</attribute> 78 * </item> 79 * <item> 80 * <attribute name="label">Copy</attribute> 81 * <attribute name="action">app.copy</attribute> 82 * <attribute name="verb-icon">edit-copy-symbolic</attribute> 83 * </item> 84 * <item> 85 * <attribute name="label">Paste</attribute> 86 * <attribute name="action">app.paste</attribute> 87 * <attribute name="verb-icon">edit-paste-symbolic</attribute> 88 * </item> 89 * </section> 90 * ]| 91 * 92 * # CSS nodes 93 * 94 * GtkPopover has a single css node called popover. It always gets the 95 * .background style class and it gets the .menu style class if it is 96 * menu-like (e.g. #GtkPopoverMenu or created using gtk_popover_new_from_model(). 97 * 98 * Particular uses of GtkPopover, such as touch selection popups 99 * or magnifiers in #GtkEntry or #GtkTextView get style classes 100 * like .touch-selection or .magnifier to differentiate from 101 * plain popovers. 102 */ 103 public class Popover : Bin 104 { 105 /** the main Gtk struct */ 106 protected GtkPopover* gtkPopover; 107 108 /** Get the main Gtk struct */ 109 public GtkPopover* getPopoverStruct() 110 { 111 return gtkPopover; 112 } 113 114 /** the main Gtk struct as a void* */ 115 protected override void* getStruct() 116 { 117 return cast(void*)gtkPopover; 118 } 119 120 protected override void setStruct(GObject* obj) 121 { 122 gtkPopover = cast(GtkPopover*)obj; 123 super.setStruct(obj); 124 } 125 126 /** 127 * Sets our main struct and passes it to the parent class. 128 */ 129 public this (GtkPopover* gtkPopover, bool ownedRef = false) 130 { 131 this.gtkPopover = gtkPopover; 132 super(cast(GtkBin*)gtkPopover, ownedRef); 133 } 134 135 136 /** */ 137 public static GType getType() 138 { 139 return gtk_popover_get_type(); 140 } 141 142 /** 143 * Creates a new popover to point to @relative_to 144 * 145 * Params: 146 * relativeTo = #GtkWidget the popover is related to 147 * 148 * Return: a new #GtkPopover 149 * 150 * Since: 3.12 151 * 152 * Throws: ConstructionException GTK+ fails to create the object. 153 */ 154 public this(Widget relativeTo) 155 { 156 auto p = gtk_popover_new((relativeTo is null) ? null : relativeTo.getWidgetStruct()); 157 158 if(p is null) 159 { 160 throw new ConstructionException("null returned by new"); 161 } 162 163 this(cast(GtkPopover*) p); 164 } 165 166 /** 167 * Creates a #GtkPopover and populates it according to 168 * @model. The popover is pointed to the @relative_to widget. 169 * 170 * The created buttons are connected to actions found in the 171 * #GtkApplicationWindow to which the popover belongs - typically 172 * by means of being attached to a widget that is contained within 173 * the #GtkApplicationWindows widget hierarchy. 174 * 175 * Actions can also be added using gtk_widget_insert_action_group() 176 * on the menus attach widget or on any of its parent widgets. 177 * 178 * Params: 179 * relativeTo = #GtkWidget the popover is related to 180 * model = a #GMenuModel 181 * 182 * Return: the new #GtkPopover 183 * 184 * Since: 3.12 185 * 186 * Throws: ConstructionException GTK+ fails to create the object. 187 */ 188 public this(Widget relativeTo, MenuModel model) 189 { 190 auto p = gtk_popover_new_from_model((relativeTo is null) ? null : relativeTo.getWidgetStruct(), (model is null) ? null : model.getMenuModelStruct()); 191 192 if(p is null) 193 { 194 throw new ConstructionException("null returned by new_from_model"); 195 } 196 197 this(cast(GtkPopover*) p); 198 } 199 200 /** 201 * Establishes a binding between a #GtkPopover and a #GMenuModel. 202 * 203 * The contents of @popover are removed and then refilled with menu items 204 * according to @model. When @model changes, @popover is updated. 205 * Calling this function twice on @popover with different @model will 206 * cause the first binding to be replaced with a binding to the new 207 * model. If @model is %NULL then any previous binding is undone and 208 * all children are removed. 209 * 210 * If @action_namespace is non-%NULL then the effect is as if all 211 * actions mentioned in the @model have their names prefixed with the 212 * namespace, plus a dot. For example, if the action “quit” is 213 * mentioned and @action_namespace is “app” then the effective action 214 * name is “app.quit”. 215 * 216 * This function uses #GtkActionable to define the action name and 217 * target values on the created menu items. If you want to use an 218 * action group other than “app” and “win”, or if you want to use a 219 * #GtkMenuShell outside of a #GtkApplicationWindow, then you will need 220 * to attach your own action group to the widget hierarchy using 221 * gtk_widget_insert_action_group(). As an example, if you created a 222 * group with a “quit” action and inserted it with the name “mygroup” 223 * then you would use the action name “mygroup.quit” in your 224 * #GMenuModel. 225 * 226 * Params: 227 * model = the #GMenuModel to bind to or %NULL to remove 228 * binding 229 * actionNamespace = the namespace for actions in @model 230 * 231 * Since: 3.12 232 */ 233 public void bindModel(MenuModel model, string actionNamespace) 234 { 235 gtk_popover_bind_model(gtkPopover, (model is null) ? null : model.getMenuModelStruct(), Str.toStringz(actionNamespace)); 236 } 237 238 /** 239 * Returns the constraint for placing this popover. 240 * See gtk_popover_set_constrain_to(). 241 * 242 * Return: the constraint for placing this popover. 243 * 244 * Since: 3.20 245 */ 246 public GtkPopoverConstraint getConstrainTo() 247 { 248 return gtk_popover_get_constrain_to(gtkPopover); 249 } 250 251 /** 252 * Gets the widget that should be set as the default while 253 * the popover is shown. 254 * 255 * Return: the default widget, 256 * or %NULL if there is none 257 * 258 * Since: 3.18 259 */ 260 public Widget getDefaultWidget() 261 { 262 auto p = gtk_popover_get_default_widget(gtkPopover); 263 264 if(p is null) 265 { 266 return null; 267 } 268 269 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 270 } 271 272 /** 273 * Returns whether the popover is modal, see gtk_popover_set_modal to 274 * see the implications of this. 275 * 276 * Return: #TRUE if @popover is modal 277 * 278 * Since: 3.12 279 */ 280 public bool getModal() 281 { 282 return gtk_popover_get_modal(gtkPopover) != 0; 283 } 284 285 /** 286 * If a rectangle to point to has been set, this function will 287 * return %TRUE and fill in @rect with such rectangle, otherwise 288 * it will return %FALSE and fill in @rect with the attached 289 * widget coordinates. 290 * 291 * Params: 292 * rect = location to store the rectangle 293 * 294 * Return: %TRUE if a rectangle to point to was set. 295 */ 296 public bool getPointingTo(out GdkRectangle rect) 297 { 298 return gtk_popover_get_pointing_to(gtkPopover, &rect) != 0; 299 } 300 301 /** 302 * Returns the preferred position of @popover. 303 * 304 * Return: The preferred position. 305 */ 306 public GtkPositionType getPosition() 307 { 308 return gtk_popover_get_position(gtkPopover); 309 } 310 311 /** 312 * Returns the widget @popover is currently attached to 313 * 314 * Return: a #GtkWidget 315 * 316 * Since: 3.12 317 */ 318 public Widget getRelativeTo() 319 { 320 auto p = gtk_popover_get_relative_to(gtkPopover); 321 322 if(p is null) 323 { 324 return null; 325 } 326 327 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 328 } 329 330 /** 331 * Returns whether show/hide transitions are enabled on this popover. 332 * 333 * Deprecated: You can show or hide the popover without transitions 334 * using gtk_widget_show() and gtk_widget_hide() while gtk_popover_popup() 335 * and gtk_popover_popdown() will use transitions. 336 * 337 * Return: #TRUE if the show and hide transitions of the given 338 * popover are enabled, #FALSE otherwise. 339 * 340 * Since: 3.16 341 */ 342 public bool getTransitionsEnabled() 343 { 344 return gtk_popover_get_transitions_enabled(gtkPopover) != 0; 345 } 346 347 /** 348 * Pops @popover down.This is different than a gtk_widget_hide() call 349 * in that it shows the popover with a transition. If you want to hide 350 * the popover without a transition, use gtk_widget_hide(). 351 * 352 * Since: 3.22 353 */ 354 public void popdown() 355 { 356 gtk_popover_popdown(gtkPopover); 357 } 358 359 /** 360 * Pops @popover up. This is different than a gtk_widget_show() call 361 * in that it shows the popover with a transition. If you want to show 362 * the popover without a transition, use gtk_widget_show(). 363 * 364 * Since: 3.22 365 */ 366 public void popup() 367 { 368 gtk_popover_popup(gtkPopover); 369 } 370 371 /** 372 * Sets a constraint for positioning this popover. 373 * 374 * Note that not all platforms support placing popovers freely, 375 * and may already impose constraints. 376 * 377 * Params: 378 * constraint = the new constraint 379 * 380 * Since: 3.20 381 */ 382 public void setConstrainTo(GtkPopoverConstraint constraint) 383 { 384 gtk_popover_set_constrain_to(gtkPopover, constraint); 385 } 386 387 /** 388 * Sets the widget that should be set as default widget while 389 * the popover is shown (see gtk_window_set_default()). #GtkPopover 390 * remembers the previous default widget and reestablishes it 391 * when the popover is dismissed. 392 * 393 * Params: 394 * widget = the new default widget, or %NULL 395 * 396 * Since: 3.18 397 */ 398 public void setDefaultWidget(Widget widget) 399 { 400 gtk_popover_set_default_widget(gtkPopover, (widget is null) ? null : widget.getWidgetStruct()); 401 } 402 403 /** 404 * Sets whether @popover is modal, a modal popover will grab all input 405 * within the toplevel and grab the keyboard focus on it when being 406 * displayed. Clicking outside the popover area or pressing Esc will 407 * dismiss the popover and ungrab input. 408 * 409 * Params: 410 * modal = #TRUE to make popover claim all input within the toplevel 411 * 412 * Since: 3.12 413 */ 414 public void setModal(bool modal) 415 { 416 gtk_popover_set_modal(gtkPopover, modal); 417 } 418 419 /** 420 * Sets the rectangle that @popover will point to, in the 421 * coordinate space of the widget @popover is attached to, 422 * see gtk_popover_set_relative_to(). 423 * 424 * Params: 425 * rect = rectangle to point to 426 * 427 * Since: 3.12 428 */ 429 public void setPointingTo(GdkRectangle* rect) 430 { 431 gtk_popover_set_pointing_to(gtkPopover, rect); 432 } 433 434 /** 435 * Sets the preferred position for @popover to appear. If the @popover 436 * is currently visible, it will be immediately updated. 437 * 438 * This preference will be respected where possible, although 439 * on lack of space (eg. if close to the window edges), the 440 * #GtkPopover may choose to appear on the opposite side 441 * 442 * Params: 443 * position = preferred popover position 444 * 445 * Since: 3.12 446 */ 447 public void setPosition(GtkPositionType position) 448 { 449 gtk_popover_set_position(gtkPopover, position); 450 } 451 452 /** 453 * Sets a new widget to be attached to @popover. If @popover is 454 * visible, the position will be updated. 455 * 456 * Note: the ownership of popovers is always given to their @relative_to 457 * widget, so if @relative_to is set to %NULL on an attached @popover, it 458 * will be detached from its previous widget, and consequently destroyed 459 * unless extra references are kept. 460 * 461 * Params: 462 * relativeTo = a #GtkWidget 463 * 464 * Since: 3.12 465 */ 466 public void setRelativeTo(Widget relativeTo) 467 { 468 gtk_popover_set_relative_to(gtkPopover, (relativeTo is null) ? null : relativeTo.getWidgetStruct()); 469 } 470 471 /** 472 * Sets whether show/hide transitions are enabled on this popover 473 * 474 * Deprecated: You can show or hide the popover without transitions 475 * using gtk_widget_show() and gtk_widget_hide() while gtk_popover_popup() 476 * and gtk_popover_popdown() will use transitions. 477 * 478 * Params: 479 * transitionsEnabled = Whether transitions are enabled 480 * 481 * Since: 3.16 482 */ 483 public void setTransitionsEnabled(bool transitionsEnabled) 484 { 485 gtk_popover_set_transitions_enabled(gtkPopover, transitionsEnabled); 486 } 487 488 protected class OnClosedDelegateWrapper 489 { 490 void delegate(Popover) dlg; 491 gulong handlerId; 492 ConnectFlags flags; 493 this(void delegate(Popover) dlg, gulong handlerId, ConnectFlags flags) 494 { 495 this.dlg = dlg; 496 this.handlerId = handlerId; 497 this.flags = flags; 498 } 499 } 500 protected OnClosedDelegateWrapper[] onClosedListeners; 501 502 /** */ 503 gulong addOnClosed(void delegate(Popover) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 504 { 505 onClosedListeners ~= new OnClosedDelegateWrapper(dlg, 0, connectFlags); 506 onClosedListeners[onClosedListeners.length - 1].handlerId = Signals.connectData( 507 this, 508 "closed", 509 cast(GCallback)&callBackClosed, 510 cast(void*)onClosedListeners[onClosedListeners.length - 1], 511 cast(GClosureNotify)&callBackClosedDestroy, 512 connectFlags); 513 return onClosedListeners[onClosedListeners.length - 1].handlerId; 514 } 515 516 extern(C) static void callBackClosed(GtkPopover* popoverStruct,OnClosedDelegateWrapper wrapper) 517 { 518 wrapper.dlg(wrapper.outer); 519 } 520 521 extern(C) static void callBackClosedDestroy(OnClosedDelegateWrapper wrapper, GClosure* closure) 522 { 523 wrapper.outer.internalRemoveOnClosed(wrapper); 524 } 525 526 protected void internalRemoveOnClosed(OnClosedDelegateWrapper source) 527 { 528 foreach(index, wrapper; onClosedListeners) 529 { 530 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 531 { 532 onClosedListeners[index] = null; 533 onClosedListeners = std.algorithm.remove(onClosedListeners, index); 534 break; 535 } 536 } 537 } 538 539 }