diff --git a/assets/style.toml b/assets/style.toml index 731de8e..b717a32 100644 --- a/assets/style.toml +++ b/assets/style.toml @@ -6,24 +6,24 @@ borders = "simple" # Alternatives are "none" and "outset" # Base colors are red, green, blue, # cyan, magenta, yellow, white and black. [colors] - background = ["#923456", "magenta"] + background = ["454", "#923456", "401", "magenta"] # If the value is an array, the first valid color will be used. # If the terminal doesn't support custom color, # non-base colors will be skipped. - shadow = ["#222222", "blue"] - view = "#888888" + shadow = ["#222288", "blue"] + view = "111" # Array and simple values have the same effect. - primary = ["#111111"] + primary = ["white"] secondary = "#EEEEEE" tertiary = "#444444" # Hex values can use lower or uppercase. # (base color MUST be lowercase) - title_primary = "#883333" + title_primary = "yellow" title_secondary = "#ffff55" # Lower precision values can use only 3 digits. - highlight = "#833" + highlight = "#F88" highlight_inactive = "#5555FF" diff --git a/src/backend.rs b/src/backend/curses.rs similarity index 82% rename from src/backend.rs rename to src/backend/curses.rs index 9dd8c8b..ba1c7cb 100644 --- a/src/backend.rs +++ b/src/backend/curses.rs @@ -1,31 +1,15 @@ +use backend; use event; use theme; use utf8; use ncurses; -pub trait Backend { - fn init(); - fn finish(); - - fn clear(); - fn refresh(); - - fn print_at((usize, usize), &str); - - fn poll_event() -> event::Event; - fn set_refresh_rate(fps: u32); - fn screen_size() -> (usize, usize); - - fn with_color(color: theme::ColorPair, f: F); - fn with_effect(effect: theme::Effect, f: F); -} - - pub struct NcursesBackend; -impl Backend for NcursesBackend { +impl backend::Backend for NcursesBackend { fn init() { + ::std::env::set_var("ESCDELAY", "25"); ncurses::setlocale(ncurses::LcCategory::all, ""); ncurses::initscr(); ncurses::keypad(ncurses::stdscr, true); @@ -34,7 +18,7 @@ impl Backend for NcursesBackend { ncurses::start_color(); ncurses::curs_set(ncurses::CURSOR_VISIBILITY::CURSOR_INVISIBLE); ncurses::wbkgd(ncurses::stdscr, - ncurses::COLOR_PAIR(theme::ColorPair::Background.ncurses_id())); + ncurses::COLOR_PAIR(theme::ColorStyle::Background.id())); } fn screen_size() -> (usize, usize) { @@ -44,16 +28,31 @@ impl Backend for NcursesBackend { (x as usize, y as usize) } + fn has_colors() -> bool { + ncurses::has_colors() + } + fn finish() { ncurses::endwin(); } - fn with_color(color: theme::ColorPair, f: F) { + + fn init_color_style(style: theme::ColorStyle, + foreground: &theme::Color, + background: &theme::Color) { + // TODO: build the color on the spot + + ncurses::init_pair(style.id(), + find_closest(foreground) as i16, + find_closest(background) as i16); + } + + fn with_color(color: theme::ColorStyle, f: F) { let mut current_style: ncurses::attr_t = 0; let mut current_color: i16 = 0; ncurses::attr_get(&mut current_style, &mut current_color); - let style = ncurses::COLOR_PAIR(color.ncurses_id()); + let style = ncurses::COLOR_PAIR(color.id()); ncurses::attron(style); f(); // ncurses::attroff(style); @@ -218,3 +217,25 @@ fn parse_ncurses_char(ch: i32) -> event::Key { _ => event::Key::Unknown(ch), } } + +fn find_closest(color: &theme::Color) -> u8 { + match *color { + theme::Color::Black => 0, + theme::Color::Red => 1, + theme::Color::Green => 2, + theme::Color::Yellow => 3, + theme::Color::Blue => 4, + theme::Color::Magenta => 5, + theme::Color::Cyan => 6, + theme::Color::White => 7, + theme::Color::Rgb(r, g, b) => { + let r = 6 * r as u16 / 256; + let g = 6 * g as u16 / 256; + let b = 6 * b as u16 / 256; + (16 + 36 * r + 6 * g + b) as u8 + } + theme::Color::RgbLowRes(r, g, b) => { + (16 + 36 * r + 6 * g + b) as u8 + } + } +} diff --git a/src/backend/mod.rs b/src/backend/mod.rs new file mode 100644 index 0000000..36c9cf2 --- /dev/null +++ b/src/backend/mod.rs @@ -0,0 +1,31 @@ +use event; +use theme; + +// Module is not named `ncurses` to avoir naming conflict +mod curses; + +pub use self::curses::NcursesBackend; + +pub trait Backend { + + fn init(); + fn finish(); + + fn clear(); + fn refresh(); + + fn has_colors() -> bool; + + fn init_color_style(style: theme::ColorStyle, + foreground: &theme::Color, + background: &theme::Color); + + fn print_at((usize, usize), &str); + + fn poll_event() -> event::Event; + fn set_refresh_rate(fps: u32); + fn screen_size() -> (usize, usize); + + fn with_color(color: theme::ColorStyle, f: F); + fn with_effect(effect: theme::Effect, f: F); +} diff --git a/src/lib.rs b/src/lib.rs index 97470bc..7f23c14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,13 +90,11 @@ impl Cursive { /// Creates a new Cursive root, and initialize ncurses. pub fn new() -> Self { // Default delay is way too long. 25 is imperceptible yet works fine. - std::env::set_var("ESCDELAY", "25"); B::init(); let theme = theme::load_default(); // let theme = theme::load_theme("assets/style.toml").unwrap(); - let mut res = Cursive { theme: theme, screens: Vec::new(), diff --git a/src/menubar.rs b/src/menubar.rs index 22bbc76..8532b59 100644 --- a/src/menubar.rs +++ b/src/menubar.rs @@ -1,5 +1,5 @@ use menu::*; -use theme::ColorPair; +use theme::ColorStyle; use printer::Printer; use event::*; @@ -22,7 +22,7 @@ impl Menubar { pub fn draw(&mut self, printer: &Printer) { // Draw the bar at the top - printer.with_color(ColorPair::Primary, |printer| { + printer.with_color(ColorStyle::Primary, |printer| { printer.print_hline((0, 0), printer.size.x, " "); }); diff --git a/src/printer.rs b/src/printer.rs index 79825a5..18595dd 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -6,7 +6,7 @@ use backend::Backend; use B; -use theme::{ColorPair, Theme, Effect}; +use theme::{ColorStyle, Theme, Effect}; use vec::{ToVec2, Vec2}; /// Convenient interface to draw on a subset of the screen. @@ -94,11 +94,11 @@ impl Printer { /// # use cursive::printer::Printer; /// # use cursive::theme; /// # let printer = Printer::new((6,4), theme::load_default()); - /// printer.with_color(theme::ColorPair::Highlight, |printer| { + /// printer.with_color(theme::ColorStyle::Highlight, |printer| { /// printer.print((0,0), "This text is highlighted!"); /// }); /// ``` - pub fn with_color(&self, c: ColorPair, f: F) + pub fn with_color(&self, c: ColorStyle, f: F) where F: FnOnce(&Printer) { B::with_color(c, || f(self)); diff --git a/src/theme.rs b/src/theme.rs index 7325250..b98a948 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -5,17 +5,24 @@ use std::io::Read; use std::fs::File; use std::path::Path; -use ncurses; +use backend::Backend; + use toml; +use B; + pub enum Effect { Simple, Reverse, } -/// Represents the color of a character and its background. +/// Possible color style for a cell. +/// +/// Represents a color pair role to use when printing something. +/// +/// The current theme will assign each role a foreground and background color. #[derive(Clone,Copy)] -pub enum ColorPair { +pub enum ColorStyle { /// Application background, where no view is present. Background, /// Color used by view shadows. Only background matters. @@ -36,19 +43,19 @@ pub enum ColorPair { HighlightInactive, } -impl ColorPair { +impl ColorStyle { /// Returns the ncurses pair ID associated with this color pair. - pub fn ncurses_id(self) -> i16 { + pub fn id(self) -> i16 { match self { - ColorPair::Background => 1, - ColorPair::Shadow => 2, - ColorPair::Primary => 3, - ColorPair::Secondary => 4, - ColorPair::Tertiary => 5, - ColorPair::TitlePrimary => 6, - ColorPair::TitleSecondary => 7, - ColorPair::Highlight => 8, - ColorPair::HighlightInactive => 9, + ColorStyle::Background => 1, + ColorStyle::Shadow => 2, + ColorStyle::Primary => 3, + ColorStyle::Secondary => 4, + ColorStyle::Tertiary => 5, + ColorStyle::TitlePrimary => 6, + ColorStyle::TitleSecondary => 7, + ColorStyle::Highlight => 8, + ColorStyle::HighlightInactive => 9, } } } @@ -61,29 +68,31 @@ pub struct Theme { /// How view borders should be drawn. pub borders: BorderStyle, /// What colors should be used through the application? - pub colors: ColorStyle, + pub colors: Palette, } -impl Theme { - fn default() -> Theme { +impl Default for Theme { + fn default() -> Self { Theme { shadow: true, borders: BorderStyle::Simple, - colors: ColorStyle { - background: Color::blue(), - shadow: Color::black(), - view: Color::white(), - primary: Color::black(), - secondary: Color::blue(), - tertiary: Color::white(), - title_primary: Color::red(), - title_secondary: Color::yellow(), - highlight: Color::red(), - highlight_inactive: Color::blue(), + colors: Palette { + background: Color::Blue, + shadow: Color::Black, + view: Color::White, + primary: Color::Black, + secondary: Color::Blue, + tertiary: Color::White, + title_primary: Color::Red, + title_secondary: Color::Yellow, + highlight: Color::Red, + highlight_inactive: Color::Blue, }, } } +} +impl Theme { fn load(&mut self, table: &toml::Table) { if let Some(&toml::Value::Boolean(shadow)) = table.get("shadow") { self.shadow = shadow; @@ -100,45 +109,48 @@ impl Theme { } } - fn apply(&self) { - Theme::apply_color(ColorPair::Background, - &self.colors.view, - &self.colors.background); - Theme::apply_color(ColorPair::Shadow, &self.colors.shadow, &self.colors.shadow); - Theme::apply_color(ColorPair::Primary, &self.colors.primary, &self.colors.view); - Theme::apply_color(ColorPair::Secondary, - &self.colors.secondary, - &self.colors.view); - Theme::apply_color(ColorPair::Tertiary, - &self.colors.tertiary, - &self.colors.view); - Theme::apply_color(ColorPair::TitlePrimary, - &self.colors.title_primary, - &self.colors.view); - Theme::apply_color(ColorPair::TitleSecondary, - &self.colors.title_secondary, - &self.colors.view); - Theme::apply_color(ColorPair::Highlight, - &self.colors.view, - &self.colors.highlight); - Theme::apply_color(ColorPair::HighlightInactive, - &self.colors.view, - &self.colors.highlight_inactive); - } - - fn apply_color(pair: ColorPair, front: &Color, back: &Color) { - ncurses::init_pair(pair.ncurses_id(), front.id, back.id); + fn activate(&self) { + // Initialize each color with the backend + B::init_color_style(ColorStyle::Background, + &self.colors.view, + &self.colors.background); + B::init_color_style(ColorStyle::Shadow, + &self.colors.shadow, + &self.colors.shadow); + B::init_color_style(ColorStyle::Primary, + &self.colors.primary, + &self.colors.view); + B::init_color_style(ColorStyle::Secondary, + &self.colors.secondary, + &self.colors.view); + B::init_color_style(ColorStyle::Tertiary, + &self.colors.tertiary, + &self.colors.view); + B::init_color_style(ColorStyle::TitlePrimary, + &self.colors.title_primary, + &self.colors.view); + B::init_color_style(ColorStyle::TitleSecondary, + &self.colors.title_secondary, + &self.colors.view); + B::init_color_style(ColorStyle::Highlight, + &self.colors.view, + &self.colors.highlight); + B::init_color_style(ColorStyle::HighlightInactive, + &self.colors.view, + &self.colors.highlight_inactive); } } -/// Specifies how View borders should be drawn. +/// Specifies how some borders should be drawn. +/// +/// Borders are used around Dialogs, select popups, and panels. #[derive(Clone,Copy,Debug)] pub enum BorderStyle { /// Don't draw any border. NoBorder, /// Simple borders. Simple, - /// Outset borders with a 3d effect. + /// Outset borders with a simple 3d effect. Outset, } @@ -156,9 +168,11 @@ impl BorderStyle { } } -/// Represents the colors the application will use in various situations. +/// Color configuration for the application. +/// +/// Assign each color role an actual color. #[derive(Clone,Debug)] -pub struct ColorStyle { +pub struct Palette { /// Color used for the application background. pub background: Color, /// Color used for View shadows. @@ -181,39 +195,57 @@ pub struct ColorStyle { pub highlight_inactive: Color, } -impl ColorStyle { +impl Palette { fn load(&mut self, table: &toml::Table) { - let mut new_id = 16; - self.background.load(table, "background", &mut new_id); - self.shadow.load(table, "shadow", &mut new_id); - self.view.load(table, "view", &mut new_id); - self.primary.load(table, "primary", &mut new_id); - self.secondary.load(table, "secondary", &mut new_id); - self.tertiary.load(table, "tertiary", &mut new_id); - self.title_primary.load(table, "title_primary", &mut new_id); - self.title_secondary.load(table, "title_secondary", &mut new_id); - self.highlight.load(table, "highlight", &mut new_id); - self.highlight_inactive.load(table, "highlight_inactive", &mut new_id); + load_color(&mut self.background, table.get("background")); + load_color(&mut self.shadow, table.get("shadow")); + load_color(&mut self.view, table.get("view")); + load_color(&mut self.primary, table.get("primary")); + load_color(&mut self.secondary, table.get("secondary")); + load_color(&mut self.tertiary, table.get("tertiary")); + load_color(&mut self.title_primary, table.get("title_primary")); + load_color(&mut self.title_secondary, table.get("title_secondary")); + load_color(&mut self.highlight, table.get("highlight")); + load_color(&mut self.highlight_inactive, table.get("highlight_inactive")); + } +} + +fn load_color(target: &mut Color, value: Option<&toml::Value>) -> bool { + if let Some(value) = value { + match *value { + toml::Value::String(ref value) => if let Some(color) = Color::parse(value) { + *target = color; + true + } else { + false + }, + toml::Value::Array(ref array) => array.iter().any(|item| load_color(target, Some(item))), + _ => false, + } + } else { + false } } /// Represents a color used by the theme. #[derive(Clone,Debug)] -pub struct Color { +pub enum Color { /// Color ID used by ncurses. - pub id: i16, + Black, + Red, + Green, + Yellow, + Blue, + Magenta, + Cyan, + White, + // 24-bit color + Rgb(u8, u8, u8), + RgbLowRes(u8, u8, u8), } impl Color { - /// Return the rgb values used by the color. - pub fn rgb(&self) -> (i16, i16, i16) { - let (mut r, mut g, mut b) = (0, 0, 0); - - ncurses::color_content(self.id, &mut r, &mut g, &mut b); - - (r, g, b) - } } /// Possible error returned when loading a theme. @@ -232,115 +264,47 @@ impl From for Error { } impl Color { - fn parse(value: &str, new_id: &mut i16) -> Option { - let color = if value == "black" { - Color::black() - } else if value == "red" { - Color::red() - } else if value == "green" { - Color::green() - } else if value == "yellow" { - Color::yellow() - } else if value == "blue" { - Color::blue() - } else if value == "magenta" { - Color::magenta() - } else if value == "cyan" { - Color::cyan() - } else if value == "white" { - Color::white() + fn parse(value: &str) -> Option { + Some(match value { + "black" => Color::Black, + "red" => Color::Red, + "green" => Color::Green, + "yellow" => Color::Yellow, + "blue" => Color::Blue, + "magenta" => Color::Magenta, + "cyan" => Color::Cyan, + "white" => Color::White, + value => return Color::parse_special(value), + }) + } + + fn parse_special(value: &str) -> Option { + if value.starts_with('#') { + + let value = &value[1..]; + // Compute per-color length, and amplitude + let (l, multiplier) = match value.len() { + 6 => (2, 1), + 3 => (1, 17), + _ => panic!("Cannot parse color: {}", value), + }; + let r = load_hex(&value[0 * l..1 * l]) * multiplier; + let g = load_hex(&value[1 * l..2 * l]) * multiplier; + let b = load_hex(&value[2 * l..3 * l]) * multiplier; + Some(Color::Rgb(r as u8, g as u8, b as u8)) + } else if value.len() == 3 { + // RGB values between 0 and 5 maybe? + let rgb: Vec<_> = value.chars().map(|c| c as i16 - '0' as i16).collect(); + println!("{:?}", rgb); + if rgb.iter().all(|&i| i >= 0 && i < 6) { + Some(Color::RgbLowRes(rgb[0] as u8, rgb[1] as u8, rgb[2] as u8)) + } else { + None + } } else { - // Let's make a new color - return Color::make_new(value, new_id); - }; - - Some(color) - } - - fn load(&mut self, table: &toml::Table, key: &str, new_id: &mut i16) { - match table.get(key) { - Some(&toml::Value::String(ref value)) => { - self.load_value(value, new_id); - } - Some(&toml::Value::Array(ref array)) => { - for color in array.iter() { - if let toml::Value::String(ref color) = *color { - if self.load_value(color, new_id) { - return; - } - } - } - } - _ => (), + None } } - - fn load_value(&mut self, value: &str, new_id: &mut i16) -> bool { - match Color::parse(value, new_id) { - Some(color) => self.id = color.id, - None => return false, - } - true - } - - fn make_new(value: &str, new_id: &mut i16) -> Option { - // if !ncurses::can_change_color() { - if !ncurses::has_colors() { - return None; - } - - if !value.starts_with('#') { - return None; - } - - if *new_id >= ncurses::COLORS as i16 { - return None; - } - - let s = &value[1..]; - let (l, max) = match s.len() { - 6 => (2, 255), - 3 => (1, 15), - _ => panic!("Cannot parse color: {}", s), - }; - - let r = (load_hex(&s[0 * l..1 * l]) as i32 * 1000 / max) as i16; - let g = (load_hex(&s[1 * l..2 * l]) as i32 * 1000 / max) as i16; - let b = (load_hex(&s[2 * l..3 * l]) as i32 * 1000 / max) as i16; - - ncurses::init_color(*new_id, r, g, b); - - let color = Color { id: *new_id }; - *new_id += 1; - - Some(color) - } - - - pub fn black() -> Self { - Color { id: 0 } - } - pub fn red() -> Self { - Color { id: 1 } - } - pub fn green() -> Self { - Color { id: 2 } - } - pub fn yellow() -> Self { - Color { id: 3 } - } - pub fn blue() -> Self { - Color { id: 4 } - } - pub fn magenta() -> Self { - Color { id: 5 } - } - pub fn cyan() -> Self { - Color { id: 6 } - } - pub fn white() -> Self { - Color { id: 7 } - } } @@ -379,6 +343,7 @@ impl Color { /// highlight_inactive = "#5555FF" /// ``` +/// Loads a theme and sets it as active. pub fn load_theme>(filename: P) -> Result { let content = { let mut content = String::new(); @@ -395,7 +360,7 @@ pub fn load_theme>(filename: P) -> Result { let mut theme = Theme::default(); theme.load(&table); - theme.apply(); + theme.activate(); Ok(theme) } @@ -403,12 +368,12 @@ pub fn load_theme>(filename: P) -> Result { /// Loads the default theme, and returns its representation. pub fn load_default() -> Theme { let theme = Theme::default(); - theme.apply(); + theme.activate(); theme } /// Loads a hexadecimal code -fn load_hex(s: &str) -> i16 { +fn load_hex(s: &str) -> u16 { let mut sum = 0; for c in s.chars() { sum *= 16; @@ -420,5 +385,5 @@ fn load_hex(s: &str) -> i16 { }; } - sum + sum as u16 } diff --git a/src/view/button.rs b/src/view/button.rs index c4d5728..e041d81 100644 --- a/src/view/button.rs +++ b/src/view/button.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use theme::ColorPair; +use theme::ColorStyle; use Cursive; use vec::Vec2; use view::{SizeRequest, View}; @@ -29,9 +29,9 @@ impl Button { impl View for Button { fn draw(&mut self, printer: &Printer) { let style = if !printer.focused { - ColorPair::Primary + ColorStyle::Primary } else { - ColorPair::Highlight + ColorStyle::Highlight }; let x = printer.size.x - 1; diff --git a/src/view/dialog.rs b/src/view/dialog.rs index 5e77d4f..d41dae4 100644 --- a/src/view/dialog.rs +++ b/src/view/dialog.rs @@ -4,7 +4,7 @@ use std::any::Any; use Cursive; use align::*; use event::*; -use theme::ColorPair; +use theme::ColorStyle; use view::{DimensionRequest, Selector, SizeRequest, TextView, View}; use view::{Button, SizedView}; use vec::{ToVec4, Vec2, Vec4}; @@ -152,7 +152,7 @@ impl View for Dialog { printer.print((x - 2, 0), "┤ "); printer.print((x + len, 0), " ├"); - printer.with_color(ColorPair::TitlePrimary, |p| p.print((x, 0), &self.title)); + printer.with_color(ColorStyle::TitlePrimary, |p| p.print((x, 0), &self.title)); } } diff --git a/src/view/edit_view.rs b/src/view/edit_view.rs index b65d42c..7544ac0 100644 --- a/src/view/edit_view.rs +++ b/src/view/edit_view.rs @@ -2,7 +2,7 @@ use unicode_segmentation::UnicodeSegmentation; use std::cmp::min; -use theme::{ColorPair, Effect}; +use theme::{ColorStyle, Effect}; use vec::Vec2; use view::{IdView, SizeRequest, View}; use event::*; @@ -85,7 +85,7 @@ impl View for EditView { fn draw(&mut self, printer: &Printer) { // let style = if focused { color::HIGHLIGHT } else { color::HIGHLIGHT_INACTIVE }; let len = self.content.chars().count(); - printer.with_color(ColorPair::Secondary, |printer| { + printer.with_color(ColorStyle::Secondary, |printer| { printer.with_effect(Effect::Reverse, |printer| { if len < self.last_length { printer.print((0, 0), &self.content); diff --git a/src/view/scroll.rs b/src/view/scroll.rs index dc2759f..b6f8453 100644 --- a/src/view/scroll.rs +++ b/src/view/scroll.rs @@ -1,6 +1,6 @@ use std::cmp::{max, min}; -use theme::ColorPair; +use theme::ColorStyle; use vec::Vec2; use printer::Printer; @@ -129,9 +129,9 @@ impl ScrollBase { let start = steps * self.start_line / (1 + self.content_height - self.view_height); let color = if printer.focused { - ColorPair::Highlight + ColorStyle::Highlight } else { - ColorPair::HighlightInactive + ColorStyle::HighlightInactive }; printer.print_vline((printer.size.x - 1, 0), printer.size.y, "|"); diff --git a/src/view/select_view.rs b/src/view/select_view.rs index 5bd5ca8..72b2ffd 100644 --- a/src/view/select_view.rs +++ b/src/view/select_view.rs @@ -1,7 +1,7 @@ use std::cmp::min; use std::rc::Rc; -use theme::ColorPair; +use theme::ColorStyle; use Cursive; use align::*; use view::{DimensionRequest, IdView, SizeRequest, View}; @@ -133,12 +133,12 @@ impl View for SelectView { self.scrollbase.draw(printer, |printer, i| { let style = if i == self.focus { if printer.focused { - ColorPair::Highlight + ColorStyle::Highlight } else { - ColorPair::HighlightInactive + ColorStyle::HighlightInactive } } else { - ColorPair::Primary + ColorStyle::Primary }; printer.with_color(style, |printer| { let l = self.items[i].label.chars().count(); diff --git a/src/view/shadow_view.rs b/src/view/shadow_view.rs index 3ad93db..d41ad09 100644 --- a/src/view/shadow_view.rs +++ b/src/view/shadow_view.rs @@ -1,7 +1,7 @@ use view::{SizeRequest, View, ViewWrapper}; use printer::Printer; use vec::Vec2; -use theme::ColorPair; +use theme::ColorStyle; /// Wrapper view that adds a shadow. /// @@ -40,7 +40,7 @@ impl ViewWrapper for ShadowView { let h = printer.size.y - 1; let w = printer.size.x - 1; - printer.with_color(ColorPair::Shadow, |printer| { + printer.with_color(ColorStyle::Shadow, |printer| { printer.print_hline((2, h), w - 1, " "); printer.print_vline((w, 2), h - 1, " "); }); diff --git a/src/view/stack_view.rs b/src/view/stack_view.rs index 9b2d9cf..f01e31d 100644 --- a/src/view/stack_view.rs +++ b/src/view/stack_view.rs @@ -4,7 +4,7 @@ use vec::Vec2; use view::{DimensionRequest, Selector, ShadowView, SizeRequest, View}; use event::{Event, EventResult}; use printer::Printer; -use theme::ColorPair; +use theme::ColorStyle; /// Simple stack of views. /// Only the top-most view is active and can receive input. @@ -49,7 +49,7 @@ impl StackView { impl View for StackView { fn draw(&mut self, printer: &Printer) { let last = self.layers.len(); - printer.with_color(ColorPair::Primary, |printer| { + printer.with_color(ColorStyle::Primary, |printer| { for (i, v) in self.layers.iter_mut().enumerate() { // Center the view let size = v.size;