properties: add a way to display pipeline properties

Pipeline properties displays all elements in
the pipeline.
This commit is contained in:
Stéphane Cerveau 2022-02-04 17:34:56 +01:00
parent 4cb965fe7f
commit e3ac490a81
5 changed files with 111 additions and 46 deletions

View file

@ -286,6 +286,7 @@ impl GPSApp {
application.add_action(&gio::SimpleAction::new("favorite.remove", None)); application.add_action(&gio::SimpleAction::new("favorite.remove", None));
application.add_action(&gio::SimpleAction::new("graph.check", None)); application.add_action(&gio::SimpleAction::new("graph.check", None));
application.add_action(&gio::SimpleAction::new("graph.pipeline_details", None));
application.add_action(&gio::SimpleAction::new("port.delete", None)); application.add_action(&gio::SimpleAction::new("port.delete", None));
application.add_action(&gio::SimpleAction::new("port.properties", None)); application.add_action(&gio::SimpleAction::new("port.properties", None));
@ -655,6 +656,13 @@ impl GPSApp {
} }
} }
); );
let app_weak = app.downgrade();
app.connect_app_menu_action("graph.pipeline_details",
move |_,_| {
let app = upgrade_weak!(app_weak);
GPSUI::properties::display_pipeline_details(&app);
}
);
pop_menu.show(); pop_menu.show();
None None
}), }),

View file

@ -235,7 +235,9 @@ impl ElementInfo {
elements.append(&mut bin_elements); 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
|| element_name.is_empty()
{
GPS_INFO!("Found {}", element_name); GPS_INFO!("Found {}", element_name);
elements.push(element); elements.push(element);
} }

View file

@ -273,6 +273,10 @@ impl Player {
} }
} }
pub fn playing(&self) -> bool {
self.state() == PipelineState::Playing || self.state() == PipelineState::Paused
}
pub fn downgrade(&self) -> PlayerWeak { pub fn downgrade(&self) -> PlayerWeak {
PlayerWeak(Rc::downgrade(&self.0)) PlayerWeak(Rc::downgrade(&self.0))
} }
@ -308,6 +312,24 @@ impl Player {
}; };
} }
pub fn pipeline_elements(&self) -> Option<Vec<String>> {
if self.playing() {
let bin = self
.pipeline
.borrow()
.clone()
.unwrap()
.dynamic_cast::<gst::Bin>()
.unwrap();
let elements_name: Vec<String> = ElementInfo::search_fo_element(&bin, "")
.iter()
.map(|e| e.factory().unwrap().name().to_string())
.collect();
return Some(elements_name);
}
None
}
// Render graph methods // Render graph methods
fn process_gst_node( fn process_gst_node(
&self, &self,

View file

@ -51,6 +51,10 @@
<attribute name="label" translatable="yes" comments="graph menu entry check graph">_Check graph</attribute> <attribute name="label" translatable="yes" comments="graph menu entry check graph">_Check graph</attribute>
<attribute name="action">app.graph.check</attribute> <attribute name="action">app.graph.check</attribute>
</item> </item>
<item>
<attribute name="label" translatable="yes" comments="graph menu entry pipeline details">_Pipeline details</attribute>
<attribute name="action">app.graph.pipeline_details</attribute>
</item>
</section> </section>
</menu> </menu>
<menu id="fav_menu"> <menu id="fav_menu">

View file

@ -170,9 +170,14 @@ pub fn property_to_widget<F: Fn(String, String) + 'static>(
} }
} }
pub fn display_plugin_properties(app: &GPSApp, element_name: &str, node_id: u32) { fn create_dialog<F: Fn(GPSApp, gtk::Dialog) + 'static>(
name: &str,
app: &GPSApp,
grid: &gtk::Grid,
f: F,
) -> gtk::Dialog {
let dialog = gtk::Dialog::with_buttons( let dialog = gtk::Dialog::with_buttons(
Some(&format!("{} properties", element_name)), Some(name),
Some(&app.window), Some(&app.window),
gtk::DialogFlags::MODAL, gtk::DialogFlags::MODAL,
&[("Close", gtk::ResponseType::Close)], &[("Close", gtk::ResponseType::Close)],
@ -180,7 +185,29 @@ pub fn display_plugin_properties(app: &GPSApp, element_name: &str, node_id: u32)
dialog.set_default_size(640, 480); dialog.set_default_size(640, 480);
dialog.set_modal(true); dialog.set_modal(true);
let app_weak = app.downgrade();
dialog.connect_response(glib::clone!(@weak dialog => move |_,_| {
let app = upgrade_weak!(app_weak);
f(app, dialog)
}));
let scrolledwindow = gtk::ScrolledWindow::builder()
.hexpand(true)
.vexpand(true)
.build();
scrolledwindow.set_child(Some(grid));
let content_area = dialog.content_area();
content_area.append(&scrolledwindow);
content_area.set_vexpand(true);
content_area.set_margin_start(10);
content_area.set_margin_end(10);
content_area.set_margin_top(10);
content_area.set_margin_bottom(10);
dialog
}
pub fn display_plugin_properties(app: &GPSApp, element_name: &str, node_id: u32) {
let update_properties: Rc<RefCell<HashMap<String, String>>> = let update_properties: Rc<RefCell<HashMap<String, String>>> =
Rc::new(RefCell::new(HashMap::new())); Rc::new(RefCell::new(HashMap::new()));
let properties = GPS::ElementInfo::element_properties(element_name).unwrap(); let properties = GPS::ElementInfo::element_properties(element_name).unwrap();
@ -216,23 +243,12 @@ pub fn display_plugin_properties(app: &GPSApp, element_name: &str, node_id: u32)
i += 1; i += 1;
} }
} }
let scrolledwindow = gtk::ScrolledWindow::builder()
.hexpand(true)
.vexpand(true)
.build();
scrolledwindow.set_child(Some(&grid));
let content_area = dialog.content_area();
content_area.append(&scrolledwindow);
content_area.set_vexpand(true);
content_area.set_margin_start(10);
content_area.set_margin_end(10);
content_area.set_margin_top(10);
content_area.set_margin_bottom(10);
let app_weak = app.downgrade(); let dialog = create_dialog(
dialog.connect_response( &format!("{} properties", element_name),
glib::clone!(@strong update_properties, @weak dialog => move |_,_| { app,
let app = upgrade_weak!(app_weak); &grid,
glib::clone!(@strong update_properties => move |app, dialog| {
for p in update_properties.borrow().values() { for p in update_properties.borrow().values() {
GPS_INFO!("updated properties {}", p); GPS_INFO!("updated properties {}", p);
} }
@ -251,16 +267,6 @@ pub fn display_pad_properties(
node_id: u32, node_id: u32,
port_id: u32, port_id: u32,
) { ) {
let dialog = gtk::Dialog::with_buttons(
Some(&format!("{} properties from {}", port_name, element_name,)),
Some(&app.window),
gtk::DialogFlags::MODAL,
&[("Close", gtk::ResponseType::Close)],
);
dialog.set_default_size(640, 480);
dialog.set_modal(true);
let update_properties: Rc<RefCell<HashMap<String, String>>> = let update_properties: Rc<RefCell<HashMap<String, String>>> =
Rc::new(RefCell::new(HashMap::new())); Rc::new(RefCell::new(HashMap::new()));
@ -317,23 +323,11 @@ pub fn display_pad_properties(
// Add all specific properties from the given element // Add all specific properties from the given element
let scrolledwindow = gtk::ScrolledWindow::builder() let dialog = create_dialog(
.hexpand(true) &format!("{} properties from {}", port_name, element_name),
.vexpand(true) app,
.build(); &grid,
scrolledwindow.set_child(Some(&grid)); glib::clone!(@strong update_properties => move |app, dialog| {
let content_area = dialog.content_area();
content_area.append(&scrolledwindow);
content_area.set_vexpand(true);
content_area.set_margin_start(10);
content_area.set_margin_end(10);
content_area.set_margin_top(10);
content_area.set_margin_bottom(10);
let app_weak = app.downgrade();
dialog.connect_response(
glib::clone!(@strong update_properties, @weak dialog => move |_,_| {
let app = upgrade_weak!(app_weak);
for p in update_properties.borrow().values() { for p in update_properties.borrow().values() {
GPS_INFO!("updated properties {}", p); GPS_INFO!("updated properties {}", p);
} }
@ -344,3 +338,38 @@ pub fn display_pad_properties(
dialog.show(); dialog.show();
} }
pub fn display_pipeline_details(app: &GPSApp) {
let grid = gtk::Grid::new();
grid.set_column_spacing(4);
grid.set_row_spacing(4);
grid.set_margin_bottom(12);
if let Some(elements) = app.player.borrow().pipeline_elements() {
let elements_list = elements.join(" ");
let label = gtk::Label::builder()
.label("Elements:")
.hexpand(true)
.halign(gtk::Align::Start)
.valign(gtk::Align::Start)
.margin_start(4)
.build();
let value = gtk::Label::builder()
.label(&elements_list)
.hexpand(true)
.halign(gtk::Align::Start)
.margin_start(4)
.wrap(true)
.build();
grid.attach(&label, 0, 0_i32, 1, 1);
grid.attach(&value, 1, 0_i32, 1, 1);
let dialog = create_dialog("Pipeline properties", app, &grid, move |_app, dialog| {
dialog.close();
});
dialog.show();
}
}