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);
}
render::clear(ctx, &render_state.color_model);
render::clear(ctx);
if let Some(block) = block {
render::render(
@ -559,6 +559,9 @@ fn gtk_draw(ctx: &cairo::Context, state: &Arc<UiMutex<State>>) -> Inhibit {
&render_state.color_model,
);
}
render::fill_background(ctx, &render_state.color_model);
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]
pub fn actual_cell_sp<'a>(&'a self, cell: &'a Cell) -> &'a Color {
cell.attrs.special.as_ref().unwrap_or(&self.sp_color)
@ -134,6 +126,14 @@ impl ColorModel {
.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)]

View File

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

View File

@ -16,7 +16,14 @@ use pangocairo;
use cursor::Cursor;
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(
color_model.bg_color.0,
color_model.bg_color.1,
@ -36,6 +43,40 @@ pub fn render<C: Cursor>(
let &CellMetrics { char_width, .. } = cell_metrics;
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) {
let mut line_x = 0.0;
@ -44,35 +85,6 @@ pub fn render<C: Cursor>(
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(
@ -104,7 +116,13 @@ fn draw_underline(
let undercurl_height = (underline_thickness * 4.0).min(max_undercurl_height);
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 {
let fg = color_model.actual_cell_fg(cell);
ctx.set_source_rgb(fg.0, fg.1, fg.2);

View File

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

View File

@ -957,7 +957,7 @@ fn gtk_draw_double_buffer(state: &State, ctx: &cairo::Context) {
buf_ctx.clip();
let render_state = state.render_state.borrow();
render::clear(buf_ctx, &render_state.color_model);
render::clear(buf_ctx);
render::render(
&buf_ctx,
state.cursor.as_ref().unwrap(),
@ -965,6 +965,7 @@ fn gtk_draw_double_buffer(state: &State, ctx: &cairo::Context) {
&state.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.paint();
@ -973,7 +974,7 @@ fn gtk_draw_double_buffer(state: &State, ctx: &cairo::Context) {
fn gtk_draw_direct(state: &State, ctx: &cairo::Context) {
let render_state = state.render_state.borrow();
render::clear(ctx, &render_state.color_model);
render::clear(ctx);
render::render(
ctx,
state.cursor.as_ref().unwrap(),
@ -981,6 +982,7 @@ fn gtk_draw_direct(state: &State, ctx: &cairo::Context) {
&state.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 {
@ -1153,7 +1155,7 @@ fn draw_initializing(state: &State, ctx: &cairo::Context) {
&render_state.font_ctx,
y,
false,
&color_model.bg_color,
&color_model,
);
}

View File

@ -13,12 +13,14 @@ use value::ValueMapExt;
struct State {
pmenu: Pmenu,
cursor: Cursor,
}
impl State {
fn new() -> Self {
State {
pmenu: Pmenu::new(),
cursor: Cursor::new(),
}
}
}
@ -38,7 +40,15 @@ impl Theme {
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) {
self.get_hl(nvim, "Cursor", |state, bg, _fg| {
state.cursor.bg = bg;
});
self.get_hl(nvim, "Pmenu", |state, bg, fg| {
state.pmenu.bg = bg;
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 bg: Option<Color>,
pub fg: Option<Color>,