use std::{cell::Cell, rc::Rc}; use crate::{ model::{builder_traits::Product, models::SignalReduce, Frequency}, model_utils::signal_reducer::{find_by_frequency_value, set_default_values}, view::{ components::{info_bar::InfoBar, input::Input}, properties::*, }, view_utils::signal_reduce_utils::*, }; use glib::clone; use gio::ListStore; use gtk::{ prelude::{BoxExt, ButtonExt, Cast, GridExt, SorterExt}, Align, *, }; pub fn signal_reducing_page(wrapper: &Box) { let values = Rc::new(Cell::new(SignalReduce::default())); let info_bar = InfoBar::get_instance(); let input_block: Grid = Grid::new(); input_block.set_column_homogeneous(true); input_block.set_row_homogeneous(true); let input_label_alignment = Alignment { horizontal: Align::Start, vertical: Align::Fill, }; let input_labels: [&str; 6] = [ "l, м:", "Rм, Ом", "Cм, пФ:", "Rи, Ом:", "Vи, мВ", "f, мГц:", ]; let all_inputs: Vec> = input_labels .iter() .enumerate() .map(|(index, label)| { let elem = Input::::builder() .label(label) .markup(true) .margins(MarginData::EqualsMargin(6)) .align(input_label_alignment) .build_entry(None); let row = index as i32 / 3; input_block.attach(elem.get(), (index as i32) - (3 * row), row, 1, 1); elem }) .collect(); let calculate_button = Button::builder().label("Расчитать").build(); let result_table_headers_labels: [&str; 4] = ["f, МГц", "Xc, Ом", "Vп, мВ", "ζ"]; let model = ListStore::new::(); set_default_values(&model); let numeric_sorter = CustomSorter::new(|a, b| { let a = a.downcast_ref::().unwrap().frequency(); let b = b.downcast_ref::().unwrap().frequency(); a.total_cmp(&b).into() }); let sorted_model = SortListModel::new(Some(model.clone()), Some(numeric_sorter.clone())); let selection_model = NoSelection::new(Some(sorted_model.clone())); let result_table = ColumnView::builder() .show_row_separators(true) .model(&selection_model) .build(); result_table.connect_activate(clone!( #[strong] numeric_sorter, move |_, _| numeric_sorter.changed(SorterChange::Different) )); for label in result_table_headers_labels { let factory = SignalListItemFactory::new(); factory.connect_setup(column_view_setup_factory); factory.connect_bind(clone!( #[strong] values, move |_, list| { match label { "f, МГц" => frequency_column_fabric(list), "Xc, Ом" => reactive_resist_fabric(list, values.get()), "Vп, мВ" => signal_source_voltage_fabric(list, values.get()), "ζ" => coef_fabric(list, values.get()), _ => {} } } )); let column = ColumnViewColumn::builder() .title(label) .expand(true) .resizable(false) .factory(&factory) .build(); result_table.append_column(&column); } let scrollable_table = ScrolledWindow::builder() .vexpand(true) .child(&result_table) .build(); let table = Frame::builder() .child(&scrollable_table) .vexpand(true) .build(); calculate_button.connect_clicked(clone!( #[strong] model, #[strong] result_table, move |_| match parse_fields(all_inputs.clone()) { Ok(results) => { if values.get() == results { info_bar.set_text_label(Some("Эти данные уже были введены.")); info_bar.show_infobar(5u64); } else { values.set(results); let new_elem = Frequency::new(values.get().frequency); if find_by_frequency_value(&model, &new_elem).is_none() { model.append(&new_elem); } update_column_view(&result_table); } } Err(error) => { let error_kind: Option<&str> = get_error_message(error); info_bar.set_text_label(error_kind); info_bar.show_infobar(5u64); } } )); wrapper.append(&input_block); wrapper.append(&calculate_button); wrapper.append(&table); }