More ncurses isolation

Also some renaming in the theme module
This commit is contained in:
Alexandre Bury 2016-06-30 23:38:01 -07:00
parent 4dcb2ea901
commit 985009e51c
14 changed files with 260 additions and 245 deletions

View File

@ -6,24 +6,24 @@ borders = "simple" # Alternatives are "none" and "outset"
# Base colors are red, green, blue, # Base colors are red, green, blue,
# cyan, magenta, yellow, white and black. # cyan, magenta, yellow, white and black.
[colors] [colors]
background = ["#923456", "magenta"] background = ["454", "#923456", "401", "magenta"]
# If the value is an array, the first valid color will be used. # If the value is an array, the first valid color will be used.
# If the terminal doesn't support custom color, # If the terminal doesn't support custom color,
# non-base colors will be skipped. # non-base colors will be skipped.
shadow = ["#222222", "blue"] shadow = ["#222288", "blue"]
view = "#888888" view = "111"
# Array and simple values have the same effect. # Array and simple values have the same effect.
primary = ["#111111"] primary = ["white"]
secondary = "#EEEEEE" secondary = "#EEEEEE"
tertiary = "#444444" tertiary = "#444444"
# Hex values can use lower or uppercase. # Hex values can use lower or uppercase.
# (base color MUST be lowercase) # (base color MUST be lowercase)
title_primary = "#883333" title_primary = "yellow"
title_secondary = "#ffff55" title_secondary = "#ffff55"
# Lower precision values can use only 3 digits. # Lower precision values can use only 3 digits.
highlight = "#833" highlight = "#F88"
highlight_inactive = "#5555FF" highlight_inactive = "#5555FF"

View File

@ -1,31 +1,15 @@
use backend;
use event; use event;
use theme; use theme;
use utf8; use utf8;
use ncurses; 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<F: FnOnce()>(color: theme::ColorPair, f: F);
fn with_effect<F: FnOnce()>(effect: theme::Effect, f: F);
}
pub struct NcursesBackend; pub struct NcursesBackend;
impl Backend for NcursesBackend { impl backend::Backend for NcursesBackend {
fn init() { fn init() {
::std::env::set_var("ESCDELAY", "25");
ncurses::setlocale(ncurses::LcCategory::all, ""); ncurses::setlocale(ncurses::LcCategory::all, "");
ncurses::initscr(); ncurses::initscr();
ncurses::keypad(ncurses::stdscr, true); ncurses::keypad(ncurses::stdscr, true);
@ -34,7 +18,7 @@ impl Backend for NcursesBackend {
ncurses::start_color(); ncurses::start_color();
ncurses::curs_set(ncurses::CURSOR_VISIBILITY::CURSOR_INVISIBLE); ncurses::curs_set(ncurses::CURSOR_VISIBILITY::CURSOR_INVISIBLE);
ncurses::wbkgd(ncurses::stdscr, ncurses::wbkgd(ncurses::stdscr,
ncurses::COLOR_PAIR(theme::ColorPair::Background.ncurses_id())); ncurses::COLOR_PAIR(theme::ColorStyle::Background.id()));
} }
fn screen_size() -> (usize, usize) { fn screen_size() -> (usize, usize) {
@ -44,16 +28,31 @@ impl Backend for NcursesBackend {
(x as usize, y as usize) (x as usize, y as usize)
} }
fn has_colors() -> bool {
ncurses::has_colors()
}
fn finish() { fn finish() {
ncurses::endwin(); ncurses::endwin();
} }
fn with_color<F: FnOnce()>(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<F: FnOnce()>(color: theme::ColorStyle, f: F) {
let mut current_style: ncurses::attr_t = 0; let mut current_style: ncurses::attr_t = 0;
let mut current_color: i16 = 0; let mut current_color: i16 = 0;
ncurses::attr_get(&mut current_style, &mut current_color); 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); ncurses::attron(style);
f(); f();
// ncurses::attroff(style); // ncurses::attroff(style);
@ -218,3 +217,25 @@ fn parse_ncurses_char(ch: i32) -> event::Key {
_ => event::Key::Unknown(ch), _ => 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
}
}
}

31
src/backend/mod.rs Normal file
View File

@ -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<F: FnOnce()>(color: theme::ColorStyle, f: F);
fn with_effect<F: FnOnce()>(effect: theme::Effect, f: F);
}

View File

@ -90,13 +90,11 @@ impl Cursive {
/// Creates a new Cursive root, and initialize ncurses. /// Creates a new Cursive root, and initialize ncurses.
pub fn new() -> Self { pub fn new() -> Self {
// Default delay is way too long. 25 is imperceptible yet works fine. // Default delay is way too long. 25 is imperceptible yet works fine.
std::env::set_var("ESCDELAY", "25");
B::init(); B::init();
let theme = theme::load_default(); let theme = theme::load_default();
// let theme = theme::load_theme("assets/style.toml").unwrap(); // let theme = theme::load_theme("assets/style.toml").unwrap();
let mut res = Cursive { let mut res = Cursive {
theme: theme, theme: theme,
screens: Vec::new(), screens: Vec::new(),

View File

@ -1,5 +1,5 @@
use menu::*; use menu::*;
use theme::ColorPair; use theme::ColorStyle;
use printer::Printer; use printer::Printer;
use event::*; use event::*;
@ -22,7 +22,7 @@ impl Menubar {
pub fn draw(&mut self, printer: &Printer) { pub fn draw(&mut self, printer: &Printer) {
// Draw the bar at the top // 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, " "); printer.print_hline((0, 0), printer.size.x, " ");
}); });

View File

@ -6,7 +6,7 @@ use backend::Backend;
use B; use B;
use theme::{ColorPair, Theme, Effect}; use theme::{ColorStyle, Theme, Effect};
use vec::{ToVec2, Vec2}; use vec::{ToVec2, Vec2};
/// Convenient interface to draw on a subset of the screen. /// Convenient interface to draw on a subset of the screen.
@ -94,11 +94,11 @@ impl Printer {
/// # use cursive::printer::Printer; /// # use cursive::printer::Printer;
/// # use cursive::theme; /// # use cursive::theme;
/// # let printer = Printer::new((6,4), theme::load_default()); /// # 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!"); /// printer.print((0,0), "This text is highlighted!");
/// }); /// });
/// ``` /// ```
pub fn with_color<F>(&self, c: ColorPair, f: F) pub fn with_color<F>(&self, c: ColorStyle, f: F)
where F: FnOnce(&Printer) where F: FnOnce(&Printer)
{ {
B::with_color(c, || f(self)); B::with_color(c, || f(self));

View File

@ -5,17 +5,24 @@ use std::io::Read;
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
use ncurses; use backend::Backend;
use toml; use toml;
use B;
pub enum Effect { pub enum Effect {
Simple, Simple,
Reverse, 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)] #[derive(Clone,Copy)]
pub enum ColorPair { pub enum ColorStyle {
/// Application background, where no view is present. /// Application background, where no view is present.
Background, Background,
/// Color used by view shadows. Only background matters. /// Color used by view shadows. Only background matters.
@ -36,19 +43,19 @@ pub enum ColorPair {
HighlightInactive, HighlightInactive,
} }
impl ColorPair { impl ColorStyle {
/// Returns the ncurses pair ID associated with this color pair. /// Returns the ncurses pair ID associated with this color pair.
pub fn ncurses_id(self) -> i16 { pub fn id(self) -> i16 {
match self { match self {
ColorPair::Background => 1, ColorStyle::Background => 1,
ColorPair::Shadow => 2, ColorStyle::Shadow => 2,
ColorPair::Primary => 3, ColorStyle::Primary => 3,
ColorPair::Secondary => 4, ColorStyle::Secondary => 4,
ColorPair::Tertiary => 5, ColorStyle::Tertiary => 5,
ColorPair::TitlePrimary => 6, ColorStyle::TitlePrimary => 6,
ColorPair::TitleSecondary => 7, ColorStyle::TitleSecondary => 7,
ColorPair::Highlight => 8, ColorStyle::Highlight => 8,
ColorPair::HighlightInactive => 9, ColorStyle::HighlightInactive => 9,
} }
} }
} }
@ -61,29 +68,31 @@ pub struct Theme {
/// How view borders should be drawn. /// How view borders should be drawn.
pub borders: BorderStyle, pub borders: BorderStyle,
/// What colors should be used through the application? /// What colors should be used through the application?
pub colors: ColorStyle, pub colors: Palette,
} }
impl Theme { impl Default for Theme {
fn default() -> Theme { fn default() -> Self {
Theme { Theme {
shadow: true, shadow: true,
borders: BorderStyle::Simple, borders: BorderStyle::Simple,
colors: ColorStyle { colors: Palette {
background: Color::blue(), background: Color::Blue,
shadow: Color::black(), shadow: Color::Black,
view: Color::white(), view: Color::White,
primary: Color::black(), primary: Color::Black,
secondary: Color::blue(), secondary: Color::Blue,
tertiary: Color::white(), tertiary: Color::White,
title_primary: Color::red(), title_primary: Color::Red,
title_secondary: Color::yellow(), title_secondary: Color::Yellow,
highlight: Color::red(), highlight: Color::Red,
highlight_inactive: Color::blue(), highlight_inactive: Color::Blue,
}, },
} }
} }
}
impl Theme {
fn load(&mut self, table: &toml::Table) { fn load(&mut self, table: &toml::Table) {
if let Some(&toml::Value::Boolean(shadow)) = table.get("shadow") { if let Some(&toml::Value::Boolean(shadow)) = table.get("shadow") {
self.shadow = shadow; self.shadow = shadow;
@ -100,45 +109,48 @@ impl Theme {
} }
} }
fn apply(&self) { fn activate(&self) {
Theme::apply_color(ColorPair::Background, // Initialize each color with the backend
B::init_color_style(ColorStyle::Background,
&self.colors.view, &self.colors.view,
&self.colors.background); &self.colors.background);
Theme::apply_color(ColorPair::Shadow, &self.colors.shadow, &self.colors.shadow); B::init_color_style(ColorStyle::Shadow,
Theme::apply_color(ColorPair::Primary, &self.colors.primary, &self.colors.view); &self.colors.shadow,
Theme::apply_color(ColorPair::Secondary, &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.secondary,
&self.colors.view); &self.colors.view);
Theme::apply_color(ColorPair::Tertiary, B::init_color_style(ColorStyle::Tertiary,
&self.colors.tertiary, &self.colors.tertiary,
&self.colors.view); &self.colors.view);
Theme::apply_color(ColorPair::TitlePrimary, B::init_color_style(ColorStyle::TitlePrimary,
&self.colors.title_primary, &self.colors.title_primary,
&self.colors.view); &self.colors.view);
Theme::apply_color(ColorPair::TitleSecondary, B::init_color_style(ColorStyle::TitleSecondary,
&self.colors.title_secondary, &self.colors.title_secondary,
&self.colors.view); &self.colors.view);
Theme::apply_color(ColorPair::Highlight, B::init_color_style(ColorStyle::Highlight,
&self.colors.view, &self.colors.view,
&self.colors.highlight); &self.colors.highlight);
Theme::apply_color(ColorPair::HighlightInactive, B::init_color_style(ColorStyle::HighlightInactive,
&self.colors.view, &self.colors.view,
&self.colors.highlight_inactive); &self.colors.highlight_inactive);
} }
fn apply_color(pair: ColorPair, front: &Color, back: &Color) {
ncurses::init_pair(pair.ncurses_id(), front.id, back.id);
}
} }
/// 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)] #[derive(Clone,Copy,Debug)]
pub enum BorderStyle { pub enum BorderStyle {
/// Don't draw any border. /// Don't draw any border.
NoBorder, NoBorder,
/// Simple borders. /// Simple borders.
Simple, Simple,
/// Outset borders with a 3d effect. /// Outset borders with a simple 3d effect.
Outset, 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)] #[derive(Clone,Debug)]
pub struct ColorStyle { pub struct Palette {
/// Color used for the application background. /// Color used for the application background.
pub background: Color, pub background: Color,
/// Color used for View shadows. /// Color used for View shadows.
@ -181,39 +195,57 @@ pub struct ColorStyle {
pub highlight_inactive: Color, pub highlight_inactive: Color,
} }
impl ColorStyle { impl Palette {
fn load(&mut self, table: &toml::Table) { fn load(&mut self, table: &toml::Table) {
let mut new_id = 16;
self.background.load(table, "background", &mut new_id); load_color(&mut self.background, table.get("background"));
self.shadow.load(table, "shadow", &mut new_id); load_color(&mut self.shadow, table.get("shadow"));
self.view.load(table, "view", &mut new_id); load_color(&mut self.view, table.get("view"));
self.primary.load(table, "primary", &mut new_id); load_color(&mut self.primary, table.get("primary"));
self.secondary.load(table, "secondary", &mut new_id); load_color(&mut self.secondary, table.get("secondary"));
self.tertiary.load(table, "tertiary", &mut new_id); load_color(&mut self.tertiary, table.get("tertiary"));
self.title_primary.load(table, "title_primary", &mut new_id); load_color(&mut self.title_primary, table.get("title_primary"));
self.title_secondary.load(table, "title_secondary", &mut new_id); load_color(&mut self.title_secondary, table.get("title_secondary"));
self.highlight.load(table, "highlight", &mut new_id); load_color(&mut self.highlight, table.get("highlight"));
self.highlight_inactive.load(table, "highlight_inactive", &mut new_id); 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. /// Represents a color used by the theme.
#[derive(Clone,Debug)] #[derive(Clone,Debug)]
pub struct Color { pub enum Color {
/// Color ID used by ncurses. /// 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 { 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. /// Possible error returned when loading a theme.
@ -232,114 +264,46 @@ impl From<io::Error> for Error {
} }
impl Color { impl Color {
fn parse(value: &str, new_id: &mut i16) -> Option<Self> { fn parse(value: &str) -> Option<Self> {
let color = if value == "black" { Some(match value {
Color::black() "black" => Color::Black,
} else if value == "red" { "red" => Color::Red,
Color::red() "green" => Color::Green,
} else if value == "green" { "yellow" => Color::Yellow,
Color::green() "blue" => Color::Blue,
} else if value == "yellow" { "magenta" => Color::Magenta,
Color::yellow() "cyan" => Color::Cyan,
} else if value == "blue" { "white" => Color::White,
Color::blue() value => return Color::parse_special(value),
} else if value == "magenta" { })
Color::magenta() }
} else if value == "cyan" {
Color::cyan() fn parse_special(value: &str) -> Option<Color> {
} else if value == "white" { if value.starts_with('#') {
Color::white()
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 { } else {
// Let's make a new color None
return Color::make_new(value, new_id);
};
Some(color)
} }
} else {
fn load(&mut self, table: &toml::Table, key: &str, new_id: &mut i16) { None
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;
}
}
}
}
_ => (),
}
}
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<Self> {
// 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" /// highlight_inactive = "#5555FF"
/// ``` /// ```
/// Loads a theme and sets it as active.
pub fn load_theme<P: AsRef<Path>>(filename: P) -> Result<Theme, Error> { pub fn load_theme<P: AsRef<Path>>(filename: P) -> Result<Theme, Error> {
let content = { let content = {
let mut content = String::new(); let mut content = String::new();
@ -395,7 +360,7 @@ pub fn load_theme<P: AsRef<Path>>(filename: P) -> Result<Theme, Error> {
let mut theme = Theme::default(); let mut theme = Theme::default();
theme.load(&table); theme.load(&table);
theme.apply(); theme.activate();
Ok(theme) Ok(theme)
} }
@ -403,12 +368,12 @@ pub fn load_theme<P: AsRef<Path>>(filename: P) -> Result<Theme, Error> {
/// Loads the default theme, and returns its representation. /// Loads the default theme, and returns its representation.
pub fn load_default() -> Theme { pub fn load_default() -> Theme {
let theme = Theme::default(); let theme = Theme::default();
theme.apply(); theme.activate();
theme theme
} }
/// Loads a hexadecimal code /// Loads a hexadecimal code
fn load_hex(s: &str) -> i16 { fn load_hex(s: &str) -> u16 {
let mut sum = 0; let mut sum = 0;
for c in s.chars() { for c in s.chars() {
sum *= 16; sum *= 16;
@ -420,5 +385,5 @@ fn load_hex(s: &str) -> i16 {
}; };
} }
sum sum as u16
} }

View File

@ -1,6 +1,6 @@
use std::rc::Rc; use std::rc::Rc;
use theme::ColorPair; use theme::ColorStyle;
use Cursive; use Cursive;
use vec::Vec2; use vec::Vec2;
use view::{SizeRequest, View}; use view::{SizeRequest, View};
@ -29,9 +29,9 @@ impl Button {
impl View for Button { impl View for Button {
fn draw(&mut self, printer: &Printer) { fn draw(&mut self, printer: &Printer) {
let style = if !printer.focused { let style = if !printer.focused {
ColorPair::Primary ColorStyle::Primary
} else { } else {
ColorPair::Highlight ColorStyle::Highlight
}; };
let x = printer.size.x - 1; let x = printer.size.x - 1;

View File

@ -4,7 +4,7 @@ use std::any::Any;
use Cursive; use Cursive;
use align::*; use align::*;
use event::*; use event::*;
use theme::ColorPair; use theme::ColorStyle;
use view::{DimensionRequest, Selector, SizeRequest, TextView, View}; use view::{DimensionRequest, Selector, SizeRequest, TextView, View};
use view::{Button, SizedView}; use view::{Button, SizedView};
use vec::{ToVec4, Vec2, Vec4}; use vec::{ToVec4, Vec2, Vec4};
@ -152,7 +152,7 @@ impl View for Dialog {
printer.print((x - 2, 0), ""); printer.print((x - 2, 0), "");
printer.print((x + len, 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));
} }
} }

View File

@ -2,7 +2,7 @@ use unicode_segmentation::UnicodeSegmentation;
use std::cmp::min; use std::cmp::min;
use theme::{ColorPair, Effect}; use theme::{ColorStyle, Effect};
use vec::Vec2; use vec::Vec2;
use view::{IdView, SizeRequest, View}; use view::{IdView, SizeRequest, View};
use event::*; use event::*;
@ -85,7 +85,7 @@ impl View for EditView {
fn draw(&mut self, printer: &Printer) { fn draw(&mut self, printer: &Printer) {
// let style = if focused { color::HIGHLIGHT } else { color::HIGHLIGHT_INACTIVE }; // let style = if focused { color::HIGHLIGHT } else { color::HIGHLIGHT_INACTIVE };
let len = self.content.chars().count(); let len = self.content.chars().count();
printer.with_color(ColorPair::Secondary, |printer| { printer.with_color(ColorStyle::Secondary, |printer| {
printer.with_effect(Effect::Reverse, |printer| { printer.with_effect(Effect::Reverse, |printer| {
if len < self.last_length { if len < self.last_length {
printer.print((0, 0), &self.content); printer.print((0, 0), &self.content);

View File

@ -1,6 +1,6 @@
use std::cmp::{max, min}; use std::cmp::{max, min};
use theme::ColorPair; use theme::ColorStyle;
use vec::Vec2; use vec::Vec2;
use printer::Printer; use printer::Printer;
@ -129,9 +129,9 @@ impl ScrollBase {
let start = steps * self.start_line / (1 + self.content_height - self.view_height); let start = steps * self.start_line / (1 + self.content_height - self.view_height);
let color = if printer.focused { let color = if printer.focused {
ColorPair::Highlight ColorStyle::Highlight
} else { } else {
ColorPair::HighlightInactive ColorStyle::HighlightInactive
}; };
printer.print_vline((printer.size.x - 1, 0), printer.size.y, "|"); printer.print_vline((printer.size.x - 1, 0), printer.size.y, "|");

View File

@ -1,7 +1,7 @@
use std::cmp::min; use std::cmp::min;
use std::rc::Rc; use std::rc::Rc;
use theme::ColorPair; use theme::ColorStyle;
use Cursive; use Cursive;
use align::*; use align::*;
use view::{DimensionRequest, IdView, SizeRequest, View}; use view::{DimensionRequest, IdView, SizeRequest, View};
@ -133,12 +133,12 @@ impl<T: 'static> View for SelectView<T> {
self.scrollbase.draw(printer, |printer, i| { self.scrollbase.draw(printer, |printer, i| {
let style = if i == self.focus { let style = if i == self.focus {
if printer.focused { if printer.focused {
ColorPair::Highlight ColorStyle::Highlight
} else { } else {
ColorPair::HighlightInactive ColorStyle::HighlightInactive
} }
} else { } else {
ColorPair::Primary ColorStyle::Primary
}; };
printer.with_color(style, |printer| { printer.with_color(style, |printer| {
let l = self.items[i].label.chars().count(); let l = self.items[i].label.chars().count();

View File

@ -1,7 +1,7 @@
use view::{SizeRequest, View, ViewWrapper}; use view::{SizeRequest, View, ViewWrapper};
use printer::Printer; use printer::Printer;
use vec::Vec2; use vec::Vec2;
use theme::ColorPair; use theme::ColorStyle;
/// Wrapper view that adds a shadow. /// Wrapper view that adds a shadow.
/// ///
@ -40,7 +40,7 @@ impl<T: View> ViewWrapper for ShadowView<T> {
let h = printer.size.y - 1; let h = printer.size.y - 1;
let w = printer.size.x - 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_hline((2, h), w - 1, " ");
printer.print_vline((w, 2), h - 1, " "); printer.print_vline((w, 2), h - 1, " ");
}); });

View File

@ -4,7 +4,7 @@ use vec::Vec2;
use view::{DimensionRequest, Selector, ShadowView, SizeRequest, View}; use view::{DimensionRequest, Selector, ShadowView, SizeRequest, View};
use event::{Event, EventResult}; use event::{Event, EventResult};
use printer::Printer; use printer::Printer;
use theme::ColorPair; use theme::ColorStyle;
/// Simple stack of views. /// Simple stack of views.
/// Only the top-most view is active and can receive input. /// Only the top-most view is active and can receive input.
@ -49,7 +49,7 @@ impl StackView {
impl View for StackView { impl View for StackView {
fn draw(&mut self, printer: &Printer) { fn draw(&mut self, printer: &Printer) {
let last = self.layers.len(); 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() { for (i, v) in self.layers.iter_mut().enumerate() {
// Center the view // Center the view
let size = v.size; let size = v.size;