Yay! 256-color mode
This commit is contained in:
parent
2f0c72e1e4
commit
6f9addc42b
|
@ -1,6 +1,6 @@
|
|||
extern crate libterm;
|
||||
|
||||
use libterm::{TermControl, raw_mode};
|
||||
use libterm::{TermControl, raw_mode, Color};
|
||||
use std::io::{Read, Write, stdout, stdin};
|
||||
|
||||
fn main() {
|
||||
|
@ -21,7 +21,7 @@ fn main() {
|
|||
match b {
|
||||
b'q' => return,
|
||||
b'c' => stdout.clear(),
|
||||
b'r' => stdout.rendition(91),
|
||||
b'r' => stdout.color(Color::Rgb(5, 0, 0)),
|
||||
a => stdout.write(&[a]),
|
||||
}.unwrap();
|
||||
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/// A terminal color.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum Color {
|
||||
/// Black.
|
||||
Black,
|
||||
/// Red.
|
||||
Red,
|
||||
/// Green.
|
||||
Green,
|
||||
/// Yellow.
|
||||
Yellow,
|
||||
/// Blue.
|
||||
Blue,
|
||||
/// Megenta.
|
||||
Magenta,
|
||||
/// Cyan.
|
||||
Cyan,
|
||||
/// White.
|
||||
White,
|
||||
/// High-intensity black.
|
||||
HiBlack,
|
||||
/// High-intensity red.
|
||||
HiRed,
|
||||
/// High-intensity green.
|
||||
HiGreen,
|
||||
/// High-intensity yellow.
|
||||
HiYellow,
|
||||
/// High-intensity blue.
|
||||
HiBlue,
|
||||
/// High-intensity megenta.
|
||||
HiMagenta,
|
||||
/// High-intensity cyan.
|
||||
HiCyan,
|
||||
/// High-intensity white.
|
||||
HiWhite,
|
||||
/// 216-color (6, 6, 6) RGB.
|
||||
Rgb(u8, u8, u8),
|
||||
/// Grayscale (max value: 24)
|
||||
Grayscale(u8),
|
||||
}
|
||||
|
||||
use Color::*;
|
||||
|
||||
impl Color {
|
||||
pub fn to_ansi_val(self) -> u8 {
|
||||
self.debug_check();
|
||||
|
||||
match self {
|
||||
Black => 0x0,
|
||||
Red => 0x1,
|
||||
Green => 0x2,
|
||||
Yellow => 0x3,
|
||||
Blue => 0x4,
|
||||
Magenta => 0x5,
|
||||
Cyan => 0x6,
|
||||
White => 0x7,
|
||||
HiBlack => 0x8,
|
||||
HiRed => 0x9,
|
||||
HiGreen => 0xA,
|
||||
HiYellow => 0xB,
|
||||
HiBlue => 0xC,
|
||||
HiMagenta => 0xD,
|
||||
HiCyan => 0xE,
|
||||
HiWhite => 0xF,
|
||||
Rgb(r, g, b) => 16 + 36 * r + 6 * g + b,
|
||||
Grayscale(shade) => 0xE8 + shade,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_check(self) {
|
||||
match self {
|
||||
Rgb(r, g, b) => {
|
||||
debug_assert!(r <= 5, "Red color fragment (r = {}) is out of bound. Make sure r ≤ 5.", r);
|
||||
debug_assert!(g <= 5, "Green color fragment (g = {}) is out of bound. Make sure g ≤ 5.", g);
|
||||
debug_assert!(b <= 5, "Blue color fragment (b = {}) is out of bound. Make sure b ≤ 5.", b);
|
||||
},
|
||||
Grayscale(shade) => {
|
||||
// Unfortunately, there are a little less than fifty shades.
|
||||
debug_assert!(shade < 24, "Grayscale out of bound (shade = {}). There are only 24 shades of gray.", shade);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
use std::io::{Write, Result as IoResult};
|
||||
use Color;
|
||||
|
||||
/// Controlling terminals.
|
||||
pub trait TermControl {
|
||||
|
@ -27,9 +28,9 @@ pub trait TermControl {
|
|||
/// Go to a given position.
|
||||
fn goto(&mut self, x: u16, y: u16) -> IoResult<usize> {
|
||||
self.csi(&[
|
||||
(x / 10000) as u8 + b'0', ((x / 1000) % 10) as u8 + b'0', ((x / 100) % 10) as u8 + b'0', ((x / 10) % 10) as u8 + b'0', (x % 10) as u8 + b'0',
|
||||
(x / 10000) as u8 + b'0', (x / 1000) as u8 % 10 + b'0', (x / 100) as u8 % 10 + b'0', (x / 10) as u8 % 10 + b'0', x as u8 % 10 + b'0',
|
||||
b';',
|
||||
(y / 10000) as u8 + b'0', ((y / 1000) % 10) as u8 + b'0', ((y / 100) % 10) as u8 + b'0', ((y / 10) % 10) as u8 + b'0', (y % 10) as u8 + b'0',
|
||||
(y / 10000) as u8 + b'0', (y / 1000) as u8 % 10 + b'0', (y / 100) as u8 % 10 + b'0', (y / 10) as u8 % 10 + b'0', y as u8 % 10 + b'0',
|
||||
b'H',
|
||||
])
|
||||
}
|
||||
|
@ -40,6 +41,36 @@ pub trait TermControl {
|
|||
b'm',
|
||||
])
|
||||
}
|
||||
/// Set foreground color
|
||||
fn color(&mut self, color: Color) -> IoResult<usize> {
|
||||
let ansi = color.to_ansi_val();
|
||||
self.csi(&[
|
||||
b'3',
|
||||
b'8',
|
||||
b';',
|
||||
b'5',
|
||||
b';',
|
||||
b'0' + ansi / 100,
|
||||
b'0' + ansi / 10 % 10,
|
||||
b'0' + ansi % 10,
|
||||
b'm',
|
||||
])
|
||||
}
|
||||
/// Set background color
|
||||
fn bg_color(&mut self, color: Color) -> IoResult<usize> {
|
||||
let ansi = color.to_ansi_val();
|
||||
self.csi(&[
|
||||
b'4',
|
||||
b'8',
|
||||
b';',
|
||||
b'5',
|
||||
b';',
|
||||
b'0' + ansi / 100,
|
||||
b'0' + ansi / 10 % 10,
|
||||
b'0' + ansi % 10,
|
||||
b'm',
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Write> TermControl for W {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#![feature(libc)]
|
||||
#[warn(missing_docs)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
mod termios;
|
||||
|
@ -11,3 +13,6 @@ pub use raw::{raw_mode, TerminalRestorer};
|
|||
|
||||
mod size;
|
||||
pub use size::termsize;
|
||||
|
||||
mod color;
|
||||
pub use color::Color;
|
||||
|
|
Loading…
Reference in New Issue