Fully refactored project architecture, imports and etc.

This commit is contained in:
doryan04 2024-03-10 12:35:02 +04:00
parent 55b2c4ec56
commit 54619cd3f9
31 changed files with 923 additions and 762 deletions

238
Cargo.lock generated
View File

@ -64,23 +64,22 @@ dependencies = [
[[package]]
name = "cairo-rs"
version = "0.18.3"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f33613627f0dea6a731b0605101fad59ba4f193a52c96c4687728d822605a8a1"
checksum = "2650f66005301bd33cc486dec076e1293c4cecf768bc7ba9bf5d2b1be339b99c"
dependencies = [
"bitflags",
"cairo-sys-rs",
"glib",
"libc",
"once_cell",
"thiserror",
]
[[package]]
name = "cairo-sys-rs"
version = "0.18.2"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51"
checksum = "fd3bb3119664efbd78b5e6c93957447944f16bdbced84c17a9f41c7829b81e64"
dependencies = [
"glib-sys",
"libc",
@ -199,22 +198,21 @@ dependencies = [
[[package]]
name = "gdk-pixbuf"
version = "0.18.3"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "446f32b74d22c33b7b258d4af4ffde53c2bf96ca2e29abdf1a785fe59bd6c82c"
checksum = "f6a23f8a0b5090494fd04924662d463f8386cc678dd3915015a838c1a3679b92"
dependencies = [
"gdk-pixbuf-sys",
"gio",
"glib",
"libc",
"once_cell",
]
[[package]]
name = "gdk-pixbuf-sys"
version = "0.18.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7"
checksum = "3dcbd04c1b2c4834cc008b4828bc917d062483b88d26effde6342e5622028f96"
dependencies = [
"gio-sys",
"glib-sys",
@ -225,9 +223,9 @@ dependencies = [
[[package]]
name = "gdk4"
version = "0.7.3"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edb019ad581f8ecf8ea8e4baa6df7c483a95b5a59be3140be6a9c3b0c632af6"
checksum = "9100b25604183f2fd97f55ef087fae96ab4934d7215118a35303e422688e6e4b"
dependencies = [
"cairo-rs",
"gdk-pixbuf",
@ -240,9 +238,9 @@ dependencies = [
[[package]]
name = "gdk4-sys"
version = "0.7.2"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbab43f332a3cf1df9974da690b5bb0e26720ed09a228178ce52175372dcfef0"
checksum = "d0b76874c40bb8d1c7d03a7231e23ac75fa577a456cd53af32ec17ec8f121626"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@ -263,9 +261,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]]
name = "gio"
version = "0.18.3"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47d809baf02bdf1b5ef4ad3bf60dd9d4977149db4612b7bbb58e56aef168193b"
checksum = "2eae10b27b6dd27e22ed0d812c6387deba295e6fc004a8b379e459b663b05a02"
dependencies = [
"futures-channel",
"futures-core",
@ -274,7 +272,6 @@ dependencies = [
"gio-sys",
"glib",
"libc",
"once_cell",
"pin-project-lite",
"smallvec",
"thiserror",
@ -282,22 +279,22 @@ dependencies = [
[[package]]
name = "gio-sys"
version = "0.18.1"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2"
checksum = "bcf8e1d9219bb294636753d307b030c1e8a032062cba74f493c431a5c8b81ce4"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"winapi",
"windows-sys",
]
[[package]]
name = "glib"
version = "0.18.3"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58cf801b6f7829fa76db37449ab67c9c98a2b1bf21076d9113225621e61a0fa6"
checksum = "ab9e86540b5d8402e905ad4ce7d6aa544092131ab564f3102175af176b90a053"
dependencies = [
"bitflags",
"futures-channel",
@ -311,20 +308,18 @@ dependencies = [
"gobject-sys",
"libc",
"memchr",
"once_cell",
"smallvec",
"thiserror",
]
[[package]]
name = "glib-macros"
version = "0.18.3"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72793962ceece3863c2965d7f10c8786323b17c7adea75a515809fa20ab799a5"
checksum = "0f5897ca27a83e4cdc7b4666850bade0a2e73e17689aabafcc9acddad9d823b8"
dependencies = [
"heck",
"proc-macro-crate 2.0.0",
"proc-macro-error",
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.39",
@ -332,9 +327,9 @@ dependencies = [
[[package]]
name = "glib-sys"
version = "0.18.1"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898"
checksum = "630f097773d7c7a0bb3258df4e8157b47dc98bbfa0e60ad9ab56174813feced4"
dependencies = [
"libc",
"system-deps",
@ -342,9 +337,9 @@ dependencies = [
[[package]]
name = "gobject-sys"
version = "0.18.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44"
checksum = "c85e2b1080b9418dd0c58b498da3a5c826030343e0ef07bde6a955d28de54979"
dependencies = [
"glib-sys",
"libc",
@ -353,9 +348,9 @@ dependencies = [
[[package]]
name = "graphene-rs"
version = "0.18.1"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2228cda1505613a7a956cca69076892cfbda84fc2b7a62b94a41a272c0c401"
checksum = "99e4d388e96c5f29e2b2f67045d229ddf826d0a8d6d282f94ed3b34452222c91"
dependencies = [
"glib",
"graphene-sys",
@ -364,9 +359,9 @@ dependencies = [
[[package]]
name = "graphene-sys"
version = "0.18.1"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc4144cee8fc8788f2a9b73dc5f1d4e1189d1f95305c4cb7bd9c1af1cfa31f59"
checksum = "236ed66cc9b18d8adf233716f75de803d0bf6fc806f60d14d948974a12e240d0"
dependencies = [
"glib-sys",
"libc",
@ -376,9 +371,9 @@ dependencies = [
[[package]]
name = "gsk4"
version = "0.7.3"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d958e351d2f210309b32d081c832d7de0aca0b077aa10d88336c6379bd01f7e"
checksum = "c65036fc8f99579e8cb37b12487969b707ab23ec8ab953682ff347cbd15d396e"
dependencies = [
"cairo-rs",
"gdk4",
@ -391,9 +386,9 @@ dependencies = [
[[package]]
name = "gsk4-sys"
version = "0.7.3"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12bd9e3effea989f020e8f1ff3fa3b8c63ba93d43b899c11a118868853a56d55"
checksum = "bd24c814379f9c3199dc53e52253ee8d0f657eae389ab282c330505289d24738"
dependencies = [
"cairo-sys-rs",
"gdk4-sys",
@ -407,9 +402,9 @@ dependencies = [
[[package]]
name = "gtk4"
version = "0.7.3"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aeb51aa3e9728575a053e1f43543cd9992ac2477e1b186ad824fd4adfb70842"
checksum = "aa82753b8c26277e4af1446c70e35b19aad4fb794a7b143859e7eeb9a4025d83"
dependencies = [
"cairo-rs",
"field-offset",
@ -428,12 +423,12 @@ dependencies = [
[[package]]
name = "gtk4-macros"
version = "0.7.2"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d57ec49cf9b657f69a05bca8027cff0a8dfd0c49e812be026fc7311f2163832f"
checksum = "40300bf071d2fcd4c94eacc09e84ec6fe73129d2ceb635cf7e55b026b5443567"
dependencies = [
"anyhow",
"proc-macro-crate 1.3.1",
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
"quote",
@ -442,9 +437,9 @@ dependencies = [
[[package]]
name = "gtk4-sys"
version = "0.7.3"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54d8c4aa23638ce9faa2caf7e2a27d4a1295af2155c8e8d28c4d4eeca7a65eb8"
checksum = "0db1b104138f087ccdc81d2c332de5dd049b89de3d384437cc1093b17cd2da18"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@ -487,6 +482,15 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "laboratory_works"
version = "0.1.0"
dependencies = [
"bitvec",
"gtk4",
"tokio",
]
[[package]]
name = "libc"
version = "0.2.150"
@ -495,9 +499,9 @@ checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "memchr"
version = "2.6.4"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "memoffset"
@ -536,30 +540,23 @@ dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "pango"
version = "0.18.3"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4"
checksum = "7809e8af4df8d024a066106b72ca6bc7253a484ae3867041a96103ef8a13188d"
dependencies = [
"gio",
"glib",
"libc",
"once_cell",
"pango-sys",
]
[[package]]
name = "pango-sys"
version = "0.18.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5"
checksum = "f52ef6a881c19fbfe3b1484df5cad411acaaba29dbec843941c3110d19f340ea"
dependencies = [
"glib-sys",
"gobject-sys",
@ -581,27 +578,17 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.27"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
dependencies = [
"once_cell",
"toml_edit 0.19.15",
]
[[package]]
name = "proc-macro-crate"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
dependencies = [
"toml_edit 0.20.7",
"toml_edit",
]
[[package]]
@ -713,9 +700,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.2"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "syn"
@ -816,7 +803,7 @@ dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.21.0",
"toml_edit",
]
[[package]]
@ -828,28 +815,6 @@ dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
]
[[package]]
name = "toml_edit"
version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
]
[[package]]
name = "toml_edit"
version = "0.21.0"
@ -869,15 +834,6 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "untitled"
version = "0.1.0"
dependencies = [
"bitvec",
"gtk4",
"tokio",
]
[[package]]
name = "version-compare"
version = "0.1.1"
@ -891,26 +847,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "winapi"
version = "0.3.9"
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
"windows-targets",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]]
name = "winnow"

View File

@ -1,5 +1,5 @@
[package]
name = "untitled"
name = "laboratory_works"
version = "0.1.0"
edition = "2021"
@ -7,5 +7,5 @@ edition = "2021"
[dependencies]
bitvec = "1.0.1"
gtk4 = "0.7.3"
gtk4 = "0.8.1"
tokio = { version = "1.0.0", features = ["rt", "rt-multi-thread", "macros"] }

View File

@ -1,47 +0,0 @@
use gtk4 as gtk;
use gtk::prelude::*;
use super::switch::*;
pub struct EventHandler<F, C>{
component: C,
callback: F,
}
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{
fn on_click(self) -> ();
}
pub trait SwEventHandler{
fn on_toggle(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> SwEventHandler for EventHandler<F, C>
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)
});
}
}

View File

@ -0,0 +1,34 @@
pub mod button_event_handlers_module{
use crate::{
model::model::model_module::*,
gtk::{
*,
prelude::*
},
};
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{
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)
});
}
}
}

View File

@ -0,0 +1,2 @@
pub mod button_event_handlers;
pub mod switch_event_handlers;

View File

@ -0,0 +1,30 @@
pub mod switch_event_handlers_module{
use crate::{
model::model::model_module::*,
view::components::switch::switch_module::SwitchExt,
gtk::{
*,
prelude::*
},
};
pub trait SwEventHandler{
fn on_toggle(self) -> ();
}
impl<F, C> SwEventHandler for EventHandler<F, C>
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("");
}
}

4
src/controller/mod.rs Normal file
View File

@ -0,0 +1,4 @@
pub mod controller;
pub mod view_utils;
pub mod model_utils;
pub mod event_handlers;

View File

@ -1,16 +1,62 @@
// ошибочная позиция 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 mod hamming_code{
use std::borrow::Borrow;
use std::collections::HashMap;
pub fn hamming_encrypt_data(data: &Vec<u8>, result_string: &mut String, length_of_code: usize) -> () {
use std::{borrow::Borrow, collections::HashMap};
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>{
let length_of_code : usize = mode.clone() as usize;
let prepared_input : String = processing_input(&raw_input);
let (fc, sc) = check_correct_input(&raw_input, &prepared_input, length_of_code);
if !fc || !sc {
Err("Ошибка. Проверьте корректность ввода.".to_string())
} else {
let mut data : String = String::new();
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);
}
}
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(){
@ -31,7 +77,12 @@ pub mod hamming_code{
}
}
pub fn hamming_decrypt_data(data: &Vec<u8>, result_string: &mut String, length_of_code: usize) -> () {
pub fn hamming_decrypt_data(
data: &Vec<u8>,
result_string: &mut String,
length_of_code: usize
) {
let mut i : usize = length_of_code;
let syndromes : HashMap<usize, (bool, bool, bool)> = HashMap::from(
@ -102,5 +153,7 @@ pub mod hamming_code{
} else {
result_string.push_str(errors.as_str())
}
}
}

View File

@ -0,0 +1 @@
pub mod hamming_code_seven_four;

View File

@ -0,0 +1,72 @@
pub mod input_utils_module {
use gtk4 as gtk;
use std::ops::Deref;
use gtk::{*, prelude::*};
use bitvec::{order::Lsb0, view::AsBits};
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
};
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 check_correct_input(input: &String, prepared_input: &String, l: usize) -> (bool, bool){
let first_condition = input
.chars()
.all(|c| {c == '1' || c == '0' || c == ' '});
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
.as_bits::<Lsb0>()
.iter()
.step_by(8)
.map(|x| *x.deref() as u8)
.collect()
}
}

View File

@ -0,0 +1 @@
pub mod input_utils;

View File

@ -1,29 +1,21 @@
extern crate core;
use gtk4 as gtk;
use gtk::*;
use view::*;
use gtk::prelude::*;
#[path="ui_src/components/switch.rs"]
mod switch;
#[path="ui_src/components/wrapper.rs"]
mod wrapper;
#[path="ui_src/properties.rs"]
mod properties;
#[path="utils/parse_input.rs"]
mod parse_input;
#[path="utils/state_controller.rs"]
mod state_controller;
mod view;
use view::view::view_module::*;
mod model;
mod controller;
use controller::*;
fn main() {
let app = Application::builder()
.application_id("com.github.gtk-rs.examples.basic")
.build();

View File

@ -1,61 +0,0 @@
use std::ops::Deref;
use bitvec::prelude::{AsBits};
use crate::model::processing_input::processing_input;
use crate::model::check_correct_input::check_correct_input;
use crate::model::from_string_to_vec_bits::from_string_to_vec_bits;
use crate::model::hamming_code::hamming_code::hamming_decrypt_data;
use crate::model::hamming_code::hamming_code::hamming_encrypt_data;
#[path="utils/model_utils/processing_input.rs"]
mod processing_input;
#[path="utils/model_utils/check_correct_input.rs"]
mod check_correct_input;
#[path="utils/model_utils/from_string_to_vec_bits.rs"]
mod from_string_to_vec_bits;
#[path="utils/hamming_code_utils/hamming_code_seven_four.rs"]
mod hamming_code;
pub enum HammingMode{
Encrypt,
Decrypt
}
// ошибочная позиция 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 = if let HammingMode::Encrypt = mode { 4 } else { 7 };
let prepared_input : String = processing_input(&raw_input);
let (fc, sc) = check_correct_input(&raw_input, &prepared_input, length_of_code);
if !fc || !sc {
Err("Ошибка. Проверьте корректность ввода.".to_string())
} else {
let mut data : String = String::new();
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);
}
}

1
src/model/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod model;

16
src/model/model.rs Normal file
View File

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

View File

@ -1,152 +0,0 @@
use gtk4 as gtk;
use gtk::*;
use gtk::prelude::*;
use glib::{
signal::{connect_raw, SignalHandlerId},
translate::*,
};
use std::boxed::Box as Box_;
mod wrapper;
mod sealed {
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 {}

View File

@ -1,20 +0,0 @@
use gtk4 as gtk;
use gtk::Orientation;
use gtk::builders::BoxBuilder;
use gtk::Box;
#[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)
}
}

View File

@ -1,118 +0,0 @@
use gtk4 as gtk;
use gtk::{Align};
use gtk::builders::*;
/**
* Types
*/
pub type Margin = (i32, i32, i32, i32);
/**
* Enums
*/
pub enum MarginData{
EqualsMargin(i32),
MultipleMargin(Margin),
}
/**
* Structs
*/
#[allow(dead_code)]
pub struct Size {
pub width: i32,
pub height: i32
}
pub struct Alignment {
pub horizontal: Align,
pub vertical : Align
}
/**
* Traits
*/
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;
}
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,
}
}
}

View File

@ -1,11 +0,0 @@
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 == ' '});
let second_condition = prepared_input.len() % l == 0;
(first_condition, second_condition)
}

View File

@ -1,14 +0,0 @@
use std::ops::Deref;
use bitvec::order::Lsb0;
use bitvec::prelude::AsBits;
pub fn from_string_to_vec_bits(raw_data: String) -> Vec<u8>{
raw_data
.as_bits::<Lsb0>()
.iter()
.step_by(8)
.map(|x| *x.deref() as u8)
.collect()
}

View File

@ -1,10 +0,0 @@
pub fn processing_input(input : &String) -> String {
input
.split_ascii_whitespace()
.filter(|&x| {
x != ""
})
.fold(String::new(), |c: String, n: &str| { c + n })
}

View File

@ -1,29 +0,0 @@
use gtk4 as gtk;
use gtk::*;
use gtk::prelude::*;
use super::model::*;
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()),
}
}

View File

@ -1,151 +0,0 @@
use gtk4 as gtk;
use gtk::*;
use gtk::prelude::*;
use super::wrapper::*;
use super::controller::*;
use super::parse_input::parse_input;
use super::state_controller::state_controller;
use super::properties::{MarginData, Setters, TextViewSetters, Alignment};
fn clearing(output : &TextView, input: &TextView){
input.buffer().set_text("");
output.buffer().set_text("");
}
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 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 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();
// actions
EventHandler::new(
hamming_crypt_button.clone(),
move |_| {
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| {
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();
// separators
let separator = Separator::builder()
.orientation(Orientation::Horizontal)
.build();
crypt_mode_wrapper.append(&crypt_mode_switch);
crypt_mode_wrapper.append(&crypt_mode_label);
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);
wrapper.append(&separator);
}
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 window = ApplicationWindow::builder()
.title("Комплексная программа для лаб. работ")
.width_request(650)
.height_request(400)
.application(application)
.child(&mutual_wrapper)
.build();
window.show();
}

View File

@ -0,0 +1,3 @@
pub mod wrapper;
pub mod switch;
pub mod tabs;

View File

@ -0,0 +1,153 @@
pub mod switch_module {
use gtk4 as gtk;
use gtk::{*, prelude::*};
use glib::{
signal::{connect_raw, SignalHandlerId},
translate::*,
};
use std::boxed::Box as Box_;
mod sealed {
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 {}
}

View File

@ -0,0 +1,71 @@
pub mod tabs_module {
use gtk4 as gtk;
use gtk::{Notebook, Label, Box};
pub type TabLabel = Label;
pub type TabContent = Box;
#[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 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));
}
pub fn add_tab(mut self, label: &str, page: TabContent) -> Self {
self.append_tab_private(label, page);
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
}
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

@ -0,0 +1,23 @@
pub mod wrapper_module {
use gtk4 as gtk;
use gtk::{Orientation, builders::BoxBuilder, Box};
#[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)
}
}
}

3
src/view/mod.rs Normal file
View File

@ -0,0 +1,3 @@
pub mod view;
pub mod components;
pub mod properties;

120
src/view/properties.rs Normal file
View File

@ -0,0 +1,120 @@
pub mod properties_module{
use gtk4 as gtk;
use gtk::{Align};
use gtk::builders::*;
/**
* Types
*/
pub type Margin = (i32, i32, i32, i32);
/**
* Enums
*/
pub enum MarginData{
EqualsMargin(i32),
MultipleMargin(Margin),
}
/**
* Structs
*/
#[allow(dead_code)]
pub struct Size {
pub width: i32,
pub height: i32
}
pub struct Alignment {
pub horizontal: Align,
pub vertical : Align
}
/**
* Traits
*/
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;
}
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,
}
}
}
}

195
src/view/view.rs Normal file
View File

@ -0,0 +1,195 @@
pub mod view_module{
use gtk4 as gtk;
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::*,
},
}
};
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: &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();
}
}