Skip to main content

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::{MenuAttributeIter, MenuLinkIter, ffi};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{SignalHandlerId, connect_raw},
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    /// ![](menu-example.png)
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    ///
104    /// - an action with no parameter type and no state
105    /// - an action with no parameter type and boolean state
106    /// - an action with string parameter type and string state
107    ///
108    /// ## Stateless
109    ///
110    /// A stateless action typically corresponds to an ordinary menu item.
111    ///
112    /// Selecting such a menu item will activate the action (with no parameter).
113    ///
114    /// ## Boolean State
115    ///
116    /// An action with a boolean state will most typically be used with a ‘toggle’
117    /// or ‘switch’ menu item. The state can be set directly, but activating the
118    /// action (with no parameter) results in the state being toggled.
119    ///
120    /// Selecting a toggle menu item will activate the action. The menu item should
121    /// be rendered as ‘checked’ when the state is true.
122    ///
123    /// ## String Parameter and State
124    ///
125    /// Actions with string parameters and state will most typically be used to
126    /// represent an enumerated choice over the items available for a group of
127    /// radio menu items. Activating the action with a string parameter is
128    /// equivalent to setting that parameter as the state.
129    ///
130    /// Radio menu items, in addition to being associated with the action, will
131    /// have a target value. Selecting that menu item will result in activation
132    /// of the action with the target value as the parameter. The menu item should
133    /// be rendered as ‘selected’ when the state of the action is equal to the
134    /// target value of the menu item.
135    ///
136    /// This is an Abstract Base Class, you cannot instantiate it.
137    ///
138    /// ## Signals
139    ///
140    ///
141    /// #### `items-changed`
142    ///  Emitted when a change has occurred to the menu.
143    ///
144    /// The only changes that can occur to a menu is that items are removed
145    /// or added.  Items may not change (except by being removed and added
146    /// back in the same location).  This signal is capable of describing
147    /// both of those changes (at the same time).
148    ///
149    /// The signal means that starting at the index @position, @removed
150    /// items were removed and @added items were added in their place.  If
151    /// @removed is zero then only items were added.  If @added is zero
152    /// then only items were removed.
153    ///
154    /// As an example, if the menu contains items a, b, c, d (in that
155    /// order) and the signal (2, 1, 3) occurs then the new composition of
156    /// the menu will be a, b, \_, \_, \_, d (with each _ representing some
157    /// new item).
158    ///
159    /// Signal handlers may query the model (particularly the added items)
160    /// and expect to see the results of the modification that is being
161    /// reported.  The signal is emitted after the modification.
162    ///
163    ///
164    ///
165    /// # Implements
166    ///
167    /// [`MenuModelExt`][trait@crate::prelude::MenuModelExt], [`trait@glib::ObjectExt`]
168    #[doc(alias = "GMenuModel")]
169    pub struct MenuModel(Object<ffi::GMenuModel, ffi::GMenuModelClass>);
170
171    match fn {
172        type_ => || ffi::g_menu_model_get_type(),
173    }
174}
175
176impl MenuModel {
177    pub const NONE: Option<&'static MenuModel> = None;
178}
179
180/// Trait containing all [`struct@MenuModel`] methods.
181///
182/// # Implementors
183///
184/// [`DBusMenuModel`][struct@crate::DBusMenuModel], [`MenuModel`][struct@crate::MenuModel], [`Menu`][struct@crate::Menu]
185pub trait MenuModelExt: IsA<MenuModel> + 'static {
186    //#[doc(alias = "g_menu_model_get_item_attribute")]
187    //#[doc(alias = "get_item_attribute")]
188    //fn is_item_attribute(&self, item_index: i32, attribute: &str, format_string: &str, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) -> bool {
189    //    unsafe { TODO: call ffi:g_menu_model_get_item_attribute() }
190    //}
191
192    /// Queries the item at position @item_index in @self for the attribute
193    /// specified by @attribute.
194    ///
195    /// If @expected_type is non-[`None`] then it specifies the expected type of
196    /// the attribute.  If it is [`None`] then any type will be accepted.
197    ///
198    /// If the attribute exists and matches @expected_type (or if the
199    /// expected type is unspecified) then the value is returned.
200    ///
201    /// If the attribute does not exist, or does not match the expected type
202    /// then [`None`] is returned.
203    /// ## `item_index`
204    /// the index of the item
205    /// ## `attribute`
206    /// the attribute to query
207    /// ## `expected_type`
208    /// the expected type of the attribute, or
209    ///     [`None`]
210    ///
211    /// # Returns
212    ///
213    /// the value of the attribute
214    #[doc(alias = "g_menu_model_get_item_attribute_value")]
215    #[doc(alias = "get_item_attribute_value")]
216    fn item_attribute_value(
217        &self,
218        item_index: i32,
219        attribute: &str,
220        expected_type: Option<&glib::VariantTy>,
221    ) -> Option<glib::Variant> {
222        unsafe {
223            from_glib_full(ffi::g_menu_model_get_item_attribute_value(
224                self.as_ref().to_glib_none().0,
225                item_index,
226                attribute.to_glib_none().0,
227                expected_type.to_glib_none().0,
228            ))
229        }
230    }
231
232    /// Queries the item at position @item_index in @self for the link
233    /// specified by @link.
234    ///
235    /// If the link exists, the linked #GMenuModel is returned.  If the link
236    /// does not exist, [`None`] is returned.
237    /// ## `item_index`
238    /// the index of the item
239    /// ## `link`
240    /// the link to query
241    ///
242    /// # Returns
243    ///
244    /// the linked #GMenuModel, or [`None`]
245    #[doc(alias = "g_menu_model_get_item_link")]
246    #[doc(alias = "get_item_link")]
247    #[must_use]
248    fn item_link(&self, item_index: i32, link: &str) -> Option<MenuModel> {
249        unsafe {
250            from_glib_full(ffi::g_menu_model_get_item_link(
251                self.as_ref().to_glib_none().0,
252                item_index,
253                link.to_glib_none().0,
254            ))
255        }
256    }
257
258    /// Query the number of items in @self.
259    ///
260    /// # Returns
261    ///
262    /// the number of items
263    #[doc(alias = "g_menu_model_get_n_items")]
264    #[doc(alias = "get_n_items")]
265    fn n_items(&self) -> i32 {
266        unsafe { ffi::g_menu_model_get_n_items(self.as_ref().to_glib_none().0) }
267    }
268
269    /// Queries if @self is mutable.
270    ///
271    /// An immutable #GMenuModel will never emit the #GMenuModel::items-changed
272    /// signal. Consumers of the model may make optimisations accordingly.
273    ///
274    /// # Returns
275    ///
276    /// [`true`] if the model is mutable (ie: "items-changed" may be
277    ///     emitted).
278    #[doc(alias = "g_menu_model_is_mutable")]
279    fn is_mutable(&self) -> bool {
280        unsafe { from_glib(ffi::g_menu_model_is_mutable(self.as_ref().to_glib_none().0)) }
281    }
282
283    /// Requests emission of the #GMenuModel::items-changed signal on @self.
284    ///
285    /// This function should never be called except by #GMenuModel
286    /// subclasses.  Any other calls to this function will very likely lead
287    /// to a violation of the interface of the model.
288    ///
289    /// The implementation should update its internal representation of the
290    /// menu before emitting the signal.  The implementation should further
291    /// expect to receive queries about the new state of the menu (and
292    /// particularly added menu items) while signal handlers are running.
293    ///
294    /// The implementation must dispatch this call directly from a mainloop
295    /// entry and not in response to calls -- particularly those from the
296    /// #GMenuModel API.  Said another way: the menu must not change while
297    /// user code is running without returning to the mainloop.
298    /// ## `position`
299    /// the position of the change
300    /// ## `removed`
301    /// the number of items removed
302    /// ## `added`
303    /// the number of items added
304    #[doc(alias = "g_menu_model_items_changed")]
305    fn items_changed(&self, position: i32, removed: i32, added: i32) {
306        unsafe {
307            ffi::g_menu_model_items_changed(
308                self.as_ref().to_glib_none().0,
309                position,
310                removed,
311                added,
312            );
313        }
314    }
315
316    /// Creates a #GMenuAttributeIter to iterate over the attributes of
317    /// the item at position @item_index in @self.
318    ///
319    /// You must free the iterator with g_object_unref() when you are done.
320    /// ## `item_index`
321    /// the index of the item
322    ///
323    /// # Returns
324    ///
325    /// a new #GMenuAttributeIter
326    #[doc(alias = "g_menu_model_iterate_item_attributes")]
327    fn iterate_item_attributes(&self, item_index: i32) -> MenuAttributeIter {
328        unsafe {
329            from_glib_full(ffi::g_menu_model_iterate_item_attributes(
330                self.as_ref().to_glib_none().0,
331                item_index,
332            ))
333        }
334    }
335
336    /// Creates a #GMenuLinkIter to iterate over the links of the item at
337    /// position @item_index in @self.
338    ///
339    /// You must free the iterator with g_object_unref() when you are done.
340    /// ## `item_index`
341    /// the index of the item
342    ///
343    /// # Returns
344    ///
345    /// a new #GMenuLinkIter
346    #[doc(alias = "g_menu_model_iterate_item_links")]
347    fn iterate_item_links(&self, item_index: i32) -> MenuLinkIter {
348        unsafe {
349            from_glib_full(ffi::g_menu_model_iterate_item_links(
350                self.as_ref().to_glib_none().0,
351                item_index,
352            ))
353        }
354    }
355
356    /// Emitted when a change has occurred to the menu.
357    ///
358    /// The only changes that can occur to a menu is that items are removed
359    /// or added.  Items may not change (except by being removed and added
360    /// back in the same location).  This signal is capable of describing
361    /// both of those changes (at the same time).
362    ///
363    /// The signal means that starting at the index @position, @removed
364    /// items were removed and @added items were added in their place.  If
365    /// @removed is zero then only items were added.  If @added is zero
366    /// then only items were removed.
367    ///
368    /// As an example, if the menu contains items a, b, c, d (in that
369    /// order) and the signal (2, 1, 3) occurs then the new composition of
370    /// the menu will be a, b, \_, \_, \_, d (with each _ representing some
371    /// new item).
372    ///
373    /// Signal handlers may query the model (particularly the added items)
374    /// and expect to see the results of the modification that is being
375    /// reported.  The signal is emitted after the modification.
376    /// ## `position`
377    /// the position of the change
378    /// ## `removed`
379    /// the number of items removed
380    /// ## `added`
381    /// the number of items added
382    #[doc(alias = "items-changed")]
383    fn connect_items_changed<F: Fn(&Self, i32, i32, i32) + 'static>(
384        &self,
385        f: F,
386    ) -> SignalHandlerId {
387        unsafe extern "C" fn items_changed_trampoline<
388            P: IsA<MenuModel>,
389            F: Fn(&P, i32, i32, i32) + 'static,
390        >(
391            this: *mut ffi::GMenuModel,
392            position: std::ffi::c_int,
393            removed: std::ffi::c_int,
394            added: std::ffi::c_int,
395            f: glib::ffi::gpointer,
396        ) {
397            unsafe {
398                let f: &F = &*(f as *const F);
399                f(
400                    MenuModel::from_glib_borrow(this).unsafe_cast_ref(),
401                    position,
402                    removed,
403                    added,
404                )
405            }
406        }
407        unsafe {
408            let f: Box_<F> = Box_::new(f);
409            connect_raw(
410                self.as_ptr() as *mut _,
411                c"items-changed".as_ptr(),
412                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
413                    items_changed_trampoline::<Self, F> as *const (),
414                )),
415                Box_::into_raw(f),
416            )
417        }
418    }
419}
420
421impl<O: IsA<MenuModel>> MenuModelExt for O {}