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 {}