From 4cdf2fd70b09d701a0e61e89c10190f2f240dfa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Cerveau?= Date: Tue, 1 Feb 2022 11:46:39 +0100 Subject: [PATCH] app: support multiple preview in a Notebook The preview is now a NoteBook and if multiple video gtk4sink are available, a page is created for each of it. --- src/app.rs | 23 ++++++++++++++++++----- src/gps/element.rs | 14 ++++++++------ src/gps/pipeline.rs | 8 +++++--- src/ui/gps.ui | 8 ++++++++ 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/app.rs b/src/app.rs index d573d7c..13cf78a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -410,17 +410,30 @@ impl GPSApp { status_bar.push(status_bar.context_id("Description"), &state.to_string()); } - pub fn set_app_preview(&self, paintable: &gdk::Paintable) { + pub fn set_app_preview(&self, paintable: &gdk::Paintable, n_sink: usize) { let picture = gtk::Picture::new(); picture.set_paintable(Some(paintable)); - let box_preview: gtk::Box = self + let notebook_preview: gtk::Notebook = self .builder - .object("box-preview") + .object("notebook-preview") .expect("Couldn't get box_preview"); - while let Some(child) = box_preview.first_child() { - box_preview.remove(&child); + if n_sink == 0 { + loop { + let i = notebook_preview.n_pages(); + if i == 0 { + break; + } + notebook_preview.remove_page(Some(i - 1)); + } } + let box_preview = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .build(); box_preview.append(&picture); + let label = gtk::Label::new(Some(&format!("Preview{}", n_sink))); + notebook_preview.insert_page(&box_preview, Some(&label), None); } pub fn build_ui(&self, application: &Application) { diff --git a/src/gps/element.rs b/src/gps/element.rs index 576ce69..2cb9539 100644 --- a/src/gps/element.rs +++ b/src/gps/element.rs @@ -223,26 +223,28 @@ impl ElementInfo { None } - pub fn search_fo_element(bin: &gst::Bin, element_name: &str) -> Option { + pub fn search_fo_element(bin: &gst::Bin, element_name: &str) -> Vec { let mut iter = bin.iterate_elements(); - let element = loop { + let mut elements: Vec = Vec::new(); + let elements = loop { match iter.next() { Ok(Some(element)) => { if element.is::() { let bin = element.dynamic_cast::().unwrap(); - break ElementInfo::search_fo_element(&bin, element_name); + let mut bin_elements = ElementInfo::search_fo_element(&bin, element_name); + elements.append(&mut bin_elements); } else { GPS_INFO!("Found factory: {}", element.factory().unwrap().name()); if element.factory().unwrap().name() == element_name { GPS_INFO!("Found {}", element_name); - break Some(element); + elements.push(element); } } } Err(gst::IteratorError::Resync) => iter.resync(), - _ => break None, + _ => break elements, } }; - element + elements } } diff --git a/src/gps/pipeline.rs b/src/gps/pipeline.rs index e8a462e..0d2a1bb 100644 --- a/src/gps/pipeline.rs +++ b/src/gps/pipeline.rs @@ -113,16 +113,18 @@ impl Pipeline { pub fn check_for_gtk4sink(&self, pipeline: &gst::Pipeline) { let bin = pipeline.clone().dynamic_cast::().unwrap(); - let gtksink = ElementInfo::search_fo_element(&bin, "gtk4paintablesink"); - if let Some(gtksink) = gtksink { + let gtksinks = ElementInfo::search_fo_element(&bin, "gtk4paintablesink"); + + for (first_sink, gtksink) in gtksinks.into_iter().enumerate() { let paintable = gtksink.property::("paintable"); self.app .borrow() .as_ref() .expect("App should be available") - .set_app_preview(&paintable); + .set_app_preview(&paintable, first_sink); } } + pub fn start_pipeline( &self, graphview: &GraphView, diff --git a/src/ui/gps.ui b/src/ui/gps.ui index 425be12..a05c5d9 100644 --- a/src/ui/gps.ui +++ b/src/ui/gps.ui @@ -295,6 +295,10 @@ + + + + True True @@ -309,6 +313,10 @@ + + + +