gstreamer_editing_services/auto/
clip.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// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5
6#[cfg(feature = "v1_18")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
8use crate::FrameNumber;
9use crate::{
10    ffi, Asset, BaseEffect, Container, Extractable, Layer, MetaContainer, TimelineElement, Track,
11    TrackElement, TrackType,
12};
13use glib::{
14    prelude::*,
15    signal::{connect_raw, SignalHandlerId},
16    translate::*,
17};
18use std::boxed::Box as Box_;
19
20glib::wrapper! {
21    /// [`Clip`][crate::Clip]-s are the core objects of a [`Layer`][crate::Layer]. Each clip may exist in
22    /// a single layer but may control several [`TrackElement`][crate::TrackElement]-s that span
23    /// several [`Track`][crate::Track]-s. A clip will ensure that all its children share the
24    /// same [`start`][struct@crate::TimelineElement#start] and [`duration`][struct@crate::TimelineElement#duration] in
25    /// their tracks, which will match the [`start`][struct@crate::TimelineElement#start] and
26    /// [`duration`][struct@crate::TimelineElement#duration] of the clip itself. Therefore, changing
27    /// the timing of the clip will change the timing of the children, and a
28    /// change in the timing of a child will change the timing of the clip and
29    /// subsequently all its siblings. As such, a clip can be treated as a
30    /// singular object in its layer.
31    ///
32    /// For most uses of a [`Timeline`][crate::Timeline], it is often sufficient to only
33    /// interact with [`Clip`][crate::Clip]-s directly, which will take care of creating and
34    /// organising the elements of the timeline's tracks.
35    ///
36    /// ## Core Children
37    ///
38    /// In more detail, clips will usually have some *core* [`TrackElement`][crate::TrackElement]
39    /// children, which are created by the clip when it is added to a layer in
40    /// a timeline. The type and form of these core children will depend on the
41    /// clip's subclass. You can use [`TrackElementExt::is_core()`][crate::prelude::TrackElementExt::is_core()] to determine
42    /// whether a track element is considered such a core track element. Note,
43    /// if a core track element is part of a clip, it will always be treated as
44    /// a core *child* of the clip. You can connect to the
45    /// [`child-added`][struct@crate::Container#child-added] signal to be notified of their creation.
46    ///
47    /// When a child is added to a clip, the timeline will select its tracks
48    /// using [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object]. Note that it may be the
49    /// case that the child will still have no set [`track`][struct@crate::TrackElement#track]
50    /// after this process. For example, if the timeline does not have a track
51    /// of the corresponding [`track-type`][struct@crate::Track#track-type]. A clip can safely contain
52    /// such children, which may have their track set later, although they will
53    /// play no functioning role in the timeline in the meantime.
54    ///
55    /// If a clip may create track elements with various
56    /// [`track-type`][struct@crate::TrackElement#track-type](s), such as a [`UriClip`][crate::UriClip], but you only
57    /// want it to create a subset of these types, you should set the
58    /// [`supported-formats`][struct@crate::Clip#supported-formats] of the clip to the subset of types. This
59    /// should be done *before* adding the clip to a layer.
60    ///
61    /// If a clip will produce several core elements of the same
62    /// [`track-type`][struct@crate::TrackElement#track-type], you should connect to the timeline's
63    /// [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object] signal to coordinate which
64    /// tracks each element should land in. Note, no two core children within a
65    /// clip can share the same [`Track`][crate::Track], so you should not select the same
66    /// track for two separate core children. Provided you stick to this rule,
67    /// it is still safe to select several tracks for the same core child, the
68    /// core child will be copied into the additional tracks. You can manually
69    /// add the child to more tracks later using [`ClipExt::add_child_to_track()`][crate::prelude::ClipExt::add_child_to_track()].
70    /// If you do not wish to use a core child, you can always select no track.
71    ///
72    /// The [`in-point`][struct@crate::TimelineElement#in-point] of the clip will control the
73    /// [`in-point`][struct@crate::TimelineElement#in-point] of its core children to be the same
74    /// value if their [`has-internal-source`][struct@crate::TrackElement#has-internal-source] is set to [`true`].
75    ///
76    /// The [`max-duration`][struct@crate::TimelineElement#max-duration] of the clip is the minimum
77    /// [`max-duration`][struct@crate::TimelineElement#max-duration] of its core children. If you set its
78    /// value to anything other than its current value, this will also set the
79    /// [`max-duration`][struct@crate::TimelineElement#max-duration] of all its core children to the same
80    /// value if their [`has-internal-source`][struct@crate::TrackElement#has-internal-source] is set to [`true`].
81    /// As a special case, whilst a clip does not yet have any core children,
82    /// its [`max-duration`][struct@crate::TimelineElement#max-duration] may be set to indicate what its
83    /// value will be once they are created.
84    ///
85    /// ## Effects
86    ///
87    /// Some subclasses ([`SourceClip`][crate::SourceClip] and [`BaseEffectClip`][crate::BaseEffectClip]) may also allow
88    /// their objects to have additional non-core [`BaseEffect`][crate::BaseEffect]-s elements as
89    /// children. These are additional effects that are applied to the output
90    /// data of the core elements. They can be added to the clip using
91    /// [`ClipExt::add_top_effect()`][crate::prelude::ClipExt::add_top_effect()], which will take care of adding the effect to
92    /// the timeline's tracks. The new effect will be placed between the clip's
93    /// core track elements and its other effects. As such, the newly added
94    /// effect will be applied to any source data **before** the other existing
95    /// effects. You can change the ordering of effects using
96    /// [`ClipExt::set_top_effect_index()`][crate::prelude::ClipExt::set_top_effect_index()].
97    ///
98    /// Tracks are selected for top effects in the same way as core children.
99    /// If you add a top effect to a clip before it is part of a timeline, and
100    /// later add the clip to a timeline, the track selection for the top
101    /// effects will occur just after the track selection for the core
102    /// children. If you add a top effect to a clip that is already part of a
103    /// timeline, the track selection will occur immediately. Since a top
104    /// effect must be applied on top of a core child, if you use
105    /// [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object], you should ensure that the
106    /// added effects are destined for a [`Track`][crate::Track] that already contains a core
107    /// child.
108    ///
109    /// In addition, if the core child in the track is not
110    /// [`active`][struct@crate::TrackElement#active], then neither can any of its effects be
111    /// [`active`][struct@crate::TrackElement#active]. Therefore, if a core child is made in-active,
112    /// all of the additional effects in the same track will also become
113    /// in-active. Similarly, if an effect is set to be active, then the core
114    /// child will also become active, but other effects will be left alone.
115    /// Finally, if an active effect is added to the track of an in-active core
116    /// child, it will become in-active as well. Note, in contrast, setting a
117    /// core child to be active, or an effect to be in-active will *not* change
118    /// the other children in the same track.
119    ///
120    /// ### Time Effects
121    ///
122    /// Some effects also change the timing of their data (see [`BaseEffect`][crate::BaseEffect]
123    /// for what counts as a time effect). Note that a [`BaseEffectClip`][crate::BaseEffectClip] will
124    /// refuse time effects, but a [`Source`][crate::Source] will allow them.
125    ///
126    /// When added to a clip, time effects may adjust the timing of other
127    /// children in the same track. Similarly, when changing the order of
128    /// effects, making them (in)-active, setting their time property values
129    /// or removing time effects. These can cause the [`duration-limit`][struct@crate::Clip#duration-limit]
130    /// to change in value. However, if such an operation would ever cause the
131    /// [`duration`][struct@crate::TimelineElement#duration] to shrink such that a clip's [`Source`][crate::Source] is
132    /// totally overlapped in the timeline, the operation would be prevented.
133    /// Note that the same can happen when adding non-time effects with a
134    /// finite [`max-duration`][struct@crate::TimelineElement#max-duration].
135    ///
136    /// Therefore, when working with time effects, you should -- more so than
137    /// usual -- not assume that setting the properties of the clip's children
138    /// will succeed. In particular, you should use
139    /// [`TimelineElementExt::set_child_property_full()`][crate::prelude::TimelineElementExt::set_child_property_full()] when setting the time
140    /// properties.
141    ///
142    /// If you wish to preserve the *internal* duration of a source in a clip
143    /// during these time effect operations, you can do something like the
144    /// following.
145    ///
146    /// **⚠️ The following code is in c ⚠️**
147    ///
148    /// ```c
149    /// void
150    /// do_time_effect_change (GESClip * clip)
151    /// {
152    ///   GList *tmp, *children;
153    ///   GESTrackElement *source;
154    ///   GstClockTime source_outpoint;
155    ///   GstClockTime new_end;
156    ///   GError *error = NULL;
157    ///
158    ///   // choose some active source in a track to preserve the internal
159    ///   // duration of
160    ///   source = ges_clip_get_track_element (clip, NULL, GES_TYPE_SOURCE);
161    ///
162    ///   // note its current internal end time
163    ///   source_outpoint = ges_clip_get_internal_time_from_timeline_time (
164    ///         clip, source, GES_TIMELINE_ELEMENT_END (clip), NULL);
165    ///
166    ///   // handle invalid out-point
167    ///
168    ///   // stop the children's control sources from clamping when their
169    ///   // out-point changes with a change in the time effects
170    ///   children = ges_container_get_children (GES_CONTAINER (clip), FALSE);
171    ///
172    ///   for (tmp = children; tmp; tmp = tmp->next)
173    ///     ges_track_element_set_auto_clamp_control_sources (tmp->data, FALSE);
174    ///
175    ///   // add time effect, or set their children properties, or move them around
176    ///   ...
177    ///   // user can make sure that if a time effect changes one source, we should
178    ///   // also change the time effect for another source. E.g. if
179    ///   // "GstVideorate::rate" is set to 2.0, we also set "GstPitch::rate" to
180    ///   // 2.0
181    ///
182    ///   // Note the duration of the clip may have already changed if the
183    ///   // duration-limit of the clip dropped below its current value
184    ///
185    ///   new_end = ges_clip_get_timeline_time_from_internal_time (
186    ///         clip, source, source_outpoint, &error);
187    ///   // handle error
188    ///
189    ///   if (!ges_timeline_elemnet_edit_full (GES_TIMELINE_ELEMENT (clip),
190    ///         -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, new_end, &error))
191    ///     // handle error
192    ///
193    ///   for (tmp = children; tmp; tmp = tmp->next)
194    ///     ges_track_element_set_auto_clamp_control_sources (tmp->data, TRUE);
195    ///
196    ///   g_list_free_full (children, gst_object_unref);
197    ///   gst_object_unref (source);
198    /// }
199    /// ```
200    ///
201    /// This is an Abstract Base Class, you cannot instantiate it.
202    ///
203    /// ## Properties
204    ///
205    ///
206    /// #### `duration-limit`
207    ///  The maximum [`duration`][struct@crate::TimelineElement#duration] that can be *currently* set
208    /// for the clip, taking into account the [`in-point`][struct@crate::TimelineElement#in-point],
209    /// [`max-duration`][struct@crate::TimelineElement#max-duration], [`active`][struct@crate::TrackElement#active], and
210    /// [`track`][struct@crate::TrackElement#track] properties of its children, as well as any
211    /// time effects. If there is no limit, this will be set to
212    /// `GST_CLOCK_TIME_NONE`.
213    ///
214    /// Note that whilst a clip has no children in any tracks, the limit will
215    /// be unknown, and similarly set to `GST_CLOCK_TIME_NONE`.
216    ///
217    /// If the duration-limit would ever go below the current
218    /// [`duration`][struct@crate::TimelineElement#duration] of the clip due to a change in the above
219    /// variables, its [`duration`][struct@crate::TimelineElement#duration] will be set to the new
220    /// limit.
221    ///
222    /// Readable
223    ///
224    ///
225    /// #### `layer`
226    ///  The layer this clip lies in.
227    ///
228    /// If you want to connect to this property's [`notify`][struct@crate::glib::Object#notify] signal,
229    /// you should connect to it with `g_signal_connect_after()` since the
230    /// signal emission may be stopped internally.
231    ///
232    /// Readable
233    ///
234    ///
235    /// #### `supported-formats`
236    ///  The [`TrackType`][crate::TrackType]-s that the clip supports, which it can create
237    /// [`TrackElement`][crate::TrackElement]-s for. Note that this can be a combination of
238    /// [`TrackType`][crate::TrackType] flags to indicate support for several
239    /// [`track-type`][struct@crate::TrackElement#track-type] elements.
240    ///
241    /// Readable | Writeable | Construct
242    /// <details><summary><h4>Container</h4></summary>
243    ///
244    ///
245    /// #### `height`
246    ///  The span of the container's children's [`priority`][struct@crate::TimelineElement#priority]
247    /// values, which is the number of integers that lie between (inclusive)
248    /// the minimum and maximum priorities found amongst the container's
249    /// children (maximum - minimum + 1).
250    ///
251    /// Readable
252    /// </details>
253    /// <details><summary><h4>TimelineElement</h4></summary>
254    ///
255    ///
256    /// #### `duration`
257    ///  The duration that the element is in effect for in the timeline (a
258    /// time difference in nanoseconds using the time coordinates of the
259    /// timeline). For example, for a source element, this would determine
260    /// for how long it should output its internal content for. For an
261    /// operation element, this would determine for how long its effect
262    /// should be applied to any source content.
263    ///
264    /// Readable | Writeable
265    ///
266    ///
267    /// #### `in-point`
268    ///  The initial offset to use internally when outputting content (in
269    /// nanoseconds, but in the time coordinates of the internal content).
270    ///
271    /// For example, for a [`VideoUriSource`][crate::VideoUriSource] that references some media
272    /// file, the "internal content" is the media file data, and the
273    /// in-point would correspond to some timestamp in the media file.
274    /// When playing the timeline, and when the element is first reached at
275    /// timeline-time [`start`][struct@crate::TimelineElement#start], it will begin outputting the
276    /// data from the timestamp in-point **onwards**, until it reaches the
277    /// end of its [`duration`][struct@crate::TimelineElement#duration] in the timeline.
278    ///
279    /// For elements that have no internal content, this should be kept
280    /// as 0.
281    ///
282    /// Readable | Writeable
283    ///
284    ///
285    /// #### `max-duration`
286    ///  The full duration of internal content that is available (a time
287    /// difference in nanoseconds using the time coordinates of the internal
288    /// content).
289    ///
290    /// This will act as a cap on the [`in-point`][struct@crate::TimelineElement#in-point] of the
291    /// element (which is in the same time coordinates), and will sometimes
292    /// be used to limit the [`duration`][struct@crate::TimelineElement#duration] of the element in
293    /// the timeline.
294    ///
295    /// For example, for a [`VideoUriSource`][crate::VideoUriSource] that references some media
296    /// file, this would be the length of the media file.
297    ///
298    /// For elements that have no internal content, or whose content is
299    /// indefinite, this should be kept as `GST_CLOCK_TIME_NONE`.
300    ///
301    /// Readable | Writeable | Construct
302    ///
303    ///
304    /// #### `name`
305    ///  The name of the element. This should be unique within its timeline.
306    ///
307    /// Readable | Writeable | Construct
308    ///
309    ///
310    /// #### `parent`
311    ///  The parent container of the element.
312    ///
313    /// Readable | Writeable
314    ///
315    ///
316    /// #### `priority`
317    ///  The priority of the element.
318    ///
319    /// Readable | Writeable
320    ///
321    ///
322    /// #### `serialize`
323    ///  Whether the element should be serialized.
324    ///
325    /// Readable | Writeable
326    ///
327    ///
328    /// #### `start`
329    ///  The starting position of the element in the timeline (in nanoseconds
330    /// and in the time coordinates of the timeline). For example, for a
331    /// source element, this would determine the time at which it should
332    /// start outputting its internal content. For an operation element, this
333    /// would determine the time at which it should start applying its effect
334    /// to any source content.
335    ///
336    /// Readable | Writeable
337    ///
338    ///
339    /// #### `timeline`
340    ///  The timeline that the element lies within.
341    ///
342    /// Readable | Writeable
343    /// </details>
344    ///
345    /// # Implements
346    ///
347    /// [`ClipExt`][trait@crate::prelude::ClipExt], [`GESContainerExt`][trait@crate::prelude::GESContainerExt], [`TimelineElementExt`][trait@crate::prelude::TimelineElementExt], [`trait@glib::ObjectExt`], [`ExtractableExt`][trait@crate::prelude::ExtractableExt], [`MetaContainerExt`][trait@crate::prelude::MetaContainerExt], [`TimelineElementExtManual`][trait@crate::prelude::TimelineElementExtManual]
348    #[doc(alias = "GESClip")]
349    pub struct Clip(Object<ffi::GESClip, ffi::GESClipClass>) @extends Container, TimelineElement, @implements Extractable, MetaContainer;
350
351    match fn {
352        type_ => || ffi::ges_clip_get_type(),
353    }
354}
355
356impl Clip {
357    pub const NONE: Option<&'static Clip> = None;
358}
359
360mod sealed {
361    pub trait Sealed {}
362    impl<T: super::IsA<super::Clip>> Sealed for T {}
363}
364
365/// Trait containing all [`struct@Clip`] methods.
366///
367/// # Implementors
368///
369/// [`Clip`][struct@crate::Clip], [`OperationClip`][struct@crate::OperationClip], [`SourceClip`][struct@crate::SourceClip]
370pub trait ClipExt: IsA<Clip> + sealed::Sealed + 'static {
371    /// Extracts a [`TrackElement`][crate::TrackElement] from an asset and adds it to the clip.
372    /// This can be used to add effects that derive from the asset to the
373    /// clip, but this method is not intended to be used to create the core
374    /// elements of the clip.
375    /// ## `asset`
376    /// An asset with `GES_TYPE_TRACK_ELEMENT` as its
377    /// [`extractable-type`][struct@crate::Asset#extractable-type]
378    ///
379    /// # Returns
380    ///
381    /// The newly created element, or
382    /// [`None`] if an error occurred.
383    #[doc(alias = "ges_clip_add_asset")]
384    fn add_asset(&self, asset: &impl IsA<Asset>) -> Result<TrackElement, glib::BoolError> {
385        unsafe {
386            Option::<_>::from_glib_none(ffi::ges_clip_add_asset(
387                self.as_ref().to_glib_none().0,
388                asset.as_ref().to_glib_none().0,
389            ))
390            .ok_or_else(|| glib::bool_error!("Failed to add asset"))
391        }
392    }
393
394    /// Adds the track element child of the clip to a specific track.
395    ///
396    /// If the given child is already in another track, this will create a copy
397    /// of the child, add it to the clip, and add this copy to the track.
398    ///
399    /// You should only call this whilst a clip is part of a [`Timeline`][crate::Timeline], and
400    /// for tracks that are in the same timeline.
401    ///
402    /// This method is an alternative to using the
403    /// [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object] signal, but can be used to
404    /// complement it when, say, you wish to copy a clip's children from one
405    /// track into a new one.
406    ///
407    /// When the child is a core child, it must be added to a track that does
408    /// not already contain another core child of the same clip. If it is not a
409    /// core child (an additional effect), then it must be added to a track
410    /// that already contains one of the core children of the same clip.
411    ///
412    /// This method can also fail if the adding the track element to the track
413    /// would break a configuration rule of the corresponding [`Timeline`][crate::Timeline],
414    /// such as causing three sources to overlap at a single time, or causing
415    /// a source to completely overlap another in the same track.
416    /// ## `child`
417    /// A child of `self`
418    /// ## `track`
419    /// The track to add `child` to
420    ///
421    /// # Returns
422    ///
423    /// The element that was added to `track`, either
424    /// `child` or a copy of child, or [`None`] if the element could not be added.
425    #[cfg(feature = "v1_18")]
426    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
427    #[doc(alias = "ges_clip_add_child_to_track")]
428    fn add_child_to_track(
429        &self,
430        child: &impl IsA<TrackElement>,
431        track: &impl IsA<Track>,
432    ) -> Result<TrackElement, glib::Error> {
433        unsafe {
434            let mut error = std::ptr::null_mut();
435            let ret = ffi::ges_clip_add_child_to_track(
436                self.as_ref().to_glib_none().0,
437                child.as_ref().to_glib_none().0,
438                track.as_ref().to_glib_none().0,
439                &mut error,
440            );
441            if error.is_null() {
442                Ok(from_glib_none(ret))
443            } else {
444                Err(from_glib_full(error))
445            }
446        }
447    }
448
449    /// Add a top effect to a clip at the given index.
450    ///
451    /// Unlike using [`GESContainerExt::add()`][crate::prelude::GESContainerExt::add()], this allows you to set the index
452    /// in advance. It will also check that no error occurred during the track
453    /// selection for the effect.
454    ///
455    /// Note, only subclasses of `GESClipClass` that have
456    /// `GES_CLIP_CLASS_CAN_ADD_EFFECTS` set to [`true`] (such as [`SourceClip`][crate::SourceClip]
457    /// and [`BaseEffectClip`][crate::BaseEffectClip]) can have additional top effects added.
458    ///
459    /// Note, if the effect is a time effect, this may be refused if the clip
460    /// would not be able to adapt itself once the effect is added.
461    /// ## `effect`
462    /// A top effect to add
463    /// ## `index`
464    /// The index to add `effect` at, or -1 to add at the highest,
465    ///  see `ges_clip_get_top_effect_index` for more information
466    ///
467    /// # Returns
468    ///
469    /// [`true`] if `effect` was successfully added to `self` at `index`.
470    #[cfg(feature = "v1_18")]
471    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
472    #[doc(alias = "ges_clip_add_top_effect")]
473    fn add_top_effect(&self, effect: &impl IsA<BaseEffect>, index: i32) -> Result<(), glib::Error> {
474        unsafe {
475            let mut error = std::ptr::null_mut();
476            let is_ok = ffi::ges_clip_add_top_effect(
477                self.as_ref().to_glib_none().0,
478                effect.as_ref().to_glib_none().0,
479                index,
480                &mut error,
481            );
482            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
483            if error.is_null() {
484                Ok(())
485            } else {
486                Err(from_glib_full(error))
487            }
488        }
489    }
490
491    /// Finds an element controlled by the clip. If `track` is given,
492    /// then only the track elements in `track` are searched for. If `type_` is
493    /// given, then this function searches for a track element of the given
494    /// `type_`.
495    ///
496    /// Note, if multiple track elements in the clip match the given criteria,
497    /// this will return the element amongst them with the highest
498    /// [`priority`][struct@crate::TimelineElement#priority] (numerically, the smallest). See
499    /// [`find_track_elements()`][Self::find_track_elements()] if you wish to find all such elements.
500    /// ## `track`
501    /// The track to search in, or [`None`] to search in
502    /// all tracks
503    /// ## `type_`
504    /// The type of track element to search for, or `G_TYPE_NONE` to
505    /// match any type
506    ///
507    /// # Returns
508    ///
509    /// The element controlled by
510    /// `self`, in `track`, and of the given `type_`, or [`None`] if no such element
511    /// could be found.
512    #[doc(alias = "ges_clip_find_track_element")]
513    fn find_track_element(
514        &self,
515        track: Option<&impl IsA<Track>>,
516        type_: glib::types::Type,
517    ) -> Option<TrackElement> {
518        unsafe {
519            from_glib_full(ffi::ges_clip_find_track_element(
520                self.as_ref().to_glib_none().0,
521                track.map(|p| p.as_ref()).to_glib_none().0,
522                type_.into_glib(),
523            ))
524        }
525    }
526
527    /// Finds the [`TrackElement`][crate::TrackElement]-s controlled by the clip that match the
528    /// given criteria. If `track` is given as [`None`] and `track_type` is given as
529    /// [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN], then the search will match all elements in any
530    /// track, including those with no track, and of any
531    /// [`track-type`][struct@crate::TrackElement#track-type]. Otherwise, if `track` is not [`None`], but
532    /// `track_type` is [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN], then only the track elements in
533    /// `track` are searched for. Otherwise, if `track_type` is not
534    /// [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN], but `track` is [`None`], then only the track
535    /// elements whose [`track-type`][struct@crate::TrackElement#track-type] matches `track_type` are
536    /// searched for. Otherwise, when both are given, the track elements that
537    /// match **either** criteria are searched for. Therefore, if you wish to
538    /// only find elements in a specific track, you should give the track as
539    /// `track`, but you should not give the track's [`track-type`][struct@crate::Track#track-type] as
540    /// `track_type` because this would also select elements from other tracks
541    /// of the same type.
542    ///
543    /// You may also give `type_` to _further_ restrict the search to track
544    /// elements of the given `type_`.
545    /// ## `track`
546    /// The track to search in, or [`None`] to search in
547    /// all tracks
548    /// ## `track_type`
549    /// The track-type of the track element to search for, or
550    /// [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN] to match any track type
551    /// ## `type_`
552    /// The type of track element to search for, or `G_TYPE_NONE` to
553    /// match any type
554    ///
555    /// # Returns
556    ///
557    /// A list of all
558    /// the [`TrackElement`][crate::TrackElement]-s controlled by `self`, in `track` or of the given
559    /// `track_type`, and of the given `type_`.
560    #[doc(alias = "ges_clip_find_track_elements")]
561    fn find_track_elements(
562        &self,
563        track: Option<&impl IsA<Track>>,
564        track_type: TrackType,
565        type_: glib::types::Type,
566    ) -> Vec<TrackElement> {
567        unsafe {
568            FromGlibPtrContainer::from_glib_full(ffi::ges_clip_find_track_elements(
569                self.as_ref().to_glib_none().0,
570                track.map(|p| p.as_ref()).to_glib_none().0,
571                track_type.into_glib(),
572                type_.into_glib(),
573            ))
574        }
575    }
576
577    /// Gets the [`duration-limit`][struct@crate::Clip#duration-limit] of the clip.
578    ///
579    /// # Returns
580    ///
581    /// The duration-limit of `self`.
582    #[cfg(feature = "v1_18")]
583    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
584    #[doc(alias = "ges_clip_get_duration_limit")]
585    #[doc(alias = "get_duration_limit")]
586    #[doc(alias = "duration-limit")]
587    fn duration_limit(&self) -> gst::ClockTime {
588        unsafe {
589            try_from_glib(ffi::ges_clip_get_duration_limit(
590                self.as_ref().to_glib_none().0,
591            ))
592            .expect("mandatory glib value is None")
593        }
594    }
595
596    /// Convert the timeline time to an internal source time of the child.
597    /// This will take any time effects placed on the clip into account (see
598    /// [`BaseEffect`][crate::BaseEffect] for what time effects are supported, and how to
599    /// declare them in GES).
600    ///
601    /// When `timeline_time` is above the [`start`][struct@crate::TimelineElement#start] of `self`,
602    /// this will return the internal time at which the content that appears at
603    /// `timeline_time` in the output of the timeline is created in `child`. For
604    /// example, if `timeline_time` corresponds to the current seek position,
605    /// this would let you know which part of a media file is being read.
606    ///
607    /// This will be done assuming the clip has an indefinite end, so the
608    /// internal time may be beyond the current out-point of the child, or even
609    /// its [`max-duration`][struct@crate::TimelineElement#max-duration].
610    ///
611    /// If, instead, `timeline_time` is below the current
612    /// [`start`][struct@crate::TimelineElement#start] of `self`, this will return what you would
613    /// need to set the [`in-point`][struct@crate::TimelineElement#in-point] of `child` to if you set
614    /// the [`start`][struct@crate::TimelineElement#start] of `self` to `timeline_time` and wanted
615    /// to keep the content of `child` currently found at the current
616    /// [`start`][struct@crate::TimelineElement#start] of `self` at the same timeline position. If
617    /// this would be negative, the conversion fails. This is useful for
618    /// determining what [`in-point`][struct@crate::TimelineElement#in-point] would result from a
619    /// [`EditMode::Trim`][crate::EditMode::Trim] to `timeline_time`.
620    ///
621    /// Note that whilst a clip has no time effects, this second return is
622    /// equivalent to finding the internal time at which the content that
623    /// appears at `timeline_time` in the timeline can be found in `child` if it
624    /// had indefinite extent in both directions. However, with non-linear time
625    /// effects this second return will be more distinct.
626    ///
627    /// In either case, the returned time would be appropriate to use for the
628    /// [`in-point`][struct@crate::TimelineElement#in-point] or [`max-duration`][struct@crate::TimelineElement#max-duration] of the
629    /// child.
630    ///
631    /// See [`timeline_time_from_internal_time()`][Self::timeline_time_from_internal_time()], which performs the
632    /// reverse.
633    /// ## `child`
634    /// An [`active`][struct@crate::TrackElement#active] child of `self` with a
635    /// [`track`][struct@crate::TrackElement#track]
636    /// ## `timeline_time`
637    /// A time in the timeline time coordinates
638    ///
639    /// # Returns
640    ///
641    /// The time in the internal coordinates of `child` corresponding
642    /// to `timeline_time`, or `GST_CLOCK_TIME_NONE` if the conversion could not
643    /// be performed.
644    #[cfg(feature = "v1_18")]
645    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
646    #[doc(alias = "ges_clip_get_internal_time_from_timeline_time")]
647    #[doc(alias = "get_internal_time_from_timeline_time")]
648    fn internal_time_from_timeline_time(
649        &self,
650        child: &impl IsA<TrackElement>,
651        timeline_time: impl Into<Option<gst::ClockTime>>,
652    ) -> Result<Option<gst::ClockTime>, glib::Error> {
653        unsafe {
654            let mut error = std::ptr::null_mut();
655            let ret = ffi::ges_clip_get_internal_time_from_timeline_time(
656                self.as_ref().to_glib_none().0,
657                child.as_ref().to_glib_none().0,
658                timeline_time.into().into_glib(),
659                &mut error,
660            );
661            if error.is_null() {
662                Ok(from_glib(ret))
663            } else {
664                Err(from_glib_full(error))
665            }
666        }
667    }
668
669    /// Gets the [`layer`][struct@crate::Clip#layer] of the clip.
670    ///
671    /// # Returns
672    ///
673    /// The layer `self` is in, or [`None`] if
674    /// `self` is not in any layer.
675    #[doc(alias = "ges_clip_get_layer")]
676    #[doc(alias = "get_layer")]
677    fn layer(&self) -> Option<Layer> {
678        unsafe { from_glib_full(ffi::ges_clip_get_layer(self.as_ref().to_glib_none().0)) }
679    }
680
681    /// Gets the [`supported-formats`][struct@crate::Clip#supported-formats] of the clip.
682    ///
683    /// # Returns
684    ///
685    /// The [`TrackType`][crate::TrackType]-s supported by `self`.
686    #[doc(alias = "ges_clip_get_supported_formats")]
687    #[doc(alias = "get_supported_formats")]
688    #[doc(alias = "supported-formats")]
689    fn supported_formats(&self) -> TrackType {
690        unsafe {
691            from_glib(ffi::ges_clip_get_supported_formats(
692                self.as_ref().to_glib_none().0,
693            ))
694        }
695    }
696
697    /// Convert the internal source time from the child to a timeline time.
698    /// This will take any time effects placed on the clip into account (see
699    /// [`BaseEffect`][crate::BaseEffect] for what time effects are supported, and how to
700    /// declare them in GES).
701    ///
702    /// When `internal_time` is above the [`in-point`][struct@crate::TimelineElement#in-point] of
703    /// `child`, this will return the timeline time at which the internal
704    /// content found at `internal_time` appears in the output of the timeline's
705    /// track. For example, this would let you know where in the timeline a
706    /// particular scene in a media file would appear.
707    ///
708    /// This will be done assuming the clip has an indefinite end, so the
709    /// timeline time may be beyond the end of the clip, or even breaking its
710    /// [`duration-limit`][struct@crate::Clip#duration-limit].
711    ///
712    /// If, instead, `internal_time` is below the current
713    /// [`in-point`][struct@crate::TimelineElement#in-point] of `child`, this will return what you would
714    /// need to set the [`start`][struct@crate::TimelineElement#start] of `self` to if you set the
715    /// [`in-point`][struct@crate::TimelineElement#in-point] of `child` to `internal_time` and wanted to
716    /// keep the content of `child` currently found at the current
717    /// [`start`][struct@crate::TimelineElement#start] of `self` at the same timeline position. If
718    /// this would be negative, the conversion fails. This is useful for
719    /// determining what position to use in a [`EditMode::Trim`][crate::EditMode::Trim] if you wish
720    /// to trim to a specific point in the internal content, such as a
721    /// particular scene in a media file.
722    ///
723    /// Note that whilst a clip has no time effects, this second return is
724    /// equivalent to finding the timeline time at which the content of `child`
725    /// at `internal_time` would be found in the timeline if it had indefinite
726    /// extent in both directions. However, with non-linear time effects this
727    /// second return will be more distinct.
728    ///
729    /// In either case, the returned time would be appropriate to use in
730    /// [`TimelineElementExt::edit()`][crate::prelude::TimelineElementExt::edit()] for [`EditMode::Trim`][crate::EditMode::Trim], and similar, if
731    /// you wish to use a particular internal point as a reference. For
732    /// example, you could choose to end a clip at a certain internal
733    /// 'out-point', similar to the [`in-point`][struct@crate::TimelineElement#in-point], by
734    /// translating the desired end time into the timeline coordinates, and
735    /// using this position to trim the end of a clip.
736    ///
737    /// See [`internal_time_from_timeline_time()`][Self::internal_time_from_timeline_time()], which performs the
738    /// reverse, or [`timeline_time_from_source_frame()`][Self::timeline_time_from_source_frame()] which does
739    /// the same conversion, but using frame numbers.
740    /// ## `child`
741    /// An [`active`][struct@crate::TrackElement#active] child of `self` with a
742    /// [`track`][struct@crate::TrackElement#track]
743    /// ## `internal_time`
744    /// A time in the internal time coordinates of `child`
745    ///
746    /// # Returns
747    ///
748    /// The time in the timeline coordinates corresponding to
749    /// `internal_time`, or `GST_CLOCK_TIME_NONE` if the conversion could not be
750    /// performed.
751    #[cfg(feature = "v1_18")]
752    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
753    #[doc(alias = "ges_clip_get_timeline_time_from_internal_time")]
754    #[doc(alias = "get_timeline_time_from_internal_time")]
755    fn timeline_time_from_internal_time(
756        &self,
757        child: &impl IsA<TrackElement>,
758        internal_time: impl Into<Option<gst::ClockTime>>,
759    ) -> Result<Option<gst::ClockTime>, glib::Error> {
760        unsafe {
761            let mut error = std::ptr::null_mut();
762            let ret = ffi::ges_clip_get_timeline_time_from_internal_time(
763                self.as_ref().to_glib_none().0,
764                child.as_ref().to_glib_none().0,
765                internal_time.into().into_glib(),
766                &mut error,
767            );
768            if error.is_null() {
769                Ok(from_glib(ret))
770            } else {
771                Err(from_glib_full(error))
772            }
773        }
774    }
775
776    /// Convert the source frame number to a timeline time. This acts the same
777    /// as [`timeline_time_from_internal_time()`][Self::timeline_time_from_internal_time()] using the core
778    /// children of the clip and using the frame number to specify the internal
779    /// position, rather than a timestamp.
780    ///
781    /// The returned timeline time can be used to seek or edit to a specific
782    /// frame.
783    ///
784    /// Note that you can get the frame timestamp of a particular clip asset
785    /// with [`ClipAssetExt::frame_time()`][crate::prelude::ClipAssetExt::frame_time()].
786    /// ## `frame_number`
787    /// The frame number to get the corresponding timestamp of
788    /// in the timeline coordinates
789    ///
790    /// # Returns
791    ///
792    /// The timestamp corresponding to `frame_number` in the core
793    /// children of `self`, in the timeline coordinates, or `GST_CLOCK_TIME_NONE`
794    /// if the conversion could not be performed.
795    #[cfg(feature = "v1_18")]
796    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
797    #[doc(alias = "ges_clip_get_timeline_time_from_source_frame")]
798    #[doc(alias = "get_timeline_time_from_source_frame")]
799    fn timeline_time_from_source_frame(
800        &self,
801        frame_number: FrameNumber,
802    ) -> Result<Option<gst::ClockTime>, glib::Error> {
803        unsafe {
804            let mut error = std::ptr::null_mut();
805            let ret = ffi::ges_clip_get_timeline_time_from_source_frame(
806                self.as_ref().to_glib_none().0,
807                frame_number,
808                &mut error,
809            );
810            if error.is_null() {
811                Ok(from_glib(ret))
812            } else {
813                Err(from_glib_full(error))
814            }
815        }
816    }
817
818    /// Gets the internal index of an effect in the clip. The index of effects
819    /// in a clip will run from 0 to n-1, where n is the total number of
820    /// effects. If two effects share the same [`track`][struct@crate::TrackElement#track], the
821    /// effect with the numerically lower index will be applied to the source
822    /// data **after** the other effect, i.e. output data will always flow from
823    /// a higher index effect to a lower index effect.
824    /// ## `effect`
825    /// The effect we want to get the index of
826    ///
827    /// # Returns
828    ///
829    /// The index of `effect` in `self`, or -1 if something went wrong.
830    #[doc(alias = "ges_clip_get_top_effect_index")]
831    #[doc(alias = "get_top_effect_index")]
832    fn top_effect_index(&self, effect: &impl IsA<BaseEffect>) -> i32 {
833        unsafe {
834            ffi::ges_clip_get_top_effect_index(
835                self.as_ref().to_glib_none().0,
836                effect.as_ref().to_glib_none().0,
837            )
838        }
839    }
840
841    #[doc(alias = "ges_clip_get_top_effect_position")]
842    #[doc(alias = "get_top_effect_position")]
843    fn top_effect_position(&self, effect: &impl IsA<BaseEffect>) -> i32 {
844        unsafe {
845            ffi::ges_clip_get_top_effect_position(
846                self.as_ref().to_glib_none().0,
847                effect.as_ref().to_glib_none().0,
848            )
849        }
850    }
851
852    /// Gets the [`BaseEffect`][crate::BaseEffect]-s that have been added to the clip. The
853    /// returned list is ordered by their internal index in the clip. See
854    /// [`top_effect_index()`][Self::top_effect_index()].
855    ///
856    /// # Returns
857    ///
858    /// A list of all
859    /// [`BaseEffect`][crate::BaseEffect]-s that have been added to `self`.
860    #[doc(alias = "ges_clip_get_top_effects")]
861    #[doc(alias = "get_top_effects")]
862    fn top_effects(&self) -> Vec<TrackElement> {
863        unsafe {
864            FromGlibPtrContainer::from_glib_full(ffi::ges_clip_get_top_effects(
865                self.as_ref().to_glib_none().0,
866            ))
867        }
868    }
869
870    /// See [`move_to_layer_full()`][Self::move_to_layer_full()], which also gives an error.
871    /// ## `layer`
872    /// The new layer
873    ///
874    /// # Returns
875    ///
876    /// [`true`] if `self` was successfully moved to `layer`.
877    #[doc(alias = "ges_clip_move_to_layer")]
878    fn move_to_layer(&self, layer: &impl IsA<Layer>) -> Result<(), glib::error::BoolError> {
879        unsafe {
880            glib::result_from_gboolean!(
881                ffi::ges_clip_move_to_layer(
882                    self.as_ref().to_glib_none().0,
883                    layer.as_ref().to_glib_none().0
884                ),
885                "Failed to move clip to specified layer"
886            )
887        }
888    }
889
890    /// Moves a clip to a new layer. If the clip already exists in a layer, it
891    /// is first removed from its current layer before being added to the new
892    /// layer.
893    /// ## `layer`
894    /// The new layer
895    ///
896    /// # Returns
897    ///
898    /// [`true`] if `self` was successfully moved to `layer`.
899    #[cfg(feature = "v1_18")]
900    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
901    #[doc(alias = "ges_clip_move_to_layer_full")]
902    fn move_to_layer_full(&self, layer: &impl IsA<Layer>) -> Result<(), glib::Error> {
903        unsafe {
904            let mut error = std::ptr::null_mut();
905            let is_ok = ffi::ges_clip_move_to_layer_full(
906                self.as_ref().to_glib_none().0,
907                layer.as_ref().to_glib_none().0,
908                &mut error,
909            );
910            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
911            if error.is_null() {
912                Ok(())
913            } else {
914                Err(from_glib_full(error))
915            }
916        }
917    }
918
919    /// Remove a top effect from the clip.
920    ///
921    /// Note, if the effect is a time effect, this may be refused if the clip
922    /// would not be able to adapt itself once the effect is removed.
923    /// ## `effect`
924    /// The top effect to remove
925    ///
926    /// # Returns
927    ///
928    /// [`true`] if `effect` was successfully added to `self` at `index`.
929    #[cfg(feature = "v1_18")]
930    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
931    #[doc(alias = "ges_clip_remove_top_effect")]
932    fn remove_top_effect(&self, effect: &impl IsA<BaseEffect>) -> Result<(), glib::Error> {
933        unsafe {
934            let mut error = std::ptr::null_mut();
935            let is_ok = ffi::ges_clip_remove_top_effect(
936                self.as_ref().to_glib_none().0,
937                effect.as_ref().to_glib_none().0,
938                &mut error,
939            );
940            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
941            if error.is_null() {
942                Ok(())
943            } else {
944                Err(from_glib_full(error))
945            }
946        }
947    }
948
949    /// Sets the [`supported-formats`][struct@crate::Clip#supported-formats] of the clip. This should normally
950    /// only be called by subclasses, which should be responsible for updating
951    /// its value, rather than the user.
952    /// ## `supportedformats`
953    /// The [`TrackType`][crate::TrackType]-s supported by `self`
954    #[doc(alias = "ges_clip_set_supported_formats")]
955    #[doc(alias = "supported-formats")]
956    fn set_supported_formats(&self, supportedformats: TrackType) {
957        unsafe {
958            ffi::ges_clip_set_supported_formats(
959                self.as_ref().to_glib_none().0,
960                supportedformats.into_glib(),
961            );
962        }
963    }
964
965    /// See [`set_top_effect_index_full()`][Self::set_top_effect_index_full()], which also gives an error.
966    /// ## `effect`
967    /// An effect within `self` to move
968    /// ## `newindex`
969    /// The index for `effect` in `self`
970    ///
971    /// # Returns
972    ///
973    /// [`true`] if `effect` was successfully moved to `newindex`.
974    #[doc(alias = "ges_clip_set_top_effect_index")]
975    fn set_top_effect_index(
976        &self,
977        effect: &impl IsA<BaseEffect>,
978        newindex: u32,
979    ) -> Result<(), glib::error::BoolError> {
980        unsafe {
981            glib::result_from_gboolean!(
982                ffi::ges_clip_set_top_effect_index(
983                    self.as_ref().to_glib_none().0,
984                    effect.as_ref().to_glib_none().0,
985                    newindex
986                ),
987                "Failed to move effect"
988            )
989        }
990    }
991
992    /// Set the index of an effect within the clip. See
993    /// [`top_effect_index()`][Self::top_effect_index()]. The new index must be an existing
994    /// index of the clip. The effect is moved to the new index, and the other
995    /// effects may be shifted in index accordingly to otherwise maintain the
996    /// ordering.
997    /// ## `effect`
998    /// An effect within `self` to move
999    /// ## `newindex`
1000    /// The index for `effect` in `self`
1001    ///
1002    /// # Returns
1003    ///
1004    /// [`true`] if `effect` was successfully moved to `newindex`.
1005    #[cfg(feature = "v1_18")]
1006    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1007    #[doc(alias = "ges_clip_set_top_effect_index_full")]
1008    fn set_top_effect_index_full(
1009        &self,
1010        effect: &impl IsA<BaseEffect>,
1011        newindex: u32,
1012    ) -> Result<(), glib::Error> {
1013        unsafe {
1014            let mut error = std::ptr::null_mut();
1015            let is_ok = ffi::ges_clip_set_top_effect_index_full(
1016                self.as_ref().to_glib_none().0,
1017                effect.as_ref().to_glib_none().0,
1018                newindex,
1019                &mut error,
1020            );
1021            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1022            if error.is_null() {
1023                Ok(())
1024            } else {
1025                Err(from_glib_full(error))
1026            }
1027        }
1028    }
1029
1030    #[doc(alias = "ges_clip_set_top_effect_priority")]
1031    fn set_top_effect_priority(
1032        &self,
1033        effect: &impl IsA<BaseEffect>,
1034        newpriority: u32,
1035    ) -> Result<(), glib::error::BoolError> {
1036        unsafe {
1037            glib::result_from_gboolean!(
1038                ffi::ges_clip_set_top_effect_priority(
1039                    self.as_ref().to_glib_none().0,
1040                    effect.as_ref().to_glib_none().0,
1041                    newpriority
1042                ),
1043                "Failed to the set top effect priority"
1044            )
1045        }
1046    }
1047
1048    /// See [`split_full()`][Self::split_full()], which also gives an error.
1049    /// ## `position`
1050    /// The timeline position at which to perform the split
1051    ///
1052    /// # Returns
1053    ///
1054    /// The newly created clip resulting
1055    /// from the splitting `self`, or [`None`] if `self` can't be split.
1056    #[doc(alias = "ges_clip_split")]
1057    fn split(&self, position: u64) -> Result<Clip, glib::BoolError> {
1058        unsafe {
1059            Option::<_>::from_glib_none(ffi::ges_clip_split(
1060                self.as_ref().to_glib_none().0,
1061                position,
1062            ))
1063            .ok_or_else(|| glib::bool_error!("Failed to split clip"))
1064        }
1065    }
1066
1067    /// Splits a clip at the given timeline position into two clips. The clip
1068    /// must already have a [`layer`][struct@crate::Clip#layer].
1069    ///
1070    /// The original clip's [`duration`][struct@crate::TimelineElement#duration] is reduced such that
1071    /// its end point matches the split position. Then a new clip is created in
1072    /// the same layer, whose [`start`][struct@crate::TimelineElement#start] matches the split
1073    /// position and [`duration`][struct@crate::TimelineElement#duration] will be set such that its end
1074    /// point matches the old end point of the original clip. Thus, the two
1075    /// clips together will occupy the same positions in the timeline as the
1076    /// original clip did.
1077    ///
1078    /// The children of the new clip will be new copies of the original clip's
1079    /// children, so it will share the same sources and use the same
1080    /// operations.
1081    ///
1082    /// The new clip will also have its [`in-point`][struct@crate::TimelineElement#in-point] set so
1083    /// that any internal data will appear in the timeline at the same time.
1084    /// Thus, when the timeline is played, the playback of data should
1085    /// appear the same. This may be complicated by any additional
1086    /// [`Effect`][crate::Effect]-s that have been placed on the original clip that depend on
1087    /// the playback time or change the data consumption rate of sources. This
1088    /// method will attempt to translate these effects such that the playback
1089    /// appears the same. In such complex situations, you may get a better
1090    /// result if you place the clip in a separate sub [`Project`][crate::Project], which only
1091    /// contains this clip (and its effects), and in the original layer
1092    /// create two neighbouring [`UriClip`][crate::UriClip]-s that reference this sub-project,
1093    /// but at a different [`in-point`][struct@crate::TimelineElement#in-point].
1094    /// ## `position`
1095    /// The timeline position at which to perform the split, between
1096    /// the start and end of the clip
1097    ///
1098    /// # Returns
1099    ///
1100    /// The newly created clip resulting
1101    /// from the splitting `self`, or [`None`] if `self` can't be split.
1102    #[cfg(feature = "v1_18")]
1103    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1104    #[doc(alias = "ges_clip_split_full")]
1105    fn split_full(&self, position: u64) -> Result<Option<Clip>, glib::Error> {
1106        unsafe {
1107            let mut error = std::ptr::null_mut();
1108            let ret =
1109                ffi::ges_clip_split_full(self.as_ref().to_glib_none().0, position, &mut error);
1110            if error.is_null() {
1111                Ok(from_glib_none(ret))
1112            } else {
1113                Err(from_glib_full(error))
1114            }
1115        }
1116    }
1117
1118    #[cfg(feature = "v1_18")]
1119    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1120    #[doc(alias = "duration-limit")]
1121    fn connect_duration_limit_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1122        unsafe extern "C" fn notify_duration_limit_trampoline<P: IsA<Clip>, F: Fn(&P) + 'static>(
1123            this: *mut ffi::GESClip,
1124            _param_spec: glib::ffi::gpointer,
1125            f: glib::ffi::gpointer,
1126        ) {
1127            let f: &F = &*(f as *const F);
1128            f(Clip::from_glib_borrow(this).unsafe_cast_ref())
1129        }
1130        unsafe {
1131            let f: Box_<F> = Box_::new(f);
1132            connect_raw(
1133                self.as_ptr() as *mut _,
1134                b"notify::duration-limit\0".as_ptr() as *const _,
1135                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1136                    notify_duration_limit_trampoline::<Self, F> as *const (),
1137                )),
1138                Box_::into_raw(f),
1139            )
1140        }
1141    }
1142
1143    #[doc(alias = "layer")]
1144    fn connect_layer_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1145        unsafe extern "C" fn notify_layer_trampoline<P: IsA<Clip>, F: Fn(&P) + 'static>(
1146            this: *mut ffi::GESClip,
1147            _param_spec: glib::ffi::gpointer,
1148            f: glib::ffi::gpointer,
1149        ) {
1150            let f: &F = &*(f as *const F);
1151            f(Clip::from_glib_borrow(this).unsafe_cast_ref())
1152        }
1153        unsafe {
1154            let f: Box_<F> = Box_::new(f);
1155            connect_raw(
1156                self.as_ptr() as *mut _,
1157                b"notify::layer\0".as_ptr() as *const _,
1158                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1159                    notify_layer_trampoline::<Self, F> as *const (),
1160                )),
1161                Box_::into_raw(f),
1162            )
1163        }
1164    }
1165
1166    #[doc(alias = "supported-formats")]
1167    fn connect_supported_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1168        unsafe extern "C" fn notify_supported_formats_trampoline<
1169            P: IsA<Clip>,
1170            F: Fn(&P) + 'static,
1171        >(
1172            this: *mut ffi::GESClip,
1173            _param_spec: glib::ffi::gpointer,
1174            f: glib::ffi::gpointer,
1175        ) {
1176            let f: &F = &*(f as *const F);
1177            f(Clip::from_glib_borrow(this).unsafe_cast_ref())
1178        }
1179        unsafe {
1180            let f: Box_<F> = Box_::new(f);
1181            connect_raw(
1182                self.as_ptr() as *mut _,
1183                b"notify::supported-formats\0".as_ptr() as *const _,
1184                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1185                    notify_supported_formats_trampoline::<Self, F> as *const (),
1186                )),
1187                Box_::into_raw(f),
1188            )
1189        }
1190    }
1191}
1192
1193impl<O: IsA<Clip>> ClipExt for O {}