mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Fix pancurses backend
This commit is contained in:
parent
98be066b4d
commit
2cdf546455
@ -11,7 +11,7 @@ mod pan;
|
|||||||
pub use self::pan::*;
|
pub use self::pan::*;
|
||||||
|
|
||||||
|
|
||||||
fn find_closest(color: &Color) -> u8 {
|
fn find_closest(color: &Color) -> i16 {
|
||||||
match *color {
|
match *color {
|
||||||
Color::Dark(BaseColor::Black) => 0,
|
Color::Dark(BaseColor::Black) => 0,
|
||||||
Color::Dark(BaseColor::Red) => 1,
|
Color::Dark(BaseColor::Red) => 1,
|
||||||
@ -33,8 +33,8 @@ fn find_closest(color: &Color) -> u8 {
|
|||||||
let r = 6 * r as u16 / 256;
|
let r = 6 * r as u16 / 256;
|
||||||
let g = 6 * g as u16 / 256;
|
let g = 6 * g as u16 / 256;
|
||||||
let b = 6 * b as u16 / 256;
|
let b = 6 * b as u16 / 256;
|
||||||
(16 + 36 * r + 6 * g + b) as u8
|
(16 + 36 * r + 6 * g + b) as i16
|
||||||
}
|
}
|
||||||
Color::RgbLowRes(r, g, b) => (16 + 36 * r + 6 * g + b) as u8,
|
Color::RgbLowRes(r, g, b) => (16 + 36 * r + 6 * g + b) as i16,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ impl Concrete {
|
|||||||
};
|
};
|
||||||
pairs.insert(pair, target);
|
pairs.insert(pair, target);
|
||||||
ncurses::init_pair(target,
|
ncurses::init_pair(target,
|
||||||
find_closest(&pair.front) as i16,
|
find_closest(&pair.front),
|
||||||
find_closest(&pair.back) as i16);
|
find_closest(&pair.back));
|
||||||
target
|
target
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ impl Concrete {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_colorstyle(&self, pair: ColorPair) {
|
fn set_colors(&self, pair: ColorPair) {
|
||||||
|
|
||||||
let i = self.get_or_create(pair);
|
let i = self.get_or_create(pair);
|
||||||
|
|
||||||
@ -99,11 +99,15 @@ impl backend::Backend for Concrete {
|
|||||||
|
|
||||||
fn with_color<F: FnOnce()>(&self, colors: ColorPair, f: F) {
|
fn with_color<F: FnOnce()>(&self, colors: ColorPair, f: F) {
|
||||||
let current = self.current_style.get();
|
let current = self.current_style.get();
|
||||||
|
if current != colors {
|
||||||
|
self.set_colors(colors);
|
||||||
|
}
|
||||||
|
|
||||||
self.set_colorstyle(colors);
|
|
||||||
f();
|
f();
|
||||||
self.set_colorstyle(current);
|
|
||||||
self.current_style.set(current);
|
if current != colors {
|
||||||
|
self.set_colors(current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
||||||
|
@ -1,17 +1,69 @@
|
|||||||
extern crate pancurses;
|
extern crate pancurses;
|
||||||
|
|
||||||
|
use self::super::find_closest;
|
||||||
|
|
||||||
use self::super::{color_id, find_closest};
|
|
||||||
use backend;
|
use backend;
|
||||||
use event::{Event, Key};
|
use event::{Event, Key};
|
||||||
use theme::{Color, ColorStyle, Effect};
|
use std::cell::{RefCell, Cell};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use theme::{Color, ColorStyle, ColorPair, Effect};
|
||||||
use utf8;
|
use utf8;
|
||||||
|
|
||||||
pub struct Concrete {
|
pub struct Concrete {
|
||||||
|
current_style: Cell<ColorPair>,
|
||||||
|
pairs: RefCell<HashMap<ColorPair, i32>>,
|
||||||
window: pancurses::Window,
|
window: pancurses::Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Concrete {
|
||||||
|
/// Save a new color pair.
|
||||||
|
fn insert_color(&self, pairs: &mut HashMap<ColorPair, i32>,
|
||||||
|
pair: ColorPair)
|
||||||
|
-> i32 {
|
||||||
|
|
||||||
|
let n = 1 + pairs.len() as i32;
|
||||||
|
|
||||||
|
// TODO: when COLORS_PAIRS is available...
|
||||||
|
let target = if 16 > n {
|
||||||
|
// We still have plenty of space for everyone.
|
||||||
|
n
|
||||||
|
} else {
|
||||||
|
// The world is too small for both of us.
|
||||||
|
let target = n - 1;
|
||||||
|
// Remove the mapping to n-1
|
||||||
|
pairs.retain(|_, &mut v| v != target);
|
||||||
|
target
|
||||||
|
};
|
||||||
|
pairs.insert(pair, target);
|
||||||
|
pancurses::init_pair(target as i16,
|
||||||
|
find_closest(&pair.front),
|
||||||
|
find_closest(&pair.back));
|
||||||
|
target
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks the pair in the cache, or re-define a color if needed.
|
||||||
|
fn get_or_create(&self, pair: ColorPair) -> i32 {
|
||||||
|
|
||||||
|
let mut pairs = self.pairs.borrow_mut();
|
||||||
|
|
||||||
|
// Find if we have this color in stock
|
||||||
|
if pairs.contains_key(&pair) {
|
||||||
|
// We got it!
|
||||||
|
pairs[&pair]
|
||||||
|
} else {
|
||||||
|
self.insert_color(&mut *pairs, pair)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_colors(&self, pair: ColorPair) {
|
||||||
|
|
||||||
|
let i = self.get_or_create(pair);
|
||||||
|
|
||||||
|
self.current_style.set(pair);
|
||||||
|
let style = pancurses::COLOR_PAIR(i as u32);
|
||||||
|
self.window.attron(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl backend::Backend for Concrete {
|
impl backend::Backend for Concrete {
|
||||||
fn init() -> Self {
|
fn init() -> Self {
|
||||||
::std::env::set_var("ESCDELAY", "25");
|
::std::env::set_var("ESCDELAY", "25");
|
||||||
@ -21,10 +73,12 @@ impl backend::Backend for Concrete {
|
|||||||
pancurses::cbreak();
|
pancurses::cbreak();
|
||||||
pancurses::start_color();
|
pancurses::start_color();
|
||||||
pancurses::curs_set(0);
|
pancurses::curs_set(0);
|
||||||
window.bkgd(pancurses::ColorPair(color_id(ColorStyle::Background) as
|
|
||||||
u8));
|
|
||||||
|
|
||||||
Concrete { window: window }
|
Concrete {
|
||||||
|
current_style: Cell::new(ColorPair::from_256colors(0, 0)),
|
||||||
|
pairs: RefCell::new(HashMap::new()),
|
||||||
|
window: window,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn screen_size(&self) -> (usize, usize) {
|
fn screen_size(&self) -> (usize, usize) {
|
||||||
@ -40,21 +94,18 @@ impl backend::Backend for Concrete {
|
|||||||
pancurses::endwin();
|
pancurses::endwin();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_color_style(&mut self, style: ColorStyle, foreground: &Color,
|
fn with_color<F: FnOnce()>(&self, colors: ColorPair, f: F) {
|
||||||
background: &Color) {
|
let current = self.current_style.get();
|
||||||
pancurses::init_pair(color_id(style),
|
|
||||||
find_closest(foreground) as i16,
|
|
||||||
find_closest(background) as i16);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_color<F: FnOnce()>(&self, color: ColorStyle, f: F) {
|
if current != colors {
|
||||||
let (_, current_color_pair) = self.window.attrget();
|
self.set_colors(colors);
|
||||||
let color_attribute = pancurses::ColorPair(color_id(color) as u8);
|
}
|
||||||
|
|
||||||
self.window.attron(color_attribute);
|
|
||||||
f();
|
f();
|
||||||
self.window
|
|
||||||
.attron(pancurses::ColorPair(current_color_pair as u8));
|
if current != colors {
|
||||||
|
self.set_colors(current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
||||||
@ -67,7 +118,12 @@ impl backend::Backend for Concrete {
|
|||||||
self.window.attroff(style);
|
self.window.attroff(style);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear(&self) {
|
fn clear(&self, color: Color) {
|
||||||
|
let id = self.get_or_create(ColorPair {
|
||||||
|
front: color,
|
||||||
|
back: color,
|
||||||
|
});
|
||||||
|
self.window.bkgd(pancurses::ColorPair(id as u8));
|
||||||
self.window.clear();
|
self.window.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,6 @@ use backend;
|
|||||||
use chan;
|
use chan;
|
||||||
use event::{Event, Key};
|
use event::{Event, Key};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fmt;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user