diff --git a/src/app.rs b/src/app.rs index 857c1eb..9d08fde 100644 --- a/src/app.rs +++ b/src/app.rs @@ -271,6 +271,8 @@ impl GPSApp { application.add_action(&gio::SimpleAction::new("delete", None)); application.set_accels_for_action("app.delete", &["d", "Delete"]); + application.add_action(&gio::SimpleAction::new("preferences", None)); + application.set_accels_for_action("app.preferences", &["p"]); application.add_action(&gio::SimpleAction::new("quit", None)); application.set_accels_for_action("app.quit", &["q"]); @@ -505,6 +507,12 @@ impl GPSApp { }); }); + let app_weak = self.downgrade(); + self.connect_app_menu_action("preferences", move |_, _| { + let app = upgrade_weak!(app_weak); + GPSUI::preferences::display_settings(&app); + }); + let app_weak = self.downgrade(); self.connect_app_menu_action("delete", move |_, _| { let app = upgrade_weak!(app_weak); diff --git a/src/gps/pipeline.rs b/src/gps/pipeline.rs index 0d2a1bb..ad9cf7c 100644 --- a/src/gps/pipeline.rs +++ b/src/gps/pipeline.rs @@ -22,6 +22,7 @@ use crate::graphmanager::{GraphView, Node, NodeType, PortDirection, PropertyExt} use crate::gps::ElementInfo; use crate::logger; +use crate::settings; use crate::GPS_INFO; use gst::glib; @@ -85,7 +86,6 @@ impl Pipeline { #[cfg(feature = "gtk4-plugin")] { gstgtk4::plugin_register_static().expect("Failed to register gstgtk4 plugin"); - ElementInfo::element_update_rank("gtk4paintablesink", gst::Rank::Primary); } Ok(pipeline) @@ -98,6 +98,18 @@ impl Pipeline { pub fn create_pipeline(&self, description: &str) -> anyhow::Result { GPS_INFO!("Creating pipeline {}", description); + if settings::Settings::load_settings() + .preferences + .get("use_gtk4_sink") + .unwrap_or(&"true".to_string()) + .parse::() + .expect("Should a boolean value") + { + ElementInfo::element_update_rank("gtk4paintablesink", gst::Rank::Primary); + } else { + ElementInfo::element_update_rank("gtk4paintablesink", gst::Rank::Marginal); + } + // Create pipeline from the description let pipeline = gst::parse_launch(&description.to_string())?; let pipeline = pipeline.downcast::(); diff --git a/src/settings.rs b/src/settings.rs index a1503a5..2bf7650 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -10,11 +10,14 @@ use crate::logger; #[derive(Debug, Serialize, Deserialize, Default)] pub struct Settings { - pub favorites: Vec, pub app_maximized: bool, pub app_width: i32, pub app_height: i32, + + // values must be emitted before tables + pub favorites: Vec, pub paned_positions: HashMap, + pub preferences: HashMap, } impl Settings { diff --git a/src/ui/gps.ui b/src/ui/gps.ui index f677ad2..0024ed8 100644 --- a/src/ui/gps.ui +++ b/src/ui/gps.ui @@ -18,6 +18,11 @@ app.save_as <primary>n + + _Preferences + app.preferences + <primary>p + _About GstPipelineStudio app.about diff --git a/src/ui/mod.rs b/src/ui/mod.rs index b55cd7a..2786de8 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -20,5 +20,6 @@ pub mod about; pub mod elements; pub mod logger; pub mod message; +pub mod preferences; pub mod properties; pub mod treeview; diff --git a/src/ui/preferences.rs b/src/ui/preferences.rs new file mode 100644 index 0000000..ea1dc96 --- /dev/null +++ b/src/ui/preferences.rs @@ -0,0 +1,84 @@ +// preferences.rs +// +// Copyright 2022 Stéphane Cerveau +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// SPDX-License-Identifier: GPL-3.0-only +use crate::app::GPSApp; + +use crate::settings; + +use gtk::glib; +use gtk::prelude::*; + +pub fn display_settings(app: &GPSApp) { + let dialog = gtk::Dialog::with_buttons( + Some("GPS settings"), + Some(&app.window), + gtk::DialogFlags::MODAL, + &[("Close", gtk::ResponseType::Close)], + ); + + dialog.set_default_size(640, 480); + dialog.set_modal(true); + + let grid = gtk::Grid::new(); + grid.set_column_spacing(4); + grid.set_row_spacing(4); + grid.set_margin_bottom(12); + + let label = gtk::Label::builder() + .label("Use gtk4paintablesink element for video rendering:") + .hexpand(true) + .halign(gtk::Align::Start) + .margin_start(4) + .build(); + let widget = gtk::CheckButton::new(); + let settings = settings::Settings::load_settings(); + widget.set_active( + settings + .preferences + .get("use_gtk4_sink") + .unwrap_or(&"true".to_string()) + .parse::() + .expect("Should a boolean value"), + ); + widget.connect_toggled(glib::clone!(@weak widget => move |c| { + let mut settings = settings::Settings::load_settings(); + settings.preferences.insert("use_gtk4_sink".to_string(), c.is_active().to_string()); + settings::Settings::save_settings(&settings); + })); + + grid.attach(&label, 0, 0, 1, 1); + grid.attach(&widget, 1, 0, 1, 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); + + dialog.connect_response(move |dialog, _| { + dialog.destroy(); + }); + dialog.show(); +}