This commit is contained in:
Tsuki 2024-02-26 17:18:01 +08:00
parent 6d23be91a4
commit 680425d212
7 changed files with 573 additions and 117 deletions

272
Cargo.lock generated
View File

@ -17,6 +17,15 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
@ -76,6 +85,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "bumpalo"
version = "3.15.1"
@ -94,7 +109,7 @@ version = "0.17.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"cairo-sys-rs",
"glib",
"libc",
@ -118,6 +133,9 @@ name = "cc"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730"
dependencies = [
"libc",
]
[[package]]
name = "cfg-expr"
@ -203,6 +221,15 @@ dependencies = [
"spin",
]
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "fragile"
version = "2.0.0"
@ -304,7 +331,7 @@ version = "0.17.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"gdk-pixbuf-sys",
"gio",
"glib",
@ -331,7 +358,7 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"cairo-rs",
"gdk-pixbuf",
"gdk4-sys",
@ -383,7 +410,7 @@ version = "0.17.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6973e92937cf98689b6a054a9e56c657ed4ff76de925e36fc331a15f0c5d30a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"futures-channel",
"futures-core",
"futures-io",
@ -410,13 +437,28 @@ dependencies = [
"winapi",
]
[[package]]
name = "git2"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b3ba52851e73b46a4c3df1d89343741112003f0f6f13beb0dfac9e457c3fdcd"
dependencies = [
"bitflags 2.4.2",
"libc",
"libgit2-sys",
"log",
"openssl-probe",
"openssl-sys",
"url",
]
[[package]]
name = "glib"
version = "0.17.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fad45ba8d4d2cea612b432717e834f48031cd8853c8aaf43b2c79fec8d144b"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"futures-channel",
"futures-core",
"futures-executor",
@ -504,7 +546,7 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"cairo-rs",
"gdk4",
"glib",
@ -536,7 +578,7 @@ version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b28a32a04cd75cef14a0983f8b0c669e0fe152a0a7725accdeb594e2c764c88b"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"cairo-rs",
"field-offset",
"futures-channel",
@ -645,6 +687,32 @@ dependencies = [
"cc",
]
[[package]]
name = "idna"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "idna"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "if_chain"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
[[package]]
name = "indexmap"
version = "2.2.3"
@ -682,7 +750,7 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"gdk-pixbuf",
"gdk4",
"gio",
@ -715,6 +783,46 @@ version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libgit2-sys"
version = "0.16.2+1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8"
dependencies = [
"cc",
"libc",
"libssh2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
]
[[package]]
name = "libssh2-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee"
dependencies = [
"cc",
"libc",
"libz-sys",
"openssl-sys",
"pkg-config",
"vcpkg",
]
[[package]]
name = "libz-sys"
version = "1.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "lock_api"
version = "0.4.11"
@ -807,13 +915,31 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "pango"
version = "0.17.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"gio",
"glib",
"libc",
@ -833,6 +959,12 @@ dependencies = [
"system-deps",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pin-project"
version = "1.1.4"
@ -933,6 +1065,35 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "relm4"
version = "0.6.2"
@ -977,12 +1138,16 @@ name = "rsproject"
version = "0.1.0"
dependencies = [
"chrono",
"git2",
"glib-build-tools",
"gtk4",
"lazy_static",
"libadwaita",
"regex",
"relm4",
"relm4-icons",
"tracker",
"validator",
]
[[package]]
@ -1164,6 +1329,21 @@ dependencies = [
"syn 2.0.50",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.36.0"
@ -1271,12 +1451,86 @@ dependencies = [
"syn 2.0.50",
]
[[package]]
name = "unicode-bidi"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
dependencies = [
"tinyvec",
]
[[package]]
name = "url"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [
"form_urlencoded",
"idna 0.5.0",
"percent-encoding",
]
[[package]]
name = "validator"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b92f40481c04ff1f4f61f304d61793c7b56ff76ac1469f1beb199b1445b253bd"
dependencies = [
"idna 0.4.0",
"lazy_static",
"regex",
"serde",
"serde_derive",
"serde_json",
"url",
"validator_derive",
]
[[package]]
name = "validator_derive"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc44ca3088bb3ba384d9aecf40c6a23a676ce23e09bdaca2073d99c207f864af"
dependencies = [
"if_chain",
"lazy_static",
"proc-macro-error",
"proc-macro2",
"quote",
"regex",
"syn 1.0.109",
"validator_types",
]
[[package]]
name = "validator_types"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "111abfe30072511849c5910134e8baf8dc05de4c0e5903d681cbd5c9c4d611e3"
dependencies = [
"proc-macro2",
"syn 1.0.109",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version-compare"
version = "0.1.1"

View File

@ -12,6 +12,10 @@ relm4 = { version = "0.6.2", features = ["libadwaita"]}
relm4-icons = { version = "0.6.0", features = ["add-filled"] }
chrono = "0.4.34"
tracker = "0.2.1"
git2 = "0.18.2"
validator = { version = "0.16.1",features=['derive'] }
lazy_static = "1.4.0"
regex = "1.10.3"
[build-dependencies]
glib-build-tools = "0.17.0"

View File

@ -32,3 +32,7 @@ paned>separator {
.lv {
background: transparent;
}
.error {
border: red;
}

View File

@ -1,6 +1,7 @@
use crate::components::new_project::NewPageModel;
use adw::prelude::*;
use gtk::prelude::*;
use gtk::Widget;
use relm4::actions::RelmActionGroup;
use relm4::{actions::*, prelude::*, Component, ComponentParts, ComponentSender};
use std::{
@ -12,7 +13,6 @@ use std::{
rc::Rc,
sync::{Arc, Mutex},
};
use gtk::Widget;
relm4::new_action_group!(FileActionGroup, "file");
relm4::new_stateless_action!(OpenAction, FileActionGroup, "open");
@ -20,7 +20,7 @@ pub type ElementKey = String;
#[derive(Debug)]
pub enum AppMsg {
NewProject
NewProject,
}
pub struct AppModel {
new_page_model: Controller<NewPageModel>,
@ -42,8 +42,8 @@ impl Component for AppModel {
view! {
#[root]
main_window=adw::ApplicationWindow {
set_default_width: 1200,
set_default_height: 900,
set_default_width: 900,
set_default_height: 600,
set_focus_on_click:true,
connect_close_request[sender] => move |_| {
let app = relm4::main_application();
@ -76,7 +76,6 @@ impl Component for AppModel {
set_maximum_size: 1000,
gtk::Box{
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_vexpand: true,
set_valign: gtk::Align::Center,
set_halign: gtk::Align::Center,
@ -85,11 +84,16 @@ impl Component for AppModel {
add_css_class: "h1",
set_text: "Rayshon Radar Project Tools"
},
gtk::Button {
set_icon_name: "add-filled",
connect_clicked[sender] => move |_| {
sender.input(AppMsg::NewProject);
},
gtk::Box{
set_halign: gtk::Align::Center,
gtk::Button {
set_icon_name: "add-filled",
set_hexpand: false,
set_size_request: (50, 50),
connect_clicked[sender] => move |_| {
sender.input(AppMsg::NewProject);
},
}
},
}
}

View File

@ -1,6 +1,9 @@
use crate::components::setting_item::{SettingItem, SettingType};
use crate::components::NewPageMsg::RadarEdit;
use crate::config::{CommonConfig, RadarConfig};
use adw::prelude::*;
use adw::{glib, PreferencesPage};
use gtk::ffi::gtk_content_fit_get_type;
use gtk::glib::clone;
use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt, ToggleButtonExt};
use gtk::ResponseType::No;
@ -10,8 +13,7 @@ use relm4::{prelude::*, view};
use std::cell::RefCell;
use std::path::PathBuf;
use std::rc::Rc;
use adw::PreferencesPage;
use crate::components::NewPageMsg::RadarEdit;
use validator::Validate;
#[tracker::track]
#[derive(Debug)]
@ -19,14 +21,16 @@ pub struct NewPageModel {
project_name: String,
radar_num: usize,
current_idx: usize,
radar_configs: Vec<RadarConfig>,
radar_configs: Vec<Rc<RefCell<RadarConfig>>>,
}
#[derive(Debug)]
pub enum NewPageMsg {
ChangeName(String),
ChangeRadarNum(usize),
SwitchToRadar,
CheckRadarConfig,
SwitchToRadar(usize),
SwitchToAlgorithm,
RadarEdit(usize),
}
@ -86,18 +90,14 @@ impl Component for NewPageModel {
add=&adw::EntryRow{
set_title: "Version",
},
#[name = "radar_num"]
add=&adw::SpinRow{
set_title: "Project Name",
// set_range: (0.0, 100.0),
set_adjustment: Some(&gtk::Adjustment::new(0.0, 0.0, 100.0, 1.0, 0.0, 0.0)),
set_value: model.radar_num as f64,
set_numeric: true,
connect_value_notify[sender] => move |s| {
sender.input(NewPageMsg::ChangeRadarNum(s.value() as usize));
}
},
// #[iterate]
// add: model.common_setting.to_settings().iter_mut().map(|v| v.widget()).collect::<Vec<_>>().iter()
},
add=&adw::PreferencesGroup{
add=&gtk::Grid{
@ -110,63 +110,30 @@ impl Component for NewPageModel {
attach[1,0,1,1] = &gtk::Button {
set_label: "Next",
set_halign: gtk::Align::End,
connect_clicked[sender, stack] => move |_| {
sender.input(NewPageMsg::SwitchToRadar);
stack.set_visible_child_name("Radar");
connect_clicked[sender, radar_num] => move |_| {
sender.input(NewPageMsg::ChangeRadarNum(radar_num.value() as usize));
sender.input(NewPageMsg::SwitchToRadar(0));
}
}
},
add=&gtk::Box{
set_hexpand: true,
set_halign: gtk::Align::Center,
#[name="progress"]
gtk::Box{
set_orientation: gtk::Orientation::Vertical,
gtk::ProgressBar{
set_margin_top: 30,
set_fraction:0.0
},
gtk::Grid{
set_margin_top: 10,
set_column_homogeneous: true,
add_css_class: "content",
attach[0,0,1,1] = &gtk::Label{
set_halign: gtk::Align::Start,
set_text:"0%"
},
attach[1,0,1,1] = &gtk::Label{
set_text:"Radar Config"
},
attach[2,0,1,1] = &gtk::Label{
set_halign: gtk::Align::End,
set_text:"0%"
},
}
}
}
}
}
},
algorithm_setting = gtk::Box{},
algorithm_setting = gtk::Box{
},
radar_setting=gtk::Box{
set_orientation: gtk::Orientation::Vertical,
set_valign: gtk::Align::Center,
gtk::Button{
set_label: "Add Radar",
connect_clicked[sender] => move |_| {
sender.input(NewPageMsg::RadarEdit(0));
}
},
#[name="radar_stack"]
adw::ViewStack{
}
},
stack.add_titled(&common_setting, Some("Common"), "Common"),
stack.add_titled(&radar_setting, Some("Radar"), "Radar"),
stack.add_titled(&algorithm_setting, Some("Algorithm"), "Algorithm"),
alg_page = stack.add_titled(&algorithm_setting, Some("Algorithm"), "Algorithm") -> gtk::StackPage{
set_visible: false
},
}
fn init(
init: Self::Init,
@ -178,36 +145,151 @@ impl Component for NewPageModel {
project_name: format!("Project {}", 0),
radar_num: 1,
radar_configs: Vec::new(),
current_idx:0,
current_idx: 0,
// common_setting: config,
tracker: 0,
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>, root: &Self::Root) {
fn update_with_view(
&mut self,
widgets: &mut Self::Widgets,
msg: Self::Input,
sender: ComponentSender<Self>,
root: &Self::Root,
) {
self.reset();
match msg {
NewPageMsg::ChangeName(name) => {
self.set_project_name(name);
}
NewPageMsg::ChangeRadarNum(num) => {
}
NewPageMsg::SwitchToRadar => {
let mut a = Vec::new();
for _ in 0..self.radar_num {
a.push(RadarConfig::default());
let stack = widgets.radar_stack.clone();
let config_stack = widgets.stack.clone();
let mut radar_configs = Vec::with_capacity(num);
for i in 0..num {
let config = Rc::new(RefCell::new(RadarConfig::default()));
let config_group = RadarConfig::to_preferences_entrys(config.clone());
relm4::view! {
page = adw::PreferencesPage{
add=&adw::PreferencesGroup{
add=&gtk::Grid{
set_hexpand: true,
set_column_homogeneous: true,
#[name = "label"]
attach[0,0,1,1] = &gtk::Label{
set_halign: gtk::Align::Start,
add_css_class: "h1",
set_text:"Radar",
},
attach[1,0,1,1] = &gtk::Label{
set_text: format!("{}/{}", i + 1, num).as_str(),
set_halign: gtk::Align::End,
add_css_class: "h3"
}
},
},
add=&adw::PreferencesGroup{
#[iterate]
add:config_group.iter()
},
add=&adw::PreferencesGroup{
add=&gtk::Grid{
set_hexpand: true,
set_column_homogeneous: true,
attach[0,0,1,1] = &gtk::Button {
set_label: "Prev",
set_halign: gtk::Align::Start,
set_sensitive: i != 0,
connect_clicked[sender] => move |_| {
sender.input(NewPageMsg::SwitchToRadar(i - 1));
}
},
attach[1,0,1,1] = &gtk::Button {
set_label: if i != num - 1 {"Next"}else{"Finish"},
set_halign: gtk::Align::End,
connect_clicked[sender] => move |_| {
if i != num - 1 {
sender.input(NewPageMsg::CheckRadarConfig);
sender.input(NewPageMsg::SwitchToRadar(i + 1));
} else {
sender.input(NewPageMsg::SwitchToAlgorithm);
}
}
}
}
}
}
}
config_group
.first()
.unwrap()
.bind_property("text", &label, "label")
.flags(glib::BindingFlags::DEFAULT)
.build();
widgets
.radar_stack
.add_titled(&page, Some(format!("{}", i).as_str()), "Radar");
radar_configs.push(config);
}
self.set_radar_configs(a);
self.radar_configs = radar_configs;
self.set_radar_num(num);
}
NewPageMsg::SwitchToRadar(idx) => {
if widgets.stack.visible_child_name().unwrap() != "Radar" {
widgets.stack.set_visible_child_name("Radar");
}
widgets
.radar_stack
.set_visible_child_name(format!("{}", idx).as_str());
}
NewPageMsg::RadarEdit(index) => {
let idx = self.get_current_idx();
self.set_current_idx(idx + 1);
}
NewPageMsg::CheckRadarConfig => {
let (valid, _) = self.check_radar_config();
if valid {
widgets.alg_page.set_visible(true);
} else {
widgets.alg_page.set_visible(false);
}
}
NewPageMsg::SwitchToAlgorithm => {
let (valid, un) = self.check_radar_config();
if valid {
widgets.alg_page.set_visible(true);
widgets.stack.set_visible_child_name("Algorithm");
} else {
widgets.alg_page.set_visible(false);
let idx = un.first().unwrap();
widgets.radar_stack.set_visible_child_name(format!("{}", idx).as_str());
}
}
}
self.update_view(widgets, sender);
}
}
impl NewPageModel {
fn check_radar_config(&self) -> (bool, Vec<usize>) {
let mut unvalided = Vec::new();
(
self.radar_configs.iter().enumerate().all(|(idx, x)| {
let c = x.borrow().validate().is_ok();
if !c {
unvalided.push(idx);
}
c
}),
unvalided,
)
}
}

View File

@ -1,8 +1,8 @@
use std::cell::{Cell, RefCell};
use adw::prelude::*;
use gtk::prelude::*;
use gtk::{StringList, Widget};
use relm4::{factory::FactoryView, gtk, prelude::*, FactorySender, RelmObjectExt};
use std::cell::{Cell, RefCell};
use std::rc::Rc;
#[derive(Debug)]
@ -12,9 +12,13 @@ pub enum Msg {}
pub enum OutputMsg {}
pub enum SettingType {
Select(Vec<String>, Option<Rc<RefCell<String>>>),
Select(Vec<String>, Option<Box<dyn Fn(&str)>>),
Action,
Entry(Option<String>, Option<Box<dyn Fn(&str) -> bool>>, Option<Rc<RefCell<String>>>),
Entry(
Option<String>,
Option<Box<dyn Fn(&str) -> bool>>,
Option<Box<dyn Fn(&str)>>,
),
Switch(bool, Option<Rc<Cell<bool>>>),
Spin(f64, f64, f64, f64, Option<Rc<Cell<f64>>>),
}
@ -32,9 +36,8 @@ impl SettingItem {
(match &mut self._type {
SettingType::Select(selects, selected) => {
let w = adw::ComboRow::builder().title(&self.title).build();
if let Some(selected) = selected {
let selected = selected.clone();
w.connect_selected_item_notify(|s| {
if let Some(selected) = selected.take() {
w.connect_selected_item_notify(move |s| {
// println!("{}", text);
// selected.set(text.to_string());
});
@ -60,18 +63,20 @@ impl SettingItem {
w.set_text(text);
}
let f = f.take();
let buffer = buffer.clone();
if let Some(buffer) = buffer {
if let Some(f) = f.take() {
let mut buffer = buffer.take();
w.connect_text_notify(move |s| {
let text = s.text();
if let Some(f) = f.as_ref(){
if !f(&text) {
s.set_text("");
return;
}
if !f(text.as_str()) {
s.add_css_class("error");
return;
} else {
s.remove_css_class("error");
}
if let Some(buffer) = buffer.as_ref(){
buffer(text.as_str());
}
*buffer.borrow_mut() = text.to_string();
});
}
w.upcast::<Widget>()

View File

@ -1,10 +1,21 @@
use crate::components::{SettingItem, SettingType};
use gtk::Widget;
use lazy_static::lazy_static;
use regex::Regex;
use std::cell::{Cell, Ref, RefCell};
use std::collections::HashMap;
use std::rc::Rc;
use crate::components::{SettingItem, SettingType};
use validator::{Validate, ValidateArgs, ValidationError};
lazy_static! {
static ref LOC: Regex = Regex::new(
r"^\s*(0|[1-9]\d*)(\.\d+)?\s*,\s*(0|[1-9]\d*)(\.\d+)?\s*,\s*(0|[1-9]\d*)(\.\d+)?\s*$"
)
.unwrap();
}
#[derive(Clone, Debug, Default, PartialOrd, PartialEq)]
pub struct CommonConfig{
pub struct CommonConfig {
pub name: Rc<RefCell<String>>,
pub version: Rc<RefCell<String>>,
radar_lens: Rc<Cell<f64>>,
@ -12,46 +23,138 @@ pub struct CommonConfig{
pub algorithms: Vec<AlgorithmConfig>,
}
#[derive( Clone, Debug, PartialOrd, PartialEq, Default)]
pub struct RadarConfig{
#[derive(Clone, Debug, PartialOrd, PartialEq, Default)]
pub struct _RadarConfig {
pub name: Rc<RefCell<String>>,
pub _type: Rc<RefCell<String>>,
loc: Rc<Cell<[f64;3]>>,
loc: Rc<Cell<[f64; 3]>>,
az_beam_width: Rc<Cell<f64>>,
el_beam_width: Rc<Cell<f64>>,
azs_method: Rc<Cell<usize>>,
els_method: Rc<Cell<usize>>,
r_limit: Rc<Cell<f64>>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Default, Validate)]
pub struct RadarConfig {
pub name: String,
pub _type: String,
#[validate(regex = "LOC")]
pub loc: String,
pub az_beam_width: f64,
pub el_beam_width: f64,
pub azs_method: usize,
pub els_method: usize,
pub r_limit: f64,
}
#[derive( Clone, Debug, PartialOrd, PartialEq)]
#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub struct AlgorithmConfig {
name: String,
version: String,
// info: HashMap<String, String>
}
macro_rules! to_setting {
($settings:ident,$config:ident, $(($branch:path, $name:literal, [$($check:expr);*], $func: expr)),+) => {
$(
let config = $config.clone();
$settings.push(SettingItem::new(
$name.to_string(),
$branch(
$($check,)*
Some(Box::new(move |x| $func(x, config.clone()))),
),
));
)+
};
}
impl RadarConfig {
pub fn to_settings(&self) -> Vec<SettingItem>{
pub fn to_settings(config: Rc<RefCell<RadarConfig>>) -> Vec<SettingItem> {
let mut settings = Vec::new();
settings.push(SettingItem::new("Name".to_string(), SettingType::Entry(None, None, None)));
settings.push(SettingItem::new("Type".to_string(), SettingType::Entry(None, None, None)));
settings.push(SettingItem::new("Location".to_string(), SettingType::Entry(None, None, None)));
settings.push(SettingItem::new("Azimuth Beam Width".to_string(), SettingType::Entry(None, None, None)));
settings.push(SettingItem::new("Elevation Beam Width".to_string(), SettingType::Entry(None,None,None)));
settings.push(SettingItem::new("Azimuth Method".to_string(), SettingType::Select(vec!["1".to_string(), "2".to_string(), "3".to_string()], None)));
settings.push(SettingItem::new("Elevation Method".to_string(), SettingType::Select(vec!["1".to_string(), "2".to_string(), "3".to_string()], None)));
settings.push(SettingItem::new("Range Limit".to_string(), SettingType::Entry(None,None,None)));
let a = vec!["a".to_string()];
let b = vec!["b".to_string()];
to_setting!(
settings,
config,
(
SettingType::Entry,
"Name",
[None; None],
move |x: &str, config: Rc<RefCell<RadarConfig>>| {
let mut config = config.borrow_mut();
config.name = x.to_string();
}
),
(
SettingType::Entry,
"Type",
[None; None],
move |x: &str, config: Rc<RefCell<RadarConfig>>| {
let mut config = config.borrow_mut();
config._type = x.to_string();
}
),
(
SettingType::Entry,
"Location",
[None; Some(Box::new(|x| LOC.is_match(x)))],
move |x: &str, config: Rc<RefCell<RadarConfig>>| {
let mut config = config.borrow_mut();
config.loc = x.to_string();
}
),
(
SettingType::Entry,
"Azimuth Beam Width",
[None; Some(Box::new(|x| x.parse::<f64>().is_ok()))],
move |x: &str, config: Rc<RefCell<RadarConfig>>| {
let mut config = config.borrow_mut();
config.az_beam_width = x.parse::<f64>().unwrap();
}
),
(
SettingType::Entry,
"Elevation Beam Width",
[None; Some(Box::new(|x| x.parse::<f64>().is_ok()))],
move |x: &str, config: Rc<RefCell<RadarConfig>>| {
let mut config = config.borrow_mut();
config.el_beam_width = x.parse::<f64>().unwrap();
}
),
(
SettingType::Select,
"Azimuth Method",
[a],
move |x, config: Rc<RefCell<RadarConfig>>| {
// config.borrow_mut().name.replace(x);
}
),
(
SettingType::Select,
"Elevation Method",
[b],
move |x, config: Rc<RefCell<RadarConfig>>| {
// config.borrow_mut().name.replace(x);
}
),
(
SettingType::Entry,
"Range Limit",
[None; None],
move |x, config: Rc<RefCell<RadarConfig>>| {
// config.borrow_mut().name.replace(x);
}
)
);
settings
}
pub fn to_preferences_group(&self) -> adw::PreferencesGroup {
pub fn to_preferences_entrys(config: Rc<RefCell<Self>>) -> Vec<Widget> {
use adw::prelude::*;
let group = adw::PreferencesGroup::default();
let mut settings = self.to_settings();
for setting in settings.iter_mut(){
group.add(&setting.widget());
let mut group = Vec::new();
let mut settings = Self::to_settings(config);
for setting in settings.iter_mut() {
group.push(setting.widget());
}
group