diff --git a/Cargo.toml b/Cargo.toml index 634ece1..3b9080e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ winapi = { version = "0.3", features = ["winbase","winuser","consoleapi","proces libc = "0.2" [[bin]] -name = "a" +name = "example_bin" path = "./examples/bin.rs" diff --git a/examples/bin.rs b/examples/bin.rs index 2f24930..d648f4b 100644 --- a/examples/bin.rs +++ b/examples/bin.rs @@ -1,18 +1,29 @@ +//! This bin folder can be used to try the examples out located in the examples directory. +//! +//! All you need to do is: +//! +//! - Download the crossterm source code. +//! - Add this in the Cargo.toml file: +//! ``` [[bin]] +//! name = "example_bin" +//! path = "./examples/bin.rs" +//! ``` +//! +//! - Run program with: `cargo run` + +// Import crossterm crate. extern crate crossterm; -use self::crossterm::crossterm_style::*; +// Add the usings for the crossterms modules to play with crossterm +use self::crossterm::crossterm_style; use self::crossterm::crossterm_cursor; -use self::crossterm::crossterm_terminal::*; - -use std::io::{stdin, stdout, Write}; +use self::crossterm::crossterm_terminal; +// Import the example modules. pub mod color; pub mod cursor; pub mod terminal; fn main() { - terminal::resize_terminal(); - - print!(paint("asdf").with(Color::Black).on(Color::Red).black().red()); - println!() + } diff --git a/examples/color/mod.rs b/examples/color/mod.rs index 0ea12dc..b5c525d 100644 --- a/examples/color/mod.rs +++ b/examples/color/mod.rs @@ -97,4 +97,33 @@ pub fn print_all_background_colors() println!("Dark Cyan : \t {}", paint(" ").on(Color::DarkCyan)); println!("Grey : \t\t {}", paint(" ").on(Color::Grey)); println!("White : \t {}", paint(" ").on(Color::White)); +} + +/// Print font with all available attributes. Note that this can only be used at unix systems and that some are not supported widely. +#[cfg(unix)] +pub fn print_font_with_attributes() +{ + println!("{}", paint("Normal text")); + println!("{}", paint("Bold text").bold()); + println!("{}", paint("Italic text").italic()); + println!("{}", paint("Slow blinking text").slow_blink()); + println!("{}", paint("Rapid blinking text").rapid_blink()); + println!("{}", paint("Hidden text").hidden()); + println!("{}", paint("Underlined text").underlined()); + println!("{}", paint("Reversed color").reverse()); + println!("{}", paint("Dim text color").dim()); + println!("{}", paint("Crossed out font").crossed_out()); +} + +/// Print all supported rgb colors +#[cfg(unix)]#[cfg(unix)] +pub fn print_supported_colors() +{ + let count = crossterm::crossterm_style::get().get_available_color_count().unwrap(); + + for i in 0..count + { + println!("{}", paint(format!("Color: {}",i)).with(Color::AnsiValue(i as u8))); + + } } \ No newline at end of file diff --git a/examples/cursor/mod.rs b/examples/cursor/mod.rs index 0c23fef..73d67df 100644 --- a/examples/cursor/mod.rs +++ b/examples/cursor/mod.rs @@ -76,16 +76,25 @@ pub fn print() get().goto(10,5).print("@"); } -/// Save cursor position for recall later -pub fn safe_position() +/// Save and reset cursor position. +pub fn safe_and_reset_position() { - get().safe_position(); -} + let mut cursor = get(); + + // Goto X: 5 Y: 5 + cursor.goto(5,5); + // Safe cursor position: X: 5 Y: 5 + cursor.safe_position(); + // Goto X: 5 Y: 20 + cursor.goto(5,20); + // Print at X: 5 Y: 20. + print!("Yea!"); + // Reset back to X: 5 Y: 5. + cursor.reset_position(); + // Print Back at X: 5 Y: 5. + print!("Back"); -/// Save cursor position for recall later -pub fn reset_position() -{ - get().reset_position(); + println!() } diff --git a/examples/terminal/mod.rs b/examples/terminal/mod.rs index 3d321d5..961bf3b 100644 --- a/examples/terminal/mod.rs +++ b/examples/terminal/mod.rs @@ -111,7 +111,7 @@ pub fn scroll_down() // Get terminal let mut terminal = get(); // Scroll down 10 lines. - let terminal_size = terminal.scroll_down(10); + terminal.scroll_down(10); } // scroll down 10 lines @@ -122,7 +122,7 @@ pub fn scroll_up() // Get terminal let mut terminal = get(); // Scroll up 10 lines. - let terminal_size = terminal.scroll_up(10); + terminal.scroll_up(10); } // Resize the terminal to X: 10, Y: 10 @@ -131,5 +131,5 @@ pub fn resize_terminal() // Get terminal let mut terminal = get(); // Get terminal size - terminal.set_size(2,2); + terminal.set_size(1,1); } diff --git a/src/crossterm_cursor/ansi_cursor.rs b/src/crossterm_cursor/ansi_cursor.rs index d4a7084..a2021b7 100644 --- a/src/crossterm_cursor/ansi_cursor.rs +++ b/src/crossterm_cursor/ansi_cursor.rs @@ -45,7 +45,7 @@ impl ITerminalCursor for AnsiCursor { write!(&mut some_writer, csi!("{}D"), count); } - fn safe_position(&self) + fn safe_position(&mut self) { let mut some_writer = io::stdout(); write!(&mut some_writer, csi!("s")); diff --git a/src/crossterm_style/color/ansi_color.rs b/src/crossterm_style/color/ansi_color.rs index dc95cdc..bd1419f 100644 --- a/src/crossterm_style/color/ansi_color.rs +++ b/src/crossterm_style/color/ansi_color.rs @@ -3,7 +3,7 @@ use std::io::Write; use std::string::String; use Construct; -use super::color::{Color, ColorType}; +use super::super::{Color, ColorType}; use super::base_color::ITerminalColor; @@ -19,14 +19,13 @@ impl Construct for ANSIColor { impl ITerminalColor for ANSIColor { fn set_fg(&self, fg_color: Color) { - - let mut some_writer = io::stdout(); - write!(&mut some_writer, csi!("38;5;{}m"), self.color_value(fg_color, ColorType::Foreground)); + let mut some_writer = io::stdout(); + write!(&mut some_writer, csi!("{}m"), self.color_value(fg_color, ColorType::Foreground)); } fn set_bg(&self, bg_color: Color) { - let mut some_writer = io::stdout(); - write!(&mut some_writer, csi!("48;5;{}m"), self.color_value(bg_color, ColorType::Background)); + let mut some_writer = io::stdout(); + write!(&mut some_writer, csi!("{}m"), self.color_value(bg_color, ColorType::Background)); } fn reset(&self) { @@ -36,23 +35,41 @@ impl ITerminalColor for ANSIColor { fn color_value(&self, color: Color, color_type: ColorType) -> String { - // Construct ANSI escape color code string. ;1 is for the brightness - match color { - Color::Black => "0", - Color::Red => "9", - Color::DarkRed =>"1", - Color::Green => "10", - Color::DarkGreen => "2", - Color::Yellow => "11", - Color::DarkYellow => "3", - Color::Blue => "12", - Color::DarkBlue => "4", - Color::Magenta => "13", - Color::DarkMagenta => "5", - Color::Cyan => "14", - Color::DarkCyan => "6", - Color::Grey => "15", - Color::White => "7", - }.to_string() + let mut ansi_value = String::new(); + + match color_type + { + ColorType::Foreground => { + ansi_value.push_str("38;") + }, + ColorType::Background => { + ansi_value.push_str("48;") + }, + } + + let rgb_val; + + let color_val = match color { + Color::Black => "5;0", + Color::Red => "5;9", + Color::DarkRed =>"5;1", + Color::Green => "5;10", + Color::DarkGreen => "5;2", + Color::Yellow => "5;11", + Color::DarkYellow => "5;3", + Color::Blue => "5;12", + Color::DarkBlue => "5;4", + Color::Magenta => "5;13", + Color::DarkMagenta => "5;5", + Color::Cyan => "5;14", + Color::DarkCyan => "5;6", + Color::Grey => "5;15", + Color::White => "5;7", + Color::Rgb{r,g,b} => { rgb_val = format!("2;{};{};{}", r,g,b); rgb_val.as_str()}, + Color::AnsiValue(val) => { rgb_val = format!("5;{}",val); rgb_val.as_str() } + }; + + ansi_value.push_str(color_val); + ansi_value } -} +} \ No newline at end of file diff --git a/src/crossterm_style/color/color.rs b/src/crossterm_style/color/color.rs index 73fbbb7..dd1b766 100644 --- a/src/crossterm_style/color/color.rs +++ b/src/crossterm_style/color/color.rs @@ -2,10 +2,12 @@ //! Like styling the font, foreground color and background color. use std::fmt; +use std::io; use Construct; use crossterm_style::{ObjectStyle, StyledObject}; use super::base_color::ITerminalColor; +use super::super::Color; #[cfg(unix)] use super::ANSIColor; @@ -96,6 +98,23 @@ impl TerminalColor { terminal_color.reset(); } } + + /// Get available color count. + pub fn get_available_color_count(&self) -> io::Result + { + use std::env; + + Ok(match env::var_os("TERM") { + Some(val) => { + if val.to_str().unwrap_or("").contains("256color") { + 256 + } else { + 8 + } + } + None => 8, + }) + } } /// Get an concrete ITerminalColor implementation based on the current operating system. diff --git a/src/crossterm_style/mod.rs b/src/crossterm_style/mod.rs index 0703a59..b9924be 100644 --- a/src/crossterm_style/mod.rs +++ b/src/crossterm_style/mod.rs @@ -16,9 +16,11 @@ pub enum Attribute { Dim = 2, Italic = 3, Underlined = 4, - Blink = 5, + SlowBlink = 5, + RapidBlink = 6, Reverse = 7, Hidden = 8, + CrossedOut = 9 } /// Colors that are available for coloring the termainal font. @@ -46,6 +48,11 @@ pub enum Color { Grey, White, + + #[cfg(unix)] + Rgb { r: u8, g: u8, b:u8 }, + #[cfg(unix)] + AnsiValue(u8) } /// Color types that can be used to determine if the Color enum is an Fore- or Background Color diff --git a/src/crossterm_style/styles/objectstyle.rs b/src/crossterm_style/styles/objectstyle.rs index f539e39..43ab86c 100644 --- a/src/crossterm_style/styles/objectstyle.rs +++ b/src/crossterm_style/styles/objectstyle.rs @@ -55,7 +55,7 @@ impl ObjectStyle { self } - pub fn add_attr(mut self, attr: Attribute) + pub fn add_attr(&mut self, attr: Attribute) { self.attrs.push(attr); } diff --git a/src/crossterm_style/styles/styledobject.rs b/src/crossterm_style/styles/styledobject.rs index ba9025e..e91006f 100644 --- a/src/crossterm_style/styles/styledobject.rs +++ b/src/crossterm_style/styles/styledobject.rs @@ -12,21 +12,24 @@ pub struct StyledObject { } impl StyledObject { - /// Sets the foreground of the styled object to the passed `Color` + /// Set the foreground of the styled object to the passed `Color` /// /// #Example /// /// ```rust - /// // create an styled object with the foreground color red. - /// let styledobject = paint("I am colored red").with(Color::Red); - /// // create an styled object with the foreground color blue. - /// let styledobject1 = paint("I am colored blue").with(Color::Blue); + /// extern crate crossterm; + /// use self::crossterm::crossterm_style::{paint,Color}; /// - /// // print the styledobject to see the result - /// println!("{}", styledobject); - /// println!("{}", styledobject1); - /// // print an styled object directly. - /// println!("{}", paint("I am colored green").with(Color::Green)); + /// // create an styled object with the foreground color red. + /// let styledobject = paint("I am colored red").with(Color::Red); + /// // create an styled object with the foreground color blue. + /// let styledobject1 = paint("I am colored blue").with(Color::Blue); + /// + /// // print the styledobject to see the result + /// println!("{}", styledobject); + /// println!("{}", styledobject1); + /// // print an styled object directly. + /// println!("{}", paint("I am colored green").with(Color::Green)); /// /// ``` pub fn with(mut self, foreground_color: Color) -> StyledObject { @@ -34,22 +37,24 @@ impl StyledObject { self } - /// Sets the background of the styled object to the passed `Color` + /// Set the background of the styled object to the passed `Color` /// /// #Example /// - /// ```rust - /// - /// // create an styled object with the background color red. - /// let styledobject = paint("I am colored red").on(Color::Red); - /// // create an styled object with the background color blue. - /// let styledobject1 = paint("I am colored blue").on(Color::Blue); + /// ```rust + /// extern crate crossterm; + /// use self::crossterm::crossterm_style::{paint,Color}; /// - /// // print the styledobjects - /// println!("{}", styledobject); - /// println!("{}", styledobject1); - /// // print an styled object directly. - /// println!("{}", paint("I am colored green").on(Color::Green)) + /// // create an styled object with the background color red. + /// let styledobject = paint("I am colored red").on(Color::Red); + /// // create an styled object with the background color blue. + /// let styledobject1 = paint("I am colored blue").on(Color::Blue); + /// + /// // print the styledobjects + /// println!("{}", styledobject); + /// println!("{}", styledobject1); + /// // print an styled object directly. + /// println!("{}", paint("I am colored green").on(Color::Green)) /// /// ``` pub fn on(mut self, background_color: Color) -> StyledObject { @@ -57,28 +62,43 @@ impl StyledObject { self } - pub fn attrs(mut self, attrs: Vec) -> StyledObject - { - for attr in attrs.iter() { - self.attr(attr); - } - - self - } - + /// Set the attribute of an styled object to the passed `Attribute` + /// + /// #Example + /// + /// ```rust + /// + /// extern crate crossterm; + /// use self::crossterm::crossterm_style::{paint,Attribute}; + /// + /// println!("{}", paint("Bold").attr(Attribute::Bold)); + /// + /// ``` + #[cfg(unix)] pub fn attr(mut self, attr: Attribute) -> StyledObject { - self.object_style.add_attr(attr); + &self.object_style.add_attr(attr); self } - #[inline(always)] pub fn bold(self) -> StyledObject { self.attr(Attribute::Bold) } - #[inline(always)] pub fn dim(self) -> StyledObject { self.attr(Attribute::Dim) } - #[inline(always)] pub fn italic(self) -> StyledObject { self.attr(Attribute::Italic) } - #[inline(always)] pub fn underlined(self) -> StyledObject { self.attr(Attribute::Underlined) } - #[inline(always)] pub fn blink(self) -> StyledObject { self.attr(Attribute::Blink) } - #[inline(always)] pub fn reverse(self) -> StyledObject { self.attr(Attribute::Reverse) } - #[inline(always)] pub fn hidden(self) -> StyledObject { self.attr(Attribute::Hidden) } + /// Increase the font intensity. + #[cfg(unix)]#[inline(always)] pub fn bold(self) -> StyledObject { self.attr(Attribute::Bold) } + /// Faint (decreased intensity) (Not widely supported). + #[cfg(unix)]#[inline(always)] pub fn dim(self) -> StyledObject { self.attr(Attribute::Dim) } + /// Make the font italic (Not widely supported; Sometimes treated as inverse). + #[cfg(unix)]#[inline(always)] pub fn italic(self) -> StyledObject { self.attr(Attribute::Italic) } + /// Underline font. + #[cfg(unix)]#[inline(always)] pub fn underlined(self) -> StyledObject { self.attr(Attribute::Underlined) } + /// Slow Blink (less than 150 per minute; not widely supported). + #[cfg(unix)]#[inline(always)] pub fn slow_blink(self) -> StyledObject { self.attr(Attribute::SlowBlink) } + /// Rapid Blink (MS-DOS ANSI.SYS; 150+ per minute; not widely supported). + #[cfg(unix)]#[inline(always)] pub fn rapid_blink(self) -> StyledObject { self.attr(Attribute::RapidBlink) } + /// Swap foreground and background colors. + #[cfg(unix)]#[inline(always)] pub fn reverse(self) -> StyledObject { self.attr(Attribute::Reverse) } + /// Hide text (Not widely supported). + #[cfg(unix)]#[inline(always)] pub fn hidden(self) -> StyledObject { self.attr(Attribute::Hidden) } + /// Characters legible, but marked for deletion. Not widely supported. + #[cfg(unix)]#[inline(always)] pub fn crossed_out(self) -> StyledObject { self.attr(Attribute::CrossedOut) } } /// This is used to make StyledObject able to be displayed. @@ -104,8 +124,8 @@ macro_rules! impl_fmt } #[cfg(unix)] - for attr in &self.object_style.attrs.iter() { - write!(f, csi!("{}m"), attr as i16); + for attr in self.object_style.attrs.iter() { + write!(f, csi!("{}m"), *attr as i16); reset = true; } diff --git a/src/crossterm_terminal/ansi_terminal.rs b/src/crossterm_terminal/ansi_terminal.rs index 2685d63..332bb42 100644 --- a/src/crossterm_terminal/ansi_terminal.rs +++ b/src/crossterm_terminal/ansi_terminal.rs @@ -51,7 +51,7 @@ impl ITerminal for UnixTerminal { write!(&mut some_writer, csi!("{}T"), count); } - fn set_size(width: i16, height: i16) { + fn set_size(&self, width: i16, height: i16) { let mut some_writer = io::stdout(); write!(&mut some_writer, csi!("8;{};{}t"), width, height); } diff --git a/src/crossterm_terminal/terminal.rs b/src/crossterm_terminal/terminal.rs index 99c8dfa..80c890e 100644 --- a/src/crossterm_terminal/terminal.rs +++ b/src/crossterm_terminal/terminal.rs @@ -121,7 +121,21 @@ impl Terminal { } } - /// Set the terminal size. + /// Set the terminal size. Note that not all terminals can be set to a very small scale. + /// + /// #Example + /// + /// ```rust + /// + /// extern crate crossterm; + /// use crossterm::crossterm_terminal; + /// + /// let mut term = crossterm_terminal::get(); + /// + /// // Set of the size to X: 10 and Y: 10 + /// let size = term.set_size(10,10); + /// + /// ``` pub fn set_size(&mut self, width: i16, height: i16) { &self.init(); diff --git a/src/kernel/windows_kernel/color.rs b/src/kernel/windows_kernel/color.rs index 018b7ad..aac968e 100644 --- a/src/kernel/windows_kernel/color.rs +++ b/src/kernel/windows_kernel/color.rs @@ -81,6 +81,7 @@ pub fn winapi_color_val(color: style::Color, color_type: style::ColorType) -> u1 Color::DarkCyan => fg_green | fg_blue, Color::Grey => fg_intensity, Color::White => fg_intensity | fg_red | fg_green | fg_blue, + _ => Color::White }; } ColorType::Background => { @@ -100,6 +101,7 @@ pub fn winapi_color_val(color: style::Color, color_type: style::ColorType) -> u1 Color::DarkCyan => bg_green | bg_blue, Color::Grey => bg_intensity, Color::White => bg_intensity | bg_red | bg_green | bg_blue, + _ => Color::White }; } }; diff --git a/src/lib.rs b/src/lib.rs index 0c45579..13f3459 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #[macro_use] mod shared; mod kernel; + pub mod crossterm_cursor; pub mod crossterm_style; pub mod crossterm_terminal; diff --git a/src/shared/functions.rs b/src/shared/functions.rs deleted file mode 100644 index 4d1d3af..0000000 --- a/src/shared/functions.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn is_cursor_out_of_range(x: i16, y: i16) { - -} diff --git a/src/shared/mod.rs b/src/shared/mod.rs index a507168..65134bb 100644 --- a/src/shared/mod.rs +++ b/src/shared/mod.rs @@ -1,4 +1,3 @@ #[macro_use] pub mod macros; pub mod traits; -pub mod functions; diff --git a/src/shared/traits.rs b/src/shared/traits.rs index 4361559..edaeef6 100644 --- a/src/shared/traits.rs +++ b/src/shared/traits.rs @@ -6,9 +6,7 @@ pub trait Construct { Self: Sized; } - - -/// This trait is used to create an empty instance of an struct. +/// This trait can be used to create an empty instance of an struct. pub trait Empty { fn empty() -> Self; } diff --git a/todo.txt b/todo.txt index 99e71dc..51316d2 100644 --- a/todo.txt +++ b/todo.txt @@ -2,4 +2,14 @@ Windows logic clear aan passen before after cursor ideas: -https://apple.stackexchange.com/questions/33736/can-a-terminal-window-be-resized-with-a-terminal-command \ No newline at end of file +https://apple.stackexchange.com/questions/33736/can-a-terminal-window-be-resized-with-a-terminal-command + + + +new inplemented: + +Safe and restore cursor +Resize terminal +Styling font with attributes +RGB color option added for unix +ANSI cutom color value input added for unix \ No newline at end of file