Draw gui cursor shape
This commit is contained in:
parent
90dc2d4a53
commit
609d593db5
126
src/cursor.rs
126
src/cursor.rs
@ -3,6 +3,7 @@ use ui_model::Color;
|
||||
use ui::UiMutex;
|
||||
use shell;
|
||||
use mode;
|
||||
use nvim;
|
||||
use nvim::{RepaintMode, RedrawEvents};
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
@ -123,7 +124,63 @@ impl Cursor {
|
||||
let current_point = ctx.get_current_point();
|
||||
ctx.set_source_rgba(1.0 - bg.0, 1.0 - bg.1, 1.0 - bg.2, 0.6 * state.alpha.0);
|
||||
|
||||
let cursor_width = if shell.mode.is(&mode::NvimMode::Insert) {
|
||||
let (y, width, height) =
|
||||
cursor_rect(&shell.mode, char_width, line_height, line_y, double_width);
|
||||
|
||||
ctx.rectangle(current_point.0, y, width, height);
|
||||
if state.anim_phase == AnimPhase::NoFocus {
|
||||
ctx.stroke();
|
||||
} else {
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cursor_rect(mode: &mode::Mode,
|
||||
char_width: f64,
|
||||
line_height: f64,
|
||||
line_y: f64,
|
||||
double_width: bool)
|
||||
-> (f64, f64, f64) {
|
||||
if let Some(mode_info) = mode.mode_info() {
|
||||
match mode_info.cursor_shape() {
|
||||
None |
|
||||
Some(&nvim::CursorShape::Unknown) |
|
||||
Some(&nvim::CursorShape::Block) => {
|
||||
let cursor_width = if double_width {
|
||||
char_width * 2.0
|
||||
} else {
|
||||
char_width
|
||||
};
|
||||
(line_y, cursor_width, line_height)
|
||||
}
|
||||
Some(&nvim::CursorShape::Vertical) => {
|
||||
let cell_percentage = mode_info.cell_percentage();
|
||||
let cursor_width = if cell_percentage > 0 {
|
||||
(char_width * cell_percentage as f64) / 100.0
|
||||
} else {
|
||||
char_width
|
||||
};
|
||||
(line_y, cursor_width, line_height)
|
||||
}
|
||||
Some(&nvim::CursorShape::Horizontal) => {
|
||||
let cell_percentage = mode_info.cell_percentage();
|
||||
let cursor_width = if double_width {
|
||||
char_width * 2.0
|
||||
} else {
|
||||
char_width
|
||||
};
|
||||
|
||||
if cell_percentage > 0 {
|
||||
let height = (line_height * cell_percentage as f64) / 100.0;
|
||||
(line_y + line_height - height, cursor_width, height)
|
||||
} else {
|
||||
(line_y, cursor_width, line_height)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let cursor_width = if mode.is(&mode::NvimMode::Insert) {
|
||||
char_width / 5.0
|
||||
} else {
|
||||
if double_width {
|
||||
@ -133,15 +190,9 @@ impl Cursor {
|
||||
}
|
||||
};
|
||||
|
||||
ctx.rectangle(current_point.0, line_y, cursor_width, line_height);
|
||||
if state.anim_phase == AnimPhase::NoFocus {
|
||||
ctx.stroke();
|
||||
} else {
|
||||
ctx.fill();
|
||||
}
|
||||
(line_y, cursor_width, line_height)
|
||||
}
|
||||
}
|
||||
|
||||
fn anim_step(state: &Arc<UiMutex<State>>) -> glib::Continue {
|
||||
let mut mut_state = state.borrow_mut();
|
||||
|
||||
@ -201,3 +252,62 @@ impl Drop for Cursor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_cursor_rect_horizontal() {
|
||||
let mut mode = mode::Mode::new();
|
||||
let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"),
|
||||
From::from("horizontal")),
|
||||
(From::from("cell_percentage"), From::from(25))]);
|
||||
mode.update("insert", 0);
|
||||
mode.set_info(true, vec![mode_info.unwrap()]);
|
||||
let char_width = 50.0;
|
||||
let line_height = 30.0;
|
||||
let line_y = 0.0;
|
||||
|
||||
let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, false);
|
||||
assert_eq!(line_y + line_height - line_height / 4.0, y);
|
||||
assert_eq!(char_width, width);
|
||||
assert_eq!(line_height / 4.0, height);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cursor_rect_horizontal_doublewidth() {
|
||||
let mut mode = mode::Mode::new();
|
||||
let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"),
|
||||
From::from("horizontal")),
|
||||
(From::from("cell_percentage"), From::from(25))]);
|
||||
mode.update("insert", 0);
|
||||
mode.set_info(true, vec![mode_info.unwrap()]);
|
||||
let char_width = 50.0;
|
||||
let line_height = 30.0;
|
||||
let line_y = 0.0;
|
||||
|
||||
let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, true);
|
||||
assert_eq!(line_y + line_height - line_height / 4.0, y);
|
||||
assert_eq!(char_width * 2.0, width);
|
||||
assert_eq!(line_height / 4.0, height);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cursor_rect_vertical() {
|
||||
let mut mode = mode::Mode::new();
|
||||
let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"),
|
||||
From::from("vertical")),
|
||||
(From::from("cell_percentage"), From::from(25))]);
|
||||
mode.update("insert", 0);
|
||||
mode.set_info(true, vec![mode_info.unwrap()]);
|
||||
let char_width = 50.0;
|
||||
let line_height = 30.0;
|
||||
let line_y = 0.0;
|
||||
|
||||
let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, false);
|
||||
assert_eq!(line_y, y);
|
||||
assert_eq!(char_width / 4.0, width);
|
||||
assert_eq!(line_height, height);
|
||||
}
|
||||
}
|
||||
|
@ -26,11 +26,10 @@ impl Mode {
|
||||
self.mode == *mode
|
||||
}
|
||||
|
||||
pub fn mode_info(&self) -> nvim::ModeInfo {
|
||||
pub fn mode_info(&self) -> Option<&nvim::ModeInfo> {
|
||||
self.info
|
||||
.as_ref()
|
||||
.and_then(|i| i.get(self.idx).cloned())
|
||||
.unwrap_or_else(nvim::ModeInfo::default)
|
||||
.and_then(|i| i.get(self.idx))
|
||||
}
|
||||
|
||||
pub fn update(&mut self, mode: &str, idx: usize) {
|
||||
|
13
src/nvim.rs
13
src/nvim.rs
@ -139,13 +139,6 @@ pub struct ModeInfo {
|
||||
}
|
||||
|
||||
impl ModeInfo {
|
||||
pub fn default() -> Self {
|
||||
ModeInfo {
|
||||
cursor_shape: Some(CursorShape::Block),
|
||||
cell_percentage: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(mode_info_arr: &Vec<(Value, Value)>) -> Result<Self, String> {
|
||||
let mode_info_map = mode_info_arr.to_attrs_map()?;
|
||||
|
||||
@ -167,12 +160,12 @@ impl ModeInfo {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn cursor_shape(&self) -> CursorShape {
|
||||
self.cursor_shape.as_ref().cloned().unwrap_or(CursorShape::Block)
|
||||
pub fn cursor_shape(&self) -> Option<&CursorShape> {
|
||||
self.cursor_shape.as_ref()
|
||||
}
|
||||
|
||||
pub fn cell_percentage(&self) -> u64 {
|
||||
self.cell_percentage.unwrap_or(100)
|
||||
self.cell_percentage.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user