diff --git a/build.rs b/build.rs index c9e1328..18cf5fd 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,5 @@ fn main() { let config = slint_build::CompilerConfiguration::new().with_style("fluent".into()); - slint_build::compile_with_config("src/ui/app-window.slint", config) - .expect("Slint build failed"); + slint_build::compile_with_config("src/ui/app.slint", config).expect("Slint build failed"); } diff --git a/src/ui.rs b/src/ui.rs index 5481871..6308fe4 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -14,7 +14,7 @@ use std::{env, fs}; slint::include_modules!(); pub fn run_ui() -> Result<(), Box> { - let ui = AppWindow::new()?; + let app = App::new()?; let public_pem_path = default_public_pem_path(); let private_pem_path = default_private_pem_path(); @@ -29,22 +29,23 @@ pub fn run_ui() -> Result<(), Box> { } let commands_list = CommandsList::create(&get_conf_dir()); - ui.set_commands_list(ModelRc::from(Rc::new(VecModel::from(commands_list.get())))); - ui.set_private_pem_path(SharedString::from( + let globals = app.global::(); + globals.set_commands_list(ModelRc::from(Rc::new(VecModel::from(commands_list.get())))); + globals.set_private_pem_path(SharedString::from( private_pem_path.to_str().ok_or("Could not convert path to string")?, )); - ui.set_public_key(fs::read_to_string(&public_pem_path)?.into()); + globals.set_public_key(fs::read_to_string(&public_pem_path)?.into()); + globals.set_command(SharedString::from(DEFAULT_COMMAND)); + globals.set_deadline(DEFAULT_DEADLINE.to_string().into()); + globals.set_ntp(SharedString::from(NTP_SYSTEM)); - ui.set_command(SharedString::from(DEFAULT_COMMAND)); - ui.set_deadline(DEFAULT_DEADLINE.to_string().into()); - ui.set_ntp(SharedString::from(NTP_SYSTEM)); - - ui.on_add_command({ - let ui_handle = ui.as_weak(); + globals.on_add_command({ + let app_handle = app.as_weak(); let mut persistent_commands_list = CommandsList::create(&get_conf_dir()); move |cmd| { - let commands_list_rc = ui_handle.unwrap().get_commands_list(); + let binding = app_handle.unwrap(); + let commands_list_rc = binding.global::().get_commands_list(); let commands_list: &VecModel = commands_list_rc .as_any() .downcast_ref() @@ -56,11 +57,12 @@ pub fn run_ui() -> Result<(), Box> { } }); - ui.on_del_command({ - let ui_handle = ui.as_weak(); + globals.on_del_command({ + let app_handle = app.as_weak(); let mut persistent_commands_list = CommandsList::create(&get_conf_dir()); move |cmd| { - let commands_list_rc = ui_handle.unwrap().get_commands_list(); + let binding = app_handle.unwrap(); + let commands_list_rc = binding.global::().get_commands_list(); let commands_list: &VecModel = commands_list_rc .as_any() .downcast_ref() @@ -76,7 +78,7 @@ pub fn run_ui() -> Result<(), Box> { } }); - ui.on_exec_command(|cmd| { + globals.on_exec_command(|cmd| { let cmd_str = cmd.to_string(); let mut cmd_vec: Vec<&str> = cmd_str.split(" ").collect(); cmd_vec.insert(0, "ruroco"); @@ -89,7 +91,7 @@ pub fn run_ui() -> Result<(), Box> { }; }); - ui.run()?; + app.run()?; Ok(()) } diff --git a/src/ui/app-window.slint b/src/ui/app-window.slint deleted file mode 100644 index c606c47..0000000 --- a/src/ui/app-window.slint +++ /dev/null @@ -1,123 +0,0 @@ -import { Button, ComboBox, ListView, StandardTableView, GridBox, Slider, LineEdit } from "std-widgets.slint"; -import { ArgRowText, ArgRowTextInput, ArgRowIntInput, ArgRowBoolInput } from "./arg-row.slint"; -import { CommandsInput } from "commands-input.slint"; - -export component AppWindow inherits Window { - in-out property <[string]> commands_list: []; - in-out property public_key: ""; - in-out property private_pem_path: ""; - property address: ""; - in-out property command: ""; - in-out property deadline: ""; - property permissive: false; - property ip: ""; - in-out property ntp: ""; - property ipv4: false; - property ipv6: false; - - callback add_command(string); - callback exec_command(string); - callback del_command(string); - - // parent layout - VerticalLayout { - HorizontalLayout { - public_key_box := LineEdit { - height: 50px; - input-type: InputType.text; - enabled: false; - text <=> root.public_key; - } - - Button { - height: 50px; - text: "Copy Public PEM key"; - clicked => { - public_key_box.select-all(); - public_key_box.copy(); - public_key_box.clear-selection() - } - } - } - - CommandsInput { - address <=> root.address; - command <=> root.command; - deadline <=> root.deadline; - permissive <=> root.permissive; - ip <=> root.ip; - ntp <=> root.ntp; - ipv4 <=> root.ipv4; - ipv6 <=> root.ipv6; - } - - HorizontalLayout { - Rectangle { - Button { - height: 50px; - text: "Add Command"; - clicked => { - root.add_command( - "send"// - + (root.address == "" ? "" : " --address " + root.address)// - + (root.private_pem_path == "" ? "" : " --private-pem-path " + root.private_pem_path)// - + (root.command == "" ? "" : " --command " + root.command)// - + " --deadline " + root.deadline// - + (root.permissive ? "--permissive" : "")// - + (root.ip == "" ? "" : " --ip " + root.ip)// - + (root.ntp == "" ? "" : " --ntp " + root.ntp)// - + (root.ipv4 ? " --ipv4" : "")// - + (root.ipv6 ? " --ipv6" : "")// - ) - } - } - } - } - - // saved commands list - VerticalLayout { - Text { - height: 50px; - text: "Saved Commands:"; - overflow: TextOverflow.clip; - horizontal-alignment: TextHorizontalAlignment.center; - vertical-alignment: TextVerticalAlignment.center; - } - - ListView { - - for text in commands_list: HorizontalLayout { - Button { - height: 50px; - width: 50px; - text: "▶"; - clicked => { - root.exec_command(text) - } - } - - Rectangle { - horizontal-stretch: 1.0; - Text { - x: 10px; - width: parent.width - self.x; - horizontal-alignment: TextHorizontalAlignment.left; - vertical-alignment: TextVerticalAlignment.center; - text: text; - overflow: TextOverflow.elide; - } - } - - Button { - height: 50px; - width: 50px; - text: "🗑"; - clicked => { - root.del_command(text) - } - } - } - } - } - } -} diff --git a/src/ui/app.slint b/src/ui/app.slint new file mode 100644 index 0000000..697f3ad --- /dev/null +++ b/src/ui/app.slint @@ -0,0 +1,30 @@ +import { TabWidget } from "std-widgets.slint"; +import { Create } from "create.slint"; +import { CommandLogic } from "command-logic.slint"; +import { PublicKey } from "public-key.slint"; +import { Execute } from "execute.slint"; + +export component App inherits Window { + title: "ruroco"; + preferred-height: 1200px; + preferred-width: 540px; + + TabWidget { + Tab { + title: "Public PEM key"; + PublicKey { } + } + + Tab { + title: "Create"; + Create { } + } + + Tab { + title: "Execute"; + Execute { } + } + } +} + +export { CommandLogic } \ No newline at end of file diff --git a/src/ui/command-logic.slint b/src/ui/command-logic.slint new file mode 100644 index 0000000..ad64cc4 --- /dev/null +++ b/src/ui/command-logic.slint @@ -0,0 +1,11 @@ +export global CommandLogic { + in-out property <[string]> commands_list: []; + in-out property public_key: ""; + in-out property private_pem_path: ""; + in-out property command: ""; + in-out property deadline: ""; + in-out property ntp: ""; + callback add_command(string); + callback exec_command(string); + callback del_command(string); +} diff --git a/src/ui/commands-input.slint b/src/ui/commands-input.slint deleted file mode 100644 index fd1e37e..0000000 --- a/src/ui/commands-input.slint +++ /dev/null @@ -1,109 +0,0 @@ -import { Button, ComboBox, ListView, StandardTableView, GridBox, Slider } from "std-widgets.slint"; -import { ArgRowText, ArgRowTextInput, ArgRowIntInput, ArgRowBoolInput } from "./arg-row.slint"; - -export component CommandsInput inherits VerticalLayout { - in-out property address: ""; - in-out property command: ""; - in-out property deadline: ""; - in-out property permissive: false; - in-out property ip: ""; - in-out property ntp: ""; - in-out property ipv4: false; - in-out property ipv6: false; - height: 60%; - - Flickable { - VerticalLayout { - padding-left: 10px; - padding-right: 10px; - - HorizontalLayout { - padding-bottom: 10px; - ArgRowText { - text: "address"; - } - - ArgRowTextInput { - input <=> root.address; - } - } - - HorizontalLayout { - padding-bottom: 10px; - ArgRowText { - text: "command"; - } - - ArgRowTextInput { - input <=> root.command; - } - } - - HorizontalLayout { - padding-bottom: 10px; - ArgRowText { - text: "deadline"; - } - - ArgRowTextInput { - input <=> root.deadline; - } - } - - HorizontalLayout { - padding-bottom: 10px; - ArgRowText { - text: "permissive"; - } - - ArgRowBoolInput { - input <=> root.permissive; - } - } - - HorizontalLayout { - padding-bottom: 10px; - ArgRowText { - text: "ip"; - } - - ArgRowTextInput { - input <=> root.ip; - } - } - - HorizontalLayout { - padding-bottom: 10px; - ArgRowText { - text: "ntp"; - } - - ArgRowTextInput { - input <=> root.ntp; - } - } - - HorizontalLayout { - padding-bottom: 10px; - ArgRowText { - text: "ipv4"; - } - - ArgRowBoolInput { - input <=> root.ipv4; - } - } - - HorizontalLayout { - padding-bottom: 10px; - ArgRowText { - text: "ipv6"; - } - - ArgRowBoolInput { - input <=> root.ipv6; - } - } - } - } -} diff --git a/src/ui/create.slint b/src/ui/create.slint new file mode 100644 index 0000000..bdd4f6e --- /dev/null +++ b/src/ui/create.slint @@ -0,0 +1,137 @@ +import { Button } from "std-widgets.slint"; +import { ArgRowText, ArgRowTextInput, ArgRowBoolInput } from "./arg-row.slint"; +import { CommandLogic } from "command-logic.slint"; + +export component Create inherits VerticalLayout { + property address: ""; + property permissive: false; + property ip: ""; + property ipv4: false; + property ipv6: false; + + Flickable { + VerticalLayout { + padding-left: 10px; + padding-right: 10px; + + HorizontalLayout { + padding-bottom: 10px; + ArgRowText { + text: "address"; + } + + ArgRowTextInput { + input <=> root.address; + } + } + + HorizontalLayout { + padding-bottom: 10px; + ArgRowText { + text: "command"; + } + + ArgRowTextInput { + input <=> CommandLogic.command; + } + } + + HorizontalLayout { + padding-bottom: 10px; + ArgRowText { + text: "deadline"; + } + + ArgRowTextInput { + input <=> CommandLogic.deadline; + } + } + + HorizontalLayout { + padding-bottom: 10px; + ArgRowText { + text: "ip"; + } + + ArgRowTextInput { + input <=> root.ip; + } + } + + HorizontalLayout { + padding-bottom: 10px; + ArgRowText { + text: "ntp"; + } + + ArgRowTextInput { + input <=> CommandLogic.ntp; + } + } + + HorizontalLayout { + padding-bottom: 10px; + VerticalLayout { + height: 50px; + padding-right: 10px; + ArgRowText { + text: "permissive"; + } + + ArgRowBoolInput { + input <=> root.permissive; + } + } + + VerticalLayout { + height: 50px; + padding-right: 10px; + ArgRowText { + text: "ipv4"; + } + + ArgRowBoolInput { + input <=> root.ipv4; + } + } + + VerticalLayout { + height: 50px; + padding-right: 10px; + ArgRowText { + text: "ipv6"; + } + + ArgRowBoolInput { + input <=> root.ipv6; + } + } + } + + Rectangle { + vertical-stretch: 2; + } + + HorizontalLayout { + Button { + height: 50px; + text: "Add Command"; + clicked => { + CommandLogic.add_command( + "send"// + + (root.address == "" ? "" : " --address " + root.address)// + + (CommandLogic.private_pem_path == "" ? "" : " --private-pem-path " + CommandLogic.private_pem_path)// + + (CommandLogic.command == "" ? "" : " --command " + CommandLogic.command)// + + " --deadline " + CommandLogic.deadline// + + (root.permissive ? "--permissive" : "")// + + (root.ip == "" ? "" : " --ip " + root.ip)// + + (CommandLogic.ntp == "" ? "" : " --ntp " + CommandLogic.ntp)// + + (root.ipv4 ? " --ipv4" : "")// + + (root.ipv6 ? " --ipv6" : "")// + ) + } + } + } + } + } +} diff --git a/src/ui/execute.slint b/src/ui/execute.slint new file mode 100644 index 0000000..165bad6 --- /dev/null +++ b/src/ui/execute.slint @@ -0,0 +1,39 @@ +import { Button, ListView } from "std-widgets.slint"; +import { CommandLogic } from "command-logic.slint"; + +export component Execute inherits VerticalLayout { + ListView { + + for text in CommandLogic.commands_list: HorizontalLayout { + Button { + height: 50px; + width: 50px; + text: "▶"; + clicked => { + CommandLogic.exec_command(text) + } + } + + Rectangle { + horizontal-stretch: 1.0; + Text { + x: 10px; + width: parent.width - self.x; + horizontal-alignment: TextHorizontalAlignment.left; + vertical-alignment: TextVerticalAlignment.center; + text: text; + overflow: TextOverflow.elide; + } + } + + Button { + height: 50px; + width: 50px; + text: "🗑"; + clicked => { + CommandLogic.del_command(text) + } + } + } + } +} diff --git a/src/ui/public-key.slint b/src/ui/public-key.slint new file mode 100644 index 0000000..9374add --- /dev/null +++ b/src/ui/public-key.slint @@ -0,0 +1,22 @@ +import { Button, TextEdit } from "std-widgets.slint"; +import { CommandLogic } from "command-logic.slint"; + +export component PublicKey inherits HorizontalLayout { + Button { + height: 100%; + width: 50%; + text: "⎘"; + clicked => { + public_key_box.select-all(); + public_key_box.copy(); + public_key_box.clear-selection() + } + } + + public_key_box := TextEdit { + height: 100%; + width: 50%; + enabled: false; + text <=> CommandLogic.public_key; + } +}