From 0b7810ce5bab03c3429cc84527076d3950355663 Mon Sep 17 00:00:00 2001 From: daa84 Date: Thu, 9 Mar 2017 13:19:44 +0300 Subject: [PATCH] Base code for underline/undercurl implementation not usable for now, one reason is not finished gtk-rs bindings --- src/nvim.rs | 3 +++ src/ui.rs | 66 ++++++++++++++++++++++++++++++++++++++++--------- src/ui_model.rs | 10 ++++++++ 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/nvim.rs b/src/nvim.rs index c9534cf..99a4feb 100644 --- a/src/nvim.rs +++ b/src/nvim.rs @@ -30,6 +30,8 @@ pub trait RedrawEvents { fn on_update_fg(&mut self, fg: i64); + fn on_update_sp(&mut self, sp: i64); + fn on_mode_change(&mut self, mode: &str); fn on_mouse_on(&mut self); @@ -169,6 +171,7 @@ fn call(ui: &mut Ui, method: &str, args: &Vec) -> result::Result<(), Stri "scroll" => ui.on_scroll(try_int!(args[0])), "update_bg" => ui.on_update_bg(try_int!(args[0])), "update_fg" => ui.on_update_fg(try_int!(args[0])), + "update_sp" => ui.on_update_sp(try_int!(args[0])), "mode_change" => ui.on_mode_change(try_str!(args[0])), "mouse_on" => ui.on_mouse_on(), "mouse_off" => ui.on_mouse_off(), diff --git a/src/ui.rs b/src/ui.rs index d6b3eaf..3ef752f 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -16,7 +16,7 @@ use gdk_sys; use glib; use neovim_lib::{Neovim, NeovimApi, Value, Integer}; -use ui_model::{UiModel, Attrs, Color, COLOR_BLACK, COLOR_WHITE}; +use ui_model::{UiModel, Attrs, Color, COLOR_BLACK, COLOR_WHITE, COLOR_RED}; use nvim::{RedrawEvents, GuiApi, ErrorReport}; use input::{convert_key, keyval_to_input_string}; @@ -51,6 +51,7 @@ pub struct Ui { cur_attrs: Option, bg_color: Color, fg_color: Color, + sp_color: Color, line_height: Option, char_width: Option, resize_timer: Option, @@ -71,6 +72,7 @@ impl Ui { cur_attrs: None, bg_color: COLOR_BLACK, fg_color: COLOR_WHITE, + sp_color: COLOR_RED, line_height: None, char_width: None, resize_timer: None, @@ -96,12 +98,14 @@ impl Ui { pub fn init(&mut self, app: >k::Application) { self.header_bar.set_show_close_button(true); - let save_image = Image::new_from_icon_name("document-save", gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32); + let save_image = Image::new_from_icon_name("document-save", + gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32); let save_btn = ToolButton::new(Some(&save_image), None); save_btn.connect_clicked(|_| edit_save_all()); self.header_bar.pack_start(&save_btn); - let paste_image = Image::new_from_icon_name("edit-paste", gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32); + let paste_image = Image::new_from_icon_name("edit-paste", + gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32); let paste_btn = ToolButton::new(Some(&paste_image), None); paste_btn.connect_clicked(|_| edit_paste()); self.header_bar.pack_start(&paste_btn); @@ -114,7 +118,7 @@ impl Ui { self.drawing_area .set_events((gdk_sys::GDK_BUTTON_RELEASE_MASK | gdk_sys::GDK_BUTTON_PRESS_MASK | gdk_sys::GDK_BUTTON_MOTION_MASK) - .bits() as i32); + .bits() as i32); self.drawing_area.connect_button_press_event(gtk_button_press); self.drawing_area.connect_button_release_event(gtk_button_release); self.drawing_area.connect_motion_notify_event(gtk_motion_notify); @@ -220,7 +224,7 @@ fn quit() { let nvim = ui.nvim(); nvim.ui_detach().expect("Error in ui_detach"); - //nvim.quit_no_save().expect("Can't stop nvim instance"); + // nvim.quit_no_save().expect("Can't stop nvim instance"); }); } @@ -343,14 +347,9 @@ fn draw(ui: &Ui, ctx: &cairo::Context) { ctx.move_to(current_point.0, current_point.1); } + if !cell.ch.is_whitespace() { - desc.unset_fields(pango::FONT_MASK_STYLE | pango::FONT_MASK_WEIGHT); - if cell.attrs.italic { - desc.set_style(pango::Style::Italic); - } - if cell.attrs.bold { - desc.set_weight(pango::Weight::Bold); - } + update_font_description(&mut desc, &cell.attrs); layout.set_font_description(Some(&desc)); buf.clear(); @@ -362,6 +361,25 @@ fn draw(ui: &Ui, ctx: &cairo::Context) { pc::show_layout(ctx, &layout); } + if cell.attrs.underline || cell.attrs.undercurl { + // [TODO]: Current gtk-rs bindings does not provide fontmetrics access + // so it is not possible to find right position for underline or undercurl position + // update_font_description(&mut desc, &cell.attrs); + // layout.get_context().unwrap().get_metrics(); + + let top_offset = line_height - 1.0; + if cell.attrs.undercurl { + ctx.move_to(current_point.0, line_y + top_offset); + ctx.line_to(current_point.0 + char_width, + line_y + top_offset); + } + else if cell.attrs.underline { + ctx.move_to(current_point.0, line_y + top_offset); + ctx.line_to(current_point.0 + char_width, + line_y + top_offset); + } + } + ctx.move_to(current_point.0 + char_width, current_point.1); } @@ -371,6 +389,17 @@ fn draw(ui: &Ui, ctx: &cairo::Context) { } +#[inline] +fn update_font_description(desc: &mut FontDescription, attrs: &Attrs) { + desc.unset_fields(pango::FONT_MASK_STYLE | pango::FONT_MASK_WEIGHT); + if attrs.italic { + desc.set_style(pango::Style::Italic); + } + if attrs.bold { + desc.set_weight(pango::Weight::Bold); + } +} + fn calc_char_bounds(ui: &Ui, ctx: &cairo::Context) -> (i32, i32) { let layout = pc::create_layout(ctx); @@ -447,6 +476,9 @@ impl RedrawEvents for Ui { if let Some(&Value::Integer(Integer::U64(bg))) = attrs.get("background") { model_attrs.background = Some(split_color(bg)); } + if let Some(&Value::Integer(Integer::U64(bg))) = attrs.get("special") { + model_attrs.special = Some(split_color(bg)); + } if attrs.contains_key("reverse") { let fg = if let Some(ref fg) = model_attrs.foreground { fg.clone() @@ -463,6 +495,8 @@ impl RedrawEvents for Ui { } model_attrs.bold = attrs.contains_key("bold"); model_attrs.italic = attrs.contains_key("italic"); + model_attrs.underline = attrs.contains_key("underline"); + model_attrs.undercurl = attrs.contains_key("undercurl"); self.cur_attrs = Some(model_attrs); } @@ -482,6 +516,14 @@ impl RedrawEvents for Ui { } } + fn on_update_sp(&mut self, sp: i64) { + if sp >= 0 { + self.sp_color = split_color(sp as u64); + } else { + self.sp_color = COLOR_RED; + } + } + fn on_mode_change(&mut self, mode: &str) { match mode { "normal" => self.mode = NvimMode::Normal, diff --git a/src/ui_model.rs b/src/ui_model.rs index 2b20554..15bbd50 100644 --- a/src/ui_model.rs +++ b/src/ui_model.rs @@ -4,13 +4,17 @@ pub struct Color(pub f64, pub f64, pub f64); pub const COLOR_BLACK: Color = Color(0.0, 0.0, 0.0); pub const COLOR_WHITE: Color = Color(1.0, 1.0, 1.0); +pub const COLOR_RED: Color = Color(1.0, 0.0, 0.0); #[derive(Clone)] pub struct Attrs { pub italic: bool, pub bold: bool, + pub underline: bool, + pub undercurl: bool, pub foreground: Option, pub background: Option, + pub special: Option, } impl Attrs { @@ -18,16 +22,22 @@ impl Attrs { Attrs { foreground: None, background: None, + special: None, italic: false, bold: false, + underline: false, + undercurl: false, } } fn clear(&mut self) { self.italic = false; self.bold = false; + self.underline = false; + self.undercurl = false; self.foreground = None; self.background = None; + self.special = None; } }