gstreamer_editing_services/auto/timeline.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
7use crate::{
8 Asset, Extractable, Group, Layer, MetaContainer, TimelineElement, Track, TrackElement, ffi,
9};
10#[cfg(feature = "v1_18")]
11#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
12use crate::{Clip, FrameNumber};
13use glib::{
14 object::ObjectType as _,
15 prelude::*,
16 signal::{SignalHandlerId, connect_raw},
17 translate::*,
18};
19use std::boxed::Box as Box_;
20
21glib::wrapper! {
22 /// = endB`, then we can say
23 /// that `A` fully overlaps `B`.
24 ///
25 /// The overlap rules for a timeline are that:
26 ///
27 /// 1. One source cannot fully overlap another source.
28 /// 2. A source can only overlap the end of up to one other source at its
29 /// start.
30 /// 3. A source can only overlap the start of up to one other source at its
31 /// end.
32 ///
33 /// The last two rules combined essentially mean that at any given timeline
34 /// position, only up to two [`Source`][crate::Source]-s may overlap at that position. So
35 /// triple or more overlaps are not allowed.
36 ///
37 /// If you switch on [`auto-transition`][struct@crate::Timeline#auto-transition], then at any moment when
38 /// the end of one source (the first source) overlaps the start of another
39 /// (the second source), a [`TransitionClip`][crate::TransitionClip] will be automatically created
40 /// for the pair in the same layer and it will cover their overlap. If the
41 /// two elements are edited in a way such that the end of the first source
42 /// no longer overlaps the start of the second, the transition will be
43 /// automatically removed from the timeline. However, if the two sources
44 /// still overlap at the same edges after the edit, then the same
45 /// transition object will be kept, but with its timing and layer adjusted
46 /// accordingly.
47 ///
48 /// NOTE: if you know what you are doing and want to be in full control of the
49 /// timeline layout, you can disable the edit APIs with
50 /// `ges_timeline_disable_edit_apis`.
51 ///
52 /// ## Saving
53 ///
54 /// To save/load a timeline, you can use the [`TimelineExt::load_from_uri()`][crate::prelude::TimelineExt::load_from_uri()]
55 /// and [`TimelineExt::save_to_uri()`][crate::prelude::TimelineExt::save_to_uri()] methods that use the default format.
56 ///
57 /// ## Playing
58 ///
59 /// A timeline is a [`gst::Bin`][crate::gst::Bin] with a source [`gst::Pad`][crate::gst::Pad] for each of its
60 /// tracks, which you can fetch with [`TimelineExt::pad_for_track()`][crate::prelude::TimelineExt::pad_for_track()]. You
61 /// will likely want to link these to some compatible sink [`gst::Element`][crate::gst::Element]-s to
62 /// be able to play or capture the content of the timeline.
63 ///
64 /// You can use a [`Pipeline`][crate::Pipeline] to easily preview/play the timeline's
65 /// content, or render it to a file.
66 ///
67 /// ## Properties
68 ///
69 ///
70 /// #### `auto-transition`
71 /// Whether to automatically create a transition whenever two
72 /// [`Source`][crate::Source]-s overlap in a track of the timeline. See
73 /// [`auto-transition`][struct@crate::Layer#auto-transition] if you want this to only happen in some
74 /// layers.
75 ///
76 /// Readable | Writable
77 ///
78 ///
79 /// #### `duration`
80 /// The current duration (in nanoseconds) of the timeline. A timeline
81 /// 'starts' at time 0, so this is the maximum end time of all of its
82 /// [`TimelineElement`][crate::TimelineElement]-s.
83 ///
84 /// Readable
85 ///
86 ///
87 /// #### `snapping-distance`
88 /// The distance (in nanoseconds) at which a [`TimelineElement`][crate::TimelineElement] being
89 /// moved within the timeline should snap one of its [`Source`][crate::Source]-s with
90 /// another [`Source`][crate::Source]-s edge. See [`EditMode`][crate::EditMode] for which edges can
91 /// snap during an edit. 0 means no snapping.
92 ///
93 /// Readable | Writable
94 /// <details><summary><h4>Bin</h4></summary>
95 ///
96 ///
97 /// #### `async-handling`
98 /// If set to [`true`], the bin will handle asynchronous state changes.
99 /// This should be used only if the bin subclass is modifying the state
100 /// of its children on its own.
101 ///
102 /// Readable | Writable
103 ///
104 ///
105 /// #### `message-forward`
106 /// Forward all children messages, even those that would normally be filtered by
107 /// the bin. This can be interesting when one wants to be notified of the EOS
108 /// state of individual elements, for example.
109 ///
110 /// The messages are converted to an ELEMENT message with the bin as the
111 /// source. The structure of the message is named `GstBinForwarded` and contains
112 /// a field named `message` that contains the original forwarded `GstMessage`.
113 ///
114 /// Readable | Writable
115 /// </details>
116 /// <details><summary><h4>Object</h4></summary>
117 ///
118 ///
119 /// #### `name`
120 /// Readable | Writable | Construct
121 ///
122 ///
123 /// #### `parent`
124 /// The parent of the object. Please note, that when changing the 'parent'
125 /// property, we don't emit [`notify`][struct@crate::glib::Object#notify] and [`deep-notify`][struct@crate::gst::Object#deep-notify]
126 /// signals due to locking issues. In some cases one can use
127 /// [`element-added`][struct@crate::gst::Bin#element-added] or [`element-removed`][struct@crate::gst::Bin#element-removed] signals on the parent to
128 /// achieve a similar effect.
129 ///
130 /// Readable | Writable
131 /// </details>
132 ///
133 /// ## Signals
134 ///
135 ///
136 /// #### `commited`
137 /// This signal will be emitted once the changes initiated by
138 /// [`TimelineExt::commit()`][crate::prelude::TimelineExt::commit()] have been executed in the backend. Use
139 /// [`TimelineExt::commit_sync()`][crate::prelude::TimelineExt::commit_sync()] if you do not want to have to connect
140 /// to this signal.
141 ///
142 ///
143 ///
144 ///
145 /// #### `group-added`
146 /// Will be emitted after the group is added to to the timeline. This can
147 /// happen when grouping with `ges_container_group`, or by adding
148 /// containers to a newly created group.
149 ///
150 /// Note that this should not be emitted whilst a timeline is being
151 /// loaded from its [`Project`][crate::Project] asset. You should connect to the
152 /// project's [`loaded`][struct@crate::Project#loaded] signal if you want to know which groups
153 /// were created for the timeline.
154 ///
155 ///
156 ///
157 ///
158 /// #### `group-removed`
159 /// Will be emitted after the group is removed from the timeline through
160 /// `ges_container_ungroup`. Note that `group` will no longer contain its
161 /// former children, these are held in `children`.
162 ///
163 /// Note that if a group is emptied, then it will no longer belong to the
164 /// timeline, but this signal will **not** be emitted in such a case.
165 ///
166 ///
167 ///
168 ///
169 /// #### `layer-added`
170 /// Will be emitted after the layer is added to the timeline.
171 ///
172 /// Note that this should not be emitted whilst a timeline is being
173 /// loaded from its [`Project`][crate::Project] asset. You should connect to the
174 /// project's [`loaded`][struct@crate::Project#loaded] signal if you want to know which
175 /// layers were created for the timeline.
176 ///
177 ///
178 ///
179 ///
180 /// #### `layer-removed`
181 /// Will be emitted after the layer is removed from the timeline.
182 ///
183 ///
184 ///
185 ///
186 /// #### `select-element-track`
187 /// Simplified version of [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object] which only
188 /// allows `track_element` to be added to a single [`Track`][crate::Track].
189 ///
190 ///
191 ///
192 ///
193 /// #### `select-tracks-for-object`
194 /// This will be emitted whenever the timeline needs to determine which
195 /// tracks a clip's children should be added to. The track element will
196 /// be added to each of the tracks given in the return. If a track
197 /// element is selected to go into multiple tracks, it will be copied
198 /// into the additional tracks, under the same clip. Note that the copy
199 /// will *not* keep its properties or state in sync with the original.
200 ///
201 /// Connect to this signal once if you wish to control which element
202 /// should be added to which track. Doing so will overwrite the default
203 /// behaviour, which adds `track_element` to all tracks whose
204 /// [`track-type`][struct@crate::Track#track-type] includes the `track_element`'s
205 /// [`track-type`][struct@crate::TrackElement#track-type].
206 ///
207 /// Note that under the default track selection, if a clip would produce
208 /// multiple core children of the same [`TrackType`][crate::TrackType], it will choose
209 /// one of the core children arbitrarily to place in the corresponding
210 /// tracks, with a warning for the other core children that are not
211 /// placed in the track. For example, this would happen for a [`UriClip`][crate::UriClip]
212 /// that points to a file that contains multiple audio streams. If you
213 /// wish to choose the stream, you could connect to this signal, and use,
214 /// say, [`UriSourceAssetExt::stream_info()`][crate::prelude::UriSourceAssetExt::stream_info()] to choose which core
215 /// source to add.
216 ///
217 /// When a clip is first added to a timeline, its core elements will
218 /// be created for the current tracks in the timeline if they have not
219 /// already been created. Then this will be emitted for each of these
220 /// core children to select which tracks, if any, they should be added
221 /// to. It will then be called for any non-core children in the clip.
222 ///
223 /// In addition, if a new track element is ever added to a clip in a
224 /// timeline (and it is not already part of a track) this will be emitted
225 /// to select which tracks the element should be added to.
226 ///
227 /// Finally, as a special case, if a track is added to the timeline
228 /// *after* it already contains clips, then it will request the creation
229 /// of the clips' core elements of the corresponding type, if they have
230 /// not already been created, and this signal will be emitted for each of
231 /// these newly created elements. In addition, this will also be released
232 /// for all other track elements in the timeline's clips that have not
233 /// yet been assigned a track. However, in this final case, the timeline
234 /// will only check whether the newly added track appears in the track
235 /// list. If it does appear, the track element will be added to the newly
236 /// added track. All other tracks in the returned track list are ignored.
237 ///
238 /// In this latter case, track elements that are already part of a track
239 /// will not be asked if they want to be copied into the new track. If
240 /// you wish to do this, you can use [`ClipExt::add_child_to_track()`][crate::prelude::ClipExt::add_child_to_track()].
241 ///
242 /// Note that the returned `GPtrArray` should own a new reference to each
243 /// of its contained [`Track`][crate::Track]. The timeline will set the `GDestroyNotify`
244 /// free function on the `GPtrArray` to dereference the elements.
245 ///
246 ///
247 ///
248 ///
249 /// #### `snapping-ended`
250 /// Will be emitted whenever a snapping event ends. After a snap event
251 /// has started (see [`snapping-started`][struct@crate::Timeline#snapping-started]), it can later end
252 /// because either another timeline edit has occurred (which may or may
253 /// not have created a new snapping event), or because the timeline has
254 /// been committed.
255 ///
256 ///
257 ///
258 ///
259 /// #### `snapping-started`
260 /// Will be emitted whenever an element's movement invokes a snapping
261 /// event during an edit (usually of one of its ancestors) because its
262 /// start or end point lies within the [`snapping-distance`][struct@crate::Timeline#snapping-distance] of
263 /// another element's start or end point.
264 ///
265 /// See [`EditMode`][crate::EditMode] to see what can snap during an edit.
266 ///
267 /// Note that only up to one snapping-started signal will be emitted per
268 /// element edit within a timeline.
269 ///
270 ///
271 ///
272 ///
273 /// #### `track-added`
274 /// Will be emitted after the track is added to the timeline.
275 ///
276 /// Note that this should not be emitted whilst a timeline is being
277 /// loaded from its [`Project`][crate::Project] asset. You should connect to the
278 /// project's [`loaded`][struct@crate::Project#loaded] signal if you want to know which
279 /// tracks were created for the timeline.
280 ///
281 ///
282 ///
283 ///
284 /// #### `track-removed`
285 /// Will be emitted after the track is removed from the timeline.
286 ///
287 ///
288 /// <details><summary><h4>Bin</h4></summary>
289 ///
290 ///
291 /// #### `deep-element-added`
292 /// Will be emitted after the element was added to `sub_bin`.
293 ///
294 ///
295 ///
296 ///
297 /// #### `deep-element-removed`
298 /// Will be emitted after the element was removed from `sub_bin`.
299 ///
300 ///
301 ///
302 ///
303 /// #### `do-latency`
304 /// Will be emitted when the bin needs to perform latency calculations. This
305 /// signal is only emitted for toplevel bins or when [`async-handling`][struct@crate::gst::Bin#async-handling] is
306 /// enabled.
307 ///
308 /// Only one signal handler is invoked. If no signals are connected, the
309 /// default handler is invoked, which will query and distribute the lowest
310 /// possible latency to all sinks.
311 ///
312 /// Connect to this signal if the default latency calculations are not
313 /// sufficient, like when you need different latencies for different sinks in
314 /// the same pipeline.
315 ///
316 ///
317 ///
318 ///
319 /// #### `element-added`
320 /// Will be emitted after the element was added to the bin.
321 ///
322 ///
323 ///
324 ///
325 /// #### `element-removed`
326 /// Will be emitted after the element was removed from the bin.
327 ///
328 ///
329 /// </details>
330 /// <details><summary><h4>Element</h4></summary>
331 ///
332 ///
333 /// #### `no-more-pads`
334 /// This signals that the element will not generate more dynamic pads.
335 /// Note that this signal will usually be emitted from the context of
336 /// the streaming thread.
337 ///
338 ///
339 ///
340 ///
341 /// #### `pad-added`
342 /// a new [`gst::Pad`][crate::gst::Pad] has been added to the element. Note that this signal will
343 /// usually be emitted from the context of the streaming thread. Also keep in
344 /// mind that if you add new elements to the pipeline in the signal handler
345 /// you will need to set them to the desired target state with
346 /// [`ElementExtManual::set_state()`][crate::gst::prelude::ElementExtManual::set_state()] or [`ElementExtManual::sync_state_with_parent()`][crate::gst::prelude::ElementExtManual::sync_state_with_parent()].
347 ///
348 ///
349 ///
350 ///
351 /// #### `pad-removed`
352 /// a [`gst::Pad`][crate::gst::Pad] has been removed from the element
353 ///
354 ///
355 /// </details>
356 /// <details><summary><h4>Object</h4></summary>
357 ///
358 ///
359 /// #### `deep-notify`
360 /// The deep notify signal is used to be notified of property changes. It is
361 /// typically attached to the toplevel bin to receive notifications from all
362 /// the elements contained in that bin.
363 ///
364 /// Detailed
365 /// </details>
366 /// <details><summary><h4>ChildProxy</h4></summary>
367 ///
368 ///
369 /// #### `child-added`
370 /// Will be emitted after the `object` was added to the `child_proxy`.
371 ///
372 ///
373 ///
374 ///
375 /// #### `child-removed`
376 /// Will be emitted after the `object` was removed from the `child_proxy`.
377 ///
378 ///
379 /// </details>
380 /// <details><summary><h4>MetaContainer</h4></summary>
381 ///
382 ///
383 /// #### `notify-meta`
384 /// This is emitted for a meta container whenever the metadata under one
385 /// of its fields changes, is set for the first time, or is removed. In
386 /// the latter case, `value` will be [`None`].
387 ///
388 /// Detailed
389 /// </details>
390 ///
391 /// # Implements
392 ///
393 /// [`TimelineExt`][trait@crate::prelude::TimelineExt], [`trait@gst::prelude::BinExt`], [`trait@gst::prelude::ElementExt`], [`trait@gst::prelude::GstObjectExt`], [`trait@glib::ObjectExt`], [`trait@gst::prelude::ChildProxyExt`], [`ExtractableExt`][trait@crate::prelude::ExtractableExt], [`MetaContainerExt`][trait@crate::prelude::MetaContainerExt]
394 #[doc(alias = "GESTimeline")]
395 pub struct Timeline(Object<ffi::GESTimeline, ffi::GESTimelineClass>) @extends gst::Bin, gst::Element, gst::Object, @implements gst::ChildProxy, Extractable, MetaContainer;
396
397 match fn {
398 type_ => || ffi::ges_timeline_get_type(),
399 }
400}
401
402impl Timeline {
403 pub const NONE: Option<&'static Timeline> = None;
404
405 /// Creates a new empty timeline.
406 ///
407 /// # Returns
408 ///
409 /// The new timeline.
410 #[doc(alias = "ges_timeline_new")]
411 pub fn new() -> Timeline {
412 assert_initialized_main_thread!();
413 unsafe { from_glib_none(ffi::ges_timeline_new()) }
414 }
415
416 /// Creates a new timeline containing a single [`AudioTrack`][crate::AudioTrack] and a
417 /// single [`VideoTrack`][crate::VideoTrack].
418 ///
419 /// # Returns
420 ///
421 /// The new timeline.
422 #[doc(alias = "ges_timeline_new_audio_video")]
423 pub fn new_audio_video() -> Timeline {
424 assert_initialized_main_thread!();
425 unsafe { from_glib_none(ffi::ges_timeline_new_audio_video()) }
426 }
427
428 /// Creates a timeline from the given URI.
429 /// ## `uri`
430 /// The URI to load from
431 ///
432 /// # Returns
433 ///
434 /// A new timeline if the uri was loaded
435 /// successfully, or [`None`] if the uri could not be loaded.
436 #[doc(alias = "ges_timeline_new_from_uri")]
437 #[doc(alias = "new_from_uri")]
438 pub fn from_uri(uri: &str) -> Result<Timeline, glib::Error> {
439 assert_initialized_main_thread!();
440 unsafe {
441 let mut error = std::ptr::null_mut();
442 let ret = ffi::ges_timeline_new_from_uri(uri.to_glib_none().0, &mut error);
443 if error.is_null() {
444 Ok(from_glib_none(ret))
445 } else {
446 Err(from_glib_full(error))
447 }
448 }
449 }
450}
451
452impl Default for Timeline {
453 fn default() -> Self {
454 Self::new()
455 }
456}
457
458/// Trait containing all [`struct@Timeline`] methods.
459///
460/// # Implementors
461///
462/// [`Timeline`][struct@crate::Timeline]
463pub trait TimelineExt: IsA<Timeline> + 'static {
464 /// Add a layer to the timeline.
465 ///
466 /// If the layer contains [`Clip`][crate::Clip]-s, then this may trigger the creation of
467 /// their core track element children for the timeline's tracks, and the
468 /// placement of the clip's children in the tracks of the timeline using
469 /// [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object]. Some errors may occur if this
470 /// would break one of the configuration rules of the timeline in one of
471 /// its tracks. In such cases, some track elements would fail to be added
472 /// to their tracks, but this method would still return [`true`]. As such, it
473 /// is advised that you only add clips to layers that already part of a
474 /// timeline. In such situations, [`LayerExt::add_clip()`][crate::prelude::LayerExt::add_clip()] is able to fail if
475 /// adding the clip would cause such an error.
476 ///
477 /// # Deprecated since 1.18
478 ///
479 /// This method requires you to ensure the layer's
480 /// [`priority`][struct@crate::Layer#priority] will be unique to the timeline. Use
481 /// [`append_layer()`][Self::append_layer()] and [`move_layer()`][Self::move_layer()] instead.
482 /// ## `layer`
483 /// The layer to add
484 ///
485 /// # Returns
486 ///
487 /// [`true`] if `layer` was properly added.
488 #[cfg_attr(feature = "v1_18", deprecated = "Since 1.18")]
489 #[allow(deprecated)]
490 #[doc(alias = "ges_timeline_add_layer")]
491 fn add_layer(&self, layer: &impl IsA<Layer>) -> Result<(), glib::error::BoolError> {
492 unsafe {
493 glib::result_from_gboolean!(
494 ffi::ges_timeline_add_layer(
495 self.as_ref().to_glib_none().0,
496 layer.as_ref().to_glib_none().0
497 ),
498 "Failed to add layer"
499 )
500 }
501 }
502
503 /// Add a track to the timeline.
504 ///
505 /// If the timeline already contains clips, then this may trigger the
506 /// creation of their core track element children for the track, and the
507 /// placement of the clip's children in the track of the timeline using
508 /// [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object]. Some errors may occur if this
509 /// would break one of the configuration rules for the timeline in the
510 /// track. In such cases, some track elements would fail to be added to the
511 /// track, but this method would still return [`true`]. As such, it is advised
512 /// that you avoid adding tracks to timelines that already contain clips.
513 /// ## `track`
514 /// The track to add
515 ///
516 /// # Returns
517 ///
518 /// [`true`] if `track` was properly added.
519 #[doc(alias = "ges_timeline_add_track")]
520 fn add_track(&self, track: &impl IsA<Track>) -> Result<(), glib::error::BoolError> {
521 unsafe {
522 glib::result_from_gboolean!(
523 ffi::ges_timeline_add_track(
524 self.as_ref().to_glib_none().0,
525 track.as_ref().to_glib_none().0
526 ),
527 "Failed to add track"
528 )
529 }
530 }
531
532 /// Append a newly created layer to the timeline. The layer will
533 /// be added at the lowest [`priority`][struct@crate::Layer#priority] (numerically, the highest).
534 ///
535 /// # Returns
536 ///
537 /// The newly created layer.
538 #[doc(alias = "ges_timeline_append_layer")]
539 fn append_layer(&self) -> Layer {
540 unsafe {
541 from_glib_none(ffi::ges_timeline_append_layer(
542 self.as_ref().to_glib_none().0,
543 ))
544 }
545 }
546
547 /// Commit all the pending changes of the clips contained in the
548 /// timeline.
549 ///
550 /// When changes happen in a timeline, they are not immediately executed
551 /// internally, in a way that effects the output data of the timeline. You
552 /// should call this method when you are done with a set of changes and you
553 /// want them to be executed.
554 ///
555 /// Any pending changes will be executed in the backend. The
556 /// [`commited`][struct@crate::Timeline#commited] signal will be emitted once this has completed.
557 /// You should not try to change the state of the timeline, seek it or add
558 /// tracks to it before receiving this signal. You can use
559 /// [`commit_sync()`][Self::commit_sync()] if you do not want to perform other tasks in
560 /// the mean time.
561 ///
562 /// Note that all the pending changes will automatically be executed when
563 /// the timeline goes from [`gst::State::Ready`][crate::gst::State::Ready] to [`gst::State::Paused`][crate::gst::State::Paused], which is
564 /// usually triggered by a corresponding state changes in a containing
565 /// [`Pipeline`][crate::Pipeline].
566 ///
567 /// # Returns
568 ///
569 /// [`true`] if pending changes were committed, or [`false`] if nothing
570 /// needed to be committed.
571 #[doc(alias = "ges_timeline_commit")]
572 fn commit(&self) -> bool {
573 unsafe { from_glib(ffi::ges_timeline_commit(self.as_ref().to_glib_none().0)) }
574 }
575
576 /// Commit all the pending changes of the clips contained in the
577 /// timeline and wait for the changes to complete.
578 ///
579 /// See [`commit()`][Self::commit()].
580 ///
581 /// # Returns
582 ///
583 /// [`true`] if pending changes were committed, or [`false`] if nothing
584 /// needed to be committed.
585 #[doc(alias = "ges_timeline_commit_sync")]
586 fn commit_sync(&self) -> bool {
587 unsafe {
588 from_glib(ffi::ges_timeline_commit_sync(
589 self.as_ref().to_glib_none().0,
590 ))
591 }
592 }
593
594 /// WARNING: When using that mode, GES won't guarantee the coherence of the
595 /// timeline. You need to ensure that the rules described in the [Overlaps and
596 /// auto transitions](`overlaps`-and-autotransitions) section are respected any time
597 /// the timeline is [commited](ges_timeline_commit) (otherwise playback will most
598 /// probably fail in different ways).
599 ///
600 /// When disabling editing APIs, GES won't be able to enforce the rules that
601 /// makes the timeline overall state to be valid but some feature won't be
602 /// usable:
603 /// * [`snapping-distance`][struct@crate::Timeline#snapping-distance]
604 /// * [`auto-transition`][struct@crate::Timeline#auto-transition]
605 /// ## `disable_edit_apis`
606 /// [`true`] to disable all the edit APIs so the user is in full
607 /// control of ensuring timeline state validity [`false`] otherwise.
608 #[cfg(feature = "v1_22")]
609 #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
610 #[doc(alias = "ges_timeline_disable_edit_apis")]
611 fn disable_edit_apis(&self, disable_edit_apis: bool) {
612 unsafe {
613 ffi::ges_timeline_disable_edit_apis(
614 self.as_ref().to_glib_none().0,
615 disable_edit_apis.into_glib(),
616 );
617 }
618 }
619
620 /// Freezes the timeline from being committed. This is usually needed while the
621 /// timeline is being rendered to ensure that not change to the timeline are
622 /// taken into account during that moment. Once the rendering is done, you
623 /// should call `ges_timeline_thaw_commit` so that committing becomes possible
624 /// again and any call to ``commit()`` that happened during the rendering is
625 /// actually taken into account.
626 #[cfg(feature = "v1_20")]
627 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
628 #[doc(alias = "ges_timeline_freeze_commit")]
629 fn freeze_commit(&self) {
630 unsafe {
631 ffi::ges_timeline_freeze_commit(self.as_ref().to_glib_none().0);
632 }
633 }
634
635 /// Gets [`auto-transition`][struct@crate::Timeline#auto-transition] for the timeline.
636 ///
637 /// # Returns
638 ///
639 /// The auto-transition of `self_`.
640 #[doc(alias = "ges_timeline_get_auto_transition")]
641 #[doc(alias = "get_auto_transition")]
642 #[doc(alias = "auto-transition")]
643 fn is_auto_transition(&self) -> bool {
644 unsafe {
645 from_glib(ffi::ges_timeline_get_auto_transition(
646 self.as_ref().to_glib_none().0,
647 ))
648 }
649 }
650
651 /// Get the current [`duration`][struct@crate::Timeline#duration] of the timeline
652 ///
653 /// # Returns
654 ///
655 /// The current duration of `self`.
656 #[doc(alias = "ges_timeline_get_duration")]
657 #[doc(alias = "get_duration")]
658 fn duration(&self) -> gst::ClockTime {
659 unsafe {
660 try_from_glib(ffi::ges_timeline_get_duration(
661 self.as_ref().to_glib_none().0,
662 ))
663 .expect("mandatory glib value is None")
664 }
665 }
666
667 ///
668 /// # Returns
669 ///
670 /// [`true`] if edit APIs are disabled, [`false`] otherwise.
671 #[cfg(feature = "v1_22")]
672 #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
673 #[doc(alias = "ges_timeline_get_edit_apis_disabled")]
674 #[doc(alias = "get_edit_apis_disabled")]
675 fn is_edit_apis_disabled(&self) -> bool {
676 unsafe {
677 from_glib(ffi::ges_timeline_get_edit_apis_disabled(
678 self.as_ref().to_glib_none().0,
679 ))
680 }
681 }
682
683 /// Gets the element contained in the timeline with the given name.
684 /// ## `name`
685 /// The name of the element to find
686 ///
687 /// # Returns
688 ///
689 /// The timeline element in `self`
690 /// with the given `name`, or [`None`] if it was not found.
691 #[doc(alias = "ges_timeline_get_element")]
692 #[doc(alias = "get_element")]
693 fn element(&self, name: &str) -> Option<TimelineElement> {
694 unsafe {
695 from_glib_full(ffi::ges_timeline_get_element(
696 self.as_ref().to_glib_none().0,
697 name.to_glib_none().0,
698 ))
699 }
700 }
701
702 /// This method allows you to convert a timeline `GstClockTime` into its
703 /// corresponding `GESFrameNumber` in the timeline's output.
704 /// ## `timestamp`
705 /// The timestamp to get the corresponding frame number of
706 ///
707 /// # Returns
708 ///
709 /// The frame number `timestamp` corresponds to.
710 #[cfg(feature = "v1_18")]
711 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
712 #[doc(alias = "ges_timeline_get_frame_at")]
713 #[doc(alias = "get_frame_at")]
714 fn frame_at(&self, timestamp: gst::ClockTime) -> FrameNumber {
715 unsafe {
716 ffi::ges_timeline_get_frame_at(self.as_ref().to_glib_none().0, timestamp.into_glib())
717 }
718 }
719
720 /// This method allows you to convert a timeline output frame number into a
721 /// timeline `GstClockTime`. For example, this time could be used to seek to a
722 /// particular frame in the timeline's output, or as the edit position for
723 /// an element within the timeline.
724 /// ## `frame_number`
725 /// The frame number to get the corresponding timestamp of in the
726 /// timeline coordinates
727 ///
728 /// # Returns
729 ///
730 /// The timestamp corresponding to `frame_number` in the output of `self`.
731 #[cfg(feature = "v1_18")]
732 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
733 #[doc(alias = "ges_timeline_get_frame_time")]
734 #[doc(alias = "get_frame_time")]
735 fn frame_time(&self, frame_number: FrameNumber) -> Option<gst::ClockTime> {
736 unsafe {
737 from_glib(ffi::ges_timeline_get_frame_time(
738 self.as_ref().to_glib_none().0,
739 frame_number,
740 ))
741 }
742 }
743
744 /// Get the list of [`Group`][crate::Group]-s present in the timeline.
745 ///
746 /// # Deprecated since 1.30
747 ///
748 /// Use [`groups_full()`][Self::groups_full()] instead for MT-safety.
749 ///
750 /// # Returns
751 ///
752 /// The list of
753 /// groups that contain clips present in `self`'s layers.
754 /// Must not be changed.
755 #[cfg_attr(feature = "v1_30", deprecated = "Since 1.30")]
756 #[allow(deprecated)]
757 #[doc(alias = "ges_timeline_get_groups")]
758 #[doc(alias = "get_groups")]
759 fn groups(&self) -> Vec<Group> {
760 unsafe {
761 FromGlibPtrContainer::from_glib_none(ffi::ges_timeline_get_groups(
762 self.as_ref().to_glib_none().0,
763 ))
764 }
765 }
766
767 /// Get the list of [`Group`][crate::Group]-s present in the timeline.
768 ///
769 /// # Returns
770 ///
771 /// The list of
772 /// groups that contain clips present in `self`'s layers.
773 #[cfg(feature = "v1_30")]
774 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
775 #[doc(alias = "ges_timeline_get_groups_full")]
776 #[doc(alias = "get_groups_full")]
777 fn groups_full(&self) -> Vec<Group> {
778 unsafe {
779 FromGlibPtrContainer::from_glib_full(ffi::ges_timeline_get_groups_full(
780 self.as_ref().to_glib_none().0,
781 ))
782 }
783 }
784
785 /// Retrieve the layer whose index in the timeline matches the given
786 /// priority.
787 /// ## `priority`
788 /// The priority/index of the layer to find
789 ///
790 /// # Returns
791 ///
792 /// The layer with the given
793 /// `priority`, or [`None`] if none was found.
794 ///
795 /// Since 1.6
796 #[doc(alias = "ges_timeline_get_layer")]
797 #[doc(alias = "get_layer")]
798 fn layer(&self, priority: u32) -> Option<Layer> {
799 unsafe {
800 from_glib_full(ffi::ges_timeline_get_layer(
801 self.as_ref().to_glib_none().0,
802 priority,
803 ))
804 }
805 }
806
807 /// Get the list of [`Layer`][crate::Layer]-s present in the timeline.
808 ///
809 /// # Returns
810 ///
811 /// The list of
812 /// layers present in `self` sorted by priority.
813 #[doc(alias = "ges_timeline_get_layers")]
814 #[doc(alias = "get_layers")]
815 fn layers(&self) -> Vec<Layer> {
816 unsafe {
817 FromGlibPtrContainer::from_glib_full(ffi::ges_timeline_get_layers(
818 self.as_ref().to_glib_none().0,
819 ))
820 }
821 }
822
823 /// Search for the [`gst::Pad`][crate::gst::Pad] corresponding to the given timeline's track.
824 /// You can link to this pad to receive the output data of the given track.
825 /// ## `track`
826 /// A track
827 ///
828 /// # Returns
829 ///
830 /// The pad corresponding to `track`,
831 /// or [`None`] if there is an error.
832 #[doc(alias = "ges_timeline_get_pad_for_track")]
833 #[doc(alias = "get_pad_for_track")]
834 fn pad_for_track(&self, track: &impl IsA<Track>) -> Option<gst::Pad> {
835 unsafe {
836 from_glib_none(ffi::ges_timeline_get_pad_for_track(
837 self.as_ref().to_glib_none().0,
838 track.as_ref().to_glib_none().0,
839 ))
840 }
841 }
842
843 /// Gets the [`snapping-distance`][struct@crate::Timeline#snapping-distance] for the timeline.
844 ///
845 /// # Returns
846 ///
847 /// The snapping distance (in nanoseconds) of `self`.
848 #[doc(alias = "ges_timeline_get_snapping_distance")]
849 #[doc(alias = "get_snapping_distance")]
850 #[doc(alias = "snapping-distance")]
851 fn snapping_distance(&self) -> Option<gst::ClockTime> {
852 unsafe {
853 from_glib(ffi::ges_timeline_get_snapping_distance(
854 self.as_ref().to_glib_none().0,
855 ))
856 }
857 }
858
859 /// Search for the [`Track`][crate::Track] corresponding to the given timeline's pad.
860 ///
861 /// # Deprecated since 1.30
862 ///
863 /// Use [`track_for_pad_full()`][Self::track_for_pad_full()] instead for MT-safety.
864 /// ## `pad`
865 /// A pad
866 ///
867 /// # Returns
868 ///
869 /// The track corresponding to `pad`,
870 /// or [`None`] if there is an error.
871 #[cfg_attr(feature = "v1_30", deprecated = "Since 1.30")]
872 #[allow(deprecated)]
873 #[doc(alias = "ges_timeline_get_track_for_pad")]
874 #[doc(alias = "get_track_for_pad")]
875 fn track_for_pad(&self, pad: &impl IsA<gst::Pad>) -> Option<Track> {
876 unsafe {
877 from_glib_none(ffi::ges_timeline_get_track_for_pad(
878 self.as_ref().to_glib_none().0,
879 pad.as_ref().to_glib_none().0,
880 ))
881 }
882 }
883
884 /// Search for the [`Track`][crate::Track] corresponding to the given timeline's pad.
885 /// ## `pad`
886 /// A pad
887 ///
888 /// # Returns
889 ///
890 /// The track corresponding to `pad`,
891 /// or [`None`] if there is an error.
892 #[cfg(feature = "v1_30")]
893 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
894 #[doc(alias = "ges_timeline_get_track_for_pad_full")]
895 #[doc(alias = "get_track_for_pad_full")]
896 fn track_for_pad_full(&self, pad: &impl IsA<gst::Pad>) -> Option<Track> {
897 unsafe {
898 from_glib_full(ffi::ges_timeline_get_track_for_pad_full(
899 self.as_ref().to_glib_none().0,
900 pad.as_ref().to_glib_none().0,
901 ))
902 }
903 }
904
905 /// Get the list of [`Track`][crate::Track]-s used by the timeline.
906 ///
907 /// # Returns
908 ///
909 /// The list of tracks
910 /// used by `self`.
911 #[doc(alias = "ges_timeline_get_tracks")]
912 #[doc(alias = "get_tracks")]
913 fn tracks(&self) -> Vec<Track> {
914 unsafe {
915 FromGlibPtrContainer::from_glib_full(ffi::ges_timeline_get_tracks(
916 self.as_ref().to_glib_none().0,
917 ))
918 }
919 }
920
921 /// Check whether the timeline is empty or not.
922 ///
923 /// # Returns
924 ///
925 /// [`true`] if `self` is empty.
926 #[doc(alias = "ges_timeline_is_empty")]
927 fn is_empty(&self) -> bool {
928 unsafe { from_glib(ffi::ges_timeline_is_empty(self.as_ref().to_glib_none().0)) }
929 }
930
931 /// Loads the contents of URI into the timeline.
932 /// ## `uri`
933 /// The URI to load from
934 ///
935 /// # Returns
936 ///
937 /// [`true`] if the timeline was loaded successfully from `uri`.
938 #[doc(alias = "ges_timeline_load_from_uri")]
939 fn load_from_uri(&self, uri: &str) -> Result<(), glib::Error> {
940 unsafe {
941 let mut error = std::ptr::null_mut();
942 let is_ok = ffi::ges_timeline_load_from_uri(
943 self.as_ref().to_glib_none().0,
944 uri.to_glib_none().0,
945 &mut error,
946 );
947 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
948 if error.is_null() {
949 Ok(())
950 } else {
951 Err(from_glib_full(error))
952 }
953 }
954 }
955
956 /// Moves a layer within the timeline to the index given by
957 /// `new_layer_priority`.
958 /// An index of 0 corresponds to the layer with the highest priority in a
959 /// timeline. If `new_layer_priority` is greater than the number of layers
960 /// present in the timeline, it will become the lowest priority layer.
961 /// ## `layer`
962 /// A layer within `self`, whose priority should be changed
963 /// ## `new_layer_priority`
964 /// The new index for `layer`
965 #[cfg(feature = "v1_16")]
966 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
967 #[doc(alias = "ges_timeline_move_layer")]
968 fn move_layer(
969 &self,
970 layer: &impl IsA<Layer>,
971 new_layer_priority: u32,
972 ) -> Result<(), glib::error::BoolError> {
973 unsafe {
974 glib::result_from_gboolean!(
975 ffi::ges_timeline_move_layer(
976 self.as_ref().to_glib_none().0,
977 layer.as_ref().to_glib_none().0,
978 new_layer_priority
979 ),
980 "Failed to move layer"
981 )
982 }
983 }
984
985 /// Paste an element inside the timeline. `element` **must** be the return of
986 /// `ges_timeline_element_copy()` with `deep=TRUE`,
987 /// and it should not be changed before pasting. `element` itself is not
988 /// placed in the timeline, instead a new element is created, alike to the
989 /// originally copied element. Note that the originally copied element must
990 /// also lie within `self`, at both the point of copying and pasting.
991 ///
992 /// Pasting may fail if it would place the timeline in an unsupported
993 /// configuration.
994 ///
995 /// After calling this function `element` should not be used. In particular,
996 /// `element` can **not** be pasted again. Instead, you can copy the
997 /// returned element and paste that copy (although, this is only possible
998 /// if the paste was successful).
999 ///
1000 /// See also [`TimelineElementExt::paste()`][crate::prelude::TimelineElementExt::paste()].
1001 /// ## `element`
1002 /// The element to paste
1003 /// ## `position`
1004 /// The position in the timeline `element` should be pasted to,
1005 /// i.e. the [`start`][struct@crate::TimelineElement#start] value for the pasted element.
1006 /// ## `layer_priority`
1007 /// The layer into which the element should be pasted.
1008 /// -1 means paste to the same layer from which `element` has been copied from
1009 ///
1010 /// # Returns
1011 ///
1012 /// The newly created element, or
1013 /// [`None`] if pasting fails.
1014 #[doc(alias = "ges_timeline_paste_element")]
1015 fn paste_element(
1016 &self,
1017 element: &impl IsA<TimelineElement>,
1018 position: gst::ClockTime,
1019 layer_priority: i32,
1020 ) -> Option<TimelineElement> {
1021 unsafe {
1022 from_glib_full(ffi::ges_timeline_paste_element(
1023 self.as_ref().to_glib_none().0,
1024 element.as_ref().to_glib_none().0,
1025 position.into_glib(),
1026 layer_priority,
1027 ))
1028 }
1029 }
1030
1031 /// Removes a layer from the timeline.
1032 /// ## `layer`
1033 /// The layer to remove
1034 ///
1035 /// # Returns
1036 ///
1037 /// [`true`] if `layer` was properly removed.
1038 #[doc(alias = "ges_timeline_remove_layer")]
1039 fn remove_layer(&self, layer: &impl IsA<Layer>) -> Result<(), glib::error::BoolError> {
1040 unsafe {
1041 glib::result_from_gboolean!(
1042 ffi::ges_timeline_remove_layer(
1043 self.as_ref().to_glib_none().0,
1044 layer.as_ref().to_glib_none().0
1045 ),
1046 "Failed to remove layer"
1047 )
1048 }
1049 }
1050
1051 /// Remove a track from the timeline.
1052 /// ## `track`
1053 /// The track to remove
1054 ///
1055 /// # Returns
1056 ///
1057 /// [`true`] if `track` was properly removed.
1058 #[doc(alias = "ges_timeline_remove_track")]
1059 fn remove_track(&self, track: &impl IsA<Track>) -> Result<(), glib::error::BoolError> {
1060 unsafe {
1061 glib::result_from_gboolean!(
1062 ffi::ges_timeline_remove_track(
1063 self.as_ref().to_glib_none().0,
1064 track.as_ref().to_glib_none().0
1065 ),
1066 "Failed to remove track"
1067 )
1068 }
1069 }
1070
1071 /// Saves the timeline to the given location. If `formatter_asset` is [`None`],
1072 /// the method will attempt to save in the same format the timeline was
1073 /// loaded from, before defaulting to the formatter with highest rank.
1074 /// ## `uri`
1075 /// The location to save to
1076 /// ## `formatter_asset`
1077 /// The formatter asset to use, or [`None`]
1078 /// ## `overwrite`
1079 /// [`true`] to overwrite file if it exists
1080 ///
1081 /// # Returns
1082 ///
1083 /// [`true`] if `self` was successfully saved to `uri`.
1084 #[doc(alias = "ges_timeline_save_to_uri")]
1085 fn save_to_uri(
1086 &self,
1087 uri: &str,
1088 formatter_asset: Option<&impl IsA<Asset>>,
1089 overwrite: bool,
1090 ) -> Result<(), glib::Error> {
1091 unsafe {
1092 let mut error = std::ptr::null_mut();
1093 let is_ok = ffi::ges_timeline_save_to_uri(
1094 self.as_ref().to_glib_none().0,
1095 uri.to_glib_none().0,
1096 formatter_asset.map(|p| p.as_ref()).to_glib_none().0,
1097 overwrite.into_glib(),
1098 &mut error,
1099 );
1100 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1101 if error.is_null() {
1102 Ok(())
1103 } else {
1104 Err(from_glib_full(error))
1105 }
1106 }
1107 }
1108
1109 /// Sets [`auto-transition`][struct@crate::Timeline#auto-transition] for the timeline. This will also set
1110 /// the corresponding [`auto-transition`][struct@crate::Layer#auto-transition] for all of the timeline's
1111 /// layers to the same value. See [`LayerExt::set_auto_transition()`][crate::prelude::LayerExt::set_auto_transition()] if you
1112 /// wish to set the layer's [`auto-transition`][struct@crate::Layer#auto-transition] individually.
1113 /// ## `auto_transition`
1114 /// Whether transitions should be automatically added
1115 /// to `self`'s layers
1116 #[doc(alias = "ges_timeline_set_auto_transition")]
1117 #[doc(alias = "auto-transition")]
1118 fn set_auto_transition(&self, auto_transition: bool) {
1119 unsafe {
1120 ffi::ges_timeline_set_auto_transition(
1121 self.as_ref().to_glib_none().0,
1122 auto_transition.into_glib(),
1123 );
1124 }
1125 }
1126
1127 /// Sets [`snapping-distance`][struct@crate::Timeline#snapping-distance] for the timeline. This new value
1128 /// will only effect future snappings and will not be used to snap the
1129 /// current element positions within the timeline.
1130 /// ## `snapping_distance`
1131 /// The snapping distance to use (in nanoseconds)
1132 #[doc(alias = "ges_timeline_set_snapping_distance")]
1133 #[doc(alias = "snapping-distance")]
1134 fn set_snapping_distance(&self, snapping_distance: gst::ClockTime) {
1135 unsafe {
1136 ffi::ges_timeline_set_snapping_distance(
1137 self.as_ref().to_glib_none().0,
1138 snapping_distance.into_glib(),
1139 );
1140 }
1141 }
1142
1143 /// Thaw the timeline so that comiting becomes possible
1144 /// again and any call to ``commit()`` that happened during the rendering is
1145 /// actually taken into account.
1146 #[cfg(feature = "v1_20")]
1147 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
1148 #[doc(alias = "ges_timeline_thaw_commit")]
1149 fn thaw_commit(&self) {
1150 unsafe {
1151 ffi::ges_timeline_thaw_commit(self.as_ref().to_glib_none().0);
1152 }
1153 }
1154
1155 /// This signal will be emitted once the changes initiated by
1156 /// [`commit()`][Self::commit()] have been executed in the backend. Use
1157 /// [`commit_sync()`][Self::commit_sync()] if you do not want to have to connect
1158 /// to this signal.
1159 #[doc(alias = "commited")]
1160 fn connect_commited<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1161 unsafe extern "C" fn commited_trampoline<P: IsA<Timeline>, F: Fn(&P) + 'static>(
1162 this: *mut ffi::GESTimeline,
1163 f: glib::ffi::gpointer,
1164 ) {
1165 unsafe {
1166 let f: &F = &*(f as *const F);
1167 f(Timeline::from_glib_borrow(this).unsafe_cast_ref())
1168 }
1169 }
1170 unsafe {
1171 let f: Box_<F> = Box_::new(f);
1172 connect_raw(
1173 self.as_ptr() as *mut _,
1174 c"commited".as_ptr(),
1175 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1176 commited_trampoline::<Self, F> as *const (),
1177 )),
1178 Box_::into_raw(f),
1179 )
1180 }
1181 }
1182
1183 /// Will be emitted after the group is added to to the timeline. This can
1184 /// happen when grouping with `ges_container_group`, or by adding
1185 /// containers to a newly created group.
1186 ///
1187 /// Note that this should not be emitted whilst a timeline is being
1188 /// loaded from its [`Project`][crate::Project] asset. You should connect to the
1189 /// project's [`loaded`][struct@crate::Project#loaded] signal if you want to know which groups
1190 /// were created for the timeline.
1191 /// ## `group`
1192 /// The group that was added to `timeline`
1193 #[doc(alias = "group-added")]
1194 fn connect_group_added<F: Fn(&Self, &Group) + 'static>(&self, f: F) -> SignalHandlerId {
1195 unsafe extern "C" fn group_added_trampoline<
1196 P: IsA<Timeline>,
1197 F: Fn(&P, &Group) + 'static,
1198 >(
1199 this: *mut ffi::GESTimeline,
1200 group: *mut ffi::GESGroup,
1201 f: glib::ffi::gpointer,
1202 ) {
1203 unsafe {
1204 let f: &F = &*(f as *const F);
1205 f(
1206 Timeline::from_glib_borrow(this).unsafe_cast_ref(),
1207 &from_glib_borrow(group),
1208 )
1209 }
1210 }
1211 unsafe {
1212 let f: Box_<F> = Box_::new(f);
1213 connect_raw(
1214 self.as_ptr() as *mut _,
1215 c"group-added".as_ptr(),
1216 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1217 group_added_trampoline::<Self, F> as *const (),
1218 )),
1219 Box_::into_raw(f),
1220 )
1221 }
1222 }
1223
1224 //#[doc(alias = "group-removed")]
1225 //fn connect_group_removed<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
1226 // Empty ctype children: *.PtrArray TypeId { ns_id: 1, id: 35 }
1227 //}
1228
1229 /// Will be emitted after the layer is added to the timeline.
1230 ///
1231 /// Note that this should not be emitted whilst a timeline is being
1232 /// loaded from its [`Project`][crate::Project] asset. You should connect to the
1233 /// project's [`loaded`][struct@crate::Project#loaded] signal if you want to know which
1234 /// layers were created for the timeline.
1235 /// ## `layer`
1236 /// The layer that was added to `timeline`
1237 #[doc(alias = "layer-added")]
1238 fn connect_layer_added<F: Fn(&Self, &Layer) + 'static>(&self, f: F) -> SignalHandlerId {
1239 unsafe extern "C" fn layer_added_trampoline<
1240 P: IsA<Timeline>,
1241 F: Fn(&P, &Layer) + 'static,
1242 >(
1243 this: *mut ffi::GESTimeline,
1244 layer: *mut ffi::GESLayer,
1245 f: glib::ffi::gpointer,
1246 ) {
1247 unsafe {
1248 let f: &F = &*(f as *const F);
1249 f(
1250 Timeline::from_glib_borrow(this).unsafe_cast_ref(),
1251 &from_glib_borrow(layer),
1252 )
1253 }
1254 }
1255 unsafe {
1256 let f: Box_<F> = Box_::new(f);
1257 connect_raw(
1258 self.as_ptr() as *mut _,
1259 c"layer-added".as_ptr(),
1260 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1261 layer_added_trampoline::<Self, F> as *const (),
1262 )),
1263 Box_::into_raw(f),
1264 )
1265 }
1266 }
1267
1268 /// Will be emitted after the layer is removed from the timeline.
1269 /// ## `layer`
1270 /// The layer that was removed from `timeline`
1271 #[doc(alias = "layer-removed")]
1272 fn connect_layer_removed<F: Fn(&Self, &Layer) + 'static>(&self, f: F) -> SignalHandlerId {
1273 unsafe extern "C" fn layer_removed_trampoline<
1274 P: IsA<Timeline>,
1275 F: Fn(&P, &Layer) + 'static,
1276 >(
1277 this: *mut ffi::GESTimeline,
1278 layer: *mut ffi::GESLayer,
1279 f: glib::ffi::gpointer,
1280 ) {
1281 unsafe {
1282 let f: &F = &*(f as *const F);
1283 f(
1284 Timeline::from_glib_borrow(this).unsafe_cast_ref(),
1285 &from_glib_borrow(layer),
1286 )
1287 }
1288 }
1289 unsafe {
1290 let f: Box_<F> = Box_::new(f);
1291 connect_raw(
1292 self.as_ptr() as *mut _,
1293 c"layer-removed".as_ptr(),
1294 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1295 layer_removed_trampoline::<Self, F> as *const (),
1296 )),
1297 Box_::into_raw(f),
1298 )
1299 }
1300 }
1301
1302 /// Simplified version of [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object] which only
1303 /// allows `track_element` to be added to a single [`Track`][crate::Track].
1304 /// ## `clip`
1305 /// The clip that `track_element` is being added to
1306 /// ## `track_element`
1307 /// The element being added
1308 ///
1309 /// # Returns
1310 ///
1311 /// A track to put `track_element` into, or [`None`] if
1312 /// it should be discarded.
1313 #[cfg(feature = "v1_18")]
1314 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1315 #[doc(alias = "select-element-track")]
1316 fn connect_select_element_track<
1317 F: Fn(&Self, &Clip, &TrackElement) -> Option<Track> + 'static,
1318 >(
1319 &self,
1320 f: F,
1321 ) -> SignalHandlerId {
1322 unsafe extern "C" fn select_element_track_trampoline<
1323 P: IsA<Timeline>,
1324 F: Fn(&P, &Clip, &TrackElement) -> Option<Track> + 'static,
1325 >(
1326 this: *mut ffi::GESTimeline,
1327 clip: *mut ffi::GESClip,
1328 track_element: *mut ffi::GESTrackElement,
1329 f: glib::ffi::gpointer,
1330 ) -> *mut ffi::GESTrack {
1331 unsafe {
1332 let f: &F = &*(f as *const F);
1333 f(
1334 Timeline::from_glib_borrow(this).unsafe_cast_ref(),
1335 &from_glib_borrow(clip),
1336 &from_glib_borrow(track_element),
1337 )
1338 .to_glib_full()
1339 }
1340 }
1341 unsafe {
1342 let f: Box_<F> = Box_::new(f);
1343 connect_raw(
1344 self.as_ptr() as *mut _,
1345 c"select-element-track".as_ptr(),
1346 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1347 select_element_track_trampoline::<Self, F> as *const (),
1348 )),
1349 Box_::into_raw(f),
1350 )
1351 }
1352 }
1353
1354 //#[doc(alias = "select-tracks-for-object")]
1355 //fn connect_select_tracks_for_object<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
1356 // Empty ctype return value *.PtrArray TypeId { ns_id: 1, id: 11 }
1357 //}
1358
1359 /// Will be emitted whenever a snapping event ends. After a snap event
1360 /// has started (see [`snapping-started`][struct@crate::Timeline#snapping-started]), it can later end
1361 /// because either another timeline edit has occurred (which may or may
1362 /// not have created a new snapping event), or because the timeline has
1363 /// been committed.
1364 /// ## `obj1`
1365 /// The first element that was snapping
1366 /// ## `obj2`
1367 /// The second element that was snapping
1368 /// ## `position`
1369 /// The position where the two objects were to be snapped to
1370 #[doc(alias = "snapping-ended")]
1371 fn connect_snapping_ended<F: Fn(&Self, &TrackElement, &TrackElement, u64) + 'static>(
1372 &self,
1373 f: F,
1374 ) -> SignalHandlerId {
1375 unsafe extern "C" fn snapping_ended_trampoline<
1376 P: IsA<Timeline>,
1377 F: Fn(&P, &TrackElement, &TrackElement, u64) + 'static,
1378 >(
1379 this: *mut ffi::GESTimeline,
1380 obj1: *mut ffi::GESTrackElement,
1381 obj2: *mut ffi::GESTrackElement,
1382 position: u64,
1383 f: glib::ffi::gpointer,
1384 ) {
1385 unsafe {
1386 let f: &F = &*(f as *const F);
1387 f(
1388 Timeline::from_glib_borrow(this).unsafe_cast_ref(),
1389 &from_glib_borrow(obj1),
1390 &from_glib_borrow(obj2),
1391 position,
1392 )
1393 }
1394 }
1395 unsafe {
1396 let f: Box_<F> = Box_::new(f);
1397 connect_raw(
1398 self.as_ptr() as *mut _,
1399 c"snapping-ended".as_ptr(),
1400 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1401 snapping_ended_trampoline::<Self, F> as *const (),
1402 )),
1403 Box_::into_raw(f),
1404 )
1405 }
1406 }
1407
1408 /// Will be emitted whenever an element's movement invokes a snapping
1409 /// event during an edit (usually of one of its ancestors) because its
1410 /// start or end point lies within the [`snapping-distance`][struct@crate::Timeline#snapping-distance] of
1411 /// another element's start or end point.
1412 ///
1413 /// See [`EditMode`][crate::EditMode] to see what can snap during an edit.
1414 ///
1415 /// Note that only up to one snapping-started signal will be emitted per
1416 /// element edit within a timeline.
1417 /// ## `obj1`
1418 /// The first element that is snapping
1419 /// ## `obj2`
1420 /// The second element that is snapping
1421 /// ## `position`
1422 /// The position where the two objects will snap to
1423 #[doc(alias = "snapping-started")]
1424 fn connect_snapping_started<F: Fn(&Self, &TrackElement, &TrackElement, u64) + 'static>(
1425 &self,
1426 f: F,
1427 ) -> SignalHandlerId {
1428 unsafe extern "C" fn snapping_started_trampoline<
1429 P: IsA<Timeline>,
1430 F: Fn(&P, &TrackElement, &TrackElement, u64) + 'static,
1431 >(
1432 this: *mut ffi::GESTimeline,
1433 obj1: *mut ffi::GESTrackElement,
1434 obj2: *mut ffi::GESTrackElement,
1435 position: u64,
1436 f: glib::ffi::gpointer,
1437 ) {
1438 unsafe {
1439 let f: &F = &*(f as *const F);
1440 f(
1441 Timeline::from_glib_borrow(this).unsafe_cast_ref(),
1442 &from_glib_borrow(obj1),
1443 &from_glib_borrow(obj2),
1444 position,
1445 )
1446 }
1447 }
1448 unsafe {
1449 let f: Box_<F> = Box_::new(f);
1450 connect_raw(
1451 self.as_ptr() as *mut _,
1452 c"snapping-started".as_ptr(),
1453 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1454 snapping_started_trampoline::<Self, F> as *const (),
1455 )),
1456 Box_::into_raw(f),
1457 )
1458 }
1459 }
1460
1461 /// Will be emitted after the track is added to the timeline.
1462 ///
1463 /// Note that this should not be emitted whilst a timeline is being
1464 /// loaded from its [`Project`][crate::Project] asset. You should connect to the
1465 /// project's [`loaded`][struct@crate::Project#loaded] signal if you want to know which
1466 /// tracks were created for the timeline.
1467 /// ## `track`
1468 /// The track that was added to `timeline`
1469 #[doc(alias = "track-added")]
1470 fn connect_track_added<F: Fn(&Self, &Track) + 'static>(&self, f: F) -> SignalHandlerId {
1471 unsafe extern "C" fn track_added_trampoline<
1472 P: IsA<Timeline>,
1473 F: Fn(&P, &Track) + 'static,
1474 >(
1475 this: *mut ffi::GESTimeline,
1476 track: *mut ffi::GESTrack,
1477 f: glib::ffi::gpointer,
1478 ) {
1479 unsafe {
1480 let f: &F = &*(f as *const F);
1481 f(
1482 Timeline::from_glib_borrow(this).unsafe_cast_ref(),
1483 &from_glib_borrow(track),
1484 )
1485 }
1486 }
1487 unsafe {
1488 let f: Box_<F> = Box_::new(f);
1489 connect_raw(
1490 self.as_ptr() as *mut _,
1491 c"track-added".as_ptr(),
1492 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1493 track_added_trampoline::<Self, F> as *const (),
1494 )),
1495 Box_::into_raw(f),
1496 )
1497 }
1498 }
1499
1500 /// Will be emitted after the track is removed from the timeline.
1501 /// ## `track`
1502 /// The track that was removed from `timeline`
1503 #[doc(alias = "track-removed")]
1504 fn connect_track_removed<F: Fn(&Self, &Track) + 'static>(&self, f: F) -> SignalHandlerId {
1505 unsafe extern "C" fn track_removed_trampoline<
1506 P: IsA<Timeline>,
1507 F: Fn(&P, &Track) + 'static,
1508 >(
1509 this: *mut ffi::GESTimeline,
1510 track: *mut ffi::GESTrack,
1511 f: glib::ffi::gpointer,
1512 ) {
1513 unsafe {
1514 let f: &F = &*(f as *const F);
1515 f(
1516 Timeline::from_glib_borrow(this).unsafe_cast_ref(),
1517 &from_glib_borrow(track),
1518 )
1519 }
1520 }
1521 unsafe {
1522 let f: Box_<F> = Box_::new(f);
1523 connect_raw(
1524 self.as_ptr() as *mut _,
1525 c"track-removed".as_ptr(),
1526 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1527 track_removed_trampoline::<Self, F> as *const (),
1528 )),
1529 Box_::into_raw(f),
1530 )
1531 }
1532 }
1533
1534 #[doc(alias = "auto-transition")]
1535 fn connect_auto_transition_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1536 unsafe extern "C" fn notify_auto_transition_trampoline<
1537 P: IsA<Timeline>,
1538 F: Fn(&P) + 'static,
1539 >(
1540 this: *mut ffi::GESTimeline,
1541 _param_spec: glib::ffi::gpointer,
1542 f: glib::ffi::gpointer,
1543 ) {
1544 unsafe {
1545 let f: &F = &*(f as *const F);
1546 f(Timeline::from_glib_borrow(this).unsafe_cast_ref())
1547 }
1548 }
1549 unsafe {
1550 let f: Box_<F> = Box_::new(f);
1551 connect_raw(
1552 self.as_ptr() as *mut _,
1553 c"notify::auto-transition".as_ptr(),
1554 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1555 notify_auto_transition_trampoline::<Self, F> as *const (),
1556 )),
1557 Box_::into_raw(f),
1558 )
1559 }
1560 }
1561
1562 #[doc(alias = "duration")]
1563 fn connect_duration_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1564 unsafe extern "C" fn notify_duration_trampoline<P: IsA<Timeline>, F: Fn(&P) + 'static>(
1565 this: *mut ffi::GESTimeline,
1566 _param_spec: glib::ffi::gpointer,
1567 f: glib::ffi::gpointer,
1568 ) {
1569 unsafe {
1570 let f: &F = &*(f as *const F);
1571 f(Timeline::from_glib_borrow(this).unsafe_cast_ref())
1572 }
1573 }
1574 unsafe {
1575 let f: Box_<F> = Box_::new(f);
1576 connect_raw(
1577 self.as_ptr() as *mut _,
1578 c"notify::duration".as_ptr(),
1579 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1580 notify_duration_trampoline::<Self, F> as *const (),
1581 )),
1582 Box_::into_raw(f),
1583 )
1584 }
1585 }
1586
1587 #[doc(alias = "snapping-distance")]
1588 fn connect_snapping_distance_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1589 unsafe extern "C" fn notify_snapping_distance_trampoline<
1590 P: IsA<Timeline>,
1591 F: Fn(&P) + 'static,
1592 >(
1593 this: *mut ffi::GESTimeline,
1594 _param_spec: glib::ffi::gpointer,
1595 f: glib::ffi::gpointer,
1596 ) {
1597 unsafe {
1598 let f: &F = &*(f as *const F);
1599 f(Timeline::from_glib_borrow(this).unsafe_cast_ref())
1600 }
1601 }
1602 unsafe {
1603 let f: Box_<F> = Box_::new(f);
1604 connect_raw(
1605 self.as_ptr() as *mut _,
1606 c"notify::snapping-distance".as_ptr(),
1607 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1608 notify_snapping_distance_trampoline::<Self, F> as *const (),
1609 )),
1610 Box_::into_raw(f),
1611 )
1612 }
1613 }
1614}
1615
1616impl<O: IsA<Timeline>> TimelineExt for O {}