gio/auto/menu_model.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, MenuAttributeIter, MenuLinkIter};
6use glib::{
7 object::ObjectType as _,
8 prelude::*,
9 signal::{connect_raw, SignalHandlerId},
10 translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15 /// `GMenuModel` represents the contents of a menu — an ordered list of
16 /// menu items. The items are associated with actions, which can be
17 /// activated through them. Items can be grouped in sections, and may
18 /// have submenus associated with them. Both items and sections usually
19 /// have some representation data, such as labels or icons. The type of
20 /// the associated action (ie whether it is stateful, and what kind of
21 /// state it has) can influence the representation of the item.
22 ///
23 /// The conceptual model of menus in `GMenuModel` is hierarchical:
24 /// sections and submenus are again represented by `GMenuModel`s.
25 /// Menus themselves do not define their own roles. Rather, the role
26 /// of a particular `GMenuModel` is defined by the item that references
27 /// it (or, in the case of the ‘root’ menu, is defined by the context
28 /// in which it is used).
29 ///
30 /// As an example, consider the visible portions of this menu:
31 ///
32 /// ## An example menu
33 ///
34 /// 
35 ///
36 /// While this kind of deeply nested menu is no longer considered good UI
37 /// practice, it serves as a good example of the concepts in `GMenuModel`.
38 /// There are 8 ‘menus’ visible in the screenshot: one menubar, two
39 /// submenus and 5 sections:
40 ///
41 /// - the toplevel menubar (containing 4 items)
42 /// - the View submenu (containing 3 sections)
43 /// - the first section of the View submenu (containing 2 items)
44 /// - the second section of the View submenu (containing 1 item)
45 /// - the final section of the View submenu (containing 1 item)
46 /// - the Highlight Mode submenu (containing 2 sections)
47 /// - the Sources section (containing 2 items)
48 /// - the Markup section (containing 2 items)
49 ///
50 /// The [example](#a-menu-example) illustrates the conceptual connection between
51 /// these 8 menus. Each large block in the figure represents a menu and the
52 /// smaller blocks within the large block represent items in that menu. Some
53 /// items contain references to other menus.
54 ///
55 /// ## A menu example
56 ///
57 /// <picture>
58 /// <source srcset="menu-model-dark.svg" media="(prefers-color-scheme: dark)">
59 /// <img src="menu-model-light.svg" alt="menu model">
60 /// </picture>
61 ///
62 /// Notice that the separators visible in the [example](#an-example-menu)
63 /// appear nowhere in the [menu model](#a-menu-example). This is because
64 /// separators are not explicitly represented in the menu model. Instead,
65 /// a separator is inserted between any two non-empty sections of a menu.
66 /// Section items can have labels just like any other item. In that case,
67 /// a display system may show a section header instead of a separator.
68 ///
69 /// The motivation for this abstract model of application controls is
70 /// that modern user interfaces tend to make these controls available
71 /// outside the application. Examples include global menus, jumplists,
72 /// dash boards, etc. To support such uses, it is necessary to ‘export’
73 /// information about actions and their representation in menus, which
74 /// is exactly what the action group exporter and the menu model exporter do for
75 /// [`ActionGroup`][crate::ActionGroup] and [`MenuModel`][crate::MenuModel]. The client-side
76 /// counterparts to make use of the exported information are
77 /// [`DBusActionGroup`][crate::DBusActionGroup] and [`DBusMenuModel`][crate::DBusMenuModel].
78 ///
79 /// The API of `GMenuModel` is very generic, with iterators for the
80 /// attributes and links of an item, see
81 /// [`MenuModelExt::iterate_item_attributes()`][crate::prelude::MenuModelExt::iterate_item_attributes()] and
82 /// [`MenuModelExt::iterate_item_links()`][crate::prelude::MenuModelExt::iterate_item_links()]. The ‘standard’ attributes and
83 /// link types have predefined names: `G_MENU_ATTRIBUTE_LABEL`,
84 /// `G_MENU_ATTRIBUTE_ACTION`, `G_MENU_ATTRIBUTE_TARGET`, `G_MENU_LINK_SECTION`
85 /// and `G_MENU_LINK_SUBMENU`.
86 ///
87 /// Items in a `GMenuModel` represent active controls if they refer to
88 /// an action that can get activated when the user interacts with the
89 /// menu item. The reference to the action is encoded by the string ID
90 /// in the `G_MENU_ATTRIBUTE_ACTION` attribute. An action ID uniquely
91 /// identifies an action in an action group. Which action group(s) provide
92 /// actions depends on the context in which the menu model is used.
93 /// E.g. when the model is exported as the application menu of a
94 /// [`GtkApplication`](https://docs.gtk.org/gtk4/class.Application.html),
95 /// actions can be application-wide or window-specific (and thus come from
96 /// two different action groups). By convention, the application-wide actions
97 /// have names that start with `app.`, while the names of window-specific
98 /// actions start with `win.`.
99 ///
100 /// While a wide variety of stateful actions is possible, the following
101 /// is the minimum that is expected to be supported by all users of exported
102 /// menu information:
103 /// - an action with no parameter type and no state
104 /// - an action with no parameter type and boolean state
105 /// - an action with string parameter type and string state
106 ///
107 /// ## Stateless
108 ///
109 /// A stateless action typically corresponds to an ordinary menu item.
110 ///
111 /// Selecting such a menu item will activate the action (with no parameter).
112 ///
113 /// ## Boolean State
114 ///
115 /// An action with a boolean state will most typically be used with a ‘toggle’
116 /// or ‘switch’ menu item. The state can be set directly, but activating the
117 /// action (with no parameter) results in the state being toggled.
118 ///
119 /// Selecting a toggle menu item will activate the action. The menu item should
120 /// be rendered as ‘checked’ when the state is true.
121 ///
122 /// ## String Parameter and State
123 ///
124 /// Actions with string parameters and state will most typically be used to
125 /// represent an enumerated choice over the items available for a group of
126 /// radio menu items. Activating the action with a string parameter is
127 /// equivalent to setting that parameter as the state.
128 ///
129 /// Radio menu items, in addition to being associated with the action, will
130 /// have a target value. Selecting that menu item will result in activation
131 /// of the action with the target value as the parameter. The menu item should
132 /// be rendered as ‘selected’ when the state of the action is equal to the
133 /// target value of the menu item.
134 ///
135 /// This is an Abstract Base Class, you cannot instantiate it.
136 ///
137 /// ## Signals
138 ///
139 ///
140 /// #### `items-changed`
141 /// Emitted when a change has occurred to the menu.
142 ///
143 /// The only changes that can occur to a menu is that items are removed
144 /// or added. Items may not change (except by being removed and added
145 /// back in the same location). This signal is capable of describing
146 /// both of those changes (at the same time).
147 ///
148 /// The signal means that starting at the index @position, @removed
149 /// items were removed and @added items were added in their place. If
150 /// @removed is zero then only items were added. If @added is zero
151 /// then only items were removed.
152 ///
153 /// As an example, if the menu contains items a, b, c, d (in that
154 /// order) and the signal (2, 1, 3) occurs then the new composition of
155 /// the menu will be a, b, _, _, _, d (with each _ representing some
156 /// new item).
157 ///
158 /// Signal handlers may query the model (particularly the added items)
159 /// and expect to see the results of the modification that is being
160 /// reported. The signal is emitted after the modification.
161 ///
162 ///
163 ///
164 /// # Implements
165 ///
166 /// [`MenuModelExt`][trait@crate::prelude::MenuModelExt], [`trait@glib::ObjectExt`]
167 #[doc(alias = "GMenuModel")]
168 pub struct MenuModel(Object<ffi::GMenuModel, ffi::GMenuModelClass>);
169
170 match fn {
171 type_ => || ffi::g_menu_model_get_type(),
172 }
173}
174
175impl MenuModel {
176 pub const NONE: Option<&'static MenuModel> = None;
177}
178
179mod sealed {
180 pub trait Sealed {}
181 impl<T: super::IsA<super::MenuModel>> Sealed for T {}
182}
183
184/// Trait containing all [`struct@MenuModel`] methods.
185///
186/// # Implementors
187///
188/// [`DBusMenuModel`][struct@crate::DBusMenuModel], [`MenuModel`][struct@crate::MenuModel], [`Menu`][struct@crate::Menu]
189pub trait MenuModelExt: IsA<MenuModel> + sealed::Sealed + 'static {
190 //#[doc(alias = "g_menu_model_get_item_attribute")]
191 //#[doc(alias = "get_item_attribute")]
192 //fn is_item_attribute(&self, item_index: i32, attribute: &str, format_string: &str, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) -> bool {
193 // unsafe { TODO: call ffi:g_menu_model_get_item_attribute() }
194 //}
195
196 /// Queries the item at position @item_index in @self for the attribute
197 /// specified by @attribute.
198 ///
199 /// If @expected_type is non-[`None`] then it specifies the expected type of
200 /// the attribute. If it is [`None`] 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 [`None`] is returned.
207 /// ## `item_index`
208 /// the index of the item
209 /// ## `attribute`
210 /// the attribute to query
211 /// ## `expected_type`
212 /// the expected type of the attribute, or
213 /// [`None`]
214 ///
215 /// # Returns
216 ///
217 /// the value of the attribute
218 #[doc(alias = "g_menu_model_get_item_attribute_value")]
219 #[doc(alias = "get_item_attribute_value")]
220 fn item_attribute_value(
221 &self,
222 item_index: i32,
223 attribute: &str,
224 expected_type: Option<&glib::VariantTy>,
225 ) -> Option<glib::Variant> {
226 unsafe {
227 from_glib_full(ffi::g_menu_model_get_item_attribute_value(
228 self.as_ref().to_glib_none().0,
229 item_index,
230 attribute.to_glib_none().0,
231 expected_type.to_glib_none().0,
232 ))
233 }
234 }
235
236 /// Queries the item at position @item_index in @self for the link
237 /// specified by @link.
238 ///
239 /// If the link exists, the linked #GMenuModel is returned. If the link
240 /// does not exist, [`None`] is returned.
241 /// ## `item_index`
242 /// the index of the item
243 /// ## `link`
244 /// the link to query
245 ///
246 /// # Returns
247 ///
248 /// the linked #GMenuModel, or [`None`]
249 #[doc(alias = "g_menu_model_get_item_link")]
250 #[doc(alias = "get_item_link")]
251 #[must_use]
252 fn item_link(&self, item_index: i32, link: &str) -> Option<MenuModel> {
253 unsafe {
254 from_glib_full(ffi::g_menu_model_get_item_link(
255 self.as_ref().to_glib_none().0,
256 item_index,
257 link.to_glib_none().0,
258 ))
259 }
260 }
261
262 /// Query the number of items in @self.
263 ///
264 /// # Returns
265 ///
266 /// the number of items
267 #[doc(alias = "g_menu_model_get_n_items")]
268 #[doc(alias = "get_n_items")]
269 fn n_items(&self) -> i32 {
270 unsafe { ffi::g_menu_model_get_n_items(self.as_ref().to_glib_none().0) }
271 }
272
273 /// Queries if @self is mutable.
274 ///
275 /// An immutable #GMenuModel will never emit the #GMenuModel::items-changed
276 /// signal. Consumers of the model may make optimisations accordingly.
277 ///
278 /// # Returns
279 ///
280 /// [`true`] if the model is mutable (ie: "items-changed" may be
281 /// emitted).
282 #[doc(alias = "g_menu_model_is_mutable")]
283 fn is_mutable(&self) -> bool {
284 unsafe { from_glib(ffi::g_menu_model_is_mutable(self.as_ref().to_glib_none().0)) }
285 }
286
287 /// Requests emission of the #GMenuModel::items-changed signal on @self.
288 ///
289 /// This function should never be called except by #GMenuModel
290 /// subclasses. Any other calls to this function will very likely lead
291 /// to a violation of the interface of the model.
292 ///
293 /// The implementation should update its internal representation of the
294 /// menu before emitting the signal. The implementation should further
295 /// expect to receive queries about the new state of the menu (and
296 /// particularly added menu items) while signal handlers are running.
297 ///
298 /// The implementation must dispatch this call directly from a mainloop
299 /// entry and not in response to calls -- particularly those from the
300 /// #GMenuModel API. Said another way: the menu must not change while
301 /// user code is running without returning to the mainloop.
302 /// ## `position`
303 /// the position of the change
304 /// ## `removed`
305 /// the number of items removed
306 /// ## `added`
307 /// the number of items added
308 #[doc(alias = "g_menu_model_items_changed")]
309 fn items_changed(&self, position: i32, removed: i32, added: i32) {
310 unsafe {
311 ffi::g_menu_model_items_changed(
312 self.as_ref().to_glib_none().0,
313 position,
314 removed,
315 added,
316 );
317 }
318 }
319
320 /// Creates a #GMenuAttributeIter to iterate over the attributes of
321 /// the item at position @item_index in @self.
322 ///
323 /// You must free the iterator with g_object_unref() when you are done.
324 /// ## `item_index`
325 /// the index of the item
326 ///
327 /// # Returns
328 ///
329 /// a new #GMenuAttributeIter
330 #[doc(alias = "g_menu_model_iterate_item_attributes")]
331 fn iterate_item_attributes(&self, item_index: i32) -> MenuAttributeIter {
332 unsafe {
333 from_glib_full(ffi::g_menu_model_iterate_item_attributes(
334 self.as_ref().to_glib_none().0,
335 item_index,
336 ))
337 }
338 }
339
340 /// Creates a #GMenuLinkIter to iterate over the links of the item at
341 /// position @item_index in @self.
342 ///
343 /// You must free the iterator with g_object_unref() when you are done.
344 /// ## `item_index`
345 /// the index of the item
346 ///
347 /// # Returns
348 ///
349 /// a new #GMenuLinkIter
350 #[doc(alias = "g_menu_model_iterate_item_links")]
351 fn iterate_item_links(&self, item_index: i32) -> MenuLinkIter {
352 unsafe {
353 from_glib_full(ffi::g_menu_model_iterate_item_links(
354 self.as_ref().to_glib_none().0,
355 item_index,
356 ))
357 }
358 }
359
360 /// Emitted when a change has occurred to the menu.
361 ///
362 /// The only changes that can occur to a menu is that items are removed
363 /// or added. Items may not change (except by being removed and added
364 /// back in the same location). This signal is capable of describing
365 /// both of those changes (at the same time).
366 ///
367 /// The signal means that starting at the index @position, @removed
368 /// items were removed and @added items were added in their place. If
369 /// @removed is zero then only items were added. If @added is zero
370 /// then only items were removed.
371 ///
372 /// As an example, if the menu contains items a, b, c, d (in that
373 /// order) and the signal (2, 1, 3) occurs then the new composition of
374 /// the menu will be a, b, _, _, _, d (with each _ representing some
375 /// new item).
376 ///
377 /// Signal handlers may query the model (particularly the added items)
378 /// and expect to see the results of the modification that is being
379 /// reported. The signal is emitted after the modification.
380 /// ## `position`
381 /// the position of the change
382 /// ## `removed`
383 /// the number of items removed
384 /// ## `added`
385 /// the number of items added
386 #[doc(alias = "items-changed")]
387 fn connect_items_changed<F: Fn(&Self, i32, i32, i32) + 'static>(
388 &self,
389 f: F,
390 ) -> SignalHandlerId {
391 unsafe extern "C" fn items_changed_trampoline<
392 P: IsA<MenuModel>,
393 F: Fn(&P, i32, i32, i32) + 'static,
394 >(
395 this: *mut ffi::GMenuModel,
396 position: std::ffi::c_int,
397 removed: std::ffi::c_int,
398 added: std::ffi::c_int,
399 f: glib::ffi::gpointer,
400 ) {
401 let f: &F = &*(f as *const F);
402 f(
403 MenuModel::from_glib_borrow(this).unsafe_cast_ref(),
404 position,
405 removed,
406 added,
407 )
408 }
409 unsafe {
410 let f: Box_<F> = Box_::new(f);
411 connect_raw(
412 self.as_ptr() as *mut _,
413 b"items-changed\0".as_ptr() as *const _,
414 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
415 items_changed_trampoline::<Self, F> as *const (),
416 )),
417 Box_::into_raw(f),
418 )
419 }
420 }
421}
422
423impl<O: IsA<MenuModel>> MenuModelExt for O {}