working cursor styling

macos-click-through
Keith Simmons 5 years ago
parent cb0d118859
commit 293bd23f9e

@ -31,6 +31,14 @@ pub struct Style {
pub blend: u8 pub blend: u8
} }
#[derive(new, Debug, Clone, PartialEq)]
pub struct ModeInfo {
#[new(default)]
pub cursor_type: Option<CursorType>,
#[new(default)]
pub cursor_style_id: Option<u64>
}
pub type GridCell = Option<(char, Style)>; pub type GridCell = Option<(char, Style)>;
#[derive(new, Debug, Clone)] #[derive(new, Debug, Clone)]
@ -41,21 +49,34 @@ pub struct DrawCommand {
pub style: Style pub style: Style
} }
#[derive(Clone)] #[derive(Debug, Clone, PartialEq)]
pub enum CursorType { pub enum CursorType {
Block, Block,
Horizontal, Horizontal,
Vertical Vertical
} }
impl CursorType {
pub fn from_type_name(name: &str) -> Option<CursorType> {
match name {
"block" => Some(CursorType::Block),
"horizontal" => Some(CursorType::Horizontal),
"vertical" => Some(CursorType::Vertical),
_ => None
}
}
}
pub struct Editor { pub struct Editor {
pub nvim: Neovim, pub nvim: Neovim,
pub grid: Vec<Vec<GridCell>>, pub grid: Vec<Vec<GridCell>>,
pub cursor_pos: (u64, u64), pub cursor_pos: (u64, u64),
pub cursor_type: CursorType, pub cursor_type: CursorType,
pub cursor_style: Option<Style>,
pub size: (u64, u64), pub size: (u64, u64),
pub default_colors: Colors, pub default_colors: Colors,
pub defined_styles: HashMap<u64, Style>, pub defined_styles: HashMap<u64, Style>,
pub mode_list: Vec<ModeInfo>,
pub previous_style: Option<Style> pub previous_style: Option<Style>
} }
@ -66,9 +87,11 @@ impl Editor {
grid: Vec::new(), grid: Vec::new(),
cursor_pos: (0, 0), cursor_pos: (0, 0),
cursor_type: CursorType::Block, cursor_type: CursorType::Block,
cursor_style: None,
size: (width, height), size: (width, height),
default_colors: Colors::new(Some(colors::WHITE), Some(colors::BLACK), Some(colors::GREY)), default_colors: Colors::new(Some(colors::WHITE), Some(colors::BLACK), Some(colors::GREY)),
defined_styles: HashMap::new(), defined_styles: HashMap::new(),
mode_list: Vec::new(),
previous_style: None previous_style: None
}; };
editor.clear(); editor.clear();
@ -122,6 +145,8 @@ impl Editor {
pub fn handle_redraw_event(&mut self, event: RedrawEvent) { pub fn handle_redraw_event(&mut self, event: RedrawEvent) {
match event { match event {
RedrawEvent::ModeInfoSet { mode_list } => self.set_mode_list(mode_list),
RedrawEvent::ModeChange { mode_index } => self.change_mode(mode_index),
RedrawEvent::Resize { width, height, .. } => self.resize(width, height), RedrawEvent::Resize { width, height, .. } => self.resize(width, height),
RedrawEvent::DefaultColorsSet { foreground, background, special } => self.set_default_colors(foreground, background, special), RedrawEvent::DefaultColorsSet { foreground, background, special } => self.set_default_colors(foreground, background, special),
RedrawEvent::HighlightAttributesDefine { id, style } => self.define_style(id, style), RedrawEvent::HighlightAttributesDefine { id, style } => self.define_style(id, style),
@ -132,6 +157,24 @@ impl Editor {
} }
} }
pub fn set_mode_list(&mut self, mode_list: Vec<ModeInfo>) {
self.mode_list = mode_list;
}
pub fn change_mode(&mut self, mode_index: u64) {
if let Some(ModeInfo { cursor_type, cursor_style_id }) = self.mode_list.get(mode_index as usize) {
if let Some(cursor_type) = cursor_type {
self.cursor_type = cursor_type.clone();
}
if let Some(cursor_style_id) = cursor_style_id {
self.cursor_style = self.defined_styles
.get(cursor_style_id)
.map(|style_reference| style_reference.clone());
}
}
}
pub fn resize(&mut self, new_width: u64, new_height: u64) { pub fn resize(&mut self, new_width: u64, new_height: u64) {
self.nvim.ui_try_resize(new_width as i64, new_height as i64).expect("Resize failed"); self.nvim.ui_try_resize(new_width as i64, new_height as i64).expect("Resize failed");
self.size = (new_width, new_height); self.size = (new_width, new_height);
@ -223,8 +266,6 @@ impl Editor {
let new_top = top as i64 - rows; let new_top = top as i64 - rows;
let new_left = left as i64 - cols; let new_left = left as i64 - cols;
dbg!(top, bot, left, right, rows, cols, new_top, new_left);
for (y, row_section) in region.into_iter().enumerate() { for (y, row_section) in region.into_iter().enumerate() {
for (x, cell) in row_section.into_iter().enumerate() { for (x, cell) in row_section.into_iter().enumerate() {
let y = new_top + y as i64; let y = new_top + y as i64;

@ -4,11 +4,12 @@ use std::fmt;
use rmpv::Value; use rmpv::Value;
use skulpin::skia_safe::Color4f; use skulpin::skia_safe::Color4f;
use crate::editor::{Colors, Style}; use crate::editor::{Colors, Style, ModeInfo, CursorType};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum EventParseError { pub enum EventParseError {
InvalidArray(Value), InvalidArray(Value),
InvalidMap(Value),
InvalidString(Value), InvalidString(Value),
InvalidU64(Value), InvalidU64(Value),
InvalidI64(Value), InvalidI64(Value),
@ -20,6 +21,7 @@ impl fmt::Display for EventParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
EventParseError::InvalidArray(value) => write!(f, "invalid array format {}", value), EventParseError::InvalidArray(value) => write!(f, "invalid array format {}", value),
EventParseError::InvalidMap(value) => write!(f, "invalid map format {}", value),
EventParseError::InvalidString(value) => write!(f, "invalid string format {}", value), EventParseError::InvalidString(value) => write!(f, "invalid string format {}", value),
EventParseError::InvalidU64(value) => write!(f, "invalid u64 format {}", value), EventParseError::InvalidU64(value) => write!(f, "invalid u64 format {}", value),
EventParseError::InvalidI64(value) => write!(f, "invalid i64 format {}", value), EventParseError::InvalidI64(value) => write!(f, "invalid i64 format {}", value),
@ -43,6 +45,8 @@ pub struct GridLineCell {
#[derive(Debug)] #[derive(Debug)]
pub enum RedrawEvent { pub enum RedrawEvent {
ModeInfoSet { mode_list: Vec<ModeInfo> },
ModeChange { mode_index: u64 },
Resize { grid: u64, width: u64, height: u64 }, Resize { grid: u64, width: u64, height: u64 },
DefaultColorsSet { foreground: Color4f, background: Color4f, special: Color4f }, DefaultColorsSet { foreground: Color4f, background: Color4f, special: Color4f },
HighlightAttributesDefine { id: u64, style: Style }, HighlightAttributesDefine { id: u64, style: Style },
@ -73,6 +77,14 @@ fn parse_array(array_value: &Value) -> Result<Vec<Value>> {
} }
} }
fn parse_map(map_value: &Value) -> Result<Vec<(Value, Value)>> {
if let Value::Map(content) = map_value.clone() {
Ok(content)
} else {
Err(EventParseError::InvalidMap(map_value.clone()))
}
}
fn parse_string(string_value: &Value) -> Result<String> { fn parse_string(string_value: &Value) -> Result<String> {
if let Value::String(content) = string_value.clone() { if let Value::String(content) = string_value.clone() {
Ok(content.into_str().ok_or(EventParseError::InvalidString(string_value.clone()))?) Ok(content.into_str().ok_or(EventParseError::InvalidString(string_value.clone()))?)
@ -97,6 +109,45 @@ fn parse_i64(i64_value: &Value) -> Result<i64> {
} }
} }
fn parse_mode_info_set(mode_info_set_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [_cursor_style_enabled, mode_info] = mode_info_set_arguments.as_slice() {
let mode_info_values = parse_array(&mode_info)?;
let mut mode_list = Vec::new();
for mode_info_value in mode_info_values {
let info_map = parse_map(&mode_info_value)?;
let mut mode_info = ModeInfo::new();
for (name, value) in info_map {
let name = parse_string(&name)?;
match name.as_ref() {
"cursor_shape" => {
mode_info.cursor_type = CursorType::from_type_name(&parse_string(&value)?);
},
"attr_id" => {
mode_info.cursor_style_id = Some(parse_u64(&value)?);
},
_ => {}
}
}
mode_list.push(mode_info);
}
Ok(RedrawEvent::ModeInfoSet {
mode_list
})
} else {
Err(EventParseError::InvalidEventFormat)
}
}
fn parse_mode_change(mode_change_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [_mode, mode_index] = mode_change_arguments.as_slice() {
Ok(RedrawEvent::ModeChange {
mode_index: parse_u64(&mode_index)?
})
} else {
Err(EventParseError::InvalidEventFormat)
}
}
fn parse_default_colors(default_colors_arguments: Vec<Value>) -> Result<RedrawEvent> { fn parse_default_colors(default_colors_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [ if let [
foreground, background, special, _term_foreground, _term_background foreground, background, special, _term_foreground, _term_background
@ -200,6 +251,13 @@ pub fn parse_redraw_event(event_value: Value) -> Result<Vec<RedrawEvent>> {
for event in &events[1..] { for event in &events[1..] {
let event_parameters = parse_array(&event)?; let event_parameters = parse_array(&event)?;
let possible_parsed_event = match event_name.clone().as_ref() { let possible_parsed_event = match event_name.clone().as_ref() {
"set_title" => None, // Ignore set title for now
"set_icon" => None, // Ignore set icon for now
"mode_info_set" => Some(parse_mode_info_set(event_parameters)?),
"option_set" => None, // Ignore option set for now
"mode_change" => Some(parse_mode_change(event_parameters)?),
"busy_start" => None, // Ignore busy start for now
"busy_stop" => None, // Ignore busy stop for now
"default_colors_set" => Some(parse_default_colors(event_parameters)?), "default_colors_set" => Some(parse_default_colors(event_parameters)?),
"hl_attr_define" => Some(parse_hl_attr_define(event_parameters)?), "hl_attr_define" => Some(parse_hl_attr_define(event_parameters)?),
"grid_line" => Some(parse_grid_line(event_parameters)?), "grid_line" => Some(parse_grid_line(event_parameters)?),

@ -126,14 +126,18 @@ fn append_modifiers(modifiers: ModifiersState, keycode_text: String, special: bo
}; };
} }
if modifiers.ctrl { if modifiers.ctrl {
special = true;
result = format!("C-{}", result); result = format!("C-{}", result);
} }
if modifiers.alt { if modifiers.alt {
special = true;
result = format!("M-{}", result); result = format!("M-{}", result);
} }
if modifiers.logo { if modifiers.logo {
special = true;
result = format!("D-{}", result); result = format!("D-{}", result);
} }
if special { if special {
result = format!("<{}>", result); result = format!("<{}>", result);
} }

@ -1,4 +1,4 @@
// #![windows_subsystem = "windows"] #![windows_subsystem = "windows"]
mod editor; mod editor;
mod events; mod events;

@ -18,9 +18,6 @@ use crate::keybindings::construct_keybinding_string;
const FONT_NAME: &str = "Delugia Nerd Font"; const FONT_NAME: &str = "Delugia Nerd Font";
const FONT_SIZE: f32 = 14.0; const FONT_SIZE: f32 = 14.0;
// fn process_draw_commands(draw_commands: &Vec<DrawCommand>, default_colors: &Colors, piet: &mut Piet, font: &PietFont) {
// }
fn draw( fn draw(
editor: &Arc<Mutex<Editor>>, editor: &Arc<Mutex<Editor>>,
canvas: &mut Canvas, canvas: &mut Canvas,
@ -69,7 +66,6 @@ fn draw(
let cursor_y = (target_cursor_y - *previous_cursor_y) * 0.5 + *previous_cursor_y; let cursor_y = (target_cursor_y - *previous_cursor_y) * 0.5 + *previous_cursor_y;
*cursor_pos = (cursor_x, cursor_y); *cursor_pos = (cursor_x, cursor_y);
let cursor_width = match cursor_type { let cursor_width = match cursor_type {
CursorType::Vertical => font_width / 8.0, CursorType::Vertical => font_width / 8.0,
CursorType::Horizontal | CursorType::Block => font_width CursorType::Horizontal | CursorType::Block => font_width

Loading…
Cancel
Save