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