Fiddle around with UI
This commit is contained in:
parent
87caba2b33
commit
68b12d553b
56
Cargo.lock
generated
56
Cargo.lock
generated
@ -79,6 +79,12 @@ dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
@ -187,6 +193,12 @@ version = "0.2.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
@ -219,6 +231,30 @@ dependencies = [
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-windows-derive"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c39357a029a532c887fb1596e0f0498613d8dd119549d400569d61c048145ac6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-windows-gui"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6212fbf8ec1f512dffe75155513c017e1d05b5ecd08e03d3ebf4be07bd9f28b1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"lazy_static",
|
||||
"stretch",
|
||||
"winapi",
|
||||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.43"
|
||||
@ -355,6 +391,16 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "stretch"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b0dc6d20ce137f302edf90f9cd3d278866fd7fb139efca6f246161222ad6d87"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.39"
|
||||
@ -373,7 +419,10 @@ dependencies = [
|
||||
"argh",
|
||||
"geo-types",
|
||||
"gpx",
|
||||
"native-windows-derive",
|
||||
"native-windows-gui",
|
||||
"thingy-lib",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -383,7 +432,6 @@ dependencies = [
|
||||
"chrono",
|
||||
"minreq",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -516,6 +564,12 @@ dependencies = [
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
@ -9,6 +9,11 @@ argh = "0.1"
|
||||
gpx = "0.8"
|
||||
geo-types = "*"
|
||||
thingy-lib = { path = "./thingy_lib/" }
|
||||
toml = "0.5"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
native-windows-gui = "1.0"
|
||||
native-windows-derive = "1.0"
|
||||
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
rustflags = ["-Ctarget-feature=+crt-static"]
|
||||
|
@ -1,14 +1,16 @@
|
||||
use super::args::*;
|
||||
pub mod args;
|
||||
|
||||
use super::errors::GenericError;
|
||||
use super::gpx;
|
||||
use super::{config_from_path, gpx, write_to};
|
||||
use args::*;
|
||||
use thingy_lib::api::API;
|
||||
use thingy_lib::chrono::NaiveDateTime;
|
||||
use thingy_lib::{try_get_datetime, Config, MessagedError};
|
||||
use thingy_lib::{try_get_datetime, MessagedError};
|
||||
|
||||
pub fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
match env.subcommand.unwrap() {
|
||||
Subcommand::Between(opt) => {
|
||||
let config = Config::from_path(&env.config)?;
|
||||
let config = config_from_path(&env.config)?;
|
||||
let mut api = API::new(config.clone());
|
||||
|
||||
let since =
|
||||
@ -33,11 +35,12 @@ pub fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
Ok(())
|
||||
}
|
||||
Subcommand::Init(opt) => {
|
||||
thingy_lib::init(&env.config, opt.api_key)?;
|
||||
let config = thingy_lib::init(opt.api_key)?;
|
||||
write_to(&config, &env.config)?;
|
||||
Ok(())
|
||||
}
|
||||
Subcommand::Api(_) => {
|
||||
let config = Config::from_path(&env.config)?;
|
||||
let config = config_from_path(&env.config)?;
|
||||
let api = API::new(config.clone());
|
||||
match thingy_lib::check_api(&api) {
|
||||
Ok(_) => {
|
||||
@ -51,13 +54,13 @@ pub fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
}
|
||||
}
|
||||
Subcommand::ShareToken(opt) => {
|
||||
let config = Config::from_path(&env.config)?;
|
||||
let config = config_from_path(&env.config)?;
|
||||
let api = API::new(config.clone());
|
||||
println!("{}", thingy_lib::sharetoken(&api, opt.device)?);
|
||||
Ok(())
|
||||
}
|
||||
Subcommand::Nick(opt) => {
|
||||
let config = Config::from_path(&env.config)?;
|
||||
let config = config_from_path(&env.config)?;
|
||||
let mut api = API::new(config.clone());
|
||||
|
||||
match opt.subcommand {
|
||||
@ -68,7 +71,7 @@ pub fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
}
|
||||
NickSub::Set(opt) => {
|
||||
thingy_lib::nick_set(&mut api, opt.device, opt.nickname)?;
|
||||
api.config.write_to(&env.config)?;
|
||||
write_to(&api.config, &env.config)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -76,7 +79,7 @@ pub fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
Subcommand::Get(opt) => {
|
||||
let config = Config::from_path(&env.config)?;
|
||||
let config = config_from_path(&env.config)?;
|
||||
let api = API::new(config.clone());
|
||||
match opt.subcommand {
|
||||
GetSub::Tag(opt) => {
|
@ -4,6 +4,9 @@ use std::fmt::{Display, Formatter};
|
||||
pub enum GenericError {
|
||||
ThingyLibError(thingy_lib::Error),
|
||||
GPXError(gpx::errors::Error),
|
||||
NWGError(nwg::NwgError),
|
||||
IOError(std::io::Error),
|
||||
TOMLError(toml::de::Error),
|
||||
MessagedError(String, Option<Box<GenericError>>),
|
||||
}
|
||||
|
||||
@ -19,11 +22,32 @@ impl From<gpx::errors::Error> for GenericError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<nwg::NwgError> for GenericError {
|
||||
fn from(error: nwg::NwgError) -> Self {
|
||||
GenericError::NWGError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for GenericError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
GenericError::IOError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<toml::de::Error> for GenericError {
|
||||
fn from(error: toml::de::Error) -> Self {
|
||||
GenericError::TOMLError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for GenericError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
let err = match self {
|
||||
GenericError::ThingyLibError(e) => e.to_string(),
|
||||
GenericError::GPXError(e) => format!("GPX error: {}", e),
|
||||
GenericError::NWGError(e) => format!("UI error: {}", e),
|
||||
GenericError::IOError(e) => format!("IO error: {}", e),
|
||||
GenericError::TOMLError(e) => format!("toml error: {}", e),
|
||||
GenericError::MessagedError(msg, err) => format!(
|
||||
"{}\n {}",
|
||||
msg,
|
||||
|
38
src/main.rs
38
src/main.rs
@ -1,12 +1,22 @@
|
||||
#![windows_subsystem = "windows"]
|
||||
|
||||
mod args;
|
||||
#[cfg(target_os = "windows")]
|
||||
extern crate native_windows_derive as nwd;
|
||||
#[cfg(target_os = "windows")]
|
||||
extern crate native_windows_gui as nwg;
|
||||
|
||||
mod cmd;
|
||||
mod errors;
|
||||
mod gpx;
|
||||
|
||||
use args::*;
|
||||
use errors::GenericError;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod ui;
|
||||
|
||||
use cmd::args::EnvOpt;
|
||||
use errors::{GenericError, MessagedError};
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::PathBuf;
|
||||
use thingy_lib::api::{LocationModel, TagModel};
|
||||
use thingy_lib::Config;
|
||||
|
||||
@ -19,10 +29,28 @@ fn main() {
|
||||
}
|
||||
} else {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
println!("Open nwg UI instead");
|
||||
if let Err(e) = ui::start_windows_ui(env) {
|
||||
eprintln!("Critical Error: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
println!("non-windows ui not supported. Please run with --help");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn config_from_path(path: &PathBuf) -> Result<Config, GenericError> {
|
||||
let mut file =
|
||||
File::open(&path).with_msg(format!("Could not find {}", path.to_str().unwrap_or("")))?;
|
||||
let mut string = String::new();
|
||||
file.read_to_string(&mut string)
|
||||
.with_msg("config file is not valid UTF-8")?;
|
||||
|
||||
Ok(toml::from_str(&string).with_msg("given config file is not a valid config file")?)
|
||||
}
|
||||
|
||||
pub fn write_to(config: &Config, path: &PathBuf) -> Result<(), GenericError> {
|
||||
let mut file = File::create(&path).unwrap();
|
||||
file.write_all(&toml::to_vec(config).unwrap())
|
||||
.with_msg("Could not write config.toml, make sure you have correct permissions.")?;
|
||||
Ok(())
|
||||
}
|
||||
|
55
src/ui/mod.rs
Normal file
55
src/ui/mod.rs
Normal file
@ -0,0 +1,55 @@
|
||||
use super::{Config, EnvOpt, GenericError};
|
||||
|
||||
use nwd::NwgUi;
|
||||
use nwg::{Font, NativeUi};
|
||||
|
||||
#[derive(Default, NwgUi)]
|
||||
pub struct APIKeyPrompt {
|
||||
#[nwg_control(size: (500, 100), position: (300, 300), title: "API-key prompt", flags: "WINDOW|VISIBLE")]
|
||||
#[nwg_events( OnWindowClose: [APIKeyPrompt::say_goodbye] )]
|
||||
window: nwg::Window,
|
||||
|
||||
#[nwg_layout(parent: window, spacing: 5)]
|
||||
grid: nwg::GridLayout,
|
||||
|
||||
#[nwg_control(text: "API-key")]
|
||||
#[nwg_layout_item(layout: grid, col: 0, row: 0, col_span: 3)]
|
||||
label: nwg::Label,
|
||||
|
||||
#[nwg_control(text: "", focus: true)]
|
||||
#[nwg_layout_item(layout: grid, col: 0, row: 1, col_span: 3)]
|
||||
name_edit: nwg::TextInput,
|
||||
|
||||
#[nwg_control(text: "Submit")]
|
||||
#[nwg_layout_item(layout: grid, col: 1, row: 2)]
|
||||
button: nwg::Button,
|
||||
}
|
||||
|
||||
impl APIKeyPrompt {
|
||||
fn say_goodbye(&self) {
|
||||
nwg::modal_info_message(
|
||||
&self.window,
|
||||
"Goodbye",
|
||||
&format!("Goodbye {}", self.name_edit.text()),
|
||||
);
|
||||
nwg::stop_thread_dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_windows_ui(env: EnvOpt) -> Result<(), GenericError> {
|
||||
nwg::init().expect("Failed to init Native Windows GUI");
|
||||
|
||||
let mut font = Font::default();
|
||||
|
||||
Font::builder()
|
||||
.family("Segoe UI")
|
||||
.size(20)
|
||||
.build(&mut font)?;
|
||||
|
||||
Font::set_global_default(Some(font));
|
||||
|
||||
let mut _app = APIKeyPrompt::build_ui(Default::default()).expect("Failed to build UI");
|
||||
nwg::dispatch_thread_events();
|
||||
|
||||
Ok(())
|
||||
}
|
@ -6,6 +6,5 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.5"
|
||||
minreq = { version = "2.2.0", features = ["https", "json-using-serde"] }
|
||||
chrono = "0.4"
|
@ -1,9 +1,5 @@
|
||||
use super::errors::{LibError, MessagedError};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
@ -26,25 +22,6 @@ pub struct Config {
|
||||
pub nicknames: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn from_path(path: &PathBuf) -> Result<Config, LibError> {
|
||||
let mut file = File::open(&path)
|
||||
.with_msg(format!("Could not find {}", path.to_str().unwrap_or("")))?;
|
||||
let mut string = String::new();
|
||||
file.read_to_string(&mut string)
|
||||
.with_msg("config file is not valid UTF-8")?;
|
||||
|
||||
Ok(toml::from_str(&string).with_msg("given config file is not a valid config file")?)
|
||||
}
|
||||
|
||||
pub fn write_to(&self, path: &PathBuf) -> Result<(), LibError> {
|
||||
let mut file = File::create(&path).unwrap();
|
||||
file.write_all(&toml::to_vec(self).unwrap())
|
||||
.with_msg("Could not write config.toml, make sure you have correct permissions.")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Config {
|
||||
Config {
|
||||
|
@ -4,7 +4,6 @@ use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LibError {
|
||||
TomlError(toml::de::Error),
|
||||
YepzonServerError(ErrorModel),
|
||||
MinreqError(minreq::Error),
|
||||
ChronoParseError(chrono::ParseError),
|
||||
@ -13,12 +12,6 @@ pub enum LibError {
|
||||
MessagedError(String, Option<Box<LibError>>),
|
||||
}
|
||||
|
||||
impl From<toml::de::Error> for LibError {
|
||||
fn from(error: toml::de::Error) -> Self {
|
||||
LibError::TomlError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<minreq::Error> for LibError {
|
||||
fn from(error: minreq::Error) -> Self {
|
||||
LibError::MinreqError(error)
|
||||
@ -56,7 +49,6 @@ impl Display for LibError {
|
||||
LibError::FromUTF8Error(e) => format!("UTF-8 error: {}", e),
|
||||
LibError::IOError(e) => format!("IO error: {}", e),
|
||||
LibError::MinreqError(e) => format!("Network error: {}", e),
|
||||
LibError::TomlError(e) => format!("Toml error: {}", e),
|
||||
LibError::YepzonServerError(e) => format!(
|
||||
"Yepzon server error: {}",
|
||||
e.message.as_ref().unwrap_or(&String::new())
|
||||
|
@ -7,7 +7,6 @@ use chrono::offset::Local;
|
||||
use chrono::{NaiveDate, NaiveDateTime, NaiveTime, ParseError};
|
||||
use errors::LibError;
|
||||
use std::io::prelude::*;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::TryRecvError;
|
||||
use std::time::Duration;
|
||||
|
||||
@ -16,12 +15,12 @@ pub use config::Config;
|
||||
pub use errors::LibError as Error;
|
||||
pub use errors::MessagedError;
|
||||
|
||||
pub fn init(path: &PathBuf, api_key: Option<String>) -> Result<(), LibError> {
|
||||
pub fn init(api_key: Option<String>) -> Result<Config, LibError> {
|
||||
let mut config = Config::default();
|
||||
if let Some(api_key) = api_key {
|
||||
config.api_key = api_key;
|
||||
}
|
||||
Ok(config.write_to(path)?)
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub fn between(
|
||||
|
Loading…
Reference in New Issue
Block a user