Merge branch 'cursor-color' (#43)

This commit is contained in:
daa 2018-05-06 13:00:21 +03:00
commit 2dc10aa611
7 changed files with 95 additions and 50 deletions

View File

@ -536,7 +536,7 @@ fn gtk_draw(ctx: &cairo::Context, state: &Arc<UiMutex<State>>) -> Inhibit {
ctx.translate(0.0, (gap / 2) as f64); ctx.translate(0.0, (gap / 2) as f64);
} }
render::clear(ctx, &render_state.color_model); render::clear(ctx);
if let Some(block) = block { if let Some(block) = block {
render::render( render::render(
@ -559,6 +559,9 @@ fn gtk_draw(ctx: &cairo::Context, state: &Arc<UiMutex<State>>) -> Inhibit {
&render_state.color_model, &render_state.color_model,
); );
} }
render::fill_background(ctx, &render_state.color_model);
Inhibit(false) Inhibit(false)
} }

View File

@ -90,14 +90,6 @@ impl ColorModel {
} }
} }
pub fn actual_cell_bg<'a>(&'a self, cell: &'a Cell) -> &'a Color {
if !cell.attrs.reverse {
cell.attrs.background.as_ref().unwrap_or(&self.bg_color)
} else {
cell.attrs.foreground.as_ref().unwrap_or(&self.fg_color)
}
}
#[inline] #[inline]
pub fn actual_cell_sp<'a>(&'a self, cell: &'a Cell) -> &'a Color { pub fn actual_cell_sp<'a>(&'a self, cell: &'a Cell) -> &'a Color {
cell.attrs.special.as_ref().unwrap_or(&self.sp_color) cell.attrs.special.as_ref().unwrap_or(&self.sp_color)
@ -134,6 +126,14 @@ impl ColorModel {
.clone() .clone()
.unwrap_or_else(|| self.fg_color.clone()) .unwrap_or_else(|| self.fg_color.clone())
} }
pub fn cursor_bg(&self) -> Color {
self.theme
.cursor()
.bg
.clone()
.unwrap_or_else(|| self.bg_color.clone())
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,5 +1,5 @@
use cairo; use cairo;
use color::Color; use color;
use ui::UiMutex; use ui::UiMutex;
use mode; use mode;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
@ -75,7 +75,7 @@ pub trait Cursor {
font_ctx: &render::Context, font_ctx: &render::Context,
line_y: f64, line_y: f64,
double_width: bool, double_width: bool,
bg: &Color, color: &color::ColorModel,
); );
} }
@ -94,7 +94,7 @@ impl Cursor for EmptyCursor {
_font_ctx: &render::Context, _font_ctx: &render::Context,
_line_y: f64, _line_y: f64,
_double_width: bool, _double_width: bool,
_bg: &Color, _color: &color::ColorModel,
) { ) {
} }
} }
@ -165,7 +165,7 @@ impl<CB: CursorRedrawCb> Cursor for BlinkCursor<CB> {
font_ctx: &render::Context, font_ctx: &render::Context,
line_y: f64, line_y: f64,
double_width: bool, double_width: bool,
bg: &Color, color: &color::ColorModel,
) { ) {
let state = self.state.borrow(); let state = self.state.borrow();
@ -174,7 +174,9 @@ impl<CB: CursorRedrawCb> Cursor for BlinkCursor<CB> {
} }
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);
let bg = color.cursor_bg();
ctx.set_source_rgba(bg.0, bg.1, bg.2, state.alpha.0);
let (y, width, height) = cursor_rect( let (y, width, height) = cursor_rect(
self.mode_info.as_ref(), self.mode_info.as_ref(),

View File

@ -16,7 +16,14 @@ use pangocairo;
use cursor::Cursor; use cursor::Cursor;
use ui_model; use ui_model;
pub fn clear(ctx: &cairo::Context, color_model: &color::ColorModel) { pub fn clear(ctx: &cairo::Context) {
ctx.set_operator(cairo::Operator::Clear);
ctx.paint();
}
pub fn fill_background(ctx: &cairo::Context, color_model: &color::ColorModel) {
// must be dest over here
//ctx.set_operator(cairo::Operator::DestOver);
ctx.set_source_rgb( ctx.set_source_rgb(
color_model.bg_color.0, color_model.bg_color.0,
color_model.bg_color.1, color_model.bg_color.1,
@ -36,6 +43,40 @@ pub fn render<C: Cursor>(
let &CellMetrics { char_width, .. } = cell_metrics; let &CellMetrics { char_width, .. } = cell_metrics;
let (cursor_row, cursor_col) = ui_model.get_cursor(); let (cursor_row, cursor_col) = ui_model.get_cursor();
// draw text
ctx.set_operator(cairo::Operator::Source);
for cell_view in ui_model.get_clip_iterator(ctx, cell_metrics) {
let mut line_x = 0.0;
for (col, cell) in cell_view.line.line.iter().enumerate() {
draw_cell(&cell_view, color_model, cell, col, line_x);
draw_underline(&cell_view, color_model, cell, line_x);
line_x += char_width;
}
}
// draw cursor
ctx.set_operator(cairo::Operator::Xor);
let (_x1, _y1, x2, y2) = ctx.clip_extents();
let line_x = cursor_col as f64 * cell_metrics.char_width;
let line_y = cursor_row as f64 * cell_metrics.line_height;
if line_x < x2 && line_y < y2 {
if let Some(cursor_line) = ui_model.model().get(cursor_row) {
let double_width = cursor_line
.line
.get(cursor_col + 1)
.map_or(false, |c| c.attrs.double_width);
ctx.move_to(line_x, line_y);
cursor.draw(ctx, font_ctx, line_y, double_width, &color_model);
}
}
// draw background
ctx.set_operator(cairo::Operator::DestOver);
for cell_view in ui_model.get_clip_iterator(ctx, cell_metrics) { for cell_view in ui_model.get_clip_iterator(ctx, cell_metrics) {
let mut line_x = 0.0; let mut line_x = 0.0;
@ -44,35 +85,6 @@ pub fn render<C: Cursor>(
line_x += char_width; line_x += char_width;
} }
} }
for cell_view in ui_model.get_clip_iterator(ctx, cell_metrics) {
let mut line_x = 0.0;
let RowView {
line, row, line_y, ..
} = cell_view;
for (col, cell) in line.line.iter().enumerate() {
draw_cell(&cell_view, color_model, cell, col, line_x);
draw_underline(&cell_view, color_model, cell, line_x);
if row == cursor_row && col == cursor_col {
let double_width = line.line
.get(col + 1)
.map_or(false, |c| c.attrs.double_width);
ctx.move_to(line_x, line_y);
cursor.draw(
ctx,
font_ctx,
line_y,
double_width,
color_model.actual_cell_bg(cell),
);
}
line_x += char_width;
}
}
} }
fn draw_underline( fn draw_underline(
@ -104,7 +116,13 @@ fn draw_underline(
let undercurl_height = (underline_thickness * 4.0).min(max_undercurl_height); let undercurl_height = (underline_thickness * 4.0).min(max_undercurl_height);
let undercurl_y = line_y + underline_position - undercurl_height / 2.0; let undercurl_y = line_y + underline_position - undercurl_height / 2.0;
pangocairo::functions::show_error_underline(ctx, line_x, undercurl_y, char_width, undercurl_height); pangocairo::functions::show_error_underline(
ctx,
line_x,
undercurl_y,
char_width,
undercurl_height,
);
} else if cell.attrs.underline { } else if cell.attrs.underline {
let fg = color_model.actual_cell_fg(cell); let fg = color_model.actual_cell_fg(cell);
ctx.set_source_rgb(fg.0, fg.1, fg.2); ctx.set_source_rgb(fg.0, fg.1, fg.2);

View File

@ -7,7 +7,6 @@ use super::context::CellMetrics;
use ui_model; use ui_model;
pub struct RowView<'a> { pub struct RowView<'a> {
pub row: usize,
pub line: &'a ui_model::Line, pub line: &'a ui_model::Line,
pub cell_metrics: &'a CellMetrics, pub cell_metrics: &'a CellMetrics,
pub line_y: f64, pub line_y: f64,
@ -24,7 +23,6 @@ impl<'a> RowView<'a> {
RowView { RowView {
line, line,
line_y: row as f64 * cell_metrics.line_height, line_y: row as f64 * cell_metrics.line_height,
row,
cell_metrics, cell_metrics,
ctx, ctx,
} }

View File

@ -957,7 +957,7 @@ fn gtk_draw_double_buffer(state: &State, ctx: &cairo::Context) {
buf_ctx.clip(); buf_ctx.clip();
let render_state = state.render_state.borrow(); let render_state = state.render_state.borrow();
render::clear(buf_ctx, &render_state.color_model); render::clear(buf_ctx);
render::render( render::render(
&buf_ctx, &buf_ctx,
state.cursor.as_ref().unwrap(), state.cursor.as_ref().unwrap(),
@ -965,6 +965,7 @@ fn gtk_draw_double_buffer(state: &State, ctx: &cairo::Context) {
&state.model, &state.model,
&render_state.color_model, &render_state.color_model,
); );
render::fill_background(buf_ctx, &render_state.color_model);
ctx.set_source_surface(&surface.surface, 0.0, 0.0); ctx.set_source_surface(&surface.surface, 0.0, 0.0);
ctx.paint(); ctx.paint();
@ -973,7 +974,7 @@ fn gtk_draw_double_buffer(state: &State, ctx: &cairo::Context) {
fn gtk_draw_direct(state: &State, ctx: &cairo::Context) { fn gtk_draw_direct(state: &State, ctx: &cairo::Context) {
let render_state = state.render_state.borrow(); let render_state = state.render_state.borrow();
render::clear(ctx, &render_state.color_model); render::clear(ctx);
render::render( render::render(
ctx, ctx,
state.cursor.as_ref().unwrap(), state.cursor.as_ref().unwrap(),
@ -981,6 +982,7 @@ fn gtk_draw_direct(state: &State, ctx: &cairo::Context) {
&state.model, &state.model,
&render_state.color_model, &render_state.color_model,
); );
render::fill_background(ctx, &render_state.color_model);
} }
fn gtk_draw(state_arc: &Arc<UiMutex<State>>, ctx: &cairo::Context) -> Inhibit { fn gtk_draw(state_arc: &Arc<UiMutex<State>>, ctx: &cairo::Context) -> Inhibit {
@ -1153,7 +1155,7 @@ fn draw_initializing(state: &State, ctx: &cairo::Context) {
&render_state.font_ctx, &render_state.font_ctx,
y, y,
false, false,
&color_model.bg_color, &color_model,
); );
} }

View File

@ -13,12 +13,14 @@ use value::ValueMapExt;
struct State { struct State {
pmenu: Pmenu, pmenu: Pmenu,
cursor: Cursor,
} }
impl State { impl State {
fn new() -> Self { fn new() -> Self {
State { State {
pmenu: Pmenu::new(), pmenu: Pmenu::new(),
cursor: Cursor::new(),
} }
} }
} }
@ -38,7 +40,15 @@ impl Theme {
Ref::map(self.state.borrow(), |s| &s.pmenu) Ref::map(self.state.borrow(), |s| &s.pmenu)
} }
pub fn cursor(&self) -> Ref<Cursor> {
Ref::map(self.state.borrow(), |s| &s.cursor)
}
pub fn queue_update(&self, nvim: &mut Neovim) { pub fn queue_update(&self, nvim: &mut Neovim) {
self.get_hl(nvim, "Cursor", |state, bg, _fg| {
state.cursor.bg = bg;
});
self.get_hl(nvim, "Pmenu", |state, bg, fg| { self.get_hl(nvim, "Pmenu", |state, bg, fg| {
state.pmenu.bg = bg; state.pmenu.bg = bg;
state.pmenu.fg = fg; state.pmenu.fg = fg;
@ -70,6 +80,18 @@ impl Theme {
} }
} }
pub struct Cursor {
pub bg: Option<Color>,
}
impl Cursor {
pub fn new() -> Self {
Cursor {
bg: None,
}
}
}
pub struct Pmenu { pub struct Pmenu {
pub bg: Option<Color>, pub bg: Option<Color>,
pub fg: Option<Color>, pub fg: Option<Color>,