colors working

macos-click-through
keith 5 years ago
parent 6ca852386f
commit ef8eef6bd3

57
Cargo.lock generated

@ -157,16 +157,6 @@ dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "derivative"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "derive-new" name = "derive-new"
version = "0.5.8" version = "0.5.8"
@ -461,14 +451,6 @@ dependencies = [
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "itertools"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.32" version = "0.3.32"
@ -707,14 +689,6 @@ name = "pkg-config"
version = "0.3.17" version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.6" version = "1.0.6"
@ -728,14 +702,6 @@ name = "quick-error"
version = "1.2.2" version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.2" version = "1.0.2"
@ -822,11 +788,9 @@ dependencies = [
name = "rust_druid_test" name = "rust_druid_test"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"derivative 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"druid-shell 0.4.0 (git+https://github.com/xi-editor/druid.git)", "druid-shell 0.4.0 (git+https://github.com/xi-editor/druid.git)",
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"neovim-lib 0.6.0 (git+https://github.com/daa84/neovim-lib)", "neovim-lib 0.6.0 (git+https://github.com/daa84/neovim-lib)",
"rmpv 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rmpv 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -854,16 +818,6 @@ name = "sourcefile"
version = "0.1.4" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.15.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.8" version = "1.0.8"
@ -905,11 +859,6 @@ name = "unicode-segmentation"
version = "1.6.0" version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.0" version = "0.2.0"
@ -1078,7 +1027,6 @@ dependencies = [
"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" "checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" "checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
"checksum core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59e78b2e0aaf43f08e7ae0d6bc96895ef72ff0921c7d4ff4762201b2dba376dd" "checksum core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59e78b2e0aaf43f08e7ae0d6bc96895ef72ff0921c7d4ff4762201b2dba376dd"
"checksum derivative 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "942ca430eef7a3806595a6737bc388bf51adb888d3fc0dd1b50f1c170167ee3a"
"checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" "checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9"
"checksum direct2d 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7fa6ff10857eb253d1ae16987ebfd27372f4129b0c7a3fa41466fbdf7e453e75" "checksum direct2d 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7fa6ff10857eb253d1ae16987ebfd27372f4129b0c7a3fa41466fbdf7e453e75"
"checksum direct3d11 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "315aa929e68ba066cb6fb86f1b22af24f517e02fd9b5734c4d07e42cb9f4aefa" "checksum direct3d11 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "315aa929e68ba066cb6fb86f1b22af24f517e02fd9b5734c4d07e42cb9f4aefa"
@ -1104,7 +1052,6 @@ dependencies = [
"checksum gtk-sys 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bbd9395497ae1d1915d1d6e522d51ae8745bf613906c34ac191c411250fc4025" "checksum gtk-sys 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bbd9395497ae1d1915d1d6e522d51ae8745bf613906c34ac191c411250fc4025"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
"checksum js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414" "checksum js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414"
"checksum kurbo 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e02e913423d086453a80e16ad9dfe8f7999b8ccfffa91c8e4a97e66bbdcaaaa7" "checksum kurbo 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e02e913423d086453a80e16ad9dfe8f7999b8ccfffa91c8e4a97e66bbdcaaaa7"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
@ -1131,10 +1078,8 @@ dependencies = [
"checksum piet-direct2d 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f1154ad35b4bab853ee64793d4461c0d520c4fa9e5ff6e72a23571e84ec53dde" "checksum piet-direct2d 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f1154ad35b4bab853ee64793d4461c0d520c4fa9e5ff6e72a23571e84ec53dde"
"checksum piet-web 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aea45edce8565c05f80062e4920a13bee72a43b146cd92a13263a59949d85d" "checksum piet-web 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aea45edce8565c05f80062e4920a13bee72a43b146cd92a13263a59949d85d"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
@ -1149,13 +1094,11 @@ dependencies = [
"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702" "checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702"
"checksum serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc" "checksum serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc"
"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" "checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" "checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"

@ -7,10 +7,11 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
itertools = "0.8.2"
druid-shell = { git = "https://github.com/xi-editor/druid.git", version = "0.4" } druid-shell = { git = "https://github.com/xi-editor/druid.git", version = "0.4" }
derive-new = "0.5" derive-new = "0.5"
derivative = "1.0.3"
env_logger = "0.7.1" env_logger = "0.7.1"
neovim-lib = { git = "https://github.com/daa84/neovim-lib", version = "0.6" } neovim-lib = { git = "https://github.com/daa84/neovim-lib", version = "0.6" }
rmpv = "0.4.2" rmpv = "0.4.2"
[profile.release]
debug = true

@ -1,51 +1,184 @@
use std::sync::{Arc, Mutex}; use std::collections::HashMap;
use druid_shell::piet::Color;
use druid_shell::piet::PietTextLayout; use neovim_lib::{Neovim, NeovimApi};
use neovim_lib::Neovim; #[derive(new, Debug, Clone)]
pub struct Colors {
pub foreground: Option<Color>,
pub background: Option<Color>,
pub special: Option<Color>
}
impl PartialEq for Colors {
fn eq(&self, other: &Colors) -> bool {
fn compare_options(a: &Option<Color>, b: &Option<Color>) -> bool {
match (a, b) {
(Some(a), Some(b)) => a.as_rgba_u32() == b.as_rgba_u32(),
(None, None) => true,
_ => false
}
}
compare_options(&self.foreground, &other.foreground) &&
compare_options(&self.background, &other.background) &&
compare_options(&self.special, &other.special)
}
}
#[derive(new, Debug, Clone, PartialEq)]
pub struct Style {
pub colors: Colors,
#[new(default)]
pub reverse: bool,
#[new(default)]
pub italic: bool,
#[new(default)]
pub bold: bool,
#[new(default)]
pub strikethrough: bool,
#[new(default)]
pub underline: bool,
#[new(default)]
pub undercurl: bool,
#[new(default)]
pub blend: u8
}
#[derive(new)]
pub struct GridLineCell {
pub grid: u16,
pub text: String,
pub row: u16,
pub col_start: u16,
pub style_id: Option<u64>
}
pub type GridCell = Option<(char, Style)>;
#[derive(Derivative, new)] #[derive(new, Debug, Clone)]
#[derivative(PartialEq)]
pub struct DrawCommand { pub struct DrawCommand {
pub text: String, pub text: String,
pub row: u64, pub row: u16,
pub col_start: u64, pub col_start: u16,
#[new(default)] pub style: Style
#[derivative(PartialEq="ignore")]
pub layout: Mutex<Option<PietTextLayout>>
} }
pub struct Editor { pub struct Editor {
pub nvim: Neovim, pub nvim: Neovim,
pub draw_commands: Vec<Vec<Arc<Option<DrawCommand>>>>, pub grid: Vec<Vec<GridCell>>,
pub cursor_pos: (u16, u16),
pub size: (u16, u16),
pub default_colors: Colors,
pub defined_styles: HashMap<u64, Style>,
pub previous_style: Option<Style>
} }
impl Editor { impl Editor {
pub fn new(nvim: Neovim, width: usize, height: usize) -> Editor { pub fn new(nvim: Neovim, width: u16, height: u16) -> Editor {
let mut draw_commands = Vec::with_capacity(height); let mut editor = Editor {
for _ in 0..width { nvim,
draw_commands.push(vec![Arc::new(None); width]); grid: Vec::new(),
cursor_pos: (0, 0),
size: (width, height),
default_colors: Colors::new(Some(Color::rgb(0xff, 0xff, 0xff)), Some(Color::rgb(0x00, 0x00, 0x00)), Some(Color::rgb(0x88, 0x88, 0x88))),
defined_styles: HashMap::new(),
previous_style: None
};
editor.clear();
editor
} }
Editor { pub fn build_draw_commands(&self) -> Vec<DrawCommand> {
nvim, self.grid.iter().enumerate().map(|(row_index, row)| {
draw_commands let mut draw_commands = Vec::new();
let mut command = None;
fn add_command(commands_list: &mut Vec<DrawCommand>, command: Option<DrawCommand>) {
if let Some(command) = command {
commands_list.push(command);
} }
} }
pub fn draw(&mut self, command: DrawCommand) { fn command_matches(command: &Option<DrawCommand>, style: &Style) -> bool {
let length = command.text.chars().count(); match command {
Some(command) => &command.style == style,
None => true
}
}
fn add_character(command: &mut Option<DrawCommand>, character: &char, row_index: u16, col_index: u16, style: Style) {
match command {
Some(command) => command.text.push(character.clone()),
None => {
command.replace(DrawCommand::new(character.to_string(), row_index, col_index, style));
}
}
}
for (col_index, cell) in row.iter().enumerate() {
if let Some((character, new_style)) = cell {
if !command_matches(&command, &new_style) {
add_command(&mut draw_commands, command);
command = None;
}
add_character(&mut command, &character, row_index as u16, col_index as u16, new_style.clone());
} else {
add_command(&mut draw_commands, command);
command = None;
}
}
add_command(&mut draw_commands, command);
draw_commands
}).flatten().collect()
}
pub fn draw(&mut self, command: GridLineCell) {
let row_index = command.row as usize; let row_index = command.row as usize;
let col_start = command.col_start as usize; let col_start = command.col_start as usize;
let pointer = Arc::new(Some(command));
let row = self.draw_commands.get_mut(row_index).expect("Draw command out of bounds"); let style = match (command.style_id, self.previous_style.clone()) {
(Some(0), _) => Style::new(self.default_colors.clone()),
(Some(style_id), _) => self.defined_styles.get(&style_id).expect("GridLineCell must use defined color").clone(),
(None, Some(previous_style)) => previous_style,
(None, None) => Style::new(self.default_colors.clone())
};
for x in 0..length { if row_index < self.grid.len() {
let pointer_index = x + col_start; let row = self.grid.get_mut(row_index).expect("Grid must have size greater than row_index");
for (i, character) in command.text.chars().enumerate() {
let pointer_index = i + col_start;
if pointer_index < row.len() { if pointer_index < row.len() {
row[pointer_index] = pointer.clone(); row[pointer_index] = Some((character, style.clone()));
} }
} }
} else {
println!("Draw command out of bounds");
}
self.previous_style = Some(style);
}
pub fn clear(&mut self) {
let (width, height) = self.size;
self.grid = vec![vec![None; width as usize]; height as usize];
}
pub fn resize(&mut self, new_width: u16, new_height: u16) {
self.nvim.ui_try_resize(new_width as i64, new_height as i64).expect("Resize failed");
self.size = (new_width, new_height);
}
pub fn define_style(&mut self, id: u64, style: Style) {
self.defined_styles.insert(id, style);
}
pub fn set_default_colors(&mut self, foreground: Color, background: Color, special: Color) {
self.default_colors = Colors::new(Some(foreground), Some(background), Some(special));
}
pub fn jump_cursor_to(&mut self, row: u16, col: u16) {
self.cursor_pos = (row, col);
} }
} }

@ -1,10 +1,10 @@
#![windows_subsystem = "windows"]
mod editor; mod editor;
mod window; mod window;
#[macro_use] #[macro_use]
extern crate derive_new; extern crate derive_new;
#[macro_use]
extern crate derivative;
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -15,49 +15,121 @@ use neovim_lib::{Neovim, UiAttachOptions, Session};
use rmpv::Value; use rmpv::Value;
use window::ui_loop; use window::ui_loop;
use editor::{Editor, DrawCommand}; use editor::{Colors, Editor, GridLineCell, Style};
use druid_shell::piet::Color;
const INITIAL_WIDTH: u16 = 100;
const INITIAL_HEIGHT: u16 = 50;
fn handle_grid_line(grid_line_arguments: &Vec<Value>, editor: &Arc<Mutex<Editor>>) { fn handle_grid_line(grid_line_arguments: &Vec<Value>, editor: &Arc<Mutex<Editor>>) {
match grid_line_arguments.as_slice() { if let [Value::Integer(grid_id), Value::Integer(row), Value::Integer(col_start), Value::Array(cells)] = grid_line_arguments.as_slice() {
[Value::Integer(grid_id), Value::Integer(row), Value::Integer(col_start), Value::Array(cells)] => { let mut col_pos = col_start.as_u64().unwrap() as u16;
let mut col_pos = col_start.as_u64().unwrap();
for cell in cells.into_iter() { for cell in cells.into_iter() {
match cell { if let Value::Array(cell_data) = cell {
Value::Array(cell_data) => { let grid_id = grid_id.as_u64().unwrap() as u16;
let row = row.as_u64().unwrap() as u16;
let mut text = match cell_data.get(0).expect("Cell must have non zero size") { let mut text = match cell_data.get(0).expect("Cell must have non zero size") {
Value::String(cell_text) => cell_text.as_str().expect("Could not process string").to_string(), Value::String(cell_text) => cell_text.as_str().expect("Could not process string").to_string(),
_ => panic!("Cell text was not a string") _ => panic!("Cell text was not a string")
}; };
match cell_data.get(2) {
Some(Value::Integer(repeat_count)) => { if let Some(Value::Integer(repeat_count)) = cell_data.get(2) {
text = text.repeat(repeat_count.as_u64().unwrap_or(1) as usize); text = text.repeat(repeat_count.as_u64().unwrap_or(1) as usize);
} }
_ => {}
};
{ let mut style_id = None;
if let Some(Value::Integer(id)) = cell_data.get(1) {
style_id = Some(id.as_u64().unwrap());
}
let mut editor = editor.lock().unwrap(); let mut editor = editor.lock().unwrap();
editor.draw(DrawCommand::new(text.to_string(), row.as_u64().unwrap(), col_pos)); let length = text.chars().count() as u16;
editor.draw(GridLineCell::new(grid_id, text, row, col_pos, style_id));
col_pos = col_pos + length;
} else {
println!("Invalid grid_line cell format: {:?}", cell);
} }
col_pos = col_pos + text.chars().count() as u64;
},
_ => println!("Invalid cell shape")
} }
} else {
println!("Invalid grid_line format: {:?}", grid_line_arguments);
} }
} }
_ => println!("Invalid grid_line format")
}; fn handle_clear(_clear_arguments: &Vec<Value>, editor: &Arc<Mutex<Editor>>) {
let mut editor = editor.lock().unwrap();
editor.clear();
}
fn handle_cursor_goto(cursor_goto_arguments: &Vec<Value>, editor: &Arc<Mutex<Editor>>) {
if let [Value::Integer(_grid_id), Value::Integer(row), Value::Integer(column)] = cursor_goto_arguments.as_slice() {
let mut editor = editor.lock().unwrap();
editor.jump_cursor_to(column.as_u64().unwrap() as u16, row.as_u64().unwrap() as u16);
} else {
println!("Invalid cursor_goto format: {:?}", cursor_goto_arguments);
}
}
fn unpack_color(packed_color: u64) -> Color {
Color::from_rgba32_u32(((packed_color as u32) << 8) + 255)
}
fn handle_default_colors(default_colors_arguments: &Vec<Value>, editor: &Arc<Mutex<Editor>>) {
if let [
Value::Integer(foreground), Value::Integer(background), Value::Integer(special),
Value::Integer(_term_foreground), Value::Integer(_term_background)
] = default_colors_arguments.as_slice() {
let foreground = unpack_color(foreground.as_u64().unwrap());
let background = unpack_color(background.as_u64().unwrap());
let special = unpack_color(special.as_u64().unwrap());
let mut editor = editor.lock().unwrap();
editor.set_default_colors(foreground, background, special);
} else {
println!("Invalid default color format.");
}
}
fn handle_hl_attr_define(hl_attr_define_arguments: &Vec<Value>, editor: &Arc<Mutex<Editor>>) {
if let [
Value::Integer(id), Value::Map(attributes), Value::Map(_terminal_attributes), Value::Array(_info)
] = hl_attr_define_arguments.as_slice() {
let id = id.as_u64().unwrap();
let mut editor = editor.lock().unwrap();
let mut style = Style::new(Colors::new(None, None, None));
for attribute in attributes {
if let (Value::String(name), value) = attribute {
match (name.as_str().unwrap(), value) {
("foreground", Value::Integer(packed_color)) => style.colors.foreground = Some(unpack_color(packed_color.as_u64().unwrap())),
("background", Value::Integer(packed_color)) => style.colors.background = Some(unpack_color(packed_color.as_u64().unwrap())),
("special", Value::Integer(packed_color)) => style.colors.special = Some(unpack_color(packed_color.as_u64().unwrap())),
_ => println!("Ignored style attribute: {}", name)
}
} else {
println!("Invalid attribute format");
}
}
editor.define_style(id, style);
}
} }
fn handle_redraw_event(event_value: Value, editor: &Arc<Mutex<Editor>>) { fn handle_redraw_event(event_value: Value, editor: &Arc<Mutex<Editor>>) {
match event_value { match event_value {
Value::Array(event_contents) => { Value::Array(event_contents) => {
let name_value = &event_contents[0]; let name_value = &event_contents[0];
let arguments_value = &event_contents[1]; let events = &event_contents[1..];
match (name_value, arguments_value) { for event in events {
match (name_value, event) {
(Value::String(event_name), Value::Array(arguments)) => { (Value::String(event_name), Value::Array(arguments)) => {
match event_name.as_str().expect("Invalid redraw command name format.") { match event_name.as_str().expect("Invalid redraw command name format.") {
"grid_resize" => println!("grid_resize event ignored"),
"default_colors_set" => handle_default_colors(arguments, editor),
"hl_attr_define" => handle_hl_attr_define(arguments, editor),
"grid_line" => handle_grid_line(arguments, &editor), "grid_line" => handle_grid_line(arguments, &editor),
"grid_clear" => handle_clear(arguments, &editor),
"grid_cursor_goto" => handle_cursor_goto(arguments, &editor),
"hl_group_set" => println!("hl_group_set event ignored"),
other => println!("Unhandled redraw command {}", other) other => println!("Unhandled redraw command {}", other)
} }
}, },
@ -65,6 +137,7 @@ fn handle_redraw_event(event_value: Value, editor: &Arc<Mutex<Editor>>) {
println!("Unrecognized redraw event structure."); println!("Unrecognized redraw event structure.");
} }
} }
}
}, },
_ => println!("Event is not an array...") _ => println!("Event is not an array...")
} }
@ -96,9 +169,9 @@ fn main() {
options.set_messages_external(false); options.set_messages_external(false);
options.set_linegrid_external(true); options.set_linegrid_external(true);
options.set_rgb(true); options.set_rgb(true);
nvim.ui_attach(100, 50, &options).unwrap(); nvim.ui_attach(INITIAL_WIDTH as i64, INITIAL_HEIGHT as i64, &options).unwrap();
let editor = Arc::new(Mutex::new(Editor::new(nvim, 100, 50))); let editor = Arc::new(Mutex::new(Editor::new(nvim, INITIAL_WIDTH, INITIAL_HEIGHT)));
let nvim_editor = editor.clone(); let nvim_editor = editor.clone();
thread::spawn(move || { thread::spawn(move || {

@ -1,7 +1,5 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::rc::Rc;
use std::any::Any; use std::any::Any;
use itertools::Itertools;
use druid_shell::{Application, WinHandler, WindowHandle, WinCtx, KeyEvent, WindowBuilder, RunLoop, HotKey, KeyCode}; use druid_shell::{Application, WinHandler, WindowHandle, WinCtx, KeyEvent, WindowBuilder, RunLoop, HotKey, KeyCode};
use druid_shell::piet::{ use druid_shell::piet::{
Piet, PietFont, Color, FontBuilder, RenderContext, Text, TextLayoutBuilder Piet, PietFont, Color, FontBuilder, RenderContext, Text, TextLayoutBuilder
@ -9,7 +7,7 @@ use druid_shell::piet::{
use druid_shell::kurbo::Rect; use druid_shell::kurbo::Rect;
use neovim_lib::NeovimApi; use neovim_lib::NeovimApi;
use crate::editor::{DrawCommand, Editor}; use crate::editor::{DrawCommand, Editor, Colors};
#[derive(new)] #[derive(new)]
struct WindowState { struct WindowState {
@ -25,13 +23,11 @@ struct WindowState {
const FONT_NAME: &str = "Delugia Nerd Font"; const FONT_NAME: &str = "Delugia Nerd Font";
const FONT_SIZE: f64 = 14.0; const FONT_SIZE: f64 = 14.0;
const FONT_WIDTH: f64 = 10.0; const FONT_WIDTH: f64 = 8.2;
const FONT_HEIGHT: f64 = 20.0; const FONT_HEIGHT: f64 = 16.4;
fn process_draw_commands(draw_commands: &Vec<Vec<Arc<Option<DrawCommand>>>>, piet: &mut Piet, font: &PietFont) { fn process_draw_commands(draw_commands: &Vec<DrawCommand>, default_colors: &Colors, piet: &mut Piet, font: &PietFont) {
for row in draw_commands { for command in draw_commands {
for possible_command in row.iter().dedup() {
if let Some(ref command) = **possible_command {
let x = command.col_start as f64 * FONT_WIDTH; let x = command.col_start as f64 * FONT_WIDTH;
let y = command.row as f64 * FONT_HEIGHT + FONT_HEIGHT; let y = command.row as f64 * FONT_HEIGHT + FONT_HEIGHT;
let top = y - FONT_HEIGHT * 0.8; let top = y - FONT_HEIGHT * 0.8;
@ -40,21 +36,11 @@ fn process_draw_commands(draw_commands: &Vec<Vec<Arc<Option<DrawCommand>>>>, pie
let height = FONT_HEIGHT; let height = FONT_HEIGHT;
let bottom_right = (x + width, top + height); let bottom_right = (x + width, top + height);
let region = Rect::from_points(top_left, bottom_right); let region = Rect::from_points(top_left, bottom_right);
piet.fill(region, &Color::rgb8(0x11, 0x11, 0x11)); piet.fill(region, &command.style.colors.background.clone().or(default_colors.background.clone()).unwrap());
let layout_ref = command.layout.lock().unwrap();
let owned;
let text_layout = if layout_ref.is_some() {
layout_ref.as_ref().unwrap()
} else {
let piet_text = piet.text(); let piet_text = piet.text();
owned = piet_text.new_text_layout(&font, &command.text).build().unwrap(); let text_layout = piet_text.new_text_layout(&font, &command.text).build().unwrap();
&owned piet.draw_text(&text_layout, (x, y), &command.style.colors.foreground.clone().or(default_colors.foreground.clone()).unwrap());
};
piet.draw_text(&text_layout, (x, y), &Color::rgb8(0xff, 0xff, 0xff));
}
}
} }
} }
@ -68,12 +54,21 @@ impl WinHandler for WindowState {
if self.font.is_none() { if self.font.is_none() {
self.font = Some(text.new_font_by_name(FONT_NAME, FONT_SIZE).build().unwrap()); self.font = Some(text.new_font_by_name(FONT_NAME, FONT_SIZE).build().unwrap());
} }
let font = self.font.as_ref().unwrap(); let font = self.font.as_ref().unwrap();
piet.clear(Color::rgb8(0x00, 0x00, 0x00));
let editor = self.editor.lock().unwrap(); let editor = self.editor.lock().unwrap();
process_draw_commands(&editor.draw_commands, piet, font); let draw_commands = editor.build_draw_commands();
piet.clear(editor.default_colors.background.clone().unwrap());
process_draw_commands(&draw_commands, &editor.default_colors, piet, font);
let (cursor_grid_x, cursor_grid_y) = editor.cursor_pos;
let cursor_x = cursor_grid_x as f64 * FONT_WIDTH;
let cursor_width = FONT_WIDTH / 8.0;
let cursor_y = cursor_grid_y as f64 * FONT_HEIGHT + FONT_HEIGHT * 0.2;
let cursor_height = FONT_HEIGHT;
let cursor = Rect::from_points((cursor_x, cursor_y), (cursor_x + cursor_width, cursor_y + cursor_height));
piet.fill(cursor, &Color::rgb8(0xff, 0xff, 0xff));
true true
} }
@ -103,7 +98,7 @@ impl WinHandler for WindowState {
self.size = (width_f, height_f); self.size = (width_f, height_f);
let mut editor = self.editor.lock().unwrap(); let mut editor = self.editor.lock().unwrap();
editor.nvim.ui_try_resize((width_f / FONT_WIDTH) as i64, (height_f / FONT_HEIGHT) as i64).expect("Resize failed"); editor.resize((width_f / FONT_WIDTH) as u16, (height_f / FONT_HEIGHT) as u16);
} }
fn as_any(&mut self) -> &mut dyn Any { fn as_any(&mut self) -> &mut dyn Any {

Loading…
Cancel
Save