From 4c230c090d0a1dd05333ab93c29e3e6d05ea3e8f Mon Sep 17 00:00:00 2001 From: doryan04 Date: Sun, 10 Mar 2024 12:54:32 +0400 Subject: [PATCH] removed unnecessary module definitions --- .../event_handlers/button_event_handlers.rs | 52 ++- .../event_handlers/switch_event_handlers.rs | 46 ++- .../model_utils/hamming_code_seven_four.rs | 246 ++++++------ src/controller/view_utils/input_utils.rs | 102 +++-- src/main.rs | 7 +- src/model/model.rs | 23 +- src/view/components/switch.rs | 293 ++++++++------- src/view/components/tabs.rs | 94 +++-- src/view/components/wrapper.rs | 27 +- src/view/properties.rs | 206 +++++------ src/view/view.rs | 349 +++++++++--------- 11 files changed, 702 insertions(+), 743 deletions(-) diff --git a/src/controller/event_handlers/button_event_handlers.rs b/src/controller/event_handlers/button_event_handlers.rs index 26572de..1981d12 100644 --- a/src/controller/event_handlers/button_event_handlers.rs +++ b/src/controller/event_handlers/button_event_handlers.rs @@ -1,34 +1,30 @@ -pub mod button_event_handlers_module{ +use crate::{ + model::model::*, + gtk::{ + *, + prelude::* + }, +}; - use crate::{ - model::model::model_module::*, - gtk::{ - *, - prelude::* - }, - }; - - impl EventHandler - where F: Fn(&C) + FnOnce(&C) + FnMut(&C){ - pub fn new(component: C, callback: F) -> EventHandler{ - Self{ - component, - callback, - } +impl EventHandler + where F: Fn(&C) + FnOnce(&C) + FnMut(&C){ + pub fn new(component: C, callback: F) -> EventHandler{ + Self{ + component, + callback, } } +} - pub trait BtnEventHandler{ - fn on_click(self) -> (); +pub trait BtnEventHandler{ + fn on_click(self) -> (); +} + +impl BtnEventHandler for EventHandler + where F: Fn(&C) + FnOnce(&C) + FnMut(&C) + 'static, C: ButtonExt + WidgetExt{ + fn on_click(self) -> () { + self.component.connect_clicked(move |button| { + (self.callback)(button) + }); } - - impl BtnEventHandler for EventHandler - where F: Fn(&C) + FnOnce(&C) + FnMut(&C) + 'static, C: ButtonExt + WidgetExt{ - fn on_click(self) -> () { - self.component.connect_clicked(move |button| { - (self.callback)(button) - }); - } - } - } \ No newline at end of file diff --git a/src/controller/event_handlers/switch_event_handlers.rs b/src/controller/event_handlers/switch_event_handlers.rs index 68a3d37..dade2be 100644 --- a/src/controller/event_handlers/switch_event_handlers.rs +++ b/src/controller/event_handlers/switch_event_handlers.rs @@ -1,30 +1,26 @@ -pub mod switch_event_handlers_module{ +use crate::{ + model::model::*, + view::components::switch::SwitchExt, + gtk::{ + *, + prelude::* + }, +}; - use crate::{ - model::model::model_module::*, - view::components::switch::switch_module::SwitchExt, - gtk::{ - *, - prelude::* - }, - }; +pub trait SwEventHandler{ + fn on_toggle(self) -> (); +} - pub trait SwEventHandler{ - fn on_toggle(self) -> (); - } - - impl SwEventHandler for EventHandler - where F: Fn(&C) + FnOnce(&C) + FnMut(&C) + 'static, C: SwitchExt + WidgetExt{ - fn on_toggle(self) -> () { - self.component.connect_state_notify(move |switch| { - (self.callback)(switch) - }); - } - } - - pub fn clearing(output : &TextView, input: &TextView){ - input.buffer().set_text(""); - output.buffer().set_text(""); +impl SwEventHandler for EventHandler + where F: Fn(&C) + FnOnce(&C) + FnMut(&C) + 'static, C: SwitchExt + WidgetExt{ + fn on_toggle(self) -> () { + self.component.connect_state_notify(move |switch| { + (self.callback)(switch) + }); } +} +pub fn clearing(output : &TextView, input: &TextView){ + input.buffer().set_text(""); + output.buffer().set_text(""); } \ No newline at end of file diff --git a/src/controller/model_utils/hamming_code_seven_four.rs b/src/controller/model_utils/hamming_code_seven_four.rs index 22d9ab1..7bc4c80 100644 --- a/src/controller/model_utils/hamming_code_seven_four.rs +++ b/src/controller/model_utils/hamming_code_seven_four.rs @@ -1,159 +1,155 @@ -pub mod hamming_code{ +use std::{borrow::Borrow, collections::HashMap}; - use std::{borrow::Borrow, collections::HashMap}; +use crate::{ + model::model::*, + controller::view_utils::input_utils::*, +}; - use crate::{ - model::model::model_module::*, - controller::view_utils::input_utils::input_utils_module::*, - }; +/// **Синдромы** +/// +/// ошибочная позиция 1 false true true. +/// +/// ошибочная позиция 2 false false true. +/// +/// ошибочная позиция 3 true false true. +/// +/// ошибочная позиция 4 false true false. +/// +/// ошибочная позиция 5 true true false. +/// +/// ошибочная позиция 6 true false false. +/// +/// ошибочная позиция 7 false false false. - /// **Синдромы** - /// - /// ошибочная позиция 1 false true true. - /// - /// ошибочная позиция 2 false false true. - /// - /// ошибочная позиция 3 true false true. - /// - /// ошибочная позиция 4 false true false. - /// - /// ошибочная позиция 5 true true false. - /// - /// ошибочная позиция 6 true false false. - /// - /// ошибочная позиция 7 false false false. +pub fn hamming(raw_input: String, mode: HammingMode) -> Result{ - pub fn hamming(raw_input: String, mode: HammingMode) -> Result{ + let length_of_code : usize = mode.clone() as usize; - let length_of_code : usize = mode.clone() as usize; + let prepared_input : String = processing_input(&raw_input); - let prepared_input : String = processing_input(&raw_input); + let (fc, sc) = check_correct_input(&raw_input, &prepared_input, length_of_code); - let (fc, sc) = check_correct_input(&raw_input, &prepared_input, length_of_code); + if !fc || !sc { - if !fc || !sc { + Err("Ошибка. Проверьте корректность ввода.".to_string()) - Err("Ошибка. Проверьте корректность ввода.".to_string()) + } else { - } else { + let mut data : String = String::new(); - let mut data : String = String::new(); - - let prepared_data: Vec = from_string_to_vec_bits(prepared_input); - - match mode { - HammingMode::Encrypt => hamming_encrypt_data(&prepared_data, &mut data, length_of_code), - HammingMode::Decrypt => hamming_decrypt_data(&prepared_data, &mut data, length_of_code), - } - - return Ok(data); + let prepared_data: Vec = from_string_to_vec_bits(prepared_input); + match mode { + HammingMode::Encrypt => hamming_encrypt_data(&prepared_data, &mut data, length_of_code), + HammingMode::Decrypt => hamming_decrypt_data(&prepared_data, &mut data, length_of_code), } + return Ok(data); + } - pub fn hamming_encrypt_data( - data: &Vec, - result_string: &mut String, - length_of_code: usize - ) { - let mut i : usize = length_of_code; +} - while i <= data.len(){ +pub fn hamming_encrypt_data( + data: &Vec, + result_string: &mut String, + length_of_code: usize +) { + let mut i : usize = length_of_code; - let data_bits = &data[i - length_of_code..i]; - let (check_bit_1, check_bit_2, check_bit_3) = ( - data_bits[0] ^ data_bits[1] ^ data_bits[3], - data_bits[0] ^ data_bits[2] ^ data_bits[3], - data_bits[1] ^ data_bits[2] ^ data_bits[3] - ); - result_string.push_str(&*format!("{check_bit_1}{}{check_bit_2}{}{check_bit_3}{}{} ", - data_bits[0], - data_bits[1], - data_bits[2], - data_bits[3])); - i += length_of_code; + while i <= data.len(){ - } - } - - pub fn hamming_decrypt_data( - data: &Vec, - result_string: &mut String, - length_of_code: usize - ) { - - let mut i : usize = length_of_code; - - let syndromes : HashMap = HashMap::from( - [ - (1, (false, true, true)), - (2, (false, false, true)), - (3, (true, false, true)), - (4, (false, true, false)), - (5, (true, true, false)), - (6, (true, false, false)), - (7, (false, false, false)), - ] + let data_bits = &data[i - length_of_code..i]; + let (check_bit_1, check_bit_2, check_bit_3) = ( + data_bits[0] ^ data_bits[1] ^ data_bits[3], + data_bits[0] ^ data_bits[2] ^ data_bits[3], + data_bits[1] ^ data_bits[2] ^ data_bits[3] ); + result_string.push_str(&*format!("{check_bit_1}{}{check_bit_2}{}{check_bit_3}{}{} ", + data_bits[0], + data_bits[1], + data_bits[2], + data_bits[3])); + i += length_of_code; - let mut errors : String = String::new(); + } +} - while i <= data.len(){ +pub fn hamming_decrypt_data( + data: &Vec, + result_string: &mut String, + length_of_code: usize +) { - let mut data_bits = &data[i - length_of_code..i]; + let mut i : usize = length_of_code; - let checked_bits : (bool, bool, bool) = - ( - (data_bits[1] ^ data_bits[3] ^ data_bits[6]) == data_bits[0], - (data_bits[1] ^ data_bits[5] ^ data_bits[6]) == data_bits[2], - (data_bits[3] ^ data_bits[5] ^ data_bits[6]) == data_bits[4] + let syndromes : HashMap = HashMap::from( + [ + (1, (false, true, true)), + (2, (false, false, true)), + (3, (true, false, true)), + (4, (false, true, false)), + (5, (true, true, false)), + (6, (true, false, false)), + (7, (false, false, false)), + ] + ); + + let mut errors : String = String::new(); + + while i <= data.len(){ + + let mut data_bits = &data[i - length_of_code..i]; + + let checked_bits : (bool, bool, bool) = + ( + (data_bits[1] ^ data_bits[3] ^ data_bits[6]) == data_bits[0], + (data_bits[1] ^ data_bits[5] ^ data_bits[6]) == data_bits[2], + (data_bits[3] ^ data_bits[5] ^ data_bits[6]) == data_bits[4] + ); + + match checked_bits { + (true, true, true) => { + i += length_of_code; + continue; + }, + _ => { + + let error_position = syndromes + .iter() + .find(move |&(&error_position, &error)| error == checked_bits). + unwrap().0; + + let correctly_code : Vec = data_bits + .iter() + .enumerate() + .map(|(index, bit)| { + if index == error_position - 1 { + if *bit == 1u8 { 0u8 } else { 1u8 } + } else { + *bit + } + }).collect(); + + let error = format!("Ошибка в коде {} {:?}, позиция ошибки {}, корректный код: {:?}; \n", + i / 7, + &data_bits, + error_position, + correctly_code ); - match checked_bits { - (true, true, true) => { - i += length_of_code; - continue; - }, - _ => { + errors.push_str(error.as_str()); - let error_position = syndromes - .iter() - .find(move |&(&error_position, &error)| error == checked_bits). - unwrap().0; + i += length_of_code; - let correctly_code : Vec = data_bits - .iter() - .enumerate() - .map(|(index, bit)| { - if index == error_position - 1 { - if *bit == 1u8 { 0u8 } else { 1u8 } - } else { - *bit - } - }).collect(); - - let error = format!("Ошибка в коде {} {:?}, позиция ошибки {}, корректный код: {:?}; \n", - i / 7, - &data_bits, - error_position, - correctly_code - ); - - errors.push_str(error.as_str()); - - i += length_of_code; - - } } } + } - if errors.len() == 0 { - result_string.push_str("Все коды корректны."); - } else { - result_string.push_str(errors.as_str()) - } - + if errors.len() == 0 { + result_string.push_str("Все коды корректны."); + } else { + result_string.push_str(errors.as_str()) } } \ No newline at end of file diff --git a/src/controller/view_utils/input_utils.rs b/src/controller/view_utils/input_utils.rs index 9237bdb..ca2a21a 100644 --- a/src/controller/view_utils/input_utils.rs +++ b/src/controller/view_utils/input_utils.rs @@ -1,72 +1,68 @@ -pub mod input_utils_module { +use gtk4 as gtk; - use gtk4 as gtk; +use std::ops::Deref; +use gtk::{*, prelude::*}; +use bitvec::{order::Lsb0, view::AsBits}; - use std::ops::Deref; - use gtk::{*, prelude::*}; - use bitvec::{order::Lsb0, view::AsBits}; +use crate::{ + model::model::*, + model_utils::hamming_code_seven_four::* +}; - use crate::{ - model::model::model_module::*, - model_utils::hamming_code_seven_four::hamming_code::* +pub fn parse_input(input : &TextView, output : &TextView, mode: bool) -> (){ + + let (iter_start, iter_end) = input.buffer().bounds(); + let parsed_input : String = input + .buffer() + .text(&iter_start, &iter_end, false) + .to_string() + .trim() + .parse() + .unwrap(); + + let operation = if mode == false { + HammingMode::Encrypt + } else { + HammingMode::Decrypt }; - pub fn parse_input(input : &TextView, output : &TextView, mode: bool) -> (){ - - let (iter_start, iter_end) = input.buffer().bounds(); - let parsed_input : String = input - .buffer() - .text(&iter_start, &iter_end, false) - .to_string() - .trim() - .parse() - .unwrap(); - - let operation = if mode == false { - HammingMode::Encrypt - } else { - HammingMode::Decrypt - }; - - match hamming(parsed_input, operation) { - Ok(res) => output.buffer().set_text(res.trim_end()), - Err(rej) => output.buffer().set_text(rej.as_str()), - } - + match hamming(parsed_input, operation) { + Ok(res) => output.buffer().set_text(res.trim_end()), + Err(rej) => output.buffer().set_text(rej.as_str()), } - pub fn processing_input(input : &String) -> String { +} - input - .split_ascii_whitespace() - .filter(|&x| { - x != "" - }) - .fold(String::new(), |c: String, n: &str| { c + n }) +pub fn processing_input(input : &String) -> String { - } + input + .split_ascii_whitespace() + .filter(|&x| { + x != "" + }) + .fold(String::new(), |c: String, n: &str| { c + n }) - pub fn check_correct_input(input: &String, prepared_input: &String, l: usize) -> (bool, bool){ +} - let first_condition = input - .chars() - .all(|c| {c == '1' || c == '0' || c == ' '}); +pub fn check_correct_input(input: &String, prepared_input: &String, l: usize) -> (bool, bool){ - let second_condition = prepared_input.len() % l == 0; + let first_condition = input + .chars() + .all(|c| {c == '1' || c == '0' || c == ' '}); - (first_condition, second_condition) + let second_condition = prepared_input.len() % l == 0; - } + (first_condition, second_condition) - pub fn from_string_to_vec_bits(raw_data: String) -> Vec{ +} - raw_data - .as_bits::() - .iter() - .step_by(8) - .map(|x| *x.deref() as u8) - .collect() +pub fn from_string_to_vec_bits(raw_data: String) -> Vec{ - } + raw_data + .as_bits::() + .iter() + .step_by(8) + .map(|x| *x.deref() as u8) + .collect() } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 08f8536..e7f1f66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,13 +6,11 @@ use gtk::*; use gtk::prelude::*; mod view; -use view::view::view_module::*; - mod model; - mod controller; -use controller::*; +use controller::*; +use view::view::*; fn main() { @@ -22,4 +20,5 @@ fn main() { app.connect_activate(ui); app.run(); + } \ No newline at end of file diff --git a/src/model/model.rs b/src/model/model.rs index 61568a3..30561da 100644 --- a/src/model/model.rs +++ b/src/model/model.rs @@ -1,16 +1,11 @@ -pub mod model_module{ - - #[repr(usize)] - #[derive(Clone)] - pub enum HammingMode{ - Encrypt = 4, - Decrypt = 7 - } - - pub struct EventHandler{ - pub(crate) component: C, - pub(crate) callback: F, - } - +#[repr(usize)] +#[derive(Clone)] +pub enum HammingMode{ + Encrypt = 4, + Decrypt = 7 } +pub struct EventHandler{ + pub(crate) component: C, + pub(crate) callback: F, +} \ No newline at end of file diff --git a/src/view/components/switch.rs b/src/view/components/switch.rs index 706ae14..8efb58c 100644 --- a/src/view/components/switch.rs +++ b/src/view/components/switch.rs @@ -1,153 +1,150 @@ -pub mod switch_module { +use gtk4 as gtk; - use gtk4 as gtk; +use gtk::{*, prelude::*}; - use gtk::{*, prelude::*}; +use glib::{ + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; - use glib::{ - signal::{connect_raw, SignalHandlerId}, - translate::*, - }; +use std::boxed::Box as Box_; - use std::boxed::Box as Box_; - - mod sealed { - pub trait Sealed {} - impl> Sealed for T {} - } - - pub trait SwitchExt: IsA + sealed::Sealed + 'static { - #[doc(alias = "gtk_switch_get_active")] - #[doc(alias = "get_active")] - fn is_active(&self) -> bool { - unsafe { from_glib(ffi::gtk_switch_get_active(self.as_ref().to_glib_none().0)) } - } - - #[doc(alias = "gtk_switch_get_state")] - #[doc(alias = "get_state")] - fn state(&self) -> bool { - unsafe { from_glib(ffi::gtk_switch_get_state(self.as_ref().to_glib_none().0)) } - } - - #[doc(alias = "gtk_switch_set_active")] - fn set_active(&self, is_active: bool) { - unsafe { - ffi::gtk_switch_set_active(self.as_ref().to_glib_none().0, is_active.into_glib()); - } - } - - #[doc(alias = "gtk_switch_set_state")] - fn set_state(&self, state: bool) { - unsafe { - ffi::gtk_switch_set_state(self.as_ref().to_glib_none().0, state.into_glib()); - } - } - - #[doc(alias = "activate")] - fn connect_activate(&self, f: F) -> SignalHandlerId { - unsafe extern "C" fn activate_trampoline, F: Fn(&P) + 'static>( - this: *mut ffi::GtkSwitch, - f: glib::ffi::gpointer, - ) { - let f: &F = &*(f as *const F); - f(Switch::from_glib_borrow(this).unsafe_cast_ref()) - } - unsafe { - let f: Box_ = Box_::new(f); - connect_raw( - self.as_ptr() as *mut _, - b"activate\0".as_ptr() as *const _, - Some(std::mem::transmute::<_, unsafe extern "C" fn()>( - activate_trampoline:: as *const (), - )), - Box_::into_raw(f), - ) - } - } - - fn emit_activate(&self) { - self.emit_by_name::<()>("activate", &[]); - } - - #[doc(alias = "state-set")] - fn connect_state_set glib::Propagation + 'static>( - &self, - f: F, - ) -> SignalHandlerId { - unsafe extern "C" fn state_set_trampoline< - P: IsA, - F: Fn(&P, bool) -> glib::Propagation + 'static, - >( - this: *mut ffi::GtkSwitch, - state: glib::ffi::gboolean, - f: glib::ffi::gpointer, - ) -> glib::ffi::gboolean { - let f: &F = &*(f as *const F); - f( - Switch::from_glib_borrow(this).unsafe_cast_ref(), - from_glib(state), - ) - .into_glib() - } - unsafe { - let f: Box_ = Box_::new(f); - connect_raw( - self.as_ptr() as *mut _, - b"state-set\0".as_ptr() as *const _, - Some(std::mem::transmute::<_, unsafe extern "C" fn()>( - state_set_trampoline:: as *const (), - )), - Box_::into_raw(f), - ) - } - } - - #[doc(alias = "active")] - fn connect_active_notify(&self, f: F) -> SignalHandlerId { - unsafe extern "C" fn notify_active_trampoline, F: Fn(&P) + 'static>( - this: *mut ffi::GtkSwitch, - _param_spec: glib::ffi::gpointer, - f: glib::ffi::gpointer, - ) { - let f: &F = &*(f as *const F); - f(Switch::from_glib_borrow(this).unsafe_cast_ref()) - } - unsafe { - let f: Box_ = Box_::new(f); - connect_raw( - self.as_ptr() as *mut _, - b"notify::active\0".as_ptr() as *const _, - Some(std::mem::transmute::<_, unsafe extern "C" fn()>( - notify_active_trampoline:: as *const (), - )), - Box_::into_raw(f), - ) - } - } - - #[doc(alias = "state")] - fn connect_state_notify(&self, f: F) -> SignalHandlerId { - unsafe extern "C" fn notify_state_trampoline, F: Fn(&P) + 'static>( - this: *mut ffi::GtkSwitch, - _param_spec: glib::ffi::gpointer, - f: glib::ffi::gpointer, - ) { - let f: &F = &*(f as *const F); - f(Switch::from_glib_borrow(this).unsafe_cast_ref()) - } - unsafe { - let f: Box_ = Box_::new(f); - connect_raw( - self.as_ptr() as *mut _, - b"notify::state\0".as_ptr() as *const _, - Some(std::mem::transmute::<_, unsafe extern "C" fn()>( - notify_state_trampoline:: as *const (), - )), - Box_::into_raw(f), - ) - } - } - } - - impl> SwitchExt for O {} +mod sealed { + pub trait Sealed {} + impl> Sealed for T {} } + +pub trait SwitchExt: IsA + sealed::Sealed + 'static { + #[doc(alias = "gtk_switch_get_active")] + #[doc(alias = "get_active")] + fn is_active(&self) -> bool { + unsafe { from_glib(ffi::gtk_switch_get_active(self.as_ref().to_glib_none().0)) } + } + + #[doc(alias = "gtk_switch_get_state")] + #[doc(alias = "get_state")] + fn state(&self) -> bool { + unsafe { from_glib(ffi::gtk_switch_get_state(self.as_ref().to_glib_none().0)) } + } + + #[doc(alias = "gtk_switch_set_active")] + fn set_active(&self, is_active: bool) { + unsafe { + ffi::gtk_switch_set_active(self.as_ref().to_glib_none().0, is_active.into_glib()); + } + } + + #[doc(alias = "gtk_switch_set_state")] + fn set_state(&self, state: bool) { + unsafe { + ffi::gtk_switch_set_state(self.as_ref().to_glib_none().0, state.into_glib()); + } + } + + #[doc(alias = "activate")] + fn connect_activate(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn activate_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::GtkSwitch, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Switch::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"activate\0".as_ptr() as *const _, + Some(std::mem::transmute::<_, unsafe extern "C" fn()>( + activate_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn emit_activate(&self) { + self.emit_by_name::<()>("activate", &[]); + } + + #[doc(alias = "state-set")] + fn connect_state_set glib::Propagation + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn state_set_trampoline< + P: IsA, + F: Fn(&P, bool) -> glib::Propagation + 'static, + >( + this: *mut ffi::GtkSwitch, + state: glib::ffi::gboolean, + f: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let f: &F = &*(f as *const F); + f( + Switch::from_glib_borrow(this).unsafe_cast_ref(), + from_glib(state), + ) + .into_glib() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"state-set\0".as_ptr() as *const _, + Some(std::mem::transmute::<_, unsafe extern "C" fn()>( + state_set_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "active")] + fn connect_active_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_active_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::GtkSwitch, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Switch::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::active\0".as_ptr() as *const _, + Some(std::mem::transmute::<_, unsafe extern "C" fn()>( + notify_active_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "state")] + fn connect_state_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_state_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::GtkSwitch, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Switch::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::state\0".as_ptr() as *const _, + Some(std::mem::transmute::<_, unsafe extern "C" fn()>( + notify_state_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl> SwitchExt for O {} \ No newline at end of file diff --git a/src/view/components/tabs.rs b/src/view/components/tabs.rs index 965e93f..12b4157 100644 --- a/src/view/components/tabs.rs +++ b/src/view/components/tabs.rs @@ -1,71 +1,67 @@ -pub mod tabs_module { +use gtk4 as gtk; - use gtk4 as gtk; +use gtk::{Notebook, Label, Box}; - use gtk::{Notebook, Label, Box}; +pub type TabLabel = Label; +pub type TabContent = Box; - pub type TabLabel = Label; - pub type TabContent = Box; +#[derive(Clone)] +pub struct TabsBuilder { + tabs: Vec<(TabLabel, TabContent)> +} - #[derive(Clone)] - pub struct TabsBuilder { - tabs: Vec<(TabLabel, TabContent)> +pub struct Tabs { + tabs_wrapper: Notebook +} + +impl Tabs { + pub fn builder() -> TabsBuilder { + TabsBuilder{ + tabs: Vec::new(), + } } - pub struct Tabs { - tabs_wrapper: Notebook + pub fn get(self) -> Notebook { + self.tabs_wrapper } - impl Tabs { - pub fn builder() -> TabsBuilder { - TabsBuilder{ - tabs: Vec::new(), - } - } +} - pub fn get(self) -> Notebook { - self.tabs_wrapper - } +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)); } - impl TabsBuilder { + pub fn add_tab(mut self, label: &str, page: TabContent) -> Self { + self.append_tab_private(label, page); - fn append_tab_private(&mut self, label: &str, page: TabContent) { - let tab_label = Label::new(Some(label)); - self.tabs.push((tab_label, page)); - } + self + } - pub fn add_tab(mut self, label: &str, page: TabContent) -> Self { + pub fn add_tabs(mut self, labels: Vec<&str>, pages: Vec) -> Self { + for (label, page) in labels.iter().zip(pages) { self.append_tab_private(label, page); - - self } - pub fn add_tabs(mut self, labels: Vec<&str>, pages: Vec) -> Self { - for (label, page) in labels.iter().zip(pages) { - self.append_tab_private(label, page); - } + self + } - self + pub fn build(&mut self, group_name: &str) -> Tabs { + let tabs_wrapper = Notebook::builder() + .group_name(group_name) + .build(); + + self.tabs + .iter() + .for_each(|(label, content)| { + tabs_wrapper.append_page(content, Some(label)); + }); + + Tabs { + tabs_wrapper } - - pub fn build(&mut self, group_name: &str) -> Tabs { - let tabs_wrapper = Notebook::builder() - .group_name(group_name) - .build(); - - self.tabs - .iter() - .for_each(|(label, content)| { - tabs_wrapper.append_page(content, Some(label)); - }); - - Tabs { - tabs_wrapper - } - } - } } \ No newline at end of file diff --git a/src/view/components/wrapper.rs b/src/view/components/wrapper.rs index 0398747..a179175 100644 --- a/src/view/components/wrapper.rs +++ b/src/view/components/wrapper.rs @@ -1,23 +1,18 @@ -pub mod wrapper_module { +use gtk4 as gtk; - use gtk4 as gtk; +use gtk::{Orientation, builders::BoxBuilder, Box}; - use gtk::{Orientation, builders::BoxBuilder, Box}; +#[allow(dead_code)] +pub struct Wrapper; - #[allow(dead_code)] - pub struct Wrapper; - - impl Wrapper{ - - pub fn row_builder() -> BoxBuilder { - Box::builder().orientation(Orientation::Vertical) - } - - pub fn col_builder() -> BoxBuilder { - Box::builder().orientation(Orientation::Horizontal) - } +impl Wrapper{ + pub fn row_builder() -> BoxBuilder { + Box::builder().orientation(Orientation::Vertical) } -} + pub fn col_builder() -> BoxBuilder { + Box::builder().orientation(Orientation::Horizontal) + } +} \ No newline at end of file diff --git a/src/view/properties.rs b/src/view/properties.rs index 58a71f1..89b96f9 100644 --- a/src/view/properties.rs +++ b/src/view/properties.rs @@ -1,120 +1,118 @@ -pub mod properties_module{ - use gtk4 as gtk; +use gtk4 as gtk; - use gtk::{Align}; - use gtk::builders::*; +use gtk::{Align}; +use gtk::builders::*; - /** - * Types - */ +/** + * Types + */ - pub type Margin = (i32, i32, i32, i32); +pub type Margin = (i32, i32, i32, i32); - /** - * Enums - */ +/** + * Enums + */ - pub enum MarginData{ - EqualsMargin(i32), - MultipleMargin(Margin), - } +pub enum MarginData{ + EqualsMargin(i32), + MultipleMargin(Margin), +} - /** - * Structs - */ +/** + * Structs + */ - #[allow(dead_code)] +#[allow(dead_code)] - pub struct Size { - pub width: i32, - pub height: i32 - } +pub struct Size { + pub width: i32, + pub height: i32 +} - pub struct Alignment { - pub horizontal: Align, - pub vertical : Align - } +pub struct Alignment { + pub horizontal: Align, + pub vertical : Align +} - /** - * Traits - */ +/** + * Traits + */ - pub trait Setters{ - fn set_margin(self, margin: MarginData) -> Self; - fn set_align(self, align: Alignment) -> Self; - } +pub trait Setters{ + fn set_margin(self, margin: MarginData) -> Self; + fn set_align(self, align: Alignment) -> Self; +} - pub trait TextViewSetters{ - fn set_text_view_margin(self, margin: MarginData) -> Self; - } +pub trait TextViewSetters{ + fn set_text_view_margin(self, margin: MarginData) -> Self; +} - impl TextViewSetters for TextViewBuilder{ - fn set_text_view_margin(self, margin: MarginData) -> Self{ - match margin{ - MarginData::EqualsMargin(margin) => - self.top_margin(margin) - .left_margin(margin) - .bottom_margin(margin) - .right_margin(margin), - MarginData::MultipleMargin(margins) => - self.top_margin(margins.0) - .left_margin(margins.1) - .bottom_margin(margins.2) - .right_margin(margins.3), - } - } - } - - /** - * Macros - */ - - macro_rules! impl_setters { - ($($t:ty),+) => { - $( - impl Setters for $t { - fn set_margin(self, margin: MarginData) -> Self{ - match margin{ - MarginData::EqualsMargin(margin) => - self.margin_top(margin) - .margin_start(margin) - .margin_bottom(margin) - .margin_end(margin), - MarginData::MultipleMargin(margins) => - self.margin_top(margins.0) - .margin_start(margins.1) - .margin_bottom(margins.2) - .margin_end(margins.3), - } - } - fn set_align(self, align: Alignment) -> Self { - self.halign(align.horizontal) - .valign(align.vertical) - } - } - )* - } - } - - impl_setters!{ButtonBuilder, EntryBuilder, TextViewBuilder, - BoxBuilder, SwitchBuilder, FrameBuilder, LabelBuilder} - - #[allow(dead_code)] - impl Size{ - pub fn new(w: i32, h: i32) -> Size{ - Size{ - width: w, - height: h, - } - } - } - - impl Alignment{ - pub fn new(horizontal: Align, vertical : Align) -> Alignment{ - Alignment{ - horizontal, - vertical, - } +impl TextViewSetters for TextViewBuilder{ + fn set_text_view_margin(self, margin: MarginData) -> Self{ + match margin{ + MarginData::EqualsMargin(margin) => + self.top_margin(margin) + .left_margin(margin) + .bottom_margin(margin) + .right_margin(margin), + MarginData::MultipleMargin(margins) => + self.top_margin(margins.0) + .left_margin(margins.1) + .bottom_margin(margins.2) + .right_margin(margins.3), } } } + +/** + * Macros + */ + +macro_rules! impl_setters { + ($($t:ty),+) => { + $( + impl Setters for $t { + fn set_margin(self, margin: MarginData) -> Self{ + match margin{ + MarginData::EqualsMargin(margin) => + self.margin_top(margin) + .margin_start(margin) + .margin_bottom(margin) + .margin_end(margin), + MarginData::MultipleMargin(margins) => + self.margin_top(margins.0) + .margin_start(margins.1) + .margin_bottom(margins.2) + .margin_end(margins.3), + } + } + fn set_align(self, align: Alignment) -> Self { + self.halign(align.horizontal) + .valign(align.vertical) + } + } + )* + } +} + +impl_setters!{ButtonBuilder, EntryBuilder, TextViewBuilder, +BoxBuilder, SwitchBuilder, FrameBuilder, LabelBuilder} + +#[allow(dead_code)] +impl Size{ + pub fn new(w: i32, h: i32) -> Size{ + Size{ + width: w, + height: h, + } + } +} + +impl Alignment{ + pub fn new(horizontal: Align, vertical : Align) -> Alignment{ + Alignment{ + horizontal, + vertical, + } + } +} \ No newline at end of file diff --git a/src/view/view.rs b/src/view/view.rs index b6e582a..0f5c988 100644 --- a/src/view/view.rs +++ b/src/view/view.rs @@ -1,195 +1,190 @@ -pub mod view_module{ +use gtk4 as gtk; - use gtk4 as gtk; +use gtk::{*, prelude::*}; - use gtk::{*, prelude::*}; - - use crate::{ - model::model::model_module::*, - view::{ - properties::properties_module::*, - components::{ - *, - tabs::tabs_module::*, - switch::switch_module::*, - wrapper::wrapper_module::*, - } - }, - controller::{ - controller::*, - view_utils::input_utils::input_utils_module::*, - event_handlers::{ - button_event_handlers::button_event_handlers_module::*, - switch_event_handlers::switch_event_handlers_module::*, - }, +use crate::{ + model::model::*, + view::{ + properties::*, + components::{ + *, + tabs::*, + switch::*, + wrapper::*, } - }; - - 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); - + }, + controller::{ + controller::*, + view_utils::input_utils::*, + event_handlers::{ + button_event_handlers::*, + switch_event_handlers::*, + }, } +}; - pub fn ui(application: &Application) { +pub fn laboratory_work_first_section(wrapper: &Box) -> (){ - let mutual_wrapper = Wrapper::row_builder() + // 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)) - .set_margin(MarginData::EqualsMargin(15)) - .spacing(10) + .label("Очистка полей") .build(); - laboratory_work_first_section(&mutual_wrapper); + let hamming_crypt_button = Button::builder() + .set_align(Alignment::new(Align::Fill, Align::Fill)) + .label("Выполнить") + .build(); - let second_wrapper = Wrapper::row_builder() - .set_align(Alignment::new(Align::Fill, Align::Fill)) - .set_margin(MarginData::EqualsMargin(15)) - .spacing(10) - .build(); + let crypt_mode_switch = Switch::new(); - second_wrapper.append(&Label::new(Some("Код Хафмана"))); + let crypt_mode_label = Label::builder() + .label("Режим: кодирование") + .build(); - let notebook = Tabs::builder() - .add_tabs( - vec!["Код Хэмминга", "Код Хафмана"], - vec![mutual_wrapper, second_wrapper] + // 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() ) - .build("Tabs") - .get(); + }).on_click(); - let window = ApplicationWindow::builder() - .title("Комплексная программа для лаб. работ") - .width_request(650) - .height_request(400) - .application(application) - .child(¬ebook) - .build(); + EventHandler::new( + crypt_mode_switch.clone(), + move |s : &Switch| { + state_controller(s, &crypt_mode_label_to_handle); + }).on_toggle(); - window.show(); - } + // 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: &Application) { + + let mutual_wrapper = 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); + + let second_wrapper = 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("Код Хафмана"))); + + let notebook = Tabs::builder() + .add_tabs( + vec!["Код Хэмминга", "Код Хафмана"], + vec![mutual_wrapper, second_wrapper] + ) + .build("Tabs") + .get(); + + let window = ApplicationWindow::builder() + .title("Комплексная программа для лаб. работ") + .width_request(650) + .height_request(400) + .application(application) + .child(¬ebook) + .build(); + + window.show(); +} \ No newline at end of file