Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Daan Sprenkels authored Oct 3, 2017
2 parents abdf907 + 45585c7 commit d456724
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
language: rust
rust:
- 1.5.0
- 1.8.0
- nightly
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustbox"
version = "0.8.1"
version = "0.9.0"
authors = ["Greg Chapple <[email protected]>"]
description = "A rust implementation of the termbox library"
repository = "https://github.com/gchp/rustbox"
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,9 @@ fn main() {
```

**NOTE:** this example can also be run with `cargo run --example hello-world`.

### Projects that use this crate:

* [hostblock](https://github.com/cgag/hostblock)
* [rust-2048](https://github.com/kdar/rust-2048)
* [marching-squares](https://github.com/crespyl/marching-squares)
30 changes: 30 additions & 0 deletions examples/hello-256-world.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
extern crate rustbox;

use std::default::Default;

use rustbox::{Color, RustBox, OutputMode};
use rustbox::Key;

fn main() {
let mut rustbox = match RustBox::init(Default::default()) {
Result::Ok(v) => v,
Result::Err(e) => panic!("{}", e),
};
rustbox.set_output_mode(OutputMode::EightBit);

rustbox.print(1, 1, rustbox::RB_BOLD, Color::Byte(0xa2), Color::Black, "Hello, world!");
rustbox.print(1, 3, rustbox::RB_NORMAL, Color::Black, Color::Byte(0x9a), "Press 'q' to quit.");
loop {
rustbox.present();
match rustbox.poll_event(false) {
Ok(rustbox::Event::KeyEvent(key)) => {
match key {
Key::Char('q') => { break; }
_ => { }
}
},
Err(e) => panic!("{}", e),
_ => { }
}
}
}
140 changes: 122 additions & 18 deletions src/rustbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,65 @@ pub enum InputMode {
AltMouse = 0x06
}

#[derive(Clone, Copy, Debug)]
pub enum OutputMode {
Current = 0,
Normal = 1,
EightBit = 2, // 256 Colors
WebSafe = 3, // 216 Colors
Grayscale = 4,
}


#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C,u16)]
pub enum Color {
Default = 0x00,
Black = 0x01,
Red = 0x02,
Green = 0x03,
Yellow = 0x04,
Blue = 0x05,
Magenta = 0x06,
Cyan = 0x07,
White = 0x08,
Black,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
White,
Byte(u16),
Default,
}
impl Color {
pub fn as_256color(&self) -> u16 {
match *self {
Color::Black => 0x00,
Color::Red => 0x01,
Color::Green => 0x02,
Color::Yellow => 0x03,
Color::Blue => 0x04,
Color::Magenta => 0x05,
Color::Cyan => 0x06,
Color::White => 0x07,
Color::Byte(b) => b,
Color::Default => panic!("Attempted to cast default color to byte"),
}
}

pub fn as_16color(&self) -> u16 {
match *self {
Color::Default => 0x00,
Color::Black => 0x01,
Color::Red => 0x02,
Color::Green => 0x03,
Color::Yellow => 0x04,
Color::Blue => 0x05,
Color::Magenta => 0x06,
Color::Cyan => 0x07,
Color::White => 0x08,
Color::Byte(b) => panic!("Attempted to cast color byte {} to 16 color mode", b),
}
}
}

impl Default for Color {
fn default() -> Color {
Color::Black
}
}

mod style {
Expand All @@ -80,7 +127,11 @@ mod style {

impl Style {
pub fn from_color(color: super::Color) -> Style {
Style { bits: color as u16 & TB_NORMAL_COLOR.bits }
Style { bits: color.as_16color() & TB_NORMAL_COLOR.bits }
}

pub fn from_256color(color: super::Color) -> Style {
Style { bits: color.as_256color() }
}
}
}
Expand Down Expand Up @@ -223,6 +274,9 @@ pub struct RustBox {
_running: running::RunningGuard,
// Termbox is not thread safe. See #39.
_phantom: PhantomData<UnsafeCell<()>>,

// Store this so we know which colours to use
output_mode: OutputMode,
}

#[derive(Clone, Copy,Debug)]
Expand All @@ -232,6 +286,11 @@ pub struct InitOptions {
/// See InputMode enum for details on the variants.
pub input_mode: InputMode,

/// Use this option to initialize with a specific output mode
///
/// See OutputMode enum for details on the variants.
pub output_mode: OutputMode,

/// Use this option to automatically buffer stderr while RustBox is running. It will be
/// written when RustBox exits.
///
Expand All @@ -246,6 +305,7 @@ impl Default for InitOptions {
fn default() -> Self {
InitOptions {
input_mode: InputMode::Current,
output_mode: OutputMode::Current,
buffer_stderr: false,
}
}
Expand Down Expand Up @@ -321,11 +381,12 @@ impl RustBox {
};

// Create the RustBox.
let rb = unsafe { match termbox::tb_init() {
let mut rb = unsafe { match termbox::tb_init() {
0 => RustBox {
_stderr: stderr,
_running: running,
_phantom: PhantomData,
output_mode: OutputMode::Current,
},
res => {
return Err(FromPrimitive::from_isize(res as isize).unwrap())
Expand All @@ -335,6 +396,11 @@ impl RustBox {
InputMode::Current => (),
_ => rb.set_input_mode(opts.input_mode),
}
match opts.output_mode {
OutputMode::Current => (),
_ => rb.set_output_mode(opts.output_mode),
}

Ok(rb)
}

Expand Down Expand Up @@ -363,20 +429,49 @@ impl RustBox {
}

pub fn print(&self, x: usize, y: usize, sty: Style, fg: Color, bg: Color, s: &str) {
let fg = Style::from_color(fg) | (sty & style::TB_ATTRIB);
let bg = Style::from_color(bg);
let fg_int;
let bg_int;

match self.output_mode {
// 256 color mode
OutputMode::EightBit => {
fg_int = Style::from_256color(fg) | (sty & style::TB_ATTRIB);
bg_int = Style::from_256color(bg);
},

// 16 color mode
_ => {
fg_int = Style::from_color(fg) | (sty & style::TB_ATTRIB);
bg_int = Style::from_color(bg);
}
}

for (i, ch) in s.chars().enumerate() {
unsafe {
self.change_cell(x+i, y, ch as u32, fg.bits(), bg.bits());
self.change_cell(x+i, y, ch as u32, fg_int.bits(), bg_int.bits());
}
}
}

pub fn print_char(&self, x: usize, y: usize, sty: Style, fg: Color, bg: Color, ch: char) {
let fg = Style::from_color(fg) | (sty & style::TB_ATTRIB);
let bg = Style::from_color(bg);
let fg_int;
let bg_int;

match self.output_mode {
// 256 color mode
OutputMode::EightBit => {
fg_int = Style::from_256color(fg) | (sty & style::TB_ATTRIB);
bg_int = Style::from_256color(bg);
},

// 16 color mode
_ => {
fg_int = Style::from_color(fg) | (sty & style::TB_ATTRIB);
bg_int = Style::from_color(bg);
}
}
unsafe {
self.change_cell(x, y, ch as u32, fg.bits(), bg.bits());
self.change_cell(x, y, ch as u32, fg_int.bits(), bg_int.bits());
}
}

Expand All @@ -401,6 +496,15 @@ impl RustBox {
termbox::tb_select_input_mode(mode as c_int);
}
}

pub fn set_output_mode(&mut self, mode: OutputMode) {
self.output_mode = mode;

unsafe {
termbox::tb_select_output_mode(mode as c_int);
}
}

}

impl Drop for RustBox {
Expand Down

0 comments on commit d456724

Please sign in to comment.