base application

This commit is contained in:
pointer-to-bios 2024-09-25 01:40:35 +08:00
parent 5c0ad57804
commit f11e2e3a64
8 changed files with 501 additions and 7 deletions

249
Cargo.lock generated
View File

@ -2,18 +2,54 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
dependencies = [
"gimli",
]
[[package]]
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "autocfg"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "backtrace"
version = "0.3.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
"windows-targets",
]
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bytes"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -45,6 +81,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.9"
@ -55,12 +97,34 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "gimli"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hermit-abi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "indexmap"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "libc"
version = "0.2.158"
@ -89,6 +153,21 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "miniz_oxide"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
"adler2",
]
[[package]]
name = "mio"
version = "1.0.2"
@ -107,6 +186,18 @@ name = "muxde"
version = "0.1.0"
dependencies = [
"crossterm",
"serde",
"tokio",
"toml",
]
[[package]]
name = "object"
version = "0.36.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
dependencies = [
"memchr",
]
[[package]]
@ -132,6 +223,30 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "pin-project-lite"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "proc-macro2"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.5.4"
@ -141,6 +256,12 @@ dependencies = [
"bitflags",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustix"
version = "0.38.37"
@ -160,6 +281,35 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_spanned"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
dependencies = [
"serde",
]
[[package]]
name = "signal-hook"
version = "0.3.17"
@ -196,6 +346,96 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "syn"
version = "2.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tokio"
version = "1.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
]
[[package]]
name = "tokio-macros"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "toml"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
@ -296,3 +536,12 @@ name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
dependencies = [
"memchr",
]

View File

@ -5,3 +5,6 @@ edition = "2021"
[dependencies]
crossterm = "0.28.1"
serde = { version = "1.0.210", features = ["derive", "serde_derive"] }
tokio = { version = "1.40.0", features = ["full"] }
toml = "0.8.19"

7
config/default.toml Normal file
View File

@ -0,0 +1,7 @@
[colortheme]
background = [26, 26, 28]
command_bar = [20, 28, 20]
[command]
new_window = "n"
quit = "q"

View File

@ -1,3 +1,170 @@
use std::{
collections::HashMap,
io::{self, stdout, Stdout, Write},
thread,
time::Duration,
};
use crossterm::{
cursor, event, queue,
style::{self, Color},
terminal::{self, disable_raw_mode, enable_raw_mode, ClearType},
};
use crate::{colortheme::ColorTheme, iterate_config, window::Window, Config};
pub struct Application {
windows: Window,
config: Config,
colortheme: ColorTheme,
stdout: Stdout,
size: (u16, u16),
windows: HashMap<usize, Window>,
command_mode: bool,
command: String,
cmdbar_show: String,
}
impl Application {
pub fn new(config: Config) -> Result<Self, io::Error> {
queue!(
stdout(),
event::EnableMouseCapture,
terminal::EnterAlternateScreen,
terminal::Clear(ClearType::All),
style::SetBackgroundColor(Color::Black)
)?;
enable_raw_mode()?;
stdout().flush()?;
Ok(Application {
colortheme: ColorTheme::from(config.get("colortheme").unwrap().as_table().unwrap()),
config,
stdout: stdout(),
size: terminal::size()?,
windows: HashMap::new(),
command_mode: true,
command: String::new(),
cmdbar_show: String::new(),
})
}
pub fn exec(&mut self) -> io::Result<()> {
self.render()?;
self.stdout.flush()?;
loop {
if event::poll(Duration::from_secs(5))? {
match event::read()? {
event::Event::FocusGained => queue!(self.stdout, cursor::Show)?,
event::Event::FocusLost => queue!(self.stdout, cursor::Hide)?,
event::Event::Key(key_event) => match key_event.code {
event::KeyCode::Backspace => {
if self.command_mode {
self.command.pop();
self.cmdbar_show.clone_from(&self.command);
}
}
event::KeyCode::Enter => (),
event::KeyCode::Left => (),
event::KeyCode::Right => (),
event::KeyCode::Up => (),
event::KeyCode::Down => (),
event::KeyCode::Home => (),
event::KeyCode::End => (),
event::KeyCode::PageUp => (),
event::KeyCode::PageDown => (),
event::KeyCode::Tab => (),
event::KeyCode::BackTab => (),
event::KeyCode::Delete => (),
event::KeyCode::Insert => (),
event::KeyCode::F(_) => (),
event::KeyCode::Char(c) => {
if self.command_mode {
self.command.push(c);
self.cmdbar_show.clone_from(&self.command);
}
}
event::KeyCode::Null => (),
event::KeyCode::Esc => (),
event::KeyCode::CapsLock => (),
event::KeyCode::ScrollLock => (),
event::KeyCode::NumLock => (),
event::KeyCode::PrintScreen => (),
event::KeyCode::Pause => (),
event::KeyCode::Menu => (),
event::KeyCode::KeypadBegin => (),
event::KeyCode::Media(media_key_code) => (),
event::KeyCode::Modifier(modifier_key_code) => (),
},
event::Event::Mouse(mouse_event) => (),
event::Event::Paste(_) => (),
event::Event::Resize(w, h) => self.size = (w, h),
}
self.render()?;
let f = |_, value| {
if let &toml::Value::String(ref s) = value {
s == &self.command
} else {
false
}
};
if let toml::Value::Table(map) = &self.config.get("command").unwrap() {
if let Some((name, _)) = iterate_config(map, &f) {
match name.as_str() {
"quit" => break,
"print" => queue!(
self.stdout,
style::SetBackgroundColor(self.colortheme.background),
cursor::SavePosition,
cursor::MoveTo(0, 0),
style::Print("Hello"),
cursor::RestorePosition,
)?,
_ => (),
}
self.command.clear();
}
}
self.stdout.flush()?;
} else {
}
}
self.render()?;
self.stdout.flush()?;
thread::sleep(Duration::from_millis(200));
Ok(())
}
fn render(&mut self) -> io::Result<()> {
let mut show = String::new();
for c in self.cmdbar_show.chars() {
show.push(c);
if cursor::position().unwrap().0 >= self.size.0 - 1 {
break;
}
}
queue!(
self.stdout,
style::SetBackgroundColor(self.colortheme.command_bar),
cursor::MoveTo(0, self.size.1 - 1),
style::Print(show),
)?;
let x = cursor::position().unwrap().0;
queue!(
self.stdout,
style::Print(" ".repeat((self.size.0 - x) as usize)),
cursor::MoveTo(x, self.size.1 - 1),
)?;
Ok(())
}
}
impl Drop for Application {
fn drop(&mut self) {
disable_raw_mode().unwrap();
queue!(
self.stdout,
terminal::LeaveAlternateScreen,
event::DisableMouseCapture,
)
.unwrap();
}
}

30
src/colortheme.rs Normal file
View File

@ -0,0 +1,30 @@
use crossterm::style::Color;
use toml::{Table, Value};
pub struct ColorTheme {
pub background: Color,
pub command_bar: Color,
}
impl From<&Table> for ColorTheme {
fn from(value: &Table) -> Self {
let f = |name| {
if let Value::Array(arr) = value.get(name).unwrap() {
Color::Rgb {
r: arr[0].as_integer().unwrap() as u8,
g: arr[1].as_integer().unwrap() as u8,
b: arr[2].as_integer().unwrap() as u8,
}
} else {
panic!();
}
};
let background = f("background");
let command_bar = f("command_bar");
Self {
background,
command_bar,
}
}
}

View File

@ -1,7 +1,32 @@
pub mod application;
pub mod colortheme;
pub mod window;
use std::io;
use application::Application;
use toml::map::Map;
pub fn run() {
let app = Application::new();
pub type Config = Map<String, toml::Value>;
pub fn iterate_config<'a, 'b: 'a, F>(config: &'b Config, f: &F) -> Option<(String, toml::Value)>
where
F: Fn(&'a str, &'b toml::Value) -> bool,
{
for (name, value) in config {
if let toml::Value::Table(map) = value {
if let Some(p) = iterate_config(map, f) {
return Some(p);
}
} else if f(name, value) {
return Some((name.clone(), value.clone()));
}
}
None
}
pub fn run(config: Config) -> io::Result<()> {
let mut app = Application::new(config)?;
app.exec()?;
Ok(())
}

View File

@ -1,3 +1,10 @@
fn main() {
crate::run();
use std::fs;
use muxde::{run, Config};
fn main() -> std::io::Result<()> {
let config = fs::read_to_string("config/default.toml")?;
let config: Config = toml::from_str(&config).unwrap();
run(config)?;
Ok(())
}

6
src/window.rs Normal file
View File

@ -0,0 +1,6 @@
pub struct Window {
pos: (u16, u16),
size: (u16, u16),
}