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.
This commit is contained in:
Stéphane Cerveau 2022-02-01 11:46:39 +01:00
parent 09f56de320
commit 4cdf2fd70b
4 changed files with 39 additions and 14 deletions

View file

@ -410,17 +410,30 @@ impl GPSApp {
status_bar.push(status_bar.context_id("Description"), &state.to_string()); 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(); let picture = gtk::Picture::new();
picture.set_paintable(Some(paintable)); picture.set_paintable(Some(paintable));
let box_preview: gtk::Box = self let notebook_preview: gtk::Notebook = self
.builder .builder
.object("box-preview") .object("notebook-preview")
.expect("Couldn't get box_preview"); .expect("Couldn't get box_preview");
while let Some(child) = box_preview.first_child() { if n_sink == 0 {
box_preview.remove(&child); 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); 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) { pub fn build_ui(&self, application: &Application) {

View file

@ -223,26 +223,28 @@ impl ElementInfo {
None None
} }
pub fn search_fo_element(bin: &gst::Bin, element_name: &str) -> Option<gst::Element> { pub fn search_fo_element(bin: &gst::Bin, element_name: &str) -> Vec<gst::Element> {
let mut iter = bin.iterate_elements(); let mut iter = bin.iterate_elements();
let element = loop { let mut elements: Vec<gst::Element> = Vec::new();
let elements = loop {
match iter.next() { match iter.next() {
Ok(Some(element)) => { Ok(Some(element)) => {
if element.is::<gst::Bin>() { if element.is::<gst::Bin>() {
let bin = element.dynamic_cast::<gst::Bin>().unwrap(); let bin = element.dynamic_cast::<gst::Bin>().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 { } else {
GPS_INFO!("Found factory: {}", element.factory().unwrap().name()); GPS_INFO!("Found factory: {}", element.factory().unwrap().name());
if element.factory().unwrap().name() == element_name { if element.factory().unwrap().name() == element_name {
GPS_INFO!("Found {}", element_name); GPS_INFO!("Found {}", element_name);
break Some(element); elements.push(element);
} }
} }
} }
Err(gst::IteratorError::Resync) => iter.resync(), Err(gst::IteratorError::Resync) => iter.resync(),
_ => break None, _ => break elements,
} }
}; };
element elements
} }
} }

View file

@ -113,16 +113,18 @@ impl Pipeline {
pub fn check_for_gtk4sink(&self, pipeline: &gst::Pipeline) { pub fn check_for_gtk4sink(&self, pipeline: &gst::Pipeline) {
let bin = pipeline.clone().dynamic_cast::<gst::Bin>().unwrap(); let bin = pipeline.clone().dynamic_cast::<gst::Bin>().unwrap();
let gtksink = ElementInfo::search_fo_element(&bin, "gtk4paintablesink"); let gtksinks = ElementInfo::search_fo_element(&bin, "gtk4paintablesink");
if let Some(gtksink) = gtksink {
for (first_sink, gtksink) in gtksinks.into_iter().enumerate() {
let paintable = gtksink.property::<gdk::Paintable>("paintable"); let paintable = gtksink.property::<gdk::Paintable>("paintable");
self.app self.app
.borrow() .borrow()
.as_ref() .as_ref()
.expect("App should be available") .expect("App should be available")
.set_app_preview(&paintable); .set_app_preview(&paintable, first_sink);
} }
} }
pub fn start_pipeline( pub fn start_pipeline(
&self, &self,
graphview: &GraphView, graphview: &GraphView,

View file

@ -295,6 +295,10 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkNotebook" id="notebook-preview">
<child>
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="vexpand">True</property> <property name="vexpand">True</property>
@ -309,6 +313,10 @@
</object> </object>
</property> </property>
</object> </object>
</property>
</object>
</child>
</object>
</child> </child>
</object> </object>
</child> </child>