From 1afac027e15623affd3e5435b88e056e0394c2f8 Mon Sep 17 00:00:00 2001 From: Ville Hakulinen Date: Mon, 17 Aug 2020 20:11:55 +0300 Subject: Support pumblend --- src/nvim_bridge/mod.rs | 3 ++ src/nvim_bridge/tests.rs | 5 +++ src/ui/color.rs | 37 ++++++++++++++++++ src/ui/popupmenu/popupmenu.rs | 89 ++++++++++++++++++++++++------------------- 4 files changed, 95 insertions(+), 39 deletions(-) diff --git a/src/nvim_bridge/mod.rs b/src/nvim_bridge/mod.rs index d5c1c07..cd7275d 100644 --- a/src/nvim_bridge/mod.rs +++ b/src/nvim_bridge/mod.rs @@ -120,6 +120,9 @@ impl Highlight { "undercurl" => { self.undercurl = unwrap_bool!(val); } + "blend" => { + self.blend = unwrap_f64!(val) / 100.0; + } "cterm_fg" => {} "cterm_bg" => {} _ => { diff --git a/src/nvim_bridge/tests.rs b/src/nvim_bridge/tests.rs index 44f2993..fa7163b 100644 --- a/src/nvim_bridge/tests.rs +++ b/src/nvim_bridge/tests.rs @@ -243,6 +243,7 @@ mod parse_redraw_event_tests { bold: true, underline: true, undercurl: false, + blend: 0.0, }, }, HlAttrDefine { @@ -256,6 +257,7 @@ mod parse_redraw_event_tests { bold: true, underline: false, undercurl: true, + blend: 0.0, }, }, HlAttrDefine { @@ -269,6 +271,7 @@ mod parse_redraw_event_tests { bold: true, underline: false, undercurl: true, + blend: 0.3, }, }, HlAttrDefine { @@ -282,6 +285,7 @@ mod parse_redraw_event_tests { bold: false, underline: false, undercurl: false, + blend: 0.0, }, }, ])]; @@ -320,6 +324,7 @@ mod parse_redraw_event_tests { ("italic".into(), true.into()), ("bold".into(), true.into()), ("undercurl".into(), true.into()), + ("blend".into(), 30.into()), )), )), Value::Array(vec!(3.into(), Value::Map(vec!()),)) diff --git a/src/ui/color.rs b/src/ui/color.rs index 6d7260a..0b7001c 100644 --- a/src/ui/color.rs +++ b/src/ui/color.rs @@ -66,6 +66,9 @@ pub struct Highlight { pub bold: bool, pub underline: bool, pub undercurl: bool, + + /// The blend value in range of 0..1. + pub blend: f64, } impl Highlight { @@ -108,6 +111,12 @@ impl Highlight { text = glib::markup_escape_text(text) ) } + + /// Apply the highlight's blend value to color. Returns the color + /// in `rgba()` format. + pub fn apply_blend(&self, color: &Color) -> String { + color.to_rgba(self.blend) + } } #[derive(Debug, Clone, Copy, Default, PartialEq)] @@ -156,4 +165,32 @@ impl Color { (self.b * 255.0) as u8 ) } + + /// Apply the blend value to color. Returns the color in `rgba()` format. + /// Note that the blend value is inverted. + pub fn to_rgba(&self, blend: f64) -> String { + format!( + "rgba({}, {}, {}, {})", + (self.r * 255.0) as u8, + (self.g * 255.0) as u8, + (self.b * 255.0) as u8, + 1.0 - blend + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_color_to_rgba() { + let c = Color { + r: 1.0, + g: 0.0, + b: 1.0, + }; + + assert_eq!(c.to_rgba(0.4), "rgba(255, 0, 255, 0.6)"); + } } diff --git a/src/ui/popupmenu/popupmenu.rs b/src/ui/popupmenu/popupmenu.rs index 75addf9..037b12e 100644 --- a/src/ui/popupmenu/popupmenu.rs +++ b/src/ui/popupmenu/popupmenu.rs @@ -5,7 +5,7 @@ use gtk::prelude::*; use crate::nvim_bridge::CompletionItem; use crate::nvim_gio::GioNeovim; -use crate::ui::color::{Color, HlDefs, HlGroup}; +use crate::ui::color::{Highlight, HlDefs, HlGroup}; use crate::ui::common::{ calc_line_space, get_preferred_horizontal_position, get_preferred_vertical_position, spawn_local, @@ -22,10 +22,8 @@ const DEFAULT_WIDTH_WITH_DETAILS: i32 = 660; #[derive(Default)] pub struct PmenuColors { - pub bg: Option, - pub fg: Option, - pub sel_bg: Option, - pub sel_fg: Option, + pub hl: Highlight, + pub hl_sel: Highlight, } struct State { @@ -385,7 +383,7 @@ impl Popupmenu { pub fn set_items(&mut self, items: Vec, hl_defs: &HlDefs) { self.items.set_items( items, - self.colors.fg.unwrap_or(hl_defs.default_fg), + self.colors.hl.foreground.unwrap_or(hl_defs.default_fg), self.font.height as f64, self.show_menu_on_all_items, ); @@ -396,8 +394,9 @@ impl Popupmenu { pub fn select(&mut self, item_num: i32, hl_defs: &HlDefs) { let state = self.state.clone(); let scrolled_list = self.scrolled_list.clone(); - let fg = self.colors.fg.unwrap_or(hl_defs.default_fg); - let fg_sel = self.colors.sel_fg.unwrap_or(hl_defs.default_fg); + let fg = self.colors.hl.foreground.unwrap_or(hl_defs.default_fg); + let fg_sel = + self.colors.hl_sel.foreground.unwrap_or(hl_defs.default_fg); let font_height = self.font.height as f64; let list = self.list.clone(); let info_label = self.info_label.clone(); @@ -500,26 +499,14 @@ impl Popupmenu { pub fn set_colors(&mut self, hl_defs: &HlDefs) { self.colors = PmenuColors { - bg: hl_defs + hl: hl_defs .get_hl_group(&HlGroup::Pmenu) .cloned() - .unwrap_or_default() - .background, - fg: hl_defs - .get_hl_group(&HlGroup::Pmenu) - .cloned() - .unwrap_or_default() - .foreground, - sel_bg: hl_defs + .unwrap_or_default(), + hl_sel: hl_defs .get_hl_group(&HlGroup::PmenuSel) .cloned() - .unwrap_or_default() - .background, - sel_fg: hl_defs - .get_hl_group(&HlGroup::PmenuSel) - .cloned() - .unwrap_or_default() - .foreground, + .unwrap_or_default(), }; self.set_styles(hl_defs); } @@ -553,7 +540,7 @@ impl Popupmenu { grid, list, row, label {{ color: #{normal_fg}; - background-color: #{normal_bg}; + background-color: {normal_bg}; outline: none; }} @@ -568,19 +555,31 @@ impl Popupmenu { row:selected, row:selected > grid, row:selected > grid > label {{ color: #{selected_fg}; - background-color: #{selected_bg}; + background-color: {selected_bg}; }} box {{ }} ", font_wild = self.font.as_wild_css(FontUnit::Point), - normal_fg = self.colors.fg.unwrap_or(hl_defs.default_fg).to_hex(), - normal_bg = self.colors.bg.unwrap_or(hl_defs.default_bg).to_hex(), - selected_bg = - self.colors.sel_bg.unwrap_or(hl_defs.default_bg).to_hex(), - selected_fg = - self.colors.sel_fg.unwrap_or(hl_defs.default_fg).to_hex(), + normal_fg = self + .colors + .hl + .foreground + .unwrap_or(hl_defs.default_fg) + .to_hex(), + normal_bg = self.colors.hl.apply_blend( + &self.colors.hl.background.unwrap_or(hl_defs.default_bg) + ), + selected_bg = self.colors.hl_sel.apply_blend( + &self.colors.hl_sel.background.unwrap_or(hl_defs.default_bg) + ), + selected_fg = self + .colors + .hl_sel + .foreground + .unwrap_or(hl_defs.default_fg) + .to_hex(), above = above.max(0), below = below.max(0), ); @@ -617,16 +616,28 @@ impl Popupmenu { GtkListBoxRow:selected > GtkGrid, GtkListBoxRow:selected > GtkGrid > GtkLabel {{ color: #{selected_fg}; - background-color: #{selected_bg}; + background-color: {selected_bg}; }} ", font_wild = self.font.as_wild_css(FontUnit::Pixel), - normal_fg = self.colors.fg.unwrap_or(hl_defs.default_fg).to_hex(), - normal_bg = self.colors.bg.unwrap_or(hl_defs.default_bg).to_hex(), - selected_bg = - self.colors.sel_bg.unwrap_or(hl_defs.default_bg).to_hex(), - selected_fg = - self.colors.sel_fg.unwrap_or(hl_defs.default_fg).to_hex(), + normal_fg = self + .colors + .hl + .foreground + .unwrap_or(hl_defs.default_fg) + .to_hex(), + normal_bg = self.colors.hl.apply_blend( + &self.colors.hl.background.unwrap_or(hl_defs.default_bg) + ), + selected_bg = self.colors.hl_sel.apply_blend( + &self.colors.hl_sel.background.unwrap_or(hl_defs.default_bg) + ), + selected_fg = self + .colors + .hl_sel + .foreground + .unwrap_or(hl_defs.default_fg) + .to_hex(), above = above.max(0), below = below.max(0), ); -- cgit v1.2.3