removed unnecessary module definitions

This commit is contained in:
doryan04 2024-03-10 12:54:32 +04:00
parent 54619cd3f9
commit 4c230c090d
11 changed files with 702 additions and 743 deletions

View File

@ -1,34 +1,30 @@
pub mod button_event_handlers_module{ use crate::{
model::model::*,
gtk::{
*,
prelude::*
},
};
use crate::{ impl<F, C> EventHandler<F, C>
model::model::model_module::*, where F: Fn(&C) + FnOnce(&C) + FnMut(&C){
gtk::{ pub fn new(component: C, callback: F) -> EventHandler<F, C>{
*, Self{
prelude::* component,
}, callback,
};
impl<F, C> EventHandler<F, C>
where F: Fn(&C) + FnOnce(&C) + FnMut(&C){
pub fn new(component: C, callback: F) -> EventHandler<F, C>{
Self{
component,
callback,
}
} }
} }
}
pub trait BtnEventHandler{ pub trait BtnEventHandler{
fn on_click(self) -> (); fn on_click(self) -> ();
}
impl<F, C> BtnEventHandler for EventHandler<F, C>
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<F, C> BtnEventHandler for EventHandler<F, C>
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)
});
}
}
} }

View File

@ -1,30 +1,26 @@
pub mod switch_event_handlers_module{ use crate::{
model::model::*,
view::components::switch::SwitchExt,
gtk::{
*,
prelude::*
},
};
use crate::{ pub trait SwEventHandler{
model::model::model_module::*, fn on_toggle(self) -> ();
view::components::switch::switch_module::SwitchExt, }
gtk::{
*,
prelude::*
},
};
pub trait SwEventHandler{ impl<F, C> SwEventHandler for EventHandler<F, C>
fn on_toggle(self) -> (); where F: Fn(&C) + FnOnce(&C) + FnMut(&C) + 'static, C: SwitchExt + WidgetExt{
} fn on_toggle(self) -> () {
self.component.connect_state_notify(move |switch| {
impl<F, C> SwEventHandler for EventHandler<F, C> (self.callback)(switch)
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("");
} }
}
pub fn clearing(output : &TextView, input: &TextView){
input.buffer().set_text("");
output.buffer().set_text("");
} }

View File

@ -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.
/// **Синдромы** pub fn hamming(raw_input: String, mode: HammingMode) -> Result<String, String>{
///
/// ошибочная позиция 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<String, String>{ 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<u8> = from_string_to_vec_bits(prepared_input);
let prepared_data: Vec<u8> = 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);
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<u8>,
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<u8>,
result_string: &mut String,
length_of_code: usize
) {
let mut i : usize = length_of_code;
let data_bits = &data[i - length_of_code..i]; while i <= data.len(){
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 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],
pub fn hamming_decrypt_data( data_bits[0] ^ data_bits[2] ^ data_bits[3],
data: &Vec<u8>, data_bits[1] ^ data_bits[2] ^ data_bits[3]
result_string: &mut String,
length_of_code: usize
) {
let mut i : usize = length_of_code;
let syndromes : HashMap<usize, (bool, bool, bool)> = 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)),
]
); );
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<u8>,
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) = let syndromes : HashMap<usize, (bool, bool, bool)> = HashMap::from(
( [
(data_bits[1] ^ data_bits[3] ^ data_bits[6]) == data_bits[0], (1, (false, true, true)),
(data_bits[1] ^ data_bits[5] ^ data_bits[6]) == data_bits[2], (2, (false, false, true)),
(data_bits[3] ^ data_bits[5] ^ data_bits[6]) == data_bits[4] (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<u8> = 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 { errors.push_str(error.as_str());
(true, true, true) => {
i += length_of_code;
continue;
},
_ => {
let error_position = syndromes i += length_of_code;
.iter()
.find(move |&(&error_position, &error)| error == checked_bits).
unwrap().0;
let correctly_code : Vec<u8> = 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 { if errors.len() == 0 {
result_string.push_str("Все коды корректны."); result_string.push_str("Все коды корректны.");
} else { } else {
result_string.push_str(errors.as_str()) result_string.push_str(errors.as_str())
}
} }
} }

View File

@ -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 crate::{
use gtk::{*, prelude::*}; model::model::*,
use bitvec::{order::Lsb0, view::AsBits}; model_utils::hamming_code_seven_four::*
};
use crate::{ pub fn parse_input(input : &TextView, output : &TextView, mode: bool) -> (){
model::model::model_module::*,
model_utils::hamming_code_seven_four::hamming_code::* 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) -> (){ match hamming(parsed_input, operation) {
Ok(res) => output.buffer().set_text(res.trim_end()),
let (iter_start, iter_end) = input.buffer().bounds(); Err(rej) => output.buffer().set_text(rej.as_str()),
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()),
}
} }
pub fn processing_input(input : &String) -> String { }
input pub fn processing_input(input : &String) -> String {
.split_ascii_whitespace()
.filter(|&x| {
x != ""
})
.fold(String::new(), |c: String, n: &str| { c + n })
} 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 pub fn check_correct_input(input: &String, prepared_input: &String, l: usize) -> (bool, bool){
.chars()
.all(|c| {c == '1' || c == '0' || c == ' '});
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<u8>{ }
raw_data pub fn from_string_to_vec_bits(raw_data: String) -> Vec<u8>{
.as_bits::<Lsb0>()
.iter()
.step_by(8)
.map(|x| *x.deref() as u8)
.collect()
} raw_data
.as_bits::<Lsb0>()
.iter()
.step_by(8)
.map(|x| *x.deref() as u8)
.collect()
} }

View File

@ -6,13 +6,11 @@ use gtk::*;
use gtk::prelude::*; use gtk::prelude::*;
mod view; mod view;
use view::view::view_module::*;
mod model; mod model;
mod controller; mod controller;
use controller::*;
use controller::*;
use view::view::*;
fn main() { fn main() {
@ -22,4 +20,5 @@ fn main() {
app.connect_activate(ui); app.connect_activate(ui);
app.run(); app.run();
} }

View File

@ -1,16 +1,11 @@
pub mod model_module{ #[repr(usize)]
#[derive(Clone)]
#[repr(usize)] pub enum HammingMode{
#[derive(Clone)] Encrypt = 4,
pub enum HammingMode{ Decrypt = 7
Encrypt = 4,
Decrypt = 7
}
pub struct EventHandler<F, C>{
pub(crate) component: C,
pub(crate) callback: F,
}
} }
pub struct EventHandler<F, C>{
pub(crate) component: C,
pub(crate) callback: F,
}

View File

@ -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::{ use std::boxed::Box as Box_;
signal::{connect_raw, SignalHandlerId},
translate::*,
};
use std::boxed::Box as Box_; mod sealed {
pub trait Sealed {}
mod sealed { impl<T: super::IsA<super::Switch>> Sealed for T {}
pub trait Sealed {}
impl<T: super::IsA<super::Switch>> Sealed for T {}
}
pub trait SwitchExt: IsA<Switch> + 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<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn activate_trampoline<P: IsA<Switch>, 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_<F> = 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::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn emit_activate(&self) {
self.emit_by_name::<()>("activate", &[]);
}
#[doc(alias = "state-set")]
fn connect_state_set<F: Fn(&Self, bool) -> glib::Propagation + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn state_set_trampoline<
P: IsA<Switch>,
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_<F> = 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::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
#[doc(alias = "active")]
fn connect_active_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_active_trampoline<P: IsA<Switch>, 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_<F> = 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::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
#[doc(alias = "state")]
fn connect_state_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_state_trampoline<P: IsA<Switch>, 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_<F> = 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::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
}
impl<O: IsA<Switch>> SwitchExt for O {}
} }
pub trait SwitchExt: IsA<Switch> + 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<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn activate_trampoline<P: IsA<Switch>, 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_<F> = 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::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn emit_activate(&self) {
self.emit_by_name::<()>("activate", &[]);
}
#[doc(alias = "state-set")]
fn connect_state_set<F: Fn(&Self, bool) -> glib::Propagation + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn state_set_trampoline<
P: IsA<Switch>,
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_<F> = 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::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
#[doc(alias = "active")]
fn connect_active_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_active_trampoline<P: IsA<Switch>, 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_<F> = 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::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
#[doc(alias = "state")]
fn connect_state_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_state_trampoline<P: IsA<Switch>, 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_<F> = 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::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
}
impl<O: IsA<Switch>> SwitchExt for O {}

View File

@ -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; #[derive(Clone)]
pub type TabContent = Box; pub struct TabsBuilder {
tabs: Vec<(TabLabel, TabContent)>
}
#[derive(Clone)] pub struct Tabs {
pub struct TabsBuilder { tabs_wrapper: Notebook
tabs: Vec<(TabLabel, TabContent)> }
impl Tabs {
pub fn builder() -> TabsBuilder {
TabsBuilder{
tabs: Vec::new(),
}
} }
pub struct Tabs { pub fn get(self) -> Notebook {
tabs_wrapper: Notebook self.tabs_wrapper
} }
impl Tabs { }
pub fn builder() -> TabsBuilder {
TabsBuilder{
tabs: Vec::new(),
}
}
pub fn get(self) -> Notebook { impl TabsBuilder {
self.tabs_wrapper
}
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) { self
let tab_label = Label::new(Some(label)); }
self.tabs.push((tab_label, page));
}
pub fn add_tab(mut self, label: &str, page: TabContent) -> Self { pub fn add_tabs(mut self, labels: Vec<&str>, pages: Vec<TabContent>) -> Self {
for (label, page) in labels.iter().zip(pages) {
self.append_tab_private(label, page); self.append_tab_private(label, page);
self
} }
pub fn add_tabs(mut self, labels: Vec<&str>, pages: Vec<TabContent>) -> Self { self
for (label, page) in labels.iter().zip(pages) { }
self.append_tab_private(label, page);
}
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
}
}
} }
} }

View File

@ -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)] impl Wrapper{
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)
}
pub fn row_builder() -> BoxBuilder {
Box::builder().orientation(Orientation::Vertical)
} }
} pub fn col_builder() -> BoxBuilder {
Box::builder().orientation(Orientation::Horizontal)
}
}

View File

@ -1,120 +1,118 @@
pub mod properties_module{ use gtk4 as gtk;
use gtk4 as gtk;
use gtk::{Align}; use gtk::{Align};
use gtk::builders::*; use gtk::builders::*;
/** /**
* Types * Types
*/ */
pub type Margin = (i32, i32, i32, i32); pub type Margin = (i32, i32, i32, i32);
/** /**
* Enums * Enums
*/ */
pub enum MarginData{ pub enum MarginData{
EqualsMargin(i32), EqualsMargin(i32),
MultipleMargin(Margin), MultipleMargin(Margin),
} }
/** /**
* Structs * Structs
*/ */
#[allow(dead_code)] #[allow(dead_code)]
pub struct Size { pub struct Size {
pub width: i32, pub width: i32,
pub height: i32 pub height: i32
} }
pub struct Alignment { pub struct Alignment {
pub horizontal: Align, pub horizontal: Align,
pub vertical : Align pub vertical : Align
} }
/** /**
* Traits * Traits
*/ */
pub trait Setters{ pub trait Setters{
fn set_margin(self, margin: MarginData) -> Self; fn set_margin(self, margin: MarginData) -> Self;
fn set_align(self, align: Alignment) -> Self; fn set_align(self, align: Alignment) -> Self;
} }
pub trait TextViewSetters{ pub trait TextViewSetters{
fn set_text_view_margin(self, margin: MarginData) -> Self; fn set_text_view_margin(self, margin: MarginData) -> Self;
} }
impl TextViewSetters for TextViewBuilder{ impl TextViewSetters for TextViewBuilder{
fn set_text_view_margin(self, margin: MarginData) -> Self{ fn set_text_view_margin(self, margin: MarginData) -> Self{
match margin{ match margin{
MarginData::EqualsMargin(margin) => MarginData::EqualsMargin(margin) =>
self.top_margin(margin) self.top_margin(margin)
.left_margin(margin) .left_margin(margin)
.bottom_margin(margin) .bottom_margin(margin)
.right_margin(margin), .right_margin(margin),
MarginData::MultipleMargin(margins) => MarginData::MultipleMargin(margins) =>
self.top_margin(margins.0) self.top_margin(margins.0)
.left_margin(margins.1) .left_margin(margins.1)
.bottom_margin(margins.2) .bottom_margin(margins.2)
.right_margin(margins.3), .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,
}
} }
} }
} }
/**
* 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,
}
}
}

View File

@ -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::*,
use crate::{ view::{
model::model::model_module::*, properties::*,
view::{ components::{
properties::properties_module::*, *,
components::{ tabs::*,
*, switch::*,
tabs::tabs_module::*, wrapper::*,
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::*,
},
} }
}; },
controller::{
pub fn laboratory_work_first_section(wrapper: &Box) -> (){ controller::*,
view_utils::input_utils::*,
// input event_handlers::{
button_event_handlers::*,
let hamming_text_view_input_label = Label::builder() switch_event_handlers::*,
.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: &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_align(Alignment::new(Align::Fill, Align::Fill))
.set_margin(MarginData::EqualsMargin(15)) .label("Очистка полей")
.spacing(10)
.build(); .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() let crypt_mode_switch = Switch::new();
.set_align(Alignment::new(Align::Fill, Align::Fill))
.set_margin(MarginData::EqualsMargin(15))
.spacing(10)
.build();
second_wrapper.append(&Label::new(Some("Код Хафмана"))); let crypt_mode_label = Label::builder()
.label("Режим: кодирование")
.build();
let notebook = Tabs::builder() // references for binding actions
.add_tabs(
vec!["Код Хэмминга", "Код Хафмана"], let clear_input_button_to_handle = clear_input_button.clone();
vec![mutual_wrapper, second_wrapper]
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") }).on_click();
.get();
let window = ApplicationWindow::builder() EventHandler::new(
.title("Комплексная программа для лаб. работ") crypt_mode_switch.clone(),
.width_request(650) move |s : &Switch| {
.height_request(400) state_controller(s, &crypt_mode_label_to_handle);
.application(application) }).on_toggle();
.child(&notebook)
.build();
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(&notebook)
.build();
window.show();
}