gtk4/auto/
builder.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, BuilderClosureFlags, BuilderScope};
6use glib::{
7    prelude::*,
8    signal::{connect_raw, SignalHandlerId},
9    translate::*,
10};
11use std::boxed::Box as Box_;
12
13glib::wrapper! {
14    /// Reads XML descriptions of a user interface and instantiates the described objects.
15    ///
16    /// To create a [`Builder`][crate::Builder] from a user interface description, call
17    /// [`from_file()`][Self::from_file()], [`from_resource()`][Self::from_resource()]
18    /// or [`from_string()`][Self::from_string()].
19    ///
20    /// In the (unusual) case that you want to add user interface
21    /// descriptions from multiple sources to the same [`Builder`][crate::Builder] you can
22    /// call [`new()`][Self::new()] to get an empty builder and populate it by
23    /// (multiple) calls to [`add_from_file()`][Self::add_from_file()],
24    /// [`add_from_resource()`][Self::add_from_resource()] or
25    /// [`add_from_string()`][Self::add_from_string()].
26    ///
27    /// A [`Builder`][crate::Builder] holds a reference to all objects that it has constructed
28    /// and drops these references when it is finalized. This finalization can
29    /// cause the destruction of non-widget objects or widgets which are not
30    /// contained in a toplevel window. For toplevel windows constructed by a
31    /// builder, it is the responsibility of the user to call
32    /// `Gtk::Window::destroy()` to get rid of them and all the widgets
33    /// they contain.
34    ///
35    /// The functions [`object()`][Self::object()] and
36    /// [`objects()`][Self::objects()] can be used to access the widgets in
37    /// the interface by the names assigned to them inside the UI description.
38    /// Toplevel windows returned by these functions will stay around until the
39    /// user explicitly destroys them with `Gtk::Window::destroy()`. Other
40    /// widgets will either be part of a larger hierarchy constructed by the
41    /// builder (in which case you should not have to worry about their lifecycle),
42    /// or without a parent, in which case they have to be added to some container
43    /// to make use of them. Non-widget objects need to be reffed with
44    /// g_object_ref() to keep them beyond the lifespan of the builder.
45    ///
46    /// ## GtkBuilder UI Definitions
47    ///
48    /// [`Builder`][crate::Builder] parses textual descriptions of user interfaces which are
49    /// specified in XML format. We refer to these descriptions as “GtkBuilder
50    /// UI definitions” or just “UI definitions” if the context is clear.
51    ///
52    /// ### Structure of UI definitions
53    ///
54    /// UI definition files are always encoded in UTF-8.
55    ///
56    /// The toplevel element is `<interface>`. It optionally takes a “domain”
57    /// attribute, which will make the builder look for translated strings
58    /// using `dgettext()` in the domain specified. This can also be done by
59    /// calling [`set_translation_domain()`][Self::set_translation_domain()] on the builder.
60    /// For example:
61    ///
62    /// ```xml
63    /// <?xml version="1.0" encoding="UTF-8">
64    /// <interface domain="your-app">
65    ///   ...
66    /// </interface>
67    /// ```
68    ///
69    /// ### Requirements
70    ///
71    /// The target toolkit version(s) are described by `<requires>` elements,
72    /// the “lib” attribute specifies the widget library in question (currently
73    /// the only supported value is “gtk”) and the “version” attribute specifies
74    /// the target version in the form “`<major>`.`<minor>`”. [`Builder`][crate::Builder] will
75    /// error out if the version requirements are not met. For example:
76    ///
77    /// ```xml
78    /// <?xml version="1.0" encoding="UTF-8">
79    /// <interface domain="your-app">
80    ///   <requires lib="gtk" version="4.0" />
81    /// </interface>
82    /// ```
83    ///
84    /// ### Objects
85    ///
86    /// Objects are defined as children of the `<interface>` element.
87    ///
88    /// Objects are described by `<object>` elements, which can contain
89    /// `<property>` elements to set properties, `<signal>` elements which
90    /// connect signals to handlers, and `<child>` elements, which describe
91    /// child objects.
92    ///
93    /// Typically, the specific kind of object represented by an `<object>`
94    /// element is specified by the “class” attribute. If the type has not
95    /// been loaded yet, GTK tries to find the `get_type()` function from the
96    /// class name by applying heuristics. This works in most cases, but if
97    /// necessary, it is possible to specify the name of the `get_type()`
98    /// function explicitly with the "type-func" attribute. If your UI definition
99    /// is referencing internal types, you should make sure to call
100    /// `g_type_ensure()` for each object type before parsing the UI definition.
101    ///
102    /// Objects may be given a name with the “id” attribute, which allows the
103    /// application to retrieve them from the builder with
104    /// [`object()`][Self::object()]. An id is also necessary to use the
105    /// object as property value in other parts of the UI definition. GTK
106    /// reserves ids starting and ending with `___` (three consecutive
107    /// underscores) for its own purposes.
108    ///
109    /// ### Properties
110    ///
111    /// Setting properties of objects is pretty straightforward with the
112    /// `<property>` element: the “name” attribute specifies the name of the
113    /// property, and the content of the element specifies the value:
114    ///
115    /// ```xml
116    /// <object class="GtkButton">
117    ///   <property name="label">Hello, world</property>
118    /// </object>
119    /// ```
120    ///
121    /// If the “translatable” attribute is set to a true value, GTK uses
122    /// `gettext()` (or `dgettext()` if the builder has a translation domain set)
123    /// to find a translation for the value. This happens before the value
124    /// is parsed, so it can be used for properties of any type, but it is
125    /// probably most useful for string properties. It is also possible to
126    /// specify a context to disambiguate short strings, and comments which
127    /// may help the translators:
128    ///
129    /// ```xml
130    /// <object class="GtkButton">
131    ///   <property name="label"
132    ///             translatable="yes"
133    ///             context="button"
134    ///             comments="A classic">Hello, world</property>
135    /// </object>
136    /// ```
137    ///
138    /// The xgettext tool that is part of gettext can extract these strings,
139    /// but note that it only looks for translatable="yes".
140    ///
141    /// [`Builder`][crate::Builder] can parse textual representations for the most common
142    /// property types:
143    ///
144    /// - characters
145    /// - strings
146    /// - integers
147    /// - floating-point numbers
148    /// - booleans (strings like “TRUE”, “t”, “yes”, “y”, “1” are interpreted
149    ///   as true values, strings like “FALSE”, “f”, “no”, “n”, “0” are interpreted
150    ///   as false values)
151    /// - string lists (separated by newlines)
152    /// - enumeration types (can be specified by their full C identifier their short
153    ///   name used when registering the enumeration type, or their integer value)
154    /// - flag types (can be specified by their C identifier or short name,
155    ///   optionally combined with “|” for bitwise OR, or a single integer value
156    ///   e.g., “GTK_INPUT_HINT_EMOJI|GTK_INPUT_HINT_LOWERCASE”, or “emoji|lowercase” or 520).
157    /// - colors (in the format understood by [`gdk::RGBA::parse()`][crate::gdk::RGBA::parse()])
158    /// - transforms (in the format understood by [`gsk::Transform::parse()`][crate::gsk::Transform::parse()])
159    /// - Pango attribute lists (in the format understood by [`pango::AttrList::to_str()`][crate::pango::AttrList::to_str()])
160    /// - Pango tab arrays (in the format understood by [`pango::TabArray::to_str()`][crate::pango::TabArray::to_str()])
161    /// - Pango font descriptions (in the format understood by [`pango::FontDescription::from_string()`][crate::pango::FontDescription::from_string()])
162    /// - `GVariant` (in the format understood by `GLib::Variant::parse()`)
163    /// - textures (can be specified as an object id, a resource path or a filename of an image file to load relative to the Builder file or the CWD if [`add_from_string()`][Self::add_from_string()] was used)
164    /// - GFile (like textures, can be specified as an object id, a URI or a filename of a file to load relative to the Builder file or the CWD if [`add_from_string()`][Self::add_from_string()] was used)
165    ///
166    /// Objects can be referred to by their name and by default refer to
167    /// objects declared in the local XML fragment and objects exposed via
168    /// [`expose_object()`][Self::expose_object()]. In general, [`Builder`][crate::Builder] allows
169    /// forward references to objects declared in the local XML; an object
170    /// doesn’t have to be constructed before it can be referred to. The
171    /// exception to this rule is that an object has to be constructed before
172    /// it can be used as the value of a construct-only property.
173    ///
174    /// ### Child objects
175    ///
176    /// Many widgets have properties for child widgets, such as
177    /// [`child`][struct@crate::Expander#child]. In this case, the preferred way to
178    /// specify the child widget in a ui file is to simply set the property:
179    ///
180    /// ```xml
181    /// <object class="GtkExpander">
182    ///   <property name="child">
183    ///     <object class="GtkLabel">
184    ///     ...
185    ///     </object>
186    ///   </property>
187    /// </object>
188    /// ```
189    ///
190    /// Generic containers that can contain an arbitrary number of children,
191    /// such as [`Box`][crate::Box] instead use the `<child>` element. A `<child>`
192    /// element contains an `<object>` element which describes the child object.
193    /// Most often, child objects are widgets inside a container, but they can
194    /// also be, e.g., actions in an action group, or columns in a tree model.
195    ///
196    /// Any object type that implements the [`Buildable`][crate::Buildable] interface can
197    /// specify how children may be added to it. Since many objects and widgets that
198    /// are included with GTK already implement the [`Buildable`][crate::Buildable] interface,
199    /// typically child objects can be added using the `<child>` element without
200    /// having to be concerned about the underlying implementation.
201    ///
202    /// See the [[`Widget`][crate::Widget] documentation](class.Widget.html#gtkwidget-as-gtkbuildable)
203    /// for many examples of using [`Builder`][crate::Builder] with widgets, including setting
204    /// child objects using the `<child>` element.
205    ///
206    /// A noteworthy special case to the general rule that only objects implementing
207    /// [`Buildable`][crate::Buildable] may specify how to handle the `<child>` element is that
208    /// [`Builder`][crate::Builder] provides special support for adding objects to a
209    /// `Gio::ListStore` by using the `<child>` element. For instance:
210    ///
211    /// ```xml
212    /// <object class="GListStore">
213    ///   <property name="item-type">MyObject</property>
214    ///   <child>
215    ///     <object class="MyObject" />
216    ///   </child>
217    ///   ...
218    /// </object>
219    /// ```
220    ///
221    /// ### Property bindings
222    ///
223    /// It is also possible to bind a property value to another object's
224    /// property value using the attributes "bind-source" to specify the
225    /// source object of the binding, and optionally, "bind-property" and
226    /// "bind-flags" to specify the source property and source binding flags
227    /// respectively. Internally, [`Builder`][crate::Builder] implements this using
228    /// `GObject::Binding` objects.
229    ///
230    /// For instance, in the example below the “label” property of the
231    /// `bottom_label` widget is bound to the “label” property of the
232    /// `top_button` widget:
233    ///
234    /// ```xml
235    /// <object class="GtkBox">
236    ///   <property name="orientation">vertical</property>
237    ///   <child>
238    ///     <object class="GtkButton" id="top_button">
239    ///       <property name="label">Hello, world</property>
240    ///     </object>
241    ///   </child>
242    ///   <child>
243    ///     <object class="GtkLabel" id="bottom_label">
244    ///       <property name="label"
245    ///                 bind-source="top_button"
246    ///                 bind-property="label"
247    ///                 bind-flags="sync-create" />
248    ///     </object>
249    ///   </child>
250    /// </object>
251    /// ```
252    ///
253    /// For more information, see the documentation of the
254    /// [`ObjectExt::bind_property()`][crate::glib::prelude::ObjectExt::bind_property()] method.
255    ///
256    /// Please note that another way to set up bindings between objects in .ui files
257    /// is to use the [`Expression`][crate::Expression] methodology. See the
258    /// [[`Expression`][crate::Expression] documentation](class.Expression.html#gtkexpression-in-ui-files)
259    /// for more information.
260    ///
261    /// ### Internal children
262    ///
263    /// Sometimes it is necessary to refer to widgets which have implicitly
264    /// been constructed by GTK as part of a composite widget, to set
265    /// properties on them or to add further children (e.g. the content area
266    /// of a [`Dialog`][crate::Dialog]). This can be achieved by setting the “internal-child”
267    /// property of the `<child>` element to a true value. Note that [`Builder`][crate::Builder]
268    /// still requires an `<object>` element for the internal child, even if it
269    /// has already been constructed.
270    ///
271    /// ### Specialized children
272    ///
273    /// A number of widgets have different places where a child can be added
274    /// (e.g. tabs vs. page content in notebooks). This can be reflected in
275    /// a UI definition by specifying the “type” attribute on a `<child>`
276    /// The possible values for the “type” attribute are described in the
277    /// sections describing the widget-specific portions of UI definitions.
278    ///
279    /// ### Signal handlers and function pointers
280    ///
281    /// Signal handlers are set up with the `<signal>` element. The “name”
282    /// attribute specifies the name of the signal, and the “handler” attribute
283    /// specifies the function to connect to the signal.
284    ///
285    /// ```xml
286    /// <object class="GtkButton" id="hello_button">
287    ///   <signal name="clicked" handler="hello_button__clicked" />
288    /// </object>
289    /// ```
290    ///
291    /// The remaining attributes, “after”, “swapped” and “object”, have the
292    /// same meaning as the corresponding parameters of the
293    /// `signal_connect_object()` or `signal_connect_data()`
294    /// functions:
295    ///
296    /// - “after” matches the `G_CONNECT_AFTER` flag, and will ensure that the
297    ///   handler is called after the default class closure for the signal
298    /// - “swapped” matches the `G_CONNECT_SWAPPED` flag, and will swap the
299    ///   instance and closure arguments when invoking the signal handler
300    /// - “object” will bind the signal handler to the lifetime of the object
301    ///   referenced by the attribute
302    ///
303    /// By default "swapped" will be set to "yes" if not specified otherwise, in
304    /// the case where "object" is set, for convenience. A “last_modification_time”
305    /// attribute is also allowed, but it does not have a meaning to the builder.
306    ///
307    /// When compiling applications for Windows, you must declare signal callbacks
308    /// with the `G_MODULE_EXPORT` decorator, or they will not be put in the symbol
309    /// table:
310    ///
311    /// **⚠️ The following code is in c ⚠️**
312    ///
313    /// ```c
314    /// G_MODULE_EXPORT void
315    /// hello_button__clicked (GtkButton *button,
316    ///                        gpointer data)
317    /// {
318    ///   // ...
319    /// }
320    /// ```
321    ///
322    /// On Linux and Unix, this is not necessary; applications should instead
323    /// be compiled with the `-Wl,--export-dynamic` argument inside their compiler
324    /// flags, and linked against `gmodule-export-2.0`.
325    ///
326    /// ## Example UI Definition
327    ///
328    /// ```xml
329    /// <interface>
330    ///   <object class="GtkDialog" id="dialog1">
331    ///     <child internal-child="content_area">
332    ///       <object class="GtkBox">
333    ///         <child internal-child="action_area">
334    ///           <object class="GtkBox">
335    ///             <child>
336    ///               <object class="GtkButton" id="ok_button">
337    ///                 <property name="label" translatable="yes">_Ok</property>
338    ///                 <property name="use-underline">True</property>
339    ///                 <signal name="clicked" handler="ok_button_clicked"/>
340    ///               </object>
341    ///             </child>
342    ///           </object>
343    ///         </child>
344    ///       </object>
345    ///     </child>
346    ///   </object>
347    /// </interface>
348    /// ```
349    ///
350    /// ## Using GtkBuildable for extending UI definitions
351    ///
352    /// Objects can implement the [`Buildable`][crate::Buildable] interface to add custom
353    /// elements and attributes to the XML. Typically, any extension will be
354    /// documented in each type that implements the interface.
355    ///
356    /// ## Menus
357    ///
358    /// In addition to objects with properties that are created with `<object>` and
359    /// `<property>` elements, [`Builder`][crate::Builder] also allows to parse XML menu definitions
360    /// as used by [`gio::Menu`][crate::gio::Menu] when exporting menu models over D-Bus, and as
361    /// described in the [`PopoverMenu`][crate::PopoverMenu] documentation. Menus can be defined
362    /// as toplevel elements, or as property values for properties of type `GMenuModel`.
363    ///
364    /// ## Templates
365    ///
366    /// When describing a [`Widget`][crate::Widget], you can use the `<template>` tag to
367    /// describe a UI bound to a specific widget type. GTK will automatically load
368    /// the UI definition when instantiating the type, and bind children and
369    /// signal handlers to instance fields and function symbols.
370    ///
371    /// For more information, see the [[`Widget`][crate::Widget] documentation](class.Widget.html#building-composite-widgets-from-template-xml)
372    /// for details.
373    ///
374    /// ## Properties
375    ///
376    ///
377    /// #### `current-object`
378    ///  The object the builder is evaluating for.
379    ///
380    /// Readable | Writeable
381    ///
382    ///
383    /// #### `scope`
384    ///  The scope the builder is operating in
385    ///
386    /// Readable | Writeable | Construct
387    ///
388    ///
389    /// #### `translation-domain`
390    ///  The translation domain used when translating property values that
391    /// have been marked as translatable.
392    ///
393    /// If the translation domain is [`None`], [`Builder`][crate::Builder] uses gettext(),
394    /// otherwise g_dgettext().
395    ///
396    /// Readable | Writeable
397    ///
398    /// # Implements
399    ///
400    /// [`trait@glib::ObjectExt`]
401    #[doc(alias = "GtkBuilder")]
402    pub struct Builder(Object<ffi::GtkBuilder, ffi::GtkBuilderClass>);
403
404    match fn {
405        type_ => || ffi::gtk_builder_get_type(),
406    }
407}
408
409impl Builder {
410    /// Creates a new empty builder object.
411    ///
412    /// This function is only useful if you intend to make multiple calls
413    /// to [`add_from_file()`][Self::add_from_file()], [`add_from_resource()`][Self::add_from_resource()]
414    /// or [`add_from_string()`][Self::add_from_string()] in order to merge multiple UI
415    /// descriptions into a single builder.
416    ///
417    /// # Returns
418    ///
419    /// a new (empty) [`Builder`][crate::Builder] object
420    #[doc(alias = "gtk_builder_new")]
421    pub fn new() -> Builder {
422        assert_initialized_main_thread!();
423        unsafe { from_glib_full(ffi::gtk_builder_new()) }
424    }
425
426    /// Parses the UI definition at @resource_path.
427    ///
428    /// If there is an error locating the resource or parsing the
429    /// description, then the program will be aborted.
430    /// ## `resource_path`
431    /// a `GResource` resource path
432    ///
433    /// # Returns
434    ///
435    /// a [`Builder`][crate::Builder] containing the described interface
436    #[doc(alias = "gtk_builder_new_from_resource")]
437    #[doc(alias = "new_from_resource")]
438    pub fn from_resource(resource_path: &str) -> Builder {
439        assert_initialized_main_thread!();
440        unsafe {
441            from_glib_full(ffi::gtk_builder_new_from_resource(
442                resource_path.to_glib_none().0,
443            ))
444        }
445    }
446
447    /// Parses the UI definition in @string.
448    ///
449    /// If @string is [`None`]-terminated, then @length should be -1.
450    /// If @length is not -1, then it is the length of @string.
451    ///
452    /// If there is an error parsing @string then the program will be
453    /// aborted. You should not attempt to parse user interface description
454    /// from untrusted sources.
455    /// ## `string`
456    /// a user interface (XML) description
457    /// ## `length`
458    /// the length of @string, or -1
459    ///
460    /// # Returns
461    ///
462    /// a [`Builder`][crate::Builder] containing the interface described by @string
463    #[doc(alias = "gtk_builder_new_from_string")]
464    #[doc(alias = "new_from_string")]
465    pub fn from_string(string: &str) -> Builder {
466        assert_initialized_main_thread!();
467        let length = string.len() as _;
468        unsafe {
469            from_glib_full(ffi::gtk_builder_new_from_string(
470                string.to_glib_none().0,
471                length,
472            ))
473        }
474    }
475
476    /// Parses a resource file containing a UI definition
477    /// and merges it with the current contents of @self.
478    ///
479    /// This function is useful if you need to call
480    /// [`set_current_object()`][Self::set_current_object()] to add user data to
481    /// callbacks before loading GtkBuilder UI. Otherwise, you probably
482    /// want [`from_resource()`][Self::from_resource()] instead.
483    ///
484    /// If an error occurs, 0 will be returned and @error will be assigned a
485    /// `GError` from the `GTK_BUILDER_ERROR`, `G_MARKUP_ERROR` or `G_RESOURCE_ERROR`
486    /// domain.
487    ///
488    /// It’s not really reasonable to attempt to handle failures of this
489    /// call.  The only reasonable thing to do when an error is detected is
490    /// to call g_error().
491    /// ## `resource_path`
492    /// the path of the resource file to parse
493    ///
494    /// # Returns
495    ///
496    /// [`true`] on success, [`false`] if an error occurred
497    #[doc(alias = "gtk_builder_add_from_resource")]
498    pub fn add_from_resource(&self, resource_path: &str) -> Result<(), glib::Error> {
499        unsafe {
500            let mut error = std::ptr::null_mut();
501            let is_ok = ffi::gtk_builder_add_from_resource(
502                self.to_glib_none().0,
503                resource_path.to_glib_none().0,
504                &mut error,
505            );
506            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
507            if error.is_null() {
508                Ok(())
509            } else {
510                Err(from_glib_full(error))
511            }
512        }
513    }
514
515    /// Parses a string containing a UI definition and merges it
516    /// with the current contents of @self.
517    ///
518    /// This function is useful if you need to call
519    /// [`set_current_object()`][Self::set_current_object()] to add user data to
520    /// callbacks before loading [`Builder`][crate::Builder] UI. Otherwise, you probably
521    /// want [`from_string()`][Self::from_string()] instead.
522    ///
523    /// Upon errors [`false`] will be returned and @error will be assigned a
524    /// `GError` from the `GTK_BUILDER_ERROR`, `G_MARKUP_ERROR` or
525    /// `G_VARIANT_PARSE_ERROR` domain.
526    ///
527    /// It’s not really reasonable to attempt to handle failures of this
528    /// call.  The only reasonable thing to do when an error is detected is
529    /// to call g_error().
530    /// ## `buffer`
531    /// the string to parse
532    /// ## `length`
533    /// the length of @buffer (may be -1 if @buffer is nul-terminated)
534    ///
535    /// # Returns
536    ///
537    /// [`true`] on success, [`false`] if an error occurred
538    #[doc(alias = "gtk_builder_add_from_string")]
539    pub fn add_from_string(&self, buffer: &str) -> Result<(), glib::Error> {
540        let length = buffer.len() as _;
541        unsafe {
542            let mut error = std::ptr::null_mut();
543            let is_ok = ffi::gtk_builder_add_from_string(
544                self.to_glib_none().0,
545                buffer.to_glib_none().0,
546                length,
547                &mut error,
548            );
549            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
550            if error.is_null() {
551                Ok(())
552            } else {
553                Err(from_glib_full(error))
554            }
555        }
556    }
557
558    /// Parses a file containing a UI definition building only the
559    /// requested objects and merges them with the current contents
560    /// of @self.
561    ///
562    /// Upon errors, 0 will be returned and @error will be assigned a
563    /// `GError` from the `GTK_BUILDER_ERROR`, `G_MARKUP_ERROR` or `G_FILE_ERROR`
564    /// domain.
565    ///
566    /// If you are adding an object that depends on an object that is not
567    /// its child (for instance a [`TreeView`][crate::TreeView] that depends on its
568    /// [`TreeModel`][crate::TreeModel]), you have to explicitly list all of them in @object_ids.
569    /// ## `filename`
570    /// the name of the file to parse
571    /// ## `object_ids`
572    /// nul-terminated array of objects to build
573    ///
574    /// # Returns
575    ///
576    /// [`true`] on success, [`false`] if an error occurred
577    #[doc(alias = "gtk_builder_add_objects_from_file")]
578    pub fn add_objects_from_file(
579        &self,
580        filename: impl AsRef<std::path::Path>,
581        object_ids: &[&str],
582    ) -> Result<(), glib::Error> {
583        unsafe {
584            let mut error = std::ptr::null_mut();
585            let is_ok = ffi::gtk_builder_add_objects_from_file(
586                self.to_glib_none().0,
587                filename.as_ref().to_glib_none().0,
588                object_ids.to_glib_none().0,
589                &mut error,
590            );
591            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
592            if error.is_null() {
593                Ok(())
594            } else {
595                Err(from_glib_full(error))
596            }
597        }
598    }
599
600    /// Parses a resource file containing a UI definition, building
601    /// only the requested objects and merges them with the current
602    /// contents of @self.
603    ///
604    /// Upon errors, 0 will be returned and @error will be assigned a
605    /// `GError` from the `GTK_BUILDER_ERROR`, `G_MARKUP_ERROR` or `G_RESOURCE_ERROR`
606    /// domain.
607    ///
608    /// If you are adding an object that depends on an object that is not
609    /// its child (for instance a [`TreeView`][crate::TreeView] that depends on its
610    /// [`TreeModel`][crate::TreeModel]), you have to explicitly list all of them in @object_ids.
611    /// ## `resource_path`
612    /// the path of the resource file to parse
613    /// ## `object_ids`
614    /// nul-terminated array of objects to build
615    ///
616    /// # Returns
617    ///
618    /// [`true`] on success, [`false`] if an error occurred
619    #[doc(alias = "gtk_builder_add_objects_from_resource")]
620    pub fn add_objects_from_resource(
621        &self,
622        resource_path: &str,
623        object_ids: &[&str],
624    ) -> Result<(), glib::Error> {
625        unsafe {
626            let mut error = std::ptr::null_mut();
627            let is_ok = ffi::gtk_builder_add_objects_from_resource(
628                self.to_glib_none().0,
629                resource_path.to_glib_none().0,
630                object_ids.to_glib_none().0,
631                &mut error,
632            );
633            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
634            if error.is_null() {
635                Ok(())
636            } else {
637                Err(from_glib_full(error))
638            }
639        }
640    }
641
642    /// Parses a string containing a UI definition, building only the
643    /// requested objects and merges them with the current contents of
644    /// @self.
645    ///
646    /// Upon errors [`false`] will be returned and @error will be assigned a
647    /// `GError` from the `GTK_BUILDER_ERROR` or `G_MARKUP_ERROR` domain.
648    ///
649    /// If you are adding an object that depends on an object that is not
650    /// its child (for instance a [`TreeView`][crate::TreeView] that depends on its
651    /// [`TreeModel`][crate::TreeModel]), you have to explicitly list all of them in @object_ids.
652    /// ## `buffer`
653    /// the string to parse
654    /// ## `length`
655    /// the length of @buffer (may be -1 if @buffer is nul-terminated)
656    /// ## `object_ids`
657    /// nul-terminated array of objects to build
658    ///
659    /// # Returns
660    ///
661    /// [`true`] on success, [`false`] if an error occurred
662    #[doc(alias = "gtk_builder_add_objects_from_string")]
663    pub fn add_objects_from_string(
664        &self,
665        buffer: &str,
666        object_ids: &[&str],
667    ) -> Result<(), glib::Error> {
668        let length = buffer.len() as _;
669        unsafe {
670            let mut error = std::ptr::null_mut();
671            let is_ok = ffi::gtk_builder_add_objects_from_string(
672                self.to_glib_none().0,
673                buffer.to_glib_none().0,
674                length,
675                object_ids.to_glib_none().0,
676                &mut error,
677            );
678            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
679            if error.is_null() {
680                Ok(())
681            } else {
682                Err(from_glib_full(error))
683            }
684        }
685    }
686
687    /// Creates a closure to invoke the function called @function_name.
688    ///
689    /// This is using the create_closure() implementation of @self's
690    /// [`BuilderScope`][crate::BuilderScope].
691    ///
692    /// If no closure could be created, [`None`] will be returned and @error
693    /// will be set.
694    /// ## `function_name`
695    /// name of the function to look up
696    /// ## `flags`
697    /// closure creation flags
698    /// ## `object`
699    /// Object to create the closure with
700    ///
701    /// # Returns
702    ///
703    /// A new closure for invoking @function_name
704    #[doc(alias = "gtk_builder_create_closure")]
705    pub fn create_closure(
706        &self,
707        function_name: &str,
708        flags: BuilderClosureFlags,
709        object: Option<&impl IsA<glib::Object>>,
710    ) -> Result<Option<glib::Closure>, glib::Error> {
711        unsafe {
712            let mut error = std::ptr::null_mut();
713            let ret = ffi::gtk_builder_create_closure(
714                self.to_glib_none().0,
715                function_name.to_glib_none().0,
716                flags.into_glib(),
717                object.map(|p| p.as_ref()).to_glib_none().0,
718                &mut error,
719            );
720            if error.is_null() {
721                Ok(from_glib_full(ret))
722            } else {
723                Err(from_glib_full(error))
724            }
725        }
726    }
727
728    /// Add @object to the @self object pool so it can be
729    /// referenced just like any other object built by builder.
730    ///
731    /// Only a single object may be added using @name. However,
732    /// it is not an error to expose the same object under multiple
733    /// names. `gtk_builder_get_object()` may be used to determine
734    /// if an object has already been added with @name.
735    /// ## `name`
736    /// the name of the object exposed to the builder
737    /// ## `object`
738    /// the object to expose
739    #[doc(alias = "gtk_builder_expose_object")]
740    pub fn expose_object(&self, name: &str, object: &impl IsA<glib::Object>) {
741        unsafe {
742            ffi::gtk_builder_expose_object(
743                self.to_glib_none().0,
744                name.to_glib_none().0,
745                object.as_ref().to_glib_none().0,
746            );
747        }
748    }
749
750    /// Main private entry point for building composite components
751    /// from template XML.
752    ///
753    /// Most likely you do not need to call this function in applications as
754    /// templates are handled by [`Widget`][crate::Widget].
755    /// ## `object`
756    /// the object that is being extended
757    /// ## `template_type`
758    /// the type that the template is for
759    /// ## `buffer`
760    /// the string to parse
761    /// ## `length`
762    /// the length of @buffer (may be -1 if @buffer is nul-terminated)
763    ///
764    /// # Returns
765    ///
766    /// A positive value on success, 0 if an error occurred
767    #[doc(alias = "gtk_builder_extend_with_template")]
768    pub fn extend_with_template(
769        &self,
770        object: &impl IsA<glib::Object>,
771        template_type: glib::types::Type,
772        buffer: &str,
773    ) -> Result<(), glib::Error> {
774        let length = buffer.len() as _;
775        unsafe {
776            let mut error = std::ptr::null_mut();
777            let is_ok = ffi::gtk_builder_extend_with_template(
778                self.to_glib_none().0,
779                object.as_ref().to_glib_none().0,
780                template_type.into_glib(),
781                buffer.to_glib_none().0,
782                length,
783                &mut error,
784            );
785            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
786            if error.is_null() {
787                Ok(())
788            } else {
789                Err(from_glib_full(error))
790            }
791        }
792    }
793
794    /// Gets all objects that have been constructed by @self.
795    ///
796    /// Note that this function does not increment the reference
797    /// counts of the returned objects.
798    ///
799    /// # Returns
800    ///
801    /// a
802    ///   newly-allocated `GSList` containing all the objects
803    ///   constructed by the `GtkBuilder instance`. It should be
804    ///   freed by g_slist_free()
805    #[doc(alias = "gtk_builder_get_objects")]
806    #[doc(alias = "get_objects")]
807    pub fn objects(&self) -> Vec<glib::Object> {
808        unsafe {
809            FromGlibPtrContainer::from_glib_container(ffi::gtk_builder_get_objects(
810                self.to_glib_none().0,
811            ))
812        }
813    }
814
815    /// Gets the scope in use that was set via gtk_builder_set_scope().
816    ///
817    /// # Returns
818    ///
819    /// the current scope
820    #[doc(alias = "gtk_builder_get_scope")]
821    #[doc(alias = "get_scope")]
822    pub fn scope(&self) -> BuilderScope {
823        unsafe { from_glib_none(ffi::gtk_builder_get_scope(self.to_glib_none().0)) }
824    }
825
826    /// Gets the translation domain of @self.
827    ///
828    /// # Returns
829    ///
830    /// the translation domain
831    #[doc(alias = "gtk_builder_get_translation_domain")]
832    #[doc(alias = "get_translation_domain")]
833    #[doc(alias = "translation-domain")]
834    pub fn translation_domain(&self) -> Option<glib::GString> {
835        unsafe {
836            from_glib_none(ffi::gtk_builder_get_translation_domain(
837                self.to_glib_none().0,
838            ))
839        }
840    }
841
842    /// Looks up a type by name.
843    ///
844    /// This is using the virtual function that [`Builder`][crate::Builder] has
845    /// for that purpose. This is mainly used when implementing
846    /// the [`Buildable`][crate::Buildable] interface on a type.
847    /// ## `type_name`
848    /// type name to lookup
849    ///
850    /// # Returns
851    ///
852    /// the `GType` found for @type_name or `G_TYPE_INVALID`
853    ///   if no type was found
854    #[doc(alias = "gtk_builder_get_type_from_name")]
855    #[doc(alias = "get_type_from_name")]
856    pub fn type_from_name(&self, type_name: &str) -> glib::types::Type {
857        unsafe {
858            from_glib(ffi::gtk_builder_get_type_from_name(
859                self.to_glib_none().0,
860                type_name.to_glib_none().0,
861            ))
862        }
863    }
864
865    /// Sets the current object for the @self.
866    ///
867    /// The current object can be thought of as the `this` object that the
868    /// builder is working for and will often be used as the default object
869    /// when an object is optional.
870    ///
871    /// `Gtk::Widget::init_template()` for example will set the current
872    /// object to the widget the template is inited for. For functions like
873    /// [`from_resource()`][Self::from_resource()], the current object will be [`None`].
874    /// ## `current_object`
875    /// the new current object
876    #[doc(alias = "gtk_builder_set_current_object")]
877    #[doc(alias = "current-object")]
878    pub fn set_current_object(&self, current_object: Option<&impl IsA<glib::Object>>) {
879        unsafe {
880            ffi::gtk_builder_set_current_object(
881                self.to_glib_none().0,
882                current_object.map(|p| p.as_ref()).to_glib_none().0,
883            );
884        }
885    }
886
887    /// Sets the scope the builder should operate in.
888    ///
889    /// If @scope is [`None`], a new `Gtk::BuilderCScope` will be created.
890    /// ## `scope`
891    /// the scope to use
892    #[doc(alias = "gtk_builder_set_scope")]
893    #[doc(alias = "scope")]
894    pub fn set_scope(&self, scope: Option<&impl IsA<BuilderScope>>) {
895        unsafe {
896            ffi::gtk_builder_set_scope(
897                self.to_glib_none().0,
898                scope.map(|p| p.as_ref()).to_glib_none().0,
899            );
900        }
901    }
902
903    /// Sets the translation domain of @self.
904    /// ## `domain`
905    /// the translation domain
906    #[doc(alias = "gtk_builder_set_translation_domain")]
907    #[doc(alias = "translation-domain")]
908    pub fn set_translation_domain(&self, domain: Option<&str>) {
909        unsafe {
910            ffi::gtk_builder_set_translation_domain(self.to_glib_none().0, domain.to_glib_none().0);
911        }
912    }
913
914    /// Demarshals a value from a string.
915    ///
916    /// This function calls g_value_init() on the @value argument,
917    /// so it need not be initialised beforehand.
918    ///
919    /// Can handle char, uchar, boolean, int, uint, long,
920    /// ulong, enum, flags, float, double, string, [`gdk::RGBA`][crate::gdk::RGBA] and
921    /// [`Adjustment`][crate::Adjustment] type values.
922    ///
923    /// Upon errors [`false`] will be returned and @error will be
924    /// assigned a `GError` from the `GTK_BUILDER_ERROR` domain.
925    /// ## `pspec`
926    /// the `GParamSpec` for the property
927    /// ## `string`
928    /// the string representation of the value
929    ///
930    /// # Returns
931    ///
932    /// [`true`] on success
933    ///
934    /// ## `value`
935    /// the `GValue` to store the result in
936    #[doc(alias = "gtk_builder_value_from_string")]
937    pub fn value_from_string(
938        &self,
939        pspec: impl AsRef<glib::ParamSpec>,
940        string: &str,
941    ) -> Result<glib::Value, glib::Error> {
942        unsafe {
943            let mut value = glib::Value::uninitialized();
944            let mut error = std::ptr::null_mut();
945            let is_ok = ffi::gtk_builder_value_from_string(
946                self.to_glib_none().0,
947                pspec.as_ref().to_glib_none().0,
948                string.to_glib_none().0,
949                value.to_glib_none_mut().0,
950                &mut error,
951            );
952            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
953            if error.is_null() {
954                Ok(value)
955            } else {
956                Err(from_glib_full(error))
957            }
958        }
959    }
960
961    /// Demarshals a value from a string.
962    ///
963    /// Unlike [`value_from_string()`][Self::value_from_string()], this function
964    /// takes a `GType` instead of `GParamSpec`.
965    ///
966    /// Calls g_value_init() on the @value argument, so it
967    /// need not be initialised beforehand.
968    ///
969    /// Upon errors [`false`] will be returned and @error will be
970    /// assigned a `GError` from the `GTK_BUILDER_ERROR` domain.
971    /// ## `type_`
972    /// the `GType` of the value
973    /// ## `string`
974    /// the string representation of the value
975    ///
976    /// # Returns
977    ///
978    /// [`true`] on success
979    ///
980    /// ## `value`
981    /// the `GValue` to store the result in
982    #[doc(alias = "gtk_builder_value_from_string_type")]
983    pub fn value_from_string_type(
984        &self,
985        type_: glib::types::Type,
986        string: &str,
987    ) -> Result<glib::Value, glib::Error> {
988        unsafe {
989            let mut value = glib::Value::uninitialized();
990            let mut error = std::ptr::null_mut();
991            let is_ok = ffi::gtk_builder_value_from_string_type(
992                self.to_glib_none().0,
993                type_.into_glib(),
994                string.to_glib_none().0,
995                value.to_glib_none_mut().0,
996                &mut error,
997            );
998            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
999            if error.is_null() {
1000                Ok(value)
1001            } else {
1002                Err(from_glib_full(error))
1003            }
1004        }
1005    }
1006
1007    #[doc(alias = "current-object")]
1008    pub fn connect_current_object_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1009        unsafe extern "C" fn notify_current_object_trampoline<F: Fn(&Builder) + 'static>(
1010            this: *mut ffi::GtkBuilder,
1011            _param_spec: glib::ffi::gpointer,
1012            f: glib::ffi::gpointer,
1013        ) {
1014            let f: &F = &*(f as *const F);
1015            f(&from_glib_borrow(this))
1016        }
1017        unsafe {
1018            let f: Box_<F> = Box_::new(f);
1019            connect_raw(
1020                self.as_ptr() as *mut _,
1021                c"notify::current-object".as_ptr() as *const _,
1022                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1023                    notify_current_object_trampoline::<F> as *const (),
1024                )),
1025                Box_::into_raw(f),
1026            )
1027        }
1028    }
1029
1030    #[doc(alias = "scope")]
1031    pub fn connect_scope_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1032        unsafe extern "C" fn notify_scope_trampoline<F: Fn(&Builder) + 'static>(
1033            this: *mut ffi::GtkBuilder,
1034            _param_spec: glib::ffi::gpointer,
1035            f: glib::ffi::gpointer,
1036        ) {
1037            let f: &F = &*(f as *const F);
1038            f(&from_glib_borrow(this))
1039        }
1040        unsafe {
1041            let f: Box_<F> = Box_::new(f);
1042            connect_raw(
1043                self.as_ptr() as *mut _,
1044                c"notify::scope".as_ptr() as *const _,
1045                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1046                    notify_scope_trampoline::<F> as *const (),
1047                )),
1048                Box_::into_raw(f),
1049            )
1050        }
1051    }
1052
1053    #[doc(alias = "translation-domain")]
1054    pub fn connect_translation_domain_notify<F: Fn(&Self) + 'static>(
1055        &self,
1056        f: F,
1057    ) -> SignalHandlerId {
1058        unsafe extern "C" fn notify_translation_domain_trampoline<F: Fn(&Builder) + 'static>(
1059            this: *mut ffi::GtkBuilder,
1060            _param_spec: glib::ffi::gpointer,
1061            f: glib::ffi::gpointer,
1062        ) {
1063            let f: &F = &*(f as *const F);
1064            f(&from_glib_borrow(this))
1065        }
1066        unsafe {
1067            let f: Box_<F> = Box_::new(f);
1068            connect_raw(
1069                self.as_ptr() as *mut _,
1070                c"notify::translation-domain".as_ptr() as *const _,
1071                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1072                    notify_translation_domain_trampoline::<F> as *const (),
1073                )),
1074                Box_::into_raw(f),
1075            )
1076        }
1077    }
1078}
1079
1080impl Default for Builder {
1081    fn default() -> Self {
1082        Self::new()
1083    }
1084}