diff --git a/gi/src/font_manager/mod.rs b/gi/src/font_manager/mod.rs index 107dceb..56b22b7 100644 --- a/gi/src/font_manager/mod.rs +++ b/gi/src/font_manager/mod.rs @@ -22,7 +22,7 @@ impl FontManager { let library = Library::init().map_err(|e| Error::InitError(e.into()))?; - let root_path = font_dir().unwrap(); + let root_path = font_dir().unwrap_or(PathBuf::from("fonts")); Ok(Self { library, diff --git a/gi/src/pg/modules/ppi.rs b/gi/src/pg/modules/ppi.rs index 231d0f6..4f6dd3c 100644 --- a/gi/src/pg/modules/ppi.rs +++ b/gi/src/pg/modules/ppi.rs @@ -604,9 +604,69 @@ impl SimpleComponent for PPIModuleConfigComponent { } } - }, + adw::SpinRow { + set_title: "Line Width", + set_digits: 1, + set_numeric: true, + set_snap_to_ticks: true, + #[wrap(Some)] + set_adjustment=>k::Adjustment::new( + init_config.line_width as f64, + 0.1, + 10.0, + 0.1, + 0.1, + 0.1 + ), + connect_value_notify[sender, config_ref] => move |this| { + let width = this.value() as f32; + config_ref.borrow_mut().set_line_width(width); + sender.output(OutputMsg::Refresh); + }, + }, + adw::SpinRow { + set_title: "Line Num", + set_digits: 0, + set_numeric: true, + set_snap_to_ticks: true, + #[wrap(Some)] + set_adjustment=>k::Adjustment::new( + init_config.range_line_num as f64, + 1.0, + 8.0, + 1.0, + 1.0, + 1.0 + ), + connect_value_notify[sender, config_ref] => move |this| { + let num = this.value() as usize; + config_ref.borrow_mut().set_range_line_num(num); + sender.output(OutputMsg::Refresh); + }, + }, + adw::SpinRow { + set_title: "Ath Line Num", + set_digits: 0, + set_numeric: true, + set_snap_to_ticks: true, + #[wrap(Some)] + set_adjustment=>k::Adjustment::new( + init_config.ath_line_num as f64, + 1.0, + 9.0, + 2.0, + 2.0, + 1.0 + ), + connect_value_notify[sender, config_ref] => move |this| { + let num = this.value() as usize; + config_ref.borrow_mut().set_ath_line_num(num); + sender.output(OutputMsg::Refresh); + }, + } + } } diff --git a/radar-g/src/components/monitor/dialog_widget.rs b/radar-g/src/components/monitor/dialog_widget.rs index 6c34e24..bf21f54 100644 --- a/radar-g/src/components/monitor/dialog_widget.rs +++ b/radar-g/src/components/monitor/dialog_widget.rs @@ -7,8 +7,16 @@ use std::collections::HashMap; use relm4::{ adw::{self, prelude::*}, factory::FactoryVecDeque, - gtk::{self, prelude::*}, + gtk::{ + self, + glib::{clone, *}, + prelude::*, + }, prelude::*, + typed_view::{ + column::{LabelColumn, RelmColumn, TypedColumnView}, + list::{RelmListItem, TypedListView}, + }, view, ComponentParts, ComponentSender, SimpleComponent, }; @@ -25,7 +33,9 @@ pub enum DialogOutput { Cancel, Open(usize), } -pub struct Dialog {} +pub struct Dialog { + list_view_wrapper: TypedColumnView, +} #[relm4::component(pub)] impl SimpleComponent for Dialog { @@ -41,28 +51,41 @@ impl SimpleComponent for Dialog { #[wrap(Some)] set_child=&adw::ToolbarView{ - set_hexpand:true, - set_vexpand:true, - add_top_bar=&adw::HeaderBar{ set_hexpand:true, - #[wrap(Some)] - set_title_widget=>k::Label{ - set_label: "Header", + set_vexpand:true, + add_top_bar=&adw::HeaderBar{ + set_hexpand:true, + #[wrap(Some)] + set_title_widget=>k::Label{ + set_label: "Header", + }, }, - }, - #[wrap(Some)] - set_content=&adw::Clamp{ - set_hexpand:true, #[wrap(Some)] - #[name(content)] - set_child=>k::Box{ - set_orientation: gtk::Orientation::Vertical, - set_hexpand:true, - set_spacing: 10, + set_content=>k::Box{ + set_orientation: gtk::Orientation::Vertical, + set_hexpand:true, + set_spacing: 10, - - }, - } + #[local_ref] + list -> gtk::ColumnView {} + }, + add_bottom_bar=>k::Box{ + set_orientation: gtk::Orientation::Horizontal, + set_hexpand:true, + set_spacing: 10, + set_margin_vertical:10, + set_margin_horizontal:15, + set_halign: gtk::Align::End, + gtk::Button{ + set_label:"Cancel", + connect_clicked[sender] => move |_| { + sender.output(DialogOutput::Cancel); + }, + }, + gtk::Button{ + set_label:"Open", + }, + }, } } @@ -74,58 +97,36 @@ impl SimpleComponent for Dialog { root: Self::Root, sender: relm4::ComponentSender, ) -> relm4::ComponentParts { + let mut list_view = TypedColumnView::new(); + list_view.append_column::(); + list_view.append_column::(); + list_view.append_column::(); + list_view.append_column::(); + + for ((id, name), modules) in init { + let data_row = DataRow { + id, + name, + type_name: "Type".to_string(), + supported_modules: modules.iter().map(|m| m.module_name.to_string()).collect(), + }; + list_view.append(data_row); + } + + let model = Self { + list_view_wrapper: list_view, + }; + + let list = &model.list_view_wrapper.view; + + let selection = list.model().unwrap(); + + selection.connect_selection_changed(|a, b, c| { + println!("Selection changed"); + println!(" b: {}, c: {}", b, c); + }); let widgets = view_output!(); - if init.len() > 1 { - view! { - label=gtk::Label { - set_label: "The file you opened contains multiple data blocks; please select one to proceed to the next step.", - add_css_class: "h3", - } - } - - widgets.content.append(&label); - } - - for ((k, name), v) in init.iter() { - view! { - tile=gtk::Expander{ - set_label: Some(&format!("Data {}: {}", k, name)), - set_expanded: true, - set_hexpand: true, - #[name(content)] - #[wrap(Some)] - set_child=>k::FlowBox{ - set_homogeneous: true, - set_column_spacing: 10, - set_row_spacing: 10, - } - }, - - } - let data_id = *k; - - for values in v.iter() { - view! { - item=gtk::Button { - set_icon_name: &values.module_icon, - connect_clicked[sender] => move |_| { - sender.output(DialogOutput::Open(data_id)); - - } - } - } - content.append(&item); - } - - widgets.content.append(&tile); - } - - let model = Self {}; - - // let widgets = model.sequence.widget().clone(); - // let contour = model.counter.widget().clone(); - ComponentParts { model: model, widgets, @@ -134,3 +135,98 @@ impl SimpleComponent for Dialog { fn update(&mut self, message: Self::Input, sender: ComponentSender) {} } + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct DataRow { + id: usize, + name: String, + type_name: String, + supported_modules: Vec, +} + +struct Widgets { + id_label: gtk::Label, + name_label: gtk::Label, + type_label: gtk::Label, + modules_selector: gtk::DropDown, +} + +pub struct ID; + +impl LabelColumn for ID { + type Item = DataRow; + type Value = usize; + const COLUMN_NAME: &'static str = "ID"; + const ENABLE_SORT: bool = true; + + fn get_cell_value(item: &Self::Item) -> Self::Value { + item.id + } + + fn format_cell_value(value: &Self::Value) -> String { + value.to_string() + } +} + +pub struct Name; + +impl LabelColumn for Name { + type Item = DataRow; + type Value = String; + const COLUMN_NAME: &'static str = "Name"; + const ENABLE_SORT: bool = true; + + fn get_cell_value(item: &Self::Item) -> Self::Value { + item.name.clone() + } + + fn format_cell_value(value: &Self::Value) -> String { + value.clone() + } +} + +pub struct Type; + +impl LabelColumn for Type { + type Item = DataRow; + type Value = String; + const COLUMN_NAME: &'static str = "Type"; + const ENABLE_SORT: bool = true; + + fn get_cell_value(item: &Self::Item) -> Self::Value { + item.type_name.clone() + } + + fn format_cell_value(value: &Self::Value) -> String { + value.clone() + } +} + +pub struct SupportedModules; + +impl RelmColumn for SupportedModules { + type Root = gtk::DropDown; + type Widgets = (); + type Item = DataRow; + const COLUMN_NAME: &'static str = "Supported Modules"; + const ENABLE_EXPAND: bool = true; + + fn setup(_item: >k::ListItem) -> (gtk::DropDown, ()) { + relm4::view! { + main = gtk::DropDown{} + } + + (main, ()) + } + + fn bind(_item: &mut Self::Item, _widgets: &mut Self::Widgets, _root: &mut Self::Root) { + let model = gtk::gio::ListStore::new::(); + + for module in _item.supported_modules.iter() { + let label = gtk::StringObject::new(&module); + model.append(&label); + } + + _root.set_model(Some(&model)); + } +} diff --git a/radar-g/src/components/monitor/monitor.rs b/radar-g/src/components/monitor/monitor.rs index ddd824d..d2b6bce 100644 --- a/radar-g/src/components/monitor/monitor.rs +++ b/radar-g/src/components/monitor/monitor.rs @@ -113,20 +113,29 @@ impl Component for MonitorModel { result.insert((data.id, data.description.clone()), module_packages); } - let dialog = Dialog::builder().launch(result).forward( - sender.input_sender(), - move |msg| match msg { - DialogOutput::Open(index) => { - let data = data.iter().find(|d| *d.0 == index).unwrap(); - MonitorInputMsg::Draw(data.1.clone()) - } - _ => MonitorInputMsg::None, - }, - ); + if result.len() == 1 && result.values().next().unwrap().len() == 1 { + sender.input(MonitorInputMsg::Draw(data.values().next().unwrap().clone())); + } else { + let new_sender = sender.clone(); + let dialog = Dialog::builder().launch(result).forward( + sender.input_sender(), + move |msg| match msg { + DialogOutput::Open(index) => { + let data = data.iter().find(|d| *d.0 == index).unwrap(); + MonitorInputMsg::Draw(data.1.clone()) + } + DialogOutput::Cancel => { + new_sender.output(MonitorOutputMsg::DialogClose); + MonitorInputMsg::None + } + _ => MonitorInputMsg::None, + }, + ); - let widget = dialog.widget().to_owned().upcast(); + let widget = dialog.widget().to_owned().upcast(); - sender.output(MonitorOutputMsg::Dialog(widget)); + sender.output(MonitorOutputMsg::Dialog(widget)); + } }); } MonitorInputMsg::QueueDraw => { diff --git a/radar-g/src/widgets/render/mod.rs b/radar-g/src/widgets/render/mod.rs index 8f3dbd5..98fa37b 100644 --- a/radar-g/src/widgets/render/mod.rs +++ b/radar-g/src/widgets/render/mod.rs @@ -123,11 +123,25 @@ impl Render { } )); + let key_detector = gtk::EventControllerKey::new(); + + key_detector.connect_key_pressed(clone!( + #[strong] + this, + move |_, key, code, modifier| { + println!("key pressed: {:?}", key); + this.imp().set_io(|io| {}); + + gtk::glib::Propagation::Proceed + } + )); + this.set_hexpand(true); this.set_vexpand(true); this.add_controller(pointer_location_detecture); this.add_controller(scale_detecture); this.add_controller(drag_detecture); + this.add_controller(key_detector); this }