From 6351f1f43fa63c0096274befd2a731258f769008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Cerveau?= Date: Thu, 18 Nov 2021 17:57:06 +0100 Subject: [PATCH] GPS: Add a dialog to select the elements This dialog allows to select and see element and its details. --- src/gps.ui | 51 ----------------- src/main.rs | 2 + src/mainwindow.rs | 10 ++-- src/pluginlistwindow.rs | 121 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 57 deletions(-) create mode 100644 src/pluginlistwindow.rs diff --git a/src/gps.ui b/src/gps.ui index b065e4c..8c8647f 100644 --- a/src/gps.ui +++ b/src/gps.ui @@ -36,57 +36,6 @@ - - False - 320 - 260 - dialog - - - False - vertical - 2 - - - False - end - - - - - - - - - False - False - 0 - - - - - True - True - in - - - True - True - - - - - - - - False - True - 1 - - - - - False dialog diff --git a/src/main.rs b/src/main.rs index 46e98ba..fd8d49a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,8 @@ // SPDX-License-Identifier: GPL-3.0-only mod mainwindow; mod pipeline; +mod pluginlistwindow; + use gtk::prelude::*; fn main() { diff --git a/src/mainwindow.rs b/src/mainwindow.rs index 7dd3571..9107fe5 100644 --- a/src/mainwindow.rs +++ b/src/mainwindow.rs @@ -9,6 +9,7 @@ use std::cell::RefCell; use std::rc::Rc; use crate::pipeline::Pipeline; +use crate::pluginlistwindow; #[derive(Debug, Clone, Default)] struct Element { name: String, @@ -68,15 +69,12 @@ pub fn build_ui(application: >k::Application) { let add_button: Button = builder .object("button-add-plugin") .expect("Couldn't get app_button"); - let add_dialog: Dialog = builder - .object("dialog-add-plugin") - .expect("Couldn't get window"); + add_button.connect_clicked(glib::clone!(@weak window => move |_| { // entry.set_text("Clicked!"); let pipeline = Pipeline::new(); - Pipeline::get_elements_list().expect("cocuou"); - add_dialog.connect_response(|dialog, _| dialog.close()); - add_dialog.show_all(); + let elements = Pipeline::get_elements_list().expect("cocuou"); + pluginlistwindow::build_plugin_list(&window, &elements); })); // Create a dialog to open a file let open_button: Button = builder diff --git a/src/pluginlistwindow.rs b/src/pluginlistwindow.rs new file mode 100644 index 0000000..32eaaee --- /dev/null +++ b/src/pluginlistwindow.rs @@ -0,0 +1,121 @@ +use crate::pipeline::ElementInfo; +use gtk::{ + glib::{self, clone}, + prelude::*, + ResponseType, +}; + +use gtk::{ + ApplicationWindow, CellRendererText, Dialog, Label, ListStore, Orientation, TreeView, + TreeViewColumn, WindowPosition, +}; + +fn create_and_fill_model(elements: &Vec) -> ListStore { + // Creation of a model with two rows. + let model = ListStore::new(&[u32::static_type(), String::static_type()]); + + // Filling up the tree view. + for (i, entry) in elements.iter().enumerate() { + model.insert_with_values( + None, + &[(0, &(i as u32 + 1)), (1, &entry.name.as_ref().unwrap())], + ); + } + model +} + +fn append_column(tree: &TreeView, id: i32) { + let column = TreeViewColumn::new(); + let cell = CellRendererText::new(); + + column.pack_start(&cell, true); + // Association of the view's column with the model's `id` column. + column.add_attribute(&cell, "text", id); + tree.append_column(&column); +} + +fn create_and_setup_view() -> TreeView { + // Creating the tree view. + let tree = TreeView::new(); + + tree.set_headers_visible(false); + // Creating the two columns inside the view. + append_column(&tree, 0); + append_column(&tree, 1); + tree +} + +pub fn build_plugin_list(window: &ApplicationWindow, elements: &Vec) { + let dialog = gtk::Dialog::with_buttons( + Some("Edit Item"), + Some(window), + gtk::DialogFlags::MODAL, + &[("Close", ResponseType::Close)], + ); + dialog.set_title("Plugin list"); + dialog.set_position(WindowPosition::Center); + dialog.set_default_size(640, 480); + + // Creating a vertical layout to place both tree view and label in the window. + let vertical_layout = gtk::Box::new(Orientation::Vertical, 0); + + // Creation of the label. + let label = Label::new(Some("")); + + let tree = create_and_setup_view(); + + let model = create_and_fill_model(elements); + // Setting the model into the view. + tree.set_model(Some(&model)); + + // Adding the view to the layout. + vertical_layout.add(&tree); + // Same goes for the label. + vertical_layout.add(&label); + + // The closure responds to selection changes by connection to "::cursor-changed" signal, + // that gets emitted when the cursor moves (focus changes). + tree.connect_cursor_changed(clone!(@weak dialog => move |tree_view| { + let selection = tree_view.selection(); + if let Some((model, iter)) = selection.selected() { + // Now getting back the values from the row corresponding to the + // iterator `iter`. + // + // The `get_value` method do the conversion between the gtk type and Rust. + label.set_text(&format!( + "Hello '{}' from row {}", + model + .value(&iter, 1) + .get::() + .expect("Treeview selection, column 1"), + model + .value(&iter, 0) + .get::() + .expect("Treeview selection, column 0"), + )); + println!( + "{}", + model + .value(&iter, 1) + .get::() + .expect("Treeview selection, column 1") + ); + + let element_name = model + .value(&iter, 1) + .get::() + .expect("Treeview selection, column 1"); + //dialog.close(); + println!("{}", element_name); + } + })); + + // Adding the layout to the window. + let content_area = dialog.content_area(); + let scrolled_window = gtk::ScrolledWindow::new(gtk::NONE_ADJUSTMENT, gtk::NONE_ADJUSTMENT); + scrolled_window.add(&vertical_layout); + content_area.add(&scrolled_window); + + dialog.connect_response(|dialog, _| dialog.close()); + dialog.show_all(); +}