GPS: Add a dialog to select the elements

This dialog allows to select and see element
and its details.
This commit is contained in:
Stéphane Cerveau 2021-11-18 17:57:06 +01:00
parent 859f936796
commit 6351f1f43f
4 changed files with 127 additions and 57 deletions

View file

@ -36,57 +36,6 @@
</object>
</child>
</object>
<object class="GtkDialog" id="dialog-add-plugin">
<property name="can-focus">False</property>
<property name="default-width">320</property>
<property name="default-height">260</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkFileChooserDialog" id="dialog-open-file">
<property name="can-focus">False</property>
<property name="type-hint">dialog</property>

View file

@ -19,6 +19,8 @@
// SPDX-License-Identifier: GPL-3.0-only
mod mainwindow;
mod pipeline;
mod pluginlistwindow;
use gtk::prelude::*;
fn main() {

View file

@ -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: &gtk::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

121
src/pluginlistwindow.rs Normal file
View file

@ -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<ElementInfo>) -> 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<ElementInfo>) {
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::<String>()
.expect("Treeview selection, column 1"),
model
.value(&iter, 0)
.get::<u32>()
.expect("Treeview selection, column 0"),
));
println!(
"{}",
model
.value(&iter, 1)
.get::<String>()
.expect("Treeview selection, column 1")
);
let element_name = model
.value(&iter, 1)
.get::<String>()
.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();
}