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 ui::UiMutex;
|
||||||
use shell;
|
use shell;
|
||||||
use mode;
|
use mode;
|
||||||
|
use nvim;
|
||||||
use nvim::{RepaintMode, RedrawEvents};
|
use nvim::{RepaintMode, RedrawEvents};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
@ -123,7 +124,63 @@ impl Cursor {
|
|||||||
let current_point = ctx.get_current_point();
|
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);
|
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
|
char_width / 5.0
|
||||||
} else {
|
} else {
|
||||||
if double_width {
|
if double_width {
|
||||||
@ -133,15 +190,9 @@ impl Cursor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.rectangle(current_point.0, line_y, cursor_width, line_height);
|
(line_y, cursor_width, line_height)
|
||||||
if state.anim_phase == AnimPhase::NoFocus {
|
|
||||||
ctx.stroke();
|
|
||||||
} else {
|
|
||||||
ctx.fill();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn anim_step(state: &Arc<UiMutex<State>>) -> glib::Continue {
|
fn anim_step(state: &Arc<UiMutex<State>>) -> glib::Continue {
|
||||||
let mut mut_state = state.borrow_mut();
|
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
|
self.mode == *mode
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mode_info(&self) -> nvim::ModeInfo {
|
pub fn mode_info(&self) -> Option<&nvim::ModeInfo> {
|
||||||
self.info
|
self.info
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|i| i.get(self.idx).cloned())
|
.and_then(|i| i.get(self.idx))
|
||||||
.unwrap_or_else(nvim::ModeInfo::default)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, mode: &str, idx: usize) {
|
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 {
|
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> {
|
pub fn new(mode_info_arr: &Vec<(Value, Value)>) -> Result<Self, String> {
|
||||||
let mode_info_map = mode_info_arr.to_attrs_map()?;
|
let mode_info_map = mode_info_arr.to_attrs_map()?;
|
||||||
|
|
||||||
@ -167,12 +160,12 @@ impl ModeInfo {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_shape(&self) -> CursorShape {
|
pub fn cursor_shape(&self) -> Option<&CursorShape> {
|
||||||
self.cursor_shape.as_ref().cloned().unwrap_or(CursorShape::Block)
|
self.cursor_shape.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cell_percentage(&self) -> u64 {
|
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