Yay! 256-color mode
This commit is contained in:
parent
2f0c72e1e4
commit
6f9addc42b
|
@ -1,6 +1,6 @@
|
||||||
extern crate libterm;
|
extern crate libterm;
|
||||||
|
|
||||||
use libterm::{TermControl, raw_mode};
|
use libterm::{TermControl, raw_mode, Color};
|
||||||
use std::io::{Read, Write, stdout, stdin};
|
use std::io::{Read, Write, stdout, stdin};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -21,7 +21,7 @@ fn main() {
|
||||||
match b {
|
match b {
|
||||||
b'q' => return,
|
b'q' => return,
|
||||||
b'c' => stdout.clear(),
|
b'c' => stdout.clear(),
|
||||||
b'r' => stdout.rendition(91),
|
b'r' => stdout.color(Color::Rgb(5, 0, 0)),
|
||||||
a => stdout.write(&[a]),
|
a => stdout.write(&[a]),
|
||||||
}.unwrap();
|
}.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 std::io::{Write, Result as IoResult};
|
||||||
|
use Color;
|
||||||
|
|
||||||
/// Controlling terminals.
|
/// Controlling terminals.
|
||||||
pub trait TermControl {
|
pub trait TermControl {
|
||||||
|
@ -27,9 +28,9 @@ pub trait TermControl {
|
||||||
/// Go to a given position.
|
/// Go to a given position.
|
||||||
fn goto(&mut self, x: u16, y: u16) -> IoResult<usize> {
|
fn goto(&mut self, x: u16, y: u16) -> IoResult<usize> {
|
||||||
self.csi(&[
|
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';',
|
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',
|
b'H',
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -40,6 +41,36 @@ pub trait TermControl {
|
||||||
b'm',
|
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 {
|
impl<W: Write> TermControl for W {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#![feature(libc)]
|
#![feature(libc)]
|
||||||
|
#[warn(missing_docs)]
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
mod termios;
|
mod termios;
|
||||||
|
@ -11,3 +13,6 @@ pub use raw::{raw_mode, TerminalRestorer};
|
||||||
|
|
||||||
mod size;
|
mod size;
|
||||||
pub use size::termsize;
|
pub use size::termsize;
|
||||||
|
|
||||||
|
mod color;
|
||||||
|
pub use color::Color;
|
||||||
|
|
Loading…
Reference in New Issue