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 gio.MenuModel; 26 27 private import gio.MenuAttributeIter; 28 private import gio.MenuLinkIter; 29 private import glib.Str; 30 private import glib.Variant; 31 private import glib.VariantType; 32 private import gobject.ObjectG; 33 private import gobject.Signals; 34 public import gtkc.gdktypes; 35 private import gtkc.gio; 36 public import gtkc.giotypes; 37 38 39 /** 40 * #GMenuModel represents the contents of a menu -- an ordered list of 41 * menu items. The items are associated with actions, which can be 42 * activated through them. Items can be grouped in sections, and may 43 * have submenus associated with them. Both items and sections usually 44 * have some representation data, such as labels or icons. The type of 45 * the associated action (ie whether it is stateful, and what kind of 46 * state it has) can influence the representation of the item. 47 * 48 * The conceptual model of menus in #GMenuModel is hierarchical: 49 * sections and submenus are again represented by #GMenuModels. 50 * Menus themselves do not define their own roles. Rather, the role 51 * of a particular #GMenuModel is defined by the item that references 52 * it (or, in the case of the 'root' menu, is defined by the context 53 * in which it is used). 54 * 55 * As an example, consider the visible portions of this menu: 56 * 57 * ## An example menu # {#menu-example} 58 * 59 * ![](menu-example.png) 60 * 61 * There are 8 "menus" visible in the screenshot: one menubar, two 62 * submenus and 5 sections: 63 * 64 * - the toplevel menubar (containing 4 items) 65 * - the View submenu (containing 3 sections) 66 * - the first section of the View submenu (containing 2 items) 67 * - the second section of the View submenu (containing 1 item) 68 * - the final section of the View submenu (containing 1 item) 69 * - the Highlight Mode submenu (containing 2 sections) 70 * - the Sources section (containing 2 items) 71 * - the Markup section (containing 2 items) 72 * 73 * The [example][menu-model] illustrates the conceptual connection between 74 * these 8 menus. Each large block in the figure represents a menu and the 75 * smaller blocks within the large block represent items in that menu. Some 76 * items contain references to other menus. 77 * 78 * ## A menu example # {#menu-model} 79 * 80 * ![](menu-model.png) 81 * 82 * Notice that the separators visible in the [example][menu-example] 83 * appear nowhere in the [menu model][menu-model]. This is because 84 * separators are not explicitly represented in the menu model. Instead, 85 * a separator is inserted between any two non-empty sections of a menu. 86 * Section items can have labels just like any other item. In that case, 87 * a display system may show a section header instead of a separator. 88 * 89 * The motivation for this abstract model of application controls is 90 * that modern user interfaces tend to make these controls available 91 * outside the application. Examples include global menus, jumplists, 92 * dash boards, etc. To support such uses, it is necessary to 'export' 93 * information about actions and their representation in menus, which 94 * is exactly what the [GActionGroup exporter][gio-GActionGroup-exporter] 95 * and the [GMenuModel exporter][gio-GMenuModel-exporter] do for 96 * #GActionGroup and #GMenuModel. The client-side counterparts to 97 * make use of the exported information are #GDBusActionGroup and 98 * #GDBusMenuModel. 99 * 100 * The API of #GMenuModel is very generic, with iterators for the 101 * attributes and links of an item, see g_menu_model_iterate_item_attributes() 102 * and g_menu_model_iterate_item_links(). The 'standard' attributes and 103 * link types have predefined names: %G_MENU_ATTRIBUTE_LABEL, 104 * %G_MENU_ATTRIBUTE_ACTION, %G_MENU_ATTRIBUTE_TARGET, %G_MENU_LINK_SECTION 105 * and %G_MENU_LINK_SUBMENU. 106 * 107 * Items in a #GMenuModel represent active controls if they refer to 108 * an action that can get activated when the user interacts with the 109 * menu item. The reference to the action is encoded by the string id 110 * in the %G_MENU_ATTRIBUTE_ACTION attribute. An action id uniquely 111 * identifies an action in an action group. Which action group(s) provide 112 * actions depends on the context in which the menu model is used. 113 * E.g. when the model is exported as the application menu of a 114 * #GtkApplication, actions can be application-wide or window-specific 115 * (and thus come from two different action groups). By convention, the 116 * application-wide actions have names that start with "app.", while the 117 * names of window-specific actions start with "win.". 118 * 119 * While a wide variety of stateful actions is possible, the following 120 * is the minimum that is expected to be supported by all users of exported 121 * menu information: 122 * - an action with no parameter type and no state 123 * - an action with no parameter type and boolean state 124 * - an action with string parameter type and string state 125 * 126 * ## Stateless 127 * 128 * A stateless action typically corresponds to an ordinary menu item. 129 * 130 * Selecting such a menu item will activate the action (with no parameter). 131 * 132 * ## Boolean State 133 * 134 * An action with a boolean state will most typically be used with a "toggle" 135 * or "switch" menu item. The state can be set directly, but activating the 136 * action (with no parameter) results in the state being toggled. 137 * 138 * Selecting a toggle menu item will activate the action. The menu item should 139 * be rendered as "checked" when the state is true. 140 * 141 * ## String Parameter and State 142 * 143 * Actions with string parameters and state will most typically be used to 144 * represent an enumerated choice over the items available for a group of 145 * radio menu items. Activating the action with a string parameter is 146 * equivalent to setting that parameter as the state. 147 * 148 * Radio menu items, in addition to being associated with the action, will 149 * have a target value. Selecting that menu item will result in activation 150 * of the action with the target value as the parameter. The menu item should 151 * be rendered as "selected" when the state of the action is equal to the 152 * target value of the menu item. 153 * 154 * Since: 2.32 155 */ 156 public class MenuModel : ObjectG 157 { 158 /** the main Gtk struct */ 159 protected GMenuModel* gMenuModel; 160 161 /** Get the main Gtk struct */ 162 public GMenuModel* getMenuModelStruct() 163 { 164 return gMenuModel; 165 } 166 167 /** the main Gtk struct as a void* */ 168 protected override void* getStruct() 169 { 170 return cast(void*)gMenuModel; 171 } 172 173 protected override void setStruct(GObject* obj) 174 { 175 gMenuModel = cast(GMenuModel*)obj; 176 super.setStruct(obj); 177 } 178 179 /** 180 * Sets our main struct and passes it to the parent class. 181 */ 182 public this (GMenuModel* gMenuModel, bool ownedRef = false) 183 { 184 this.gMenuModel = gMenuModel; 185 super(cast(GObject*)gMenuModel, ownedRef); 186 } 187 188 189 /** */ 190 public static GType getType() 191 { 192 return g_menu_model_get_type(); 193 } 194 195 /** 196 * Queries the item at position @item_index in @model for the attribute 197 * specified by @attribute. 198 * 199 * If @expected_type is non-%NULL then it specifies the expected type of 200 * the attribute. If it is %NULL then any type will be accepted. 201 * 202 * If the attribute exists and matches @expected_type (or if the 203 * expected type is unspecified) then the value is returned. 204 * 205 * If the attribute does not exist, or does not match the expected type 206 * then %NULL is returned. 207 * 208 * Params: 209 * itemIndex = the index of the item 210 * attribute = the attribute to query 211 * expectedType = the expected type of the attribute, or 212 * %NULL 213 * 214 * Return: the value of the attribute 215 * 216 * Since: 2.32 217 */ 218 public Variant getItemAttributeValue(int itemIndex, string attribute, VariantType expectedType) 219 { 220 auto p = g_menu_model_get_item_attribute_value(gMenuModel, itemIndex, Str.toStringz(attribute), (expectedType is null) ? null : expectedType.getVariantTypeStruct()); 221 222 if(p is null) 223 { 224 return null; 225 } 226 227 return new Variant(cast(GVariant*) p, true); 228 } 229 230 /** 231 * Queries the item at position @item_index in @model for the link 232 * specified by @link. 233 * 234 * If the link exists, the linked #GMenuModel is returned. If the link 235 * does not exist, %NULL is returned. 236 * 237 * Params: 238 * itemIndex = the index of the item 239 * link = the link to query 240 * 241 * Return: the linked #GMenuModel, or %NULL 242 * 243 * Since: 2.32 244 */ 245 public MenuModel getItemLink(int itemIndex, string link) 246 { 247 auto p = g_menu_model_get_item_link(gMenuModel, itemIndex, Str.toStringz(link)); 248 249 if(p is null) 250 { 251 return null; 252 } 253 254 return ObjectG.getDObject!(MenuModel)(cast(GMenuModel*) p, true); 255 } 256 257 /** 258 * Query the number of items in @model. 259 * 260 * Return: the number of items 261 * 262 * Since: 2.32 263 */ 264 public int getNItems() 265 { 266 return g_menu_model_get_n_items(gMenuModel); 267 } 268 269 /** 270 * Queries if @model is mutable. 271 * 272 * An immutable #GMenuModel will never emit the #GMenuModel::items-changed 273 * signal. Consumers of the model may make optimisations accordingly. 274 * 275 * Return: %TRUE if the model is mutable (ie: "items-changed" may be 276 * emitted). 277 * 278 * Since: 2.32 279 */ 280 public bool isMutable() 281 { 282 return g_menu_model_is_mutable(gMenuModel) != 0; 283 } 284 285 /** 286 * Requests emission of the #GMenuModel::items-changed signal on @model. 287 * 288 * This function should never be called except by #GMenuModel 289 * subclasses. Any other calls to this function will very likely lead 290 * to a violation of the interface of the model. 291 * 292 * The implementation should update its internal representation of the 293 * menu before emitting the signal. The implementation should further 294 * expect to receive queries about the new state of the menu (and 295 * particularly added menu items) while signal handlers are running. 296 * 297 * The implementation must dispatch this call directly from a mainloop 298 * entry and not in response to calls -- particularly those from the 299 * #GMenuModel API. Said another way: the menu must not change while 300 * user code is running without returning to the mainloop. 301 * 302 * Params: 303 * position = the position of the change 304 * removed = the number of items removed 305 * added = the number of items added 306 * 307 * Since: 2.32 308 */ 309 public void itemsChanged(int position, int removed, int added) 310 { 311 g_menu_model_items_changed(gMenuModel, position, removed, added); 312 } 313 314 /** 315 * Creates a #GMenuAttributeIter to iterate over the attributes of 316 * the item at position @item_index in @model. 317 * 318 * You must free the iterator with g_object_unref() when you are done. 319 * 320 * Params: 321 * itemIndex = the index of the item 322 * 323 * Return: a new #GMenuAttributeIter 324 * 325 * Since: 2.32 326 */ 327 public MenuAttributeIter iterateItemAttributes(int itemIndex) 328 { 329 auto p = g_menu_model_iterate_item_attributes(gMenuModel, itemIndex); 330 331 if(p is null) 332 { 333 return null; 334 } 335 336 return ObjectG.getDObject!(MenuAttributeIter)(cast(GMenuAttributeIter*) p, true); 337 } 338 339 /** 340 * Creates a #GMenuLinkIter to iterate over the links of the item at 341 * position @item_index in @model. 342 * 343 * You must free the iterator with g_object_unref() when you are done. 344 * 345 * Params: 346 * itemIndex = the index of the item 347 * 348 * Return: a new #GMenuLinkIter 349 * 350 * Since: 2.32 351 */ 352 public MenuLinkIter iterateItemLinks(int itemIndex) 353 { 354 auto p = g_menu_model_iterate_item_links(gMenuModel, itemIndex); 355 356 if(p is null) 357 { 358 return null; 359 } 360 361 return ObjectG.getDObject!(MenuLinkIter)(cast(GMenuLinkIter*) p, true); 362 } 363 364 int[string] connectedSignals; 365 366 void delegate(int, int, int, MenuModel)[] onItemsChangedListeners; 367 /** 368 * Emitted when a change has occured to the menu. 369 * 370 * The only changes that can occur to a menu is that items are removed 371 * or added. Items may not change (except by being removed and added 372 * back in the same location). This signal is capable of describing 373 * both of those changes (at the same time). 374 * 375 * The signal means that starting at the index @position, @removed 376 * items were removed and @added items were added in their place. If 377 * @removed is zero then only items were added. If @added is zero 378 * then only items were removed. 379 * 380 * As an example, if the menu contains items a, b, c, d (in that 381 * order) and the signal (2, 1, 3) occurs then the new composition of 382 * the menu will be a, b, _, _, _, d (with each _ representing some 383 * new item). 384 * 385 * Signal handlers may query the model (particularly the added items) 386 * and expect to see the results of the modification that is being 387 * reported. The signal is emitted after the modification. 388 * 389 * Params: 390 * position = the position of the change 391 * removed = the number of items removed 392 * added = the number of items added 393 */ 394 void addOnItemsChanged(void delegate(int, int, int, MenuModel) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 395 { 396 if ( "items-changed" !in connectedSignals ) 397 { 398 Signals.connectData( 399 this, 400 "items-changed", 401 cast(GCallback)&callBackItemsChanged, 402 cast(void*)this, 403 null, 404 connectFlags); 405 connectedSignals["items-changed"] = 1; 406 } 407 onItemsChangedListeners ~= dlg; 408 } 409 extern(C) static void callBackItemsChanged(GMenuModel* menumodelStruct, int position, int removed, int added, MenuModel _menumodel) 410 { 411 foreach ( void delegate(int, int, int, MenuModel) dlg; _menumodel.onItemsChangedListeners ) 412 { 413 dlg(position, removed, added, _menumodel); 414 } 415 } 416 }