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("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.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();
None
}),

View file

@ -235,7 +235,9 @@ impl ElementInfo {
elements.append(&mut bin_elements);
} else {
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);
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 {
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
fn process_gst_node(
&self,

View file

@ -51,6 +51,10 @@
<attribute name="label" translatable="yes" comments="graph menu entry check graph">_Check graph</attribute>
<attribute name="action">app.graph.check</attribute>
</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>
</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(
Some(&format!("{} properties", element_name)),
Some(name),
Some(&app.window),
gtk::DialogFlags::MODAL,
&[("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_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>>> =
Rc::new(RefCell::new(HashMap::new()));
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;
}
}
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();
dialog.connect_response(
glib::clone!(@strong update_properties, @weak dialog => move |_,_| {
let app = upgrade_weak!(app_weak);
let dialog = create_dialog(
&format!("{} properties", element_name),
app,
&grid,
glib::clone!(@strong update_properties => move |app, dialog| {
for p in update_properties.borrow().values() {
GPS_INFO!("updated properties {}", p);
}
@ -251,16 +267,6 @@ pub fn display_pad_properties(
node_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>>> =
Rc::new(RefCell::new(HashMap::new()));
@ -317,23 +323,11 @@ pub fn display_pad_properties(
// Add all specific properties from the given element
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();
dialog.connect_response(
glib::clone!(@strong update_properties, @weak dialog => move |_,_| {
let app = upgrade_weak!(app_weak);
let dialog = create_dialog(
&format!("{} properties from {}", port_name, element_name),
app,
&grid,
glib::clone!(@strong update_properties => move |app, dialog| {
for p in update_properties.borrow().values() {
GPS_INFO!("updated properties {}", p);
}
@ -344,3 +338,38 @@ pub fn display_pad_properties(
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();
}
}