From 5687d6773ac0793440ab047b167ac2959ab3e207 Mon Sep 17 00:00:00 2001 From: doryan04 Date: Sun, 17 Mar 2024 21:34:12 +0400 Subject: [PATCH] added inputs components and created page for fifth lab --- .../builder_traits.rs} | 0 src/model/mod.rs | 3 +- src/view/components/input.rs | 92 ++++++++++ src/view/components/mod.rs | 4 +- src/view/components/pages.rs | 14 +- src/view/components/tabs.rs | 17 +- src/view/mod.rs | 3 +- src/view/pages/hamming_code.rs | 152 ++++++++++++++++ src/view/pages/mod.rs | 2 + src/view/pages/signal_reducing.rs | 78 +++++++++ src/view/view.rs | 162 ++---------------- 11 files changed, 359 insertions(+), 168 deletions(-) rename src/{view/components/builder_pattern_traits.rs => model/builder_traits.rs} (100%) create mode 100644 src/view/components/input.rs create mode 100644 src/view/pages/hamming_code.rs create mode 100644 src/view/pages/mod.rs create mode 100644 src/view/pages/signal_reducing.rs diff --git a/src/view/components/builder_pattern_traits.rs b/src/model/builder_traits.rs similarity index 100% rename from src/view/components/builder_pattern_traits.rs rename to src/model/builder_traits.rs diff --git a/src/model/mod.rs b/src/model/mod.rs index 99bbd12..8ad3783 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -1 +1,2 @@ -pub mod model; \ No newline at end of file +pub mod model; +pub mod builder_traits; \ No newline at end of file diff --git a/src/view/components/input.rs b/src/view/components/input.rs new file mode 100644 index 0000000..3117803 --- /dev/null +++ b/src/view/components/input.rs @@ -0,0 +1,92 @@ +use gtk4 as gtk; + +use crate::{ + view::properties::*, + model::builder_traits::* +}; +use gtk::{*, prelude::*}; + +pub type InputLabel = String; + +pub struct Input { + component: Box +} + +pub struct InputBuilder { + align: Align, + label: InputLabel, + margins: MarginData, +} + +impl Product for Input { + fn builder() -> InputBuilder { + InputBuilder { + align: Align::Start, + label: String::new(), + margins: MarginData::EqualsMargin(5), + } + } + + fn get(self) -> Box { + self.component + } +} + +impl InputBuilder { + + pub fn set_label(mut self, label: &str) -> Self { + + self.label = String::from(label); + + self + + } + + pub fn set_align(mut self, align: Align) -> Self { + + self.align = align; + + self + + } + + pub fn set_margins(mut self, margin: MarginData) -> Self { + + self.margins = margin; + + self + + } + + pub fn build(self, monospace: bool, wrap_mode: WrapMode, input_height: i32) -> Input { + + let input_component = Box::new(Orientation::Vertical, 0); + + let input_label = Label::builder() + .halign(self.align) + .set_margin(self.margins) + .label(self.label) + .build(); + + let text_view_input = TextView::builder() + .monospace(monospace) + .height_request(input_height) + .set_text_view_margin(MarginData::EqualsMargin(6)) + .wrap_mode(wrap_mode) + .build(); + + let text_view_input_frame = Frame::builder() + .child(&text_view_input) + .set_margin(MarginData::MultipleMargin((0, 5, 0, 5))) + .build(); + + input_component.append(&input_label); + input_component.append(&text_view_input_frame); + + Input { + component: input_component + } + + } + +} \ No newline at end of file diff --git a/src/view/components/mod.rs b/src/view/components/mod.rs index 49d6e39..e113937 100644 --- a/src/view/components/mod.rs +++ b/src/view/components/mod.rs @@ -1,5 +1,7 @@ pub mod tabs; +pub mod input; pub mod pages; pub mod switch; pub mod wrapper; -pub mod builder_pattern_traits; + +use crate::model::builder_traits; diff --git a/src/view/components/pages.rs b/src/view/components/pages.rs index 9a85e42..e956dec 100644 --- a/src/view/components/pages.rs +++ b/src/view/components/pages.rs @@ -12,7 +12,7 @@ use gtk::{ prelude::{BoxExt, IsA}, }; -use crate::view::components::builder_pattern_traits::{Builder, Product}; +use crate::view::components::builder_traits::{Builder, Product}; pub type Page<'a> = (&'a str, &'a str, &'a Box); @@ -25,6 +25,7 @@ pub struct PagesBuilder{ } impl Product for Pages { + fn builder() -> PagesBuilder { PagesBuilder { pages_content: Stack::new(), @@ -34,9 +35,11 @@ impl Product for Pages { fn get(self) -> Box { self.wrapper } + } impl Builder, i32> for PagesBuilder{ + fn build(&self, build_param: i32) -> Pages { let stack_sidebar = StackSidebar::new(); let stack_switcher = StackSwitcher::new(); @@ -56,17 +59,18 @@ impl Builder, i32> for PagesBuilder{ fn append_item(self, item: Page) -> Self { self.append_page_private(item); + self } fn append_items(self, items: Vec) -> Self { - items.iter() - .for_each(|&item| { - self.append_page_private(item); - }); + for item in items { + self.append_page_private(item); + } self } + } impl PagesBuilder { diff --git a/src/view/components/tabs.rs b/src/view/components/tabs.rs index b206c46..8be52f2 100644 --- a/src/view/components/tabs.rs +++ b/src/view/components/tabs.rs @@ -1,12 +1,11 @@ use gtk4 as gtk; -use std::boxed::Box as BoxPtr; use gtk::{Notebook, Label, Box}; -use super::builder_pattern_traits::*; +use super::builder_traits::*; pub type TabLabel = Label; pub type TabContent = Box; -pub type TabPage = (BoxPtr, TabContent); +pub type TabPage<'a> = (&'a str, TabContent); #[derive(Clone)] pub struct TabsBuilder { @@ -31,7 +30,7 @@ impl Product for Tabs { } -impl Builder for TabsBuilder{ +impl Builder, &str> for TabsBuilder{ fn build(&self, build_param: &str) -> Tabs { let tabs_wrapper = Notebook::builder() @@ -50,14 +49,14 @@ impl Builder for TabsBuilder{ } fn append_item(mut self, item: TabPage) -> Self { - self.append_tab_private(&item.0, item.1); + self.append_tab_private(item); self } fn append_items(mut self, items: Vec) -> Self { for item in items{ - self.append_tab_private(&item.0, item.1); + self.append_tab_private(item); } self @@ -68,9 +67,9 @@ impl Builder for TabsBuilder{ impl TabsBuilder { - fn append_tab_private(&mut self, label: &str, page: TabContent) { - let tab_label = Label::new(Some(label)); - self.tabs.push((tab_label, page)); + fn append_tab_private(&mut self, item: TabPage) { + let tab_label = Label::new(Some(item.0)); + self.tabs.push((tab_label, item.1)); } } \ No newline at end of file diff --git a/src/view/mod.rs b/src/view/mod.rs index 5b8a5f4..d832617 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -1,3 +1,4 @@ pub mod view; +pub mod pages; pub mod components; -pub mod properties; \ No newline at end of file +pub mod properties; diff --git a/src/view/pages/hamming_code.rs b/src/view/pages/hamming_code.rs new file mode 100644 index 0000000..c0cbe6e --- /dev/null +++ b/src/view/pages/hamming_code.rs @@ -0,0 +1,152 @@ +use gtk4 as gtk; + +use crate::{ + model::model::*, + view::{ + properties::*, + components::{ + *, + switch::*, + wrapper::*, + } + }, + controller::{ + controller::*, + view_utils::input_utils::*, + event_handlers::{ + button_event_handlers::*, + switch_event_handlers::*, + }, + } +}; + +use gtk::{*, prelude::*}; + +pub fn hamming_code_page(wrapper: &Box) -> (){ + + // input + + let hamming_text_view_input_label = Label::builder() + .halign(Align::Start) + .set_margin(MarginData::MultipleMargin((10, 5, 0, 0))) + .label(String::from("Поле ввода для кода:")) + .build(); + + let hamming_text_view_input = TextView::builder() + .monospace(true) + .set_text_view_margin(MarginData::EqualsMargin(6)) + .wrap_mode(WrapMode::Word) + .build(); + + let hamming_text_view_input_frame = Frame::builder() + .child(&hamming_text_view_input) + .height_request(64) + .set_margin(MarginData::MultipleMargin((0, 5, 0, 5))) + .build(); + + // output + + let hamming_text_view_output_label = Label::builder() + .halign(Align::Start) + .set_margin(MarginData::MultipleMargin((10, 5, 0, 0))) + .label(String::from("Результат:")) + .build(); + + let hamming_text_view_output = TextView::builder() + .monospace(true) + .editable(false) + .set_text_view_margin(MarginData::EqualsMargin(6)) + .wrap_mode(WrapMode::Word) + .build(); + + let hamming_text_view_output_frame = Frame::builder() + .child(&hamming_text_view_output) + .height_request(64) + .set_margin(MarginData::MultipleMargin((0, 5, 0, 5))) + .build(); + + // interactive panel + + let clear_input_button = + Button::builder() + .set_align(Alignment::new(Align::Fill, Align::Fill)) + .label("Очистка полей") + .build(); + + let hamming_crypt_button = Button::builder() + .set_align(Alignment::new(Align::Fill, Align::Fill)) + .label("Выполнить") + .build(); + + let crypt_mode_switch = Switch::new(); + + let crypt_mode_label = Label::builder() + .label("Режим: кодирование") + .build(); + + // references for binding actions + + let clear_input_button_to_handle = clear_input_button.clone(); + + let crypt_mode_label_to_handle = crypt_mode_label.clone(); + let crypt_mode_switch_to_handle = crypt_mode_switch.clone(); + + let text_view_input_for_parse = hamming_text_view_input.clone(); + let text_view_output_for_output = hamming_text_view_output.clone(); + + let text_view_input_for_clearing = hamming_text_view_input.clone(); + let text_view_output_for_clearing = hamming_text_view_input.clone(); + + // actions + + EventHandler::new( + clear_input_button_to_handle, + move |_| { + clearing(&text_view_input_for_clearing, &text_view_output_for_clearing); + } + ).on_click(); + + EventHandler::new( + hamming_crypt_button.clone(), + move |button: &Button| { + parse_input( + &text_view_input_for_parse, + &text_view_output_for_output, + crypt_mode_switch_to_handle.state() + ) + }).on_click(); + + EventHandler::new( + crypt_mode_switch.clone(), + move |s : &Switch| { + state_controller(s, &crypt_mode_label_to_handle); + }).on_toggle(); + + // wrappers + + let crypt_mode_wrapper = Wrapper::col_builder() + .set_align(Alignment::new(Align::Fill, Align::Center)) + .hexpand(true) + .spacing(10) + .build(); + + let interactive_components_wrapper = Wrapper::col_builder() + .set_align(Alignment::new(Align::Fill, Align::Fill)) + .set_margin(MarginData::MultipleMargin((0, 5, 0, 5))) + .spacing(10) + .build(); + + crypt_mode_wrapper.append(&crypt_mode_switch); + crypt_mode_wrapper.append(&crypt_mode_label); + + interactive_components_wrapper.append(&clear_input_button); + interactive_components_wrapper.append(&crypt_mode_wrapper); + interactive_components_wrapper.append(&hamming_crypt_button); + + wrapper.append(&hamming_text_view_input_label); + wrapper.append(&hamming_text_view_input_frame); + wrapper.append(&interactive_components_wrapper); + wrapper.append(&hamming_text_view_output_label); + wrapper.append(&hamming_text_view_output_frame); + +} \ No newline at end of file diff --git a/src/view/pages/mod.rs b/src/view/pages/mod.rs new file mode 100644 index 0000000..975bbcd --- /dev/null +++ b/src/view/pages/mod.rs @@ -0,0 +1,2 @@ +pub mod hamming_code; +pub mod signal_reducing; \ No newline at end of file diff --git a/src/view/pages/signal_reducing.rs b/src/view/pages/signal_reducing.rs new file mode 100644 index 0000000..8c51a61 --- /dev/null +++ b/src/view/pages/signal_reducing.rs @@ -0,0 +1,78 @@ +use gtk4 as gtk; + +use gtk::{*, prelude::*}; +use crate::model::builder_traits::Product; +use crate::view::{ + properties::*, + components::{ + wrapper::*, + input::Input, + }, +}; + +pub fn signal_reducing_page(wrapper: &Box) { + + let inputs_first_line = Box::new(Orientation::Horizontal, 5); + + inputs_first_line.set_valign(Align::Fill); + + let input_height : i32 = 20; + + let wire_length_input = Input::builder() + .set_label("Длина провода (L = [м]):") + .set_align(Align::Fill) + .set_margins(MarginData::EqualsMargin(5)) + .build(true, WrapMode::Word, input_height) + .get(); + + let resistance_input = Input::builder() + .set_label("Сопротивление (Rм = [Ом * м]):") + .set_align(Align::Fill) + .set_margins(MarginData::EqualsMargin(5)) + .build(true, WrapMode::Word, input_height) + .get(); + + let capacity_input = Input::builder() + .set_label("Ёмкость (Cм = [пФ * м]):") + .set_align(Align::Fill) + .set_margins(MarginData::EqualsMargin(5)) + .build(true, WrapMode::Word, input_height) + .get(); + + let inputs_second_line = Box::new(Orientation::Horizontal, 5); + + inputs_second_line.set_valign(Align::Fill); + + let voltage_input = Input::builder() + .set_label("Напряжение (Vи = [мВ]):") + .set_align(Align::Fill) + .set_margins(MarginData::EqualsMargin(5)) + .build(true, WrapMode::Word, input_height) + .get(); + + let source_implicit_resistance_input = Input::builder() + .set_label("Сопротивление источника (R = [Ом]):") + .set_align(Align::Fill) + .set_margins(MarginData::EqualsMargin(5)) + .build(true, WrapMode::Word, input_height) + .get(); + + let freq_input = Input::builder() + .set_label("Частота (f = [МГц]):") + .set_align(Align::Fill) + .set_margins(MarginData::EqualsMargin(5)) + .build(true, WrapMode::Word, input_height) + .get(); + + + inputs_first_line.append(&wire_length_input); + inputs_first_line.append(&resistance_input); + inputs_first_line.append(&capacity_input); + inputs_second_line.append(&voltage_input); + inputs_second_line.append(&source_implicit_resistance_input); + inputs_second_line.append(&freq_input); + + wrapper.append(&inputs_first_line); + wrapper.append(&inputs_second_line); + +} \ No newline at end of file diff --git a/src/view/view.rs b/src/view/view.rs index 46b303b..fbd439c 100644 --- a/src/view/view.rs +++ b/src/view/view.rs @@ -1,190 +1,50 @@ -use crate::view::components::builder_pattern_traits::{Builder, Product}; +use crate::model::builder_traits::*; use gtk4 as gtk; -use gtk::{*, prelude::*}; -use gtk4::StackTransitionType::SlideLeftRight; +use gtk::{*, prelude::*, StackTransitionType::SlideLeftRight}; use crate::{ - model::model::*, view::{ properties::*, components::{ *, - tabs::*, - switch::*, wrapper::*, - } - }, - controller::{ - controller::*, - view_utils::input_utils::*, - event_handlers::{ - button_event_handlers::*, - switch_event_handlers::*, }, - } + pages::* + }, }; use crate::view::components::pages::Pages; -pub fn laboratory_work_first_section(wrapper: &Box) -> (){ - - // input - - let hamming_text_view_input_label = Label::builder() - .halign(Align::Start) - .set_margin(MarginData::MultipleMargin((10, 5, 0, 0))) - .label(String::from("Поле ввода для кода:")) - .build(); - - let hamming_text_view_input = TextView::builder() - .monospace(true) - .set_text_view_margin(MarginData::EqualsMargin(6)) - .wrap_mode(WrapMode::Word) - .build(); - - let hamming_text_view_input_frame = Frame::builder() - .child(&hamming_text_view_input) - .height_request(64) - .set_margin(MarginData::MultipleMargin((0, 5, 0, 5))) - .build(); - - // output - - let hamming_text_view_output_label = Label::builder() - .halign(Align::Start) - .set_margin(MarginData::MultipleMargin((10, 5, 0, 0))) - .label(String::from("Результат:")) - .build(); - - let hamming_text_view_output = TextView::builder() - .monospace(true) - .editable(false) - .set_text_view_margin(MarginData::EqualsMargin(6)) - .wrap_mode(WrapMode::Word) - .build(); - - let hamming_text_view_output_frame = Frame::builder() - .child(&hamming_text_view_output) - .height_request(64) - .set_margin(MarginData::MultipleMargin((0, 5, 0, 5))) - .build(); - - // interactive panel - - let clear_input_button = - Button::builder() - .set_align(Alignment::new(Align::Fill, Align::Fill)) - .label("Очистка полей") - .build(); - - let hamming_crypt_button = Button::builder() - .set_align(Alignment::new(Align::Fill, Align::Fill)) - .label("Выполнить") - .build(); - - let crypt_mode_switch = Switch::new(); - - let crypt_mode_label = Label::builder() - .label("Режим: кодирование") - .build(); - - // references for binding actions - - let clear_input_button_to_handle = clear_input_button.clone(); - - let crypt_mode_label_to_handle = crypt_mode_label.clone(); - let crypt_mode_switch_to_handle = crypt_mode_switch.clone(); - - let text_view_input_for_parse = hamming_text_view_input.clone(); - let text_view_output_for_output = hamming_text_view_output.clone(); - - let text_view_input_for_clearing = hamming_text_view_input.clone(); - let text_view_output_for_clearing = hamming_text_view_input.clone(); - - // actions - - EventHandler::new( - clear_input_button_to_handle, - move |_| { - clearing(&text_view_input_for_clearing, &text_view_output_for_clearing); - } - ).on_click(); - - EventHandler::new( - hamming_crypt_button.clone(), - move |button: &Button| { - parse_input( - &text_view_input_for_parse, - &text_view_output_for_output, - crypt_mode_switch_to_handle.state() - ) - }).on_click(); - - EventHandler::new( - crypt_mode_switch.clone(), - move |s : &Switch| { - state_controller(s, &crypt_mode_label_to_handle); - }).on_toggle(); - - // wrappers - - let crypt_mode_wrapper = Wrapper::col_builder() - .set_align(Alignment::new(Align::Fill, Align::Center)) - .hexpand(true) - .spacing(10) - .build(); - - let interactive_components_wrapper = Wrapper::col_builder() - .set_align(Alignment::new(Align::Fill, Align::Fill)) - .set_margin(MarginData::MultipleMargin((0, 5, 0, 5))) - .spacing(10) - .build(); - - crypt_mode_wrapper.append(&crypt_mode_switch); - crypt_mode_wrapper.append(&crypt_mode_label); - - interactive_components_wrapper.append(&clear_input_button); - interactive_components_wrapper.append(&crypt_mode_wrapper); - interactive_components_wrapper.append(&hamming_crypt_button); - - wrapper.append(&hamming_text_view_input_label); - wrapper.append(&hamming_text_view_input_frame); - wrapper.append(&interactive_components_wrapper); - wrapper.append(&hamming_text_view_output_label); - wrapper.append(&hamming_text_view_output_frame); - -} - pub fn ui(application: &adw::Application) { - let mutual_wrapper = Wrapper::row_builder() + let hamming_code = Wrapper::row_builder() .set_align(Alignment::new(Align::Fill, Align::Fill)) .set_margin(MarginData::EqualsMargin(15)) .spacing(10) .build(); - laboratory_work_first_section(&mutual_wrapper); + hamming_code::hamming_code_page(&hamming_code); - let second_wrapper = Wrapper::row_builder() + let signal_reducing = Wrapper::row_builder() .set_align(Alignment::new(Align::Fill, Align::Fill)) .set_margin(MarginData::EqualsMargin(15)) .spacing(10) .build(); - second_wrapper.append(&Label::new(Some("Код Хафмана"))); + signal_reducing::signal_reducing_page(&signal_reducing); let pages = Pages::builder() .set_transition(SlideLeftRight, 200) .append_items(vec![ - ("Код Хэмминга", "Код Хэмминга", &mutual_wrapper), - ("Код Хафмана", "Код Хафмана", &second_wrapper) + ("Код Хэмминга", "Код Хэмминга", &hamming_code), + ("Затухание сигнала", "Затухание сигнала", &signal_reducing) ]) .build(5) .get(); let window = ApplicationWindow::builder() .title("Комплексная программа для лаб. работ") - .width_request(650) + .width_request(700) .height_request(400) .application(application) .child(&pages)