update ui and add some function

This commit is contained in:
Guangzong Chen 2021-09-27 00:05:02 -04:00
parent 7a9bdf7145
commit e4791d534e
No known key found for this signature in database
GPG Key ID: E3E141D720E7F9A3
4 changed files with 345 additions and 127 deletions

219
Cargo.lock generated
View File

@ -38,30 +38,6 @@ version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
[[package]]
name = "atk"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a83b21d2aa75e464db56225e1bda2dd5993311ba1095acaa8fa03d1ae67026ba"
dependencies = [
"atk-sys",
"bitflags",
"glib",
"libc",
]
[[package]]
name = "atk-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -106,7 +82,7 @@ checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80"
dependencies = [
"glib-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
@ -124,6 +100,15 @@ dependencies = [
"smallvec",
]
[[package]]
name = "cfg-expr"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edae0b9625d1fce32f7d64b71784d9b1bf8469ec1a9c417e44aaf16a9cbd7571"
dependencies = [
"smallvec",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
@ -215,22 +200,6 @@ dependencies = [
"slab",
]
[[package]]
name = "gdk"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a453eae5ec10345b3a96ca1b547328bfc94edd40aa95b08f14bb4c35863db140"
dependencies = [
"bitflags",
"cairo-rs",
"gdk-pixbuf",
"gdk-sys",
"gio",
"glib",
"libc",
"pango",
]
[[package]]
name = "gdk-pixbuf"
version = "0.14.0"
@ -253,24 +222,40 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
name = "gdk-sys"
version = "0.14.0"
name = "gdk4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e"
checksum = "4c0f7f98ad25b81ac9462f74a091b0e4c0983ed1e74d19a38230c772b4dcef81"
dependencies = [
"bitflags",
"cairo-rs",
"gdk-pixbuf",
"gdk4-sys",
"gio",
"glib",
"libc",
"pango",
]
[[package]]
name = "gdk4-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "262a79666b42e1884577f11a050439a964b95dec55343ac6ace7930e1415fa18"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"graphene-sys",
"libc",
"pango-sys",
"pkg-config",
"system-deps",
"system-deps 4.0.0",
]
[[package]]
@ -299,7 +284,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
"winapi",
]
@ -344,7 +329,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae"
dependencies = [
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
@ -355,58 +340,96 @@ checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5"
dependencies = [
"glib-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
name = "gtk"
version = "0.14.1"
name = "graphene-rs"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6603bb79ded6ac6f3bac203794383afa8b1d6a8656d34a93a88f0b22826cd46c"
checksum = "f1460a39f06e491e6112f27e71e51435c833ba370723224dd1743dfd1f201f19"
dependencies = [
"glib",
"graphene-sys",
"libc",
]
[[package]]
name = "graphene-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7d23fb7a9547e5f072a7e0cd49cd648fedeb786d122b106217511980cbb8962"
dependencies = [
"glib-sys",
"libc",
"pkg-config",
"system-deps 3.2.0",
]
[[package]]
name = "gsk4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20b71f2e2cc699c2e0fbfa22899eeaffd84f9c1dc01e9263deac8664eec22dc0"
dependencies = [
"bitflags",
"cairo-rs",
"gdk4",
"glib",
"graphene-rs",
"gsk4-sys",
"libc",
"pango",
]
[[package]]
name = "gsk4-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30468aff80e4faadf22f9ba164ea17511a69a9995d7a13827a13424ef47b2472"
dependencies = [
"cairo-sys-rs",
"gdk4-sys",
"glib-sys",
"gobject-sys",
"graphene-sys",
"libc",
"pango-sys",
"system-deps 4.0.0",
]
[[package]]
name = "gtk4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "906f9308d15789d96a736881582181d710ae0937197119df459f3d2b46ef6776"
dependencies = [
"atk",
"bitflags",
"cairo-rs",
"field-offset",
"futures-channel",
"gdk",
"gdk-pixbuf",
"gdk4",
"gio",
"glib",
"gtk-sys",
"gtk3-macros",
"graphene-rs",
"gsk4",
"gtk4-macros",
"gtk4-sys",
"libc",
"once_cell",
"pango",
"pkg-config",
]
[[package]]
name = "gtk-sys"
version = "0.14.0"
name = "gtk4-macros"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e"
dependencies = [
"atk-sys",
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pango-sys",
"system-deps",
]
[[package]]
name = "gtk3-macros"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79"
checksum = "4d0d008cdf23214c697482415dd20f666bdf3cc9f5e803b017223c17c5b59a6e"
dependencies = [
"anyhow",
"heck",
"itertools",
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
@ -414,6 +437,25 @@ dependencies = [
"syn",
]
[[package]]
name = "gtk4-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d06be0a6322aa77dd372f726e97efbcbb192d9a824a414a8874f238effd7747c"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk4-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"graphene-sys",
"gsk4-sys",
"libc",
"pango-sys",
"system-deps 4.0.0",
]
[[package]]
name = "heck"
version = "0.3.3"
@ -547,7 +589,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
@ -687,7 +729,7 @@ dependencies = [
"colored",
"gio",
"glib",
"gtk",
"gtk4",
"serialport",
]
@ -756,7 +798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6"
dependencies = [
"anyhow",
"cfg-expr",
"cfg-expr 0.8.1",
"heck",
"itertools",
"pkg-config",
@ -767,6 +809,19 @@ dependencies = [
"version-compare",
]
[[package]]
name = "system-deps"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c1889ab44c2a423ba9ba4d64cd04989b25c0280ca7ade813f05368418722a04"
dependencies = [
"cfg-expr 0.9.0",
"heck",
"pkg-config",
"toml",
"version-compare",
]
[[package]]
name = "thiserror"
version = "1.0.29"

View File

@ -14,6 +14,7 @@ colored = "2.0.0"
#futures-preview = { version = "=0.3.0-alpha.16", features = ["async-await", "nightly"] }
closure = "0.3.0"
gtk = "0.14.1"
gtk4 = "0.3.0"
glib = "0.14.5"
gio = "0.14.6"

View File

@ -7,9 +7,8 @@ use std::env;
use serialport::{SerialPort, StopBits, Parity, FlowControl, DataBits};
// use mio_serial::{StopBits, SerialStream, Parity, SerialPortBuilder, FlowControl, DataBits, SerialPort};
extern crate gtk;
extern crate glib;
extern crate gio;
// extern crate glib;
// extern crate gio;
#[derive(Copy, Clone)]
struct PortConfig {
@ -22,22 +21,6 @@ struct PortConfig {
}
use gtk::{Application, ApplicationWindow, Orientation};
use gtk::prelude::*;
// #[derive(Copy, Clone)]
// enum MessageType { UserCommand, ReceiveMessage, ErrorMessage }
//
// #[derive(Copy, Clone)]
// enum UserCommand { Open, Close, Send, Set }
//
// #[derive(Clone)]
// struct Message {
// meeesage_type: MessageType,
// content: String,
// command: UserCommand,
// args: Vec<String>,
// }
use closure::closure;
use std::time::Duration;
@ -45,10 +28,14 @@ enum Message {
UiUpdateLog(String),
UiUpdateReceiveMsg(String),
UiCleanReceiveMsg,
UiCleanLog,
UiShowLog,
UiHideLog,
MainCmdOpen(String),
MainCmdClose,
MainCmdSend(String),
MainCmdSet(Vec<String>),
PortCmdClose,
PortCmdSend(String),
@ -58,6 +45,24 @@ enum Message {
PortError(String),
}
// use gtk::pango::*;
// use gtk::gdk::Display;
// use gtk::{Application, ApplicationWindow, Orientation, CssProvider, StyleContext};
// use gtk::prelude::StyleContextExt;
// use gtk::prelude::*;
use gtk4::prelude::*;
// ::prelude::*;
// use gtk::prelude::WidgetExt;
use gtk4::{Application, ApplicationWindow, CssProvider, Entry, StyleContext, STYLE_PROVIDER_PRIORITY_APPLICATION, Orientation, ScrolledWindow, ScrollablePolicy, WrapMode};
use gtk4::gdk::Display;
// use gtk::gdk::{Display, Screen};
// use gtk::{
// Application, ApplicationWindow, Box as Box_, Button, ComboBoxText, CssProvider, Entry,
// Orientation, StyleContext, STYLE_PROVIDER_PRIORITY_APPLICATION,
// };
fn main() {
let app = Application::builder()
.application_id("org.example.HelloWorld")
@ -69,52 +74,97 @@ fn main() {
.default_height(200)
.title("hello world!")
.build();
let ui_layout_box = gtk::Box::new(Orientation::Vertical, 1);
ui_main_window.add(&ui_layout_box);
let ui_receive_view = gtk::TextView::new();
let ui_command_editor = gtk::Entry::new();
ui_layout_box.pack_start(&ui_receive_view, true, true, 5);
ui_layout_box.pack_start(&ui_command_editor, false, true, 5);
let provider = CssProvider::new();
provider.load_from_data(include_bytes!("style.css"));
// StyleContext::add_providoer_for_screen(&provider, STYLE_PROVIDER_PRIORITY_APPLICATION);
StyleContext::add_provider_for_display(
&Display::default().expect("Error initializing gtk css provider."),
// &Screen::default().expect("Error"),
&provider,
STYLE_PROVIDER_PRIORITY_APPLICATION,
);
let ui_layout_box = gtk4::Box::new(Orientation::Vertical, 1);
ui_main_window.set_child(Some(&ui_layout_box));
let ui_receive_view = gtk4::TextView::new();
let ui_command_editor = gtk4::Entry::new();
ui_command_editor.add_css_class("entry1");
ui_receive_view.set_vexpand(true);
let ui_main_scroller_window = ScrolledWindow::builder().build();
ui_main_scroller_window.set_child(Some(&ui_receive_view));
ui_receive_view.set_vscroll_policy(ScrollablePolicy::Natural);
// ui_layout_box.append(&ui_receive_view);
ui_layout_box.append(&ui_main_scroller_window);
ui_layout_box.append(&ui_command_editor);
ui_receive_view.set_editable(false);
ui_receive_view.show();
ui_command_editor.show();
ui_layout_box.show();
let ui_log_window = ApplicationWindow::builder()
.application(app)
.default_width(200)
.default_height(320)
.default_width(350)
.default_height(450)
.title("log")
.build();
ui_log_window.set_hide_on_close(true);
let ui_log_view = gtk4::TextView::new();
ui_log_view.set_can_focus(false);
ui_log_view.set_editable(false);
// ui_log_view.set_vscroll_policy(ScrollablePolicy::Natural);
ui_log_view.set_wrap_mode(WrapMode::Char);
ui_log_view.set_css_classes(&["textview1"]);
ui_log_window.set_child(Some(&ui_log_view));
let ui_log_view = gtk::TextView::new();
ui_log_view.show();
ui_log_window.add(&ui_log_view);
ui_log_window.show();
ui_main_window.show();
ui_log_view.show();
let (sender_ui_upd, receiver_ui_upd) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
let tmp_command_editor = ui_command_editor.clone();
receiver_ui_upd.attach(None, move |msg| {
match msg {
Message::UiUpdateLog(text) => {
let buf = ui_log_view.buffer().unwrap();
let buf = ui_log_view.buffer();
buf.insert(&mut buf.end_iter(), text.as_str());
// ui_log_view.scroll_to_mark(&buf.get_insert(),0.0, true,0.5,0.5);
}
Message::UiUpdateReceiveMsg(text) => {
let buf = ui_receive_view.buffer().unwrap();
let buf = ui_receive_view.buffer();
buf.insert(&mut buf.end_iter(), text.as_str());
ui_receive_view.scroll_to_mark(&buf.get_insert(),0.0, true,0.5,0.5);
}
Message::UiCleanReceiveMsg => {
let buf = ui_receive_view.buffer().unwrap();
let buf = ui_receive_view.buffer();
buf.set_text("") ;
}
Message::UiCleanLog => {
let buf = ui_log_view.buffer();
buf.set_text("");
}
Message::UiShowLog => {
ui_log_window.show();
}
Message::UiHideLog => {
ui_log_window.hide();
}
_ => {}
}
// ui_log_view.pango_context().set_font_description(&font);
glib::Continue(true)
});
let sender_ui_upd_command_editor = sender_ui_upd.clone();
let to_ui = sender_ui_upd.clone();
let (gui2main_tx, gui2main_rx) = channel::<Message>();
@ -124,23 +174,28 @@ fn main() {
let command_buf = x.buffer();
let command = command_buf.text();
command_buf.set_text("");
process_cmd(command, sender_ui_upd_command_editor.clone(), gui2main_tx.clone());
process_cmd(command, to_ui.clone(), gui2main_tx.clone());
});
ui_main_window.show();
});
app.run();
}
fn process_cmd(command: String, sender_ui_upd_command_editor: glib::Sender<Message>, gui2main_tx: Sender<Message>) {
fn process_cmd(command: String, to_ui: glib::Sender<Message>, gui2main_tx: Sender<Message>) {
let command_split: Vec<&str> = command.split_whitespace().collect();
if command_split.len() != 0 {
let cmd = command_split[0].to_ascii_lowercase();
match cmd.as_str() {
"set" => {}
"set" => {
if command_split.len() == 1 {
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
} else {
let args: Vec<String> = command_split[1..].to_vec().into_iter().map(|item| String::from(item)).collect();
gui2main_tx.send(Message::MainCmdSet(args)).unwrap();
}
}
"open" => {
if command_split.len() == 1 {
sender_ui_upd_command_editor.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
} else {
let args: Vec<String> = command_split[1..].to_vec().into_iter().map(|item| String::from(item)).collect();
gui2main_tx.send(Message::MainCmdOpen(args[0].clone())).unwrap();
@ -150,13 +205,35 @@ fn process_cmd(command: String, sender_ui_upd_command_editor: glib::Sender<Messa
gui2main_tx.send(Message::MainCmdClose).unwrap();
}
"list" => {
sender_ui_upd_command_editor.send(Message::UiUpdateLog(list_available_ports())).unwrap();
to_ui.send(Message::UiUpdateLog(list_available_ports())).unwrap();
}
"send" => {
gui2main_tx.send(Message::MainCmdSend(command[5..].parse().unwrap())).unwrap();
}
"clean" => {
sender_ui_upd_command_editor.send(Message::UiCleanReceiveMsg).unwrap();
to_ui.send(Message::UiCleanReceiveMsg).unwrap();
to_ui.send(Message::UiCleanLog).unwrap();
}
"show" => {
if command_split.len() == 1 {
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
} else {
match command_split[1] {
"log" => { to_ui.send(Message::UiShowLog).unwrap(); }
_ => {}
}
}
}
"hide" => {
if command_split.len() == 1 {
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
} else {
match command_split[1] {
"log" => { to_ui.send(Message::UiHideLog).unwrap(); }
_ => {}
}
}
}
_ => {}
}
@ -165,7 +242,7 @@ fn process_cmd(command: String, sender_ui_upd_command_editor: glib::Sender<Messa
fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::Sender<Message>) {
let (mut main2port_tx, _rx_port_receive) = channel::<Message>();
let port_default_config = PortConfig {
let mut port_default_config = PortConfig {
baud_rate: 115_200,
data_bits: DataBits::Eight,
parity: Parity::None,
@ -200,6 +277,82 @@ fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::S
Message::MainCmdSend(msg) => {
main2port_tx.send(Message::PortCmdSend(msg)).unwrap();
}
Message::MainCmdSet(args) => {
match args[0].as_str() {
"baudrate" => {
if args.len() != 2 {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
} else {
if let Ok(value) = args[1].parse::<u32>() {
port_default_config.baud_rate = value;
} else {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
}
}
}
"databit" => {
if args.len() != 2 {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
} else {
if let Ok(value) = args[1].parse::<u32>() {
match value {
8 => port_default_config.data_bits = DataBits::Eight,
7 => port_default_config.data_bits = DataBits::Seven,
6 => port_default_config.data_bits = DataBits::Six,
5 => port_default_config.data_bits = DataBits::Five,
_ => { ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(); }
}
} else {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
}
}
}
"parity" => {
if args.len() != 2 {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
} else {
if let Ok(value) = args[1].parse::<u32>() {
match value {
0 => port_default_config.parity = Parity::None,
1 => port_default_config.parity = Parity::Odd,
2 => port_default_config.parity = Parity::Even,
_ => { ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(); }
}
} else {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
}
}
}
"stopbit" => {
if args.len() != 2 {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
} else {
if let Ok(value) = args[1].parse::<u32>() {
match value {
0 => port_default_config.stopbit = StopBits::One,
1 => port_default_config.stopbit = StopBits::Two,
_ => { ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(); }
}
} else {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
}
}
}
"flowcontrol" => {
if args.len() != 2 {
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
} else {
match args[1].as_str() {
"hard" => port_default_config.flow_control = FlowControl::Hardware,
"soft" => port_default_config.flow_control = FlowControl::Software,
"none" => port_default_config.flow_control = FlowControl::None,
_ => { ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(); }
}
}
}
_ => { ui_upd.send(Message::UiUpdateLog("command does not support!\n".to_string())).unwrap(); }
}
}
Message::PortHaveData(data) => unsafe {
ui_upd.send(Message::UiUpdateReceiveMsg(String::from_utf8_unchecked(data))).unwrap();
}

9
src/style.css Normal file
View File

@ -0,0 +1,9 @@
entry.entry1 {
/*background: linear-gradient(to right, #f00, #0f0);*/
/*color: blue;*/
font-weight: bold;
font-size: 17pt;
}
textview.textview1 {
font-size: 20px;
}