Tested all windows logic also fixed bug with resetting terminal color.
This commit is contained in:
parent
74ef83bb3f
commit
23dc4f661e
@ -28,8 +28,8 @@ path = "src/lib.rs"
|
|||||||
# path = "./examples/Crossterm 0.3.1/bin.rs"
|
# path = "./examples/Crossterm 0.3.1/bin.rs"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "simple"
|
name = "examples"
|
||||||
path = "examples/simple.rs"
|
path = "examples/examples.rs"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "logging"
|
name = "logging"
|
||||||
|
10
changes.md
Normal file
10
changes.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
1. improved performance: removed mutexes, removed state manager, removed unceasingly RC types.
|
||||||
|
2. This create supports multithreading by implementing `Send`
|
||||||
|
2. nicer looking coloring module.
|
||||||
|
4. Added input functionality.
|
||||||
|
4. Able to have different screens to write to.
|
||||||
|
|
||||||
|
2. cursor, color, terminal functions have other parameters.
|
||||||
|
3. bug fix resetting console color
|
||||||
|
6. Added Screen type
|
||||||
|
8. removed paint from Crossterm type.
|
@ -7,5 +7,3 @@ It has 4 modules:
|
|||||||
- input (this is about all input actions you can perform on with terminal)
|
- input (this is about all input actions you can perform on with terminal)
|
||||||
- crossterm_type (this is about the struct `Crossterm`)
|
- crossterm_type (this is about the struct `Crossterm`)
|
||||||
- program examples (this folder will contain some real life examples)
|
- program examples (this folder will contain some real life examples)
|
||||||
|
|
||||||
To run any example where there is a `main()` you could run `cargo run --example simple`.
|
|
@ -1,206 +1,130 @@
|
|||||||
//!
|
//!
|
||||||
//! Examples of coloring the terminal.
|
//! Examples of coloring the terminal.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
extern crate crossterm;
|
extern crate crossterm;
|
||||||
|
|
||||||
use self::crossterm::style::Color;
|
use self::crossterm::style::{Color, style, color};
|
||||||
use self::crossterm::terminal;
|
use self::crossterm::{terminal, Screen};
|
||||||
use self::crossterm::Context;
|
|
||||||
|
|
||||||
/// print some red font | demonstration.
|
/// print some red font | demonstration.
|
||||||
pub fn paint_foreground() {
|
pub fn paint_foreground() {
|
||||||
let context = Context::new();
|
let screen = Screen::default();
|
||||||
let terminal = terminal::terminal(&context);
|
|
||||||
|
|
||||||
// Pass an string to the `paint()` method with you want to paint.
|
// Pass an string to the `paint()` method with you want to paint.
|
||||||
// This will give you an object back wits can be styled and displayed.
|
// This will give you an object back wits can be styled and displayed.
|
||||||
let mut styledobject = terminal.paint("Red font");
|
// Call the method `with()` on the object given by `style()` and pass in any Color from the Color enum.
|
||||||
// Call the method `with()` on the object given by `paint()` and pass in any Color from the Color enum.
|
let mut styledobject = style("Red foreground").with(Color::Red);
|
||||||
styledobject = styledobject.with(Color::Red);
|
|
||||||
// Print the object to the console and see the result.
|
|
||||||
println!("{}", styledobject);
|
|
||||||
|
|
||||||
// Crossterm provides method chaining so that the above points can be inlined.
|
// Print the object to the given screen and.
|
||||||
println!("{}", terminal.paint("Red font").with(Color::Red));
|
styledobject.paint(&screen);
|
||||||
|
|
||||||
|
style("Some colored text").with(Color::Blue).on(Color::Black).paint(&screen);
|
||||||
|
|
||||||
|
// Crossterm provides method chaining for coloring so that the above points can be inlined.
|
||||||
|
style(format!("Red foreground color : \t {}", "■")).with(Color::Red).paint(&screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// print some font on red background | demonstration.
|
/// print some font on red background | demonstration.
|
||||||
pub fn paint_background() {
|
pub fn paint_background() {
|
||||||
let context = Context::new();
|
let screen = Screen::default();
|
||||||
let terminal = terminal::terminal(&context);
|
|
||||||
|
|
||||||
// Pass an string to the `paint()` method with you want to paint.
|
// Pass an string to the `paint()` method with you want to paint.
|
||||||
// This will give you an object back wits can be styled and displayed.
|
// This will give you an object back wits can be styled and displayed.
|
||||||
let mut styledobject = terminal.paint("Red background color");
|
// Call the method `on()` on the object given by `style()` and pass in any Color from the Color enum.
|
||||||
// Call the method `on()` on the object given by `paint()` and pass in an Color from the Color enum.
|
let mut styledobject = style("Red background color").on(Color::Red);
|
||||||
styledobject = styledobject.on(Color::Red);
|
|
||||||
// Print the object to the console and check see the result
|
|
||||||
println!("{}", styledobject);
|
|
||||||
|
|
||||||
// Crossterm provides method chaining so that the above points can be inlined.
|
// Print the object to the given screen and.
|
||||||
println!("{}", terminal.paint("Red background color").on(Color::Red));
|
styledobject.paint(&screen);
|
||||||
}
|
|
||||||
|
|
||||||
/// print font with fore- background color | demonstration.
|
// Crossterm provides method chaining for coloring so that the above points can be inlined.
|
||||||
pub fn paint_foreground_and_background() {
|
style(format!("Red background color : \t {}", "■")).with(Color::Red).paint(&screen);
|
||||||
let context = Context::new();
|
|
||||||
let terminal = terminal::terminal(&context);
|
|
||||||
|
|
||||||
// Pass an string to the `paint()` method with you want to paint.
|
|
||||||
// This will give you an object back wits can be styled and displayed.
|
|
||||||
let mut styledobject = terminal.paint("Red font on blue background color");
|
|
||||||
/* Foreground color:
|
|
||||||
Call the method `with()` on the object given by `paint()`
|
|
||||||
Pass in an Color from the Color enum.
|
|
||||||
*/
|
|
||||||
styledobject = styledobject.with(Color::Red);
|
|
||||||
/* Background color:
|
|
||||||
Call the method `on()` on the object given by `paint()`
|
|
||||||
Pass in an Color from the Color enum.
|
|
||||||
*/
|
|
||||||
styledobject = styledobject.on(Color::Blue);
|
|
||||||
// Print the object to the console and see the result.
|
|
||||||
println!("{}", styledobject);
|
|
||||||
|
|
||||||
// Crossterm provides method chaining so that the above points can be inlined.
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
terminal
|
|
||||||
.paint("Red font on blue background color")
|
|
||||||
.with(Color::Red)
|
|
||||||
.on(Color::Blue)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print all available foreground colors | demonstration.
|
/// Print all available foreground colors | demonstration.
|
||||||
pub fn print_all_foreground_colors() {
|
pub fn print_all_foreground_colors() {
|
||||||
let context = Context::new();
|
let screen = Screen::default();
|
||||||
let terminal = terminal::terminal(&context);
|
|
||||||
|
|
||||||
println!("Black : \t {}", terminal.paint("■").with(Color::Black));
|
style(format!("Black : \t\t {} \n", "■")).with(Color::Black).paint(&screen);
|
||||||
println!("Red : \t\t {}", terminal.paint("■").with(Color::Red));
|
style(format!("Red : \t\t {} \n", "■")).with(Color::Red).paint(&screen);
|
||||||
println!(
|
style(format!("Cyan : \t\t {} \n", "■")).with(Color::Cyan).paint(&screen);
|
||||||
"Dark Red: \t {}",
|
style(format!("DarkCyan : \t {} \n", "■")).with(Color::DarkCyan).paint(&screen);
|
||||||
terminal.paint("■").with(Color::DarkRed)
|
style(format!("DarkRed : \t {} \n", "■")).with(Color::DarkRed).paint(&screen);
|
||||||
);
|
style(format!("Green : \t {} \n", "■")).with(Color::Green).paint(&screen);
|
||||||
println!("Green : \t {}", terminal.paint("■").with(Color::Green));
|
style(format!("DarkGreen : \t {} \n", "■")).with(Color::DarkGreen).paint(&screen);
|
||||||
println!(
|
style(format!("Blue : \t\t {} \n", "■")).with(Color::Blue).paint(&screen);
|
||||||
"Dark Green : \t {}",
|
style(format!("DarkBlue : \t {} \n", "■")).with(Color::DarkBlue).paint(&screen);
|
||||||
terminal.paint("■").with(Color::DarkGreen)
|
style(format!("Magenta : \t {} \n", "■")).with(Color::Magenta).paint(&screen);
|
||||||
);
|
style(format!("DarkMagenta : \t {} \n", "■")).with(Color::DarkMagenta).paint(&screen);
|
||||||
println!("Yellow : \t {}", terminal.paint("■").with(Color::Yellow));
|
style(format!("Yellow : \t {} \n", "■")).with(Color::Yellow).paint(&screen);
|
||||||
println!(
|
style(format!("DarkYellow : \t {} \n", "■")).with(Color::DarkYellow).paint(&screen);
|
||||||
"Dark Yellow : \t {}",
|
style(format!("Grey : \t\t {} \n", "■")).with(Color::Grey).paint(&screen);
|
||||||
terminal.paint("■").with(Color::DarkYellow)
|
style(format!("White : \t {} \n", "■")).with(Color::White).paint(&screen);
|
||||||
);
|
|
||||||
println!("Blue : \t\t {}", terminal.paint("■").with(Color::Blue));
|
#[cfg(unix)]
|
||||||
println!(
|
style("RGB color (10,10,10) ").with(Color::Rgb {
|
||||||
"Dark Blue : \t {}",
|
r: 10,
|
||||||
terminal.paint("■").with(Color::DarkBlue)
|
g: 10,
|
||||||
);
|
b: 10
|
||||||
println!(
|
}).paint(&screen);
|
||||||
"Magenta : \t {}",
|
|
||||||
terminal.paint("■").with(Color::Magenta)
|
#[cfg(unix)]
|
||||||
);
|
style("RGB color (10,10,10) ").with(Color::AnsiValue(50)).paint(&screen);
|
||||||
println!(
|
|
||||||
"Dark Magenta : \t {}",
|
|
||||||
terminal.paint("■").with(Color::DarkMagenta)
|
|
||||||
);
|
|
||||||
println!("Cyan : \t\t {}", terminal.paint("■").with(Color::Cyan));
|
|
||||||
println!(
|
|
||||||
"Dark Cyan : \t {}",
|
|
||||||
terminal.paint("■").with(Color::DarkCyan)
|
|
||||||
);
|
|
||||||
println!("Grey : \t\t {}", terminal.paint("■").with(Color::Grey));
|
|
||||||
println!("White : \t {}", terminal.paint("■").with(Color::White));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print all available foreground colors | demonstration.
|
/// Print all available foreground colors | demonstration.
|
||||||
pub fn print_all_background_colors() {
|
pub fn print_all_background_colors() {
|
||||||
let context = Context::new();
|
let screen = Screen::default();
|
||||||
let terminal = terminal::terminal(&context);
|
|
||||||
|
style(format!("Black : \t {} \n", "■")).on(Color::Black).paint(&screen);
|
||||||
|
style(format!("Red : \t\t {} \n", "■")).on(Color::Red).paint(&screen);
|
||||||
|
style(format!("Cyan : \t\t {} \n", "■")).on(Color::Cyan).paint(&screen);
|
||||||
|
style(format!("DarkCyan : \t {} \n", "■")).on(Color::DarkCyan).paint(&screen);
|
||||||
|
style(format!("DarkRed : \t {} \n", "■")).on(Color::DarkRed).paint(&screen);
|
||||||
|
style(format!("Green : \t {} \n", "■")).on(Color::Green).paint(&screen);
|
||||||
|
style(format!("DarkGreen : \t {} \n", "■")).on(Color::DarkGreen).paint(&screen);
|
||||||
|
style(format!("Blue : \t\t {} \n", "■")).on(Color::Blue).paint(&screen);
|
||||||
|
style(format!("DarkBlue : \t {} \n", "■")).on(Color::DarkBlue).paint(&screen);
|
||||||
|
style(format!("Magenta : \t {} \n", "■")).on(Color::Magenta).paint(&screen);
|
||||||
|
style(format!("DarkMagenta : \t {} \n", "■")).on(Color::DarkMagenta).paint(&screen);
|
||||||
|
style(format!("Yellow : \t {} \n", "■")).on(Color::Yellow).paint(&screen);
|
||||||
|
style(format!("DarkYellow : \t {} \n", "■")).on(Color::DarkYellow).paint(&screen);
|
||||||
|
style(format!("Grey : \t\t {} \n", "■")).on(Color::Grey).paint(&screen);
|
||||||
|
style(format!("White : \t {} \n", "■")).on(Color::White).paint(&screen);
|
||||||
|
|
||||||
println!("Black : \t {}", terminal.paint(" ").on(Color::Black));
|
|
||||||
println!("Red : \t\t {}", terminal.paint(" ").on(Color::Red));
|
|
||||||
println!("Dark Red: \t {}", terminal.paint(" ").on(Color::DarkRed));
|
|
||||||
println!("Green : \t {}", terminal.paint(" ").on(Color::Green));
|
|
||||||
println!(
|
|
||||||
"Dark Green : \t {}",
|
|
||||||
terminal.paint(" ").on(Color::DarkGreen)
|
|
||||||
);
|
|
||||||
println!("Yellow : \t {}", terminal.paint(" ").on(Color::Yellow));
|
|
||||||
println!(
|
|
||||||
"Dark Yellow : \t {}",
|
|
||||||
terminal.paint(" ").on(Color::DarkYellow)
|
|
||||||
);
|
|
||||||
println!("Blue : \t\t {}", terminal.paint(" ").on(Color::Blue));
|
|
||||||
println!(
|
|
||||||
"Dark Blue : \t {}",
|
|
||||||
terminal.paint(" ").on(Color::DarkBlue)
|
|
||||||
);
|
|
||||||
println!("Magenta : \t {}", terminal.paint(" ").on(Color::Magenta));
|
|
||||||
println!(
|
|
||||||
"Dark Magenta : \t {}",
|
|
||||||
terminal.paint(" ").on(Color::DarkMagenta)
|
|
||||||
);
|
|
||||||
println!("Cyan : \t\t {}", terminal.paint(" ").on(Color::Cyan));
|
|
||||||
println!(
|
|
||||||
"Dark Cyan : \t {}",
|
|
||||||
terminal.paint(" ").on(Color::DarkCyan)
|
|
||||||
);
|
|
||||||
println!("Grey : \t\t {}", terminal.paint(" ").on(Color::Grey));
|
|
||||||
println!("White : \t {}", terminal.paint(" ").on(Color::White));
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
println!(
|
style("RGB color (10,10,10) ").on(Color::Rgb {
|
||||||
"RGB (10,10,10): \t {}",
|
r: 10,
|
||||||
terminal.paint(" ").on(Color::Rgb {
|
g: 10,
|
||||||
r: 10,
|
b: 10
|
||||||
g: 10,
|
}).paint(&screen);
|
||||||
b: 10
|
|
||||||
})
|
|
||||||
);
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
println!(
|
style("RGB color (10,10,10) ").on(Color::AnsiValue(50)).paint(&screen);
|
||||||
"RGB (10,10,10): \t {}",
|
|
||||||
terminal.paint(" ").on(Color::AnsiValue(50))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print font with all available attributes. Note that this can only be used at unix systems and that some are not supported widely | demonstration..
|
/// Print font with all available attributes. Note that this can only be used at unix systems and that some are not supported widely | demonstration..
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn print_font_with_attributes() {
|
pub fn print_font_with_attributes() {
|
||||||
let context = Context::new();
|
let screen = Screen::default();
|
||||||
let terminal = terminal::terminal(&context);
|
style("Normal text").paint(&screen);
|
||||||
|
style("Bold text").bold().paint(&screen);
|
||||||
println!("{}", terminal.paint("Normal text"));
|
style("Italic text").italic().paint(&screen);
|
||||||
println!("{}", terminal.paint("Bold text").bold());
|
style("Slow blinking text").slow().paint(&screen);
|
||||||
println!("{}", terminal.paint("Italic text").italic());
|
style("Rapid blinking text").rapid().paint(&screen);
|
||||||
println!("{}", terminal.paint("Slow blinking text").slow_blink());
|
style("Hidden text").hidden().paint(&screen);
|
||||||
println!("{}", terminal.paint("Rapid blinking text").rapid_blink());
|
style("Underlined text").underlined().paint(&screen);
|
||||||
println!("{}", terminal.paint("Hidden text").hidden());
|
style("Reversed text").reverse().paint(&screen);
|
||||||
println!("{}", terminal.paint("Underlined text").underlined());
|
style("Dim text").dim().paint(&screen);
|
||||||
println!("{}", terminal.paint("Reversed color").reverse());
|
style("Crossed out font").crossed_out().paint(&screen);
|
||||||
println!("{}", terminal.paint("Dim text color").dim());
|
|
||||||
println!("{}", terminal.paint("Crossed out font").crossed_out());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print all supported rgb colors | demonstration.
|
/// Print all supported RGB colors | demonstration.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn print_supported_colors() {
|
pub fn print_supported_colors() {
|
||||||
let context = Context::new();
|
let screen = Screen::default();
|
||||||
let terminal = terminal::terminal(&context);
|
let count = color(&screen)
|
||||||
|
|
||||||
let count = crossterm::style::color(&context)
|
|
||||||
.get_available_color_count()
|
.get_available_color_count()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
println!(
|
style(format!("White : \t {}", i)).on(Color::AnsiValue(i as u8)).paint(&screen);
|
||||||
"{}",
|
|
||||||
terminal
|
|
||||||
.paint(format!("Color: {}", i))
|
|
||||||
.with(Color::AnsiValue(i as u8))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
extern crate crossterm;
|
|
||||||
|
|
||||||
use crossterm::Crossterm;
|
|
||||||
|
|
||||||
/// use the `Crossterm` to get an instance to the cursor module | demonstration.
|
|
||||||
pub fn use_crossterm_cursor()
|
|
||||||
{
|
|
||||||
let crossterm = Crossterm::new();
|
|
||||||
let mut cursor = crossterm.cursor();
|
|
||||||
cursor.goto(5,5).print("test");
|
|
||||||
}
|
|
||||||
|
|
||||||
use crossterm::style::Color;
|
|
||||||
|
|
||||||
/// use the `Crossterm` to get an instance to the color module | demonstration.
|
|
||||||
pub fn use_crossterm_color()
|
|
||||||
{
|
|
||||||
let crossterm = Crossterm::new();
|
|
||||||
let mut color = crossterm.color();
|
|
||||||
color.set_bg(Color::Red);
|
|
||||||
color.set_fg(Color::Green);
|
|
||||||
}
|
|
||||||
|
|
||||||
use crossterm::terminal::ClearType;
|
|
||||||
|
|
||||||
/// use the `Crossterm` to get an instance to the terminal module | demonstration.
|
|
||||||
pub fn use_crossterm_terminal()
|
|
||||||
{
|
|
||||||
let crossterm = Crossterm::new();
|
|
||||||
let mut terminal = crossterm.terminal();
|
|
||||||
terminal.clear(ClearType::All);
|
|
||||||
terminal.set_size(40,40);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// paint text with colors using `Crossterm` | demonstration.
|
|
||||||
pub fn use_crossterm_paint()
|
|
||||||
{
|
|
||||||
let crossterm = Crossterm::new();
|
|
||||||
crossterm.paint("Black on BLUE").with(Color::Black).on(Color::Blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// write text to terminal using `Crossterm` | demonstration.
|
|
||||||
pub fn use_crossterm_write()
|
|
||||||
{
|
|
||||||
let crossterm = Crossterm::new();
|
|
||||||
crossterm.write("some text \nsome text on new line");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Switch to alternate screen using the `Context` of `Crossterm` | demonstration.
|
|
||||||
pub fn create_alternate_screen_from_crossterm()
|
|
||||||
{
|
|
||||||
use crossterm::screen::*;
|
|
||||||
use std::convert::From;
|
|
||||||
|
|
||||||
let crossterm = Crossterm::new();
|
|
||||||
|
|
||||||
{
|
|
||||||
// move into alternate screen
|
|
||||||
let alternate_screen = AlternateScreen::from(crossterm.context());
|
|
||||||
|
|
||||||
// this will move the cursor and print `some text` on the alternate screen.
|
|
||||||
crossterm.cursor().goto(10, 10).print("Some text");
|
|
||||||
} // <- alternate screen ends here an will be switched back to main screen.
|
|
||||||
|
|
||||||
// print "Some other text" on the mainscreen at x: 0, y: 10
|
|
||||||
crossterm.cursor().goto(0,10).print("Some other text");
|
|
||||||
}
|
|
@ -4,34 +4,28 @@
|
|||||||
|
|
||||||
extern crate crossterm;
|
extern crate crossterm;
|
||||||
use self::crossterm::cursor::{cursor, TerminalCursor};
|
use self::crossterm::cursor::{cursor, TerminalCursor};
|
||||||
use self::crossterm::Context;
|
use self::crossterm::Screen;
|
||||||
|
|
||||||
/// Set the cursor to position X: 10, Y: 5 in the terminal.
|
/// Set the cursor to position X: 10, Y: 5 in the terminal.
|
||||||
pub fn goto() {
|
pub fn goto() {
|
||||||
let context = Context::new();
|
|
||||||
|
|
||||||
// Get the cursor
|
// Get the cursor
|
||||||
let mut cursor = cursor(&context);
|
let mut cursor = cursor(&Screen::default());
|
||||||
// Set the cursor to position X: 10, Y: 5 in the terminal
|
// Set the cursor to position X: 10, Y: 5 in the terminal
|
||||||
cursor.goto(10, 5);
|
cursor.goto(10, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get the cursor position
|
/// get the cursor position
|
||||||
pub fn pos() {
|
pub fn pos() {
|
||||||
let context = Context::new();
|
|
||||||
|
|
||||||
// Get the cursor
|
// Get the cursor
|
||||||
let mut cursor = cursor(&context);
|
let mut cursor = cursor(&Screen::default());
|
||||||
// get the cursor position.
|
// get the cursor position.
|
||||||
let (x, y) = cursor.pos();
|
let (x, y) = cursor.pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move the cursor 3 up | demonstration.
|
/// Move the cursor 3 up | demonstration.
|
||||||
pub fn move_up() {
|
pub fn move_up() {
|
||||||
let context = Context::new();
|
|
||||||
|
|
||||||
// Get the cursor
|
// Get the cursor
|
||||||
let mut cursor = cursor(&context);
|
let mut cursor = cursor(&Screen::default());
|
||||||
|
|
||||||
// Move the cursor to position 3 times to the up in the terminal
|
// Move the cursor to position 3 times to the up in the terminal
|
||||||
cursor.move_up(10);
|
cursor.move_up(10);
|
||||||
@ -39,66 +33,55 @@ pub fn move_up() {
|
|||||||
|
|
||||||
/// Move the cursor 3 to the right | demonstration.
|
/// Move the cursor 3 to the right | demonstration.
|
||||||
pub fn move_right() {
|
pub fn move_right() {
|
||||||
let context = Context::new();
|
let mut cursor = cursor(&Screen::default());
|
||||||
|
|
||||||
// Get the cursor
|
|
||||||
let mut cursor = cursor(&context);
|
|
||||||
// Move the cursor to position 3 times to the right in the terminal
|
// Move the cursor to position 3 times to the right in the terminal
|
||||||
cursor.move_right(3);
|
cursor.move_right(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move the cursor 3 down | demonstration.
|
/// Move the cursor 3 down | demonstration.
|
||||||
pub fn move_down() {
|
pub fn move_down() {
|
||||||
let context = Context::new();
|
let mut cursor = cursor(&Screen::default());
|
||||||
|
|
||||||
// Get the cursor
|
|
||||||
let mut cursor = cursor(&context);
|
|
||||||
// Move the cursor to position 3 times to the down in the terminal
|
// Move the cursor to position 3 times to the down in the terminal
|
||||||
cursor.move_down(3);
|
cursor.move_down(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move the cursor 3 to the left | demonstration.
|
/// Move the cursor 3 to the left | demonstration.
|
||||||
pub fn move_left() {
|
pub fn move_left() {
|
||||||
let context = Context::new();
|
let mut cursor = cursor(&Screen::default());
|
||||||
|
|
||||||
// Get the cursor
|
|
||||||
let mut cursor = cursor(&context);
|
|
||||||
// Move the cursor to position 3 times to the left in the terminal
|
// Move the cursor to position 3 times to the left in the terminal
|
||||||
cursor.move_left(3);
|
cursor.move_left(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print character at X: 10 Y: 5 | demonstration.
|
///// Print character at X: 10 Y: 5 | demonstration.
|
||||||
pub fn print() {
|
//pub fn print() {
|
||||||
let context = Context::new();
|
// let context = Context::new();
|
||||||
|
//
|
||||||
// To print an some displayable content on an certain position.
|
// // To print an some displayable content on an certain position.
|
||||||
|
//
|
||||||
// Get the cursor
|
// // Get the cursor
|
||||||
let mut cursor = cursor(&context);
|
// let mut cursor = cursor(&context);
|
||||||
// Set the cursor to position X: 10, Y: 5 in the terminal
|
// // Set the cursor to position X: 10, Y: 5 in the terminal
|
||||||
cursor.goto(10, 5);
|
// cursor.goto(10, 5);
|
||||||
// Print the @ symbol at position X: 10, Y: 5 in the terminal
|
// // Print the @ symbol at position X: 10, Y: 5 in the terminal
|
||||||
print!("@");
|
// print!("@");
|
||||||
// Rust is line buffered inorder to print at an certain position we need to clear the buffer first.
|
// // Rust is line buffered inorder to print at an certain position we need to clear the buffer first.
|
||||||
use std;
|
// use std;
|
||||||
use std::io::Write;
|
// use std::io::Write;
|
||||||
std::io::stdout().flush();
|
// std::io::stdout().flush();
|
||||||
|
//
|
||||||
/* Because the above method is a little to much code,
|
// /* Because the above method is a little to much code,
|
||||||
you can use the `print()` method for printing an value at an certain position in the terminal.
|
// you can use the `print()` method for printing an value at an certain position in the terminal.
|
||||||
|
//
|
||||||
Crossterm provides method chaining so that the above points can be inlined.
|
// Crossterm provides method chaining so that the above points can be inlined.
|
||||||
*/
|
// */
|
||||||
|
//
|
||||||
cursor.goto(10, 5).print("@");
|
// cursor.goto(10, 5).print("@");
|
||||||
}
|
//}
|
||||||
|
|
||||||
/// Save and reset cursor position | demonstration..
|
/// Save and reset cursor position | demonstration..
|
||||||
pub fn safe_and_reset_position() {
|
pub fn safe_and_reset_position() {
|
||||||
let context = Context::new();
|
let mut cursor = cursor(&Screen::default());
|
||||||
|
|
||||||
let mut cursor = cursor(&context);
|
|
||||||
|
|
||||||
// Goto X: 5 Y: 5
|
// Goto X: 5 Y: 5
|
||||||
cursor.goto(5, 5);
|
cursor.goto(5, 5);
|
||||||
// Safe cursor position: X: 5 Y: 5
|
// Safe cursor position: X: 5 Y: 5
|
||||||
@ -117,25 +100,19 @@ pub fn safe_and_reset_position() {
|
|||||||
|
|
||||||
/// Hide cursor display | demonstration.
|
/// Hide cursor display | demonstration.
|
||||||
pub fn hide_cursor() {
|
pub fn hide_cursor() {
|
||||||
let context = Context::new();
|
let mut cursor = cursor(&Screen::default());
|
||||||
|
|
||||||
let cursor = cursor(&context);
|
|
||||||
cursor.hide();
|
cursor.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show cursor display | demonstration.
|
/// Show cursor display | demonstration.
|
||||||
pub fn show_cursor() {
|
pub fn show_cursor() {
|
||||||
let context = Context::new();
|
let mut cursor = cursor(&Screen::default());
|
||||||
|
|
||||||
let cursor = cursor(&context);
|
|
||||||
cursor.show();
|
cursor.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show cursor display, only works on certain terminals.| demonstration
|
/// Show cursor display, only works on certain terminals.| demonstration
|
||||||
pub fn blink_cursor() {
|
pub fn blink_cursor() {
|
||||||
let context = Context::new();
|
let mut cursor = cursor(&Screen::default());
|
||||||
|
|
||||||
let cursor = cursor(&context);
|
|
||||||
cursor.blink(false);
|
cursor.blink(false);
|
||||||
cursor.blink(false);
|
cursor.blink(false);
|
||||||
}
|
}
|
||||||
|
20
examples/examples.rs
Normal file
20
examples/examples.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
//! 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.
|
||||||
|
//! - Run program with: `cargo run --example examples`
|
||||||
|
|
||||||
|
extern crate crossterm;
|
||||||
|
|
||||||
|
// modules that could be test
|
||||||
|
mod terminal;
|
||||||
|
mod color;
|
||||||
|
mod cursor;
|
||||||
|
mod some_types;
|
||||||
|
mod input;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// call some test module function
|
||||||
|
}
|
@ -10,44 +10,41 @@ use std::time::Duration;
|
|||||||
|
|
||||||
/// this will capture the input until the given key.
|
/// this will capture the input until the given key.
|
||||||
pub fn read_async_until() {
|
pub fn read_async_until() {
|
||||||
let screen = Screen::new();
|
// create raw screen
|
||||||
|
let screen = Screen::new(true);
|
||||||
let crossterm = Crossterm::new();
|
let crossterm = Crossterm::new();
|
||||||
|
|
||||||
if let Ok(raw) = screen.enable_raw_modes()
|
// init some modules we use for this demo
|
||||||
{
|
let input = crossterm.input(&screen);
|
||||||
// init some modules we use for this demo
|
let terminal = crossterm.terminal(&screen);
|
||||||
let input = crossterm.input(&raw.screen);
|
let mut cursor = crossterm.cursor(&screen);
|
||||||
let terminal = crossterm.terminal(&raw.screen);
|
|
||||||
let mut cursor = crossterm.cursor(&raw.screen);
|
|
||||||
|
|
||||||
|
let mut stdin = input.read_until_async(b'\r').bytes();
|
||||||
|
|
||||||
let mut stdin = input.read_until_async(b'\r').bytes();
|
for i in 0..100 {
|
||||||
|
terminal.clear(ClearType::All);
|
||||||
|
cursor.goto(1, 1);
|
||||||
|
let a = stdin.next();
|
||||||
|
|
||||||
for i in 0..100 {
|
println!("pressed key: {:?}", a);
|
||||||
terminal.clear(ClearType::All);
|
|
||||||
cursor.goto(1, 1);
|
|
||||||
let a = stdin.next();
|
|
||||||
|
|
||||||
println!("pressed key: {:?}", a);
|
if let Some(Ok(b'\r')) = a {
|
||||||
|
println!("The enter key is hit and program is not listening to input anymore.");
|
||||||
if let Some(Ok(b'\r')) = a {
|
break;
|
||||||
println!("The enter key is hit and program is not listening to input anymore.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Ok(b'x')) = a {
|
|
||||||
println!("The key: x was pressed and program is terminated.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread::sleep(time::Duration::from_millis(100));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(Ok(b'x')) = a {
|
||||||
|
println!("The key: x was pressed and program is terminated.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread::sleep(time::Duration::from_millis(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// this will read pressed characters async until `x` is typed .
|
/// this will read pressed characters async until `x` is typed .
|
||||||
pub fn read_async() {
|
pub fn read_async() {
|
||||||
let input = input(&Screen::new());
|
let input = input(&Screen::default());
|
||||||
|
|
||||||
let mut stdin = input.read_async().bytes();
|
let mut stdin = input.read_async().bytes();
|
||||||
|
|
||||||
@ -66,16 +63,13 @@ pub fn read_async() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_async_demo() {
|
pub fn read_async_demo() {
|
||||||
let screen = Screen::new();
|
let screen = Screen::new(true);
|
||||||
let crossterm = Crossterm::new();
|
let crossterm = Crossterm::new();
|
||||||
|
|
||||||
// put stdout in raw mode so that characters wil not be outputted.
|
|
||||||
let raw = screen.enable_raw_modes().unwrap();
|
|
||||||
|
|
||||||
// init some modules we use for this demo
|
// init some modules we use for this demo
|
||||||
let input = crossterm.input(&raw.screen);
|
let input = crossterm.input(&screen);
|
||||||
let terminal = crossterm.terminal(&raw.screen);
|
let terminal = crossterm.terminal(&screen);
|
||||||
let mut cursor = crossterm.cursor(&raw.screen);
|
let mut cursor = crossterm.cursor(&screen);
|
||||||
|
|
||||||
// this will setup the async reading.
|
// this will setup the async reading.
|
||||||
let mut stdin = input.read_async().bytes();
|
let mut stdin = input.read_async().bytes();
|
||||||
@ -106,41 +100,37 @@ pub fn read_async_demo() {
|
|||||||
pub fn async_reading_on_alternate_screen() {
|
pub fn async_reading_on_alternate_screen() {
|
||||||
use crossterm::screen::AlternateScreen;
|
use crossterm::screen::AlternateScreen;
|
||||||
|
|
||||||
let screen = Screen::new();
|
let screen = Screen::new(false);
|
||||||
let crossterm = Crossterm::new();
|
let crossterm = Crossterm::new();
|
||||||
|
|
||||||
// switch to alternate screen
|
// switch to alternate screen
|
||||||
if let Ok(alternate) = screen.enable_alternate_modes()
|
if let Ok(alternate) = screen.enable_alternate_modes(true)
|
||||||
{
|
{
|
||||||
// put alternate screen in raw mode so that characters wil not be outputted.
|
// init some modules we use for this demo
|
||||||
if let Ok(raw) = alternate.enable_raw_modes()
|
let input = crossterm.input(&alternate.screen);
|
||||||
{
|
let terminal = crossterm.terminal(&alternate.screen);
|
||||||
// init some modules we use for this demo
|
let mut cursor = crossterm.cursor(&alternate.screen);
|
||||||
let input = crossterm.input(&raw.screen);
|
|
||||||
let terminal = crossterm.terminal(&raw.screen);
|
|
||||||
let mut cursor = crossterm.cursor(&raw.screen);
|
|
||||||
|
|
||||||
// this will setup the async reading.
|
// this will setup the async reading.
|
||||||
let mut stdin = input.read_async().bytes();
|
let mut stdin = input.read_async().bytes();
|
||||||
|
|
||||||
// loop until the enter key (\r) is pressed.
|
// loop until the enter key (\r) is pressed.
|
||||||
loop {
|
loop {
|
||||||
terminal.clear(ClearType::All);
|
terminal.clear(ClearType::All);
|
||||||
cursor.goto(1, 1);
|
cursor.goto(1, 1);
|
||||||
|
|
||||||
// get the next pressed key
|
// get the next pressed key
|
||||||
let pressed_key = stdin.next();
|
let pressed_key = stdin.next();
|
||||||
|
|
||||||
terminal.write(format!("\r{:?} <- Character pressed", pressed_key));
|
terminal.write(format!("\r{:?} <- Character pressed", pressed_key));
|
||||||
|
|
||||||
// check if pressed key is enter (\r)
|
// check if pressed key is enter (\r)
|
||||||
if let Some(Ok(b'\r')) = pressed_key {
|
if let Some(Ok(b'\r')) = pressed_key {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
// wait 200 ms and reset cursor write
|
|
||||||
thread::sleep(Duration::from_millis(200));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wait 200 ms and reset cursor write
|
||||||
|
thread::sleep(Duration::from_millis(200));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use self::crossterm::input::input;
|
|||||||
use self::crossterm::Screen;
|
use self::crossterm::Screen;
|
||||||
|
|
||||||
pub fn read_char() {
|
pub fn read_char() {
|
||||||
let input = input(&Screen::new());
|
let input = input(&Screen::default());
|
||||||
|
|
||||||
match input.read_char() {
|
match input.read_char() {
|
||||||
Ok(s) => println!("char typed: {}", s),
|
Ok(s) => println!("char typed: {}", s),
|
||||||
@ -13,7 +13,7 @@ pub fn read_char() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_line() {
|
pub fn read_line() {
|
||||||
let input = input(&Screen::new());
|
let input = input(&Screen::default());
|
||||||
|
|
||||||
match input.read_line() {
|
match input.read_line() {
|
||||||
Ok(s) => println!("string typed: {}", s),
|
Ok(s) => println!("string typed: {}", s),
|
||||||
|
@ -7,3 +7,4 @@ The programs are:
|
|||||||
- First depth search:
|
- First depth search:
|
||||||
This is an search algorithm implemented visually. This program uses the following functionalities: cursor movement, coloring, alternate screen and terminal clearing.
|
This is an search algorithm implemented visually. This program uses the following functionalities: cursor movement, coloring, alternate screen and terminal clearing.
|
||||||
- Duplex: This is a terminal application where there is some kind of conterminous output and with async input. So you could type an command while text is being outputted.
|
- Duplex: This is a terminal application where there is some kind of conterminous output and with async input. So you could type an command while text is being outputted.
|
||||||
|
- This is an async logging program to demonstrate asynchronous working with crossterm.
|
@ -26,10 +26,10 @@ fn main()
|
|||||||
pub fn run()
|
pub fn run()
|
||||||
{
|
{
|
||||||
// This is represents the current screen.
|
// This is represents the current screen.
|
||||||
let screen = Screen::new();
|
let screen = Screen::new(true);
|
||||||
|
|
||||||
// set size of terminal so the map we are going to draw is fitting the screen.
|
// set size of terminal so the map we are going to draw is fitting the screen.
|
||||||
terminal(&screen).set_size(110,50);
|
terminal(&screen).set_size(60,110);
|
||||||
|
|
||||||
print_welcome_screen(&screen);
|
print_welcome_screen(&screen);
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ pub fn run()
|
|||||||
fn start_algorithm(screen: &Screen)
|
fn start_algorithm(screen: &Screen)
|
||||||
{
|
{
|
||||||
// we first want to switch to alternate screen. On the alternate screen we are going to run or firstdepthsearch algorithm
|
// we first want to switch to alternate screen. On the alternate screen we are going to run or firstdepthsearch algorithm
|
||||||
if let Ok(ref alternate_screen) = screen.enable_alternate_modes()
|
if let Ok(ref alternate_screen) = screen.enable_alternate_modes(true)
|
||||||
{
|
{
|
||||||
// setup the map size and the position to start searching for a path.
|
// setup the map size and the position to start searching for a path.
|
||||||
let map_size = Size::new(100, 40);
|
let map_size = Size::new(100, 40);
|
||||||
@ -58,41 +58,38 @@ fn start_algorithm(screen: &Screen)
|
|||||||
fn print_welcome_screen(screen: &Screen)
|
fn print_welcome_screen(screen: &Screen)
|
||||||
{
|
{
|
||||||
// create the handle for the cursor and terminal.
|
// create the handle for the cursor and terminal.
|
||||||
if let Ok(raw) = screen.enable_raw_modes()
|
let crossterm = Crossterm::new();
|
||||||
{
|
let terminal = crossterm.terminal(&screen);
|
||||||
let crossterm = Crossterm::new();
|
let cursor = crossterm.cursor(&screen);
|
||||||
let terminal = crossterm.terminal(&screen);
|
let input = crossterm.input(&screen);
|
||||||
let cursor = crossterm.cursor(&raw.screen);
|
|
||||||
let input = crossterm.input(&raw.screen);
|
|
||||||
|
|
||||||
// clear the screen and print the welcome message.
|
// clear the screen and print the welcome message.
|
||||||
terminal.clear(ClearType::All);
|
terminal.clear(ClearType::All);
|
||||||
cursor.goto(0, 0);
|
cursor.goto(0, 0);
|
||||||
terminal.write(WELCOME_MESSAGE.join("\n"));
|
terminal.write(WELCOME_MESSAGE.join("\n"));
|
||||||
|
|
||||||
cursor.hide();
|
cursor.hide();
|
||||||
cursor.goto(0, 10);
|
cursor.goto(0, 10);
|
||||||
terminal.write(
|
terminal.write(
|
||||||
"The first depth search algorithm will start in: Seconds\n\
|
"The first depth search algorithm will start in: Seconds\n\
|
||||||
Press `q` to abort the program"
|
Press `q` to abort the program"
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut stdin = input.read_async().bytes();
|
let mut stdin = input.read_async().bytes();
|
||||||
|
|
||||||
// print some progress example.
|
// print some progress example.
|
||||||
for i in (1..5).rev() {
|
for i in (1..5).rev() {
|
||||||
let a = stdin.next();
|
let a = stdin.next();
|
||||||
|
|
||||||
if let Some(Ok(b'q')) = a {
|
if let Some(Ok(b'q')) = a {
|
||||||
terminal.exit();
|
terminal.exit();
|
||||||
}
|
|
||||||
|
|
||||||
// print the current counter at the line of `Seconds to Go: {counter}`
|
|
||||||
cursor.goto(48, 10);
|
|
||||||
crossterm.style(format!("{}", i)).with(Color::Red).on(Color::Blue).paint(&screen);
|
|
||||||
|
|
||||||
// 1 second delay
|
|
||||||
thread::sleep(time::Duration::from_secs(1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print the current counter at the line of `Seconds to Go: {counter}`
|
||||||
|
cursor.goto(48, 10);
|
||||||
|
crossterm.style(format!("{}", i)).with(Color::Red).on(Color::Blue).paint(&screen);
|
||||||
|
|
||||||
|
// 1 second delay
|
||||||
|
thread::sleep(time::Duration::from_secs(1));
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,35 +0,0 @@
|
|||||||
|
|
||||||
//! 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`
|
|
||||||
extern crate crossterm;
|
|
||||||
|
|
||||||
use crossterm::style::Color;
|
|
||||||
use crossterm::Crossterm;
|
|
||||||
use crossterm::write::Stdout;
|
|
||||||
use crossterm::common::screen::Screen;
|
|
||||||
use std::io::Write;
|
|
||||||
// mod terminal;
|
|
||||||
// mod color;
|
|
||||||
// mod cursor;
|
|
||||||
// mod crossterm_type;
|
|
||||||
mod input;
|
|
||||||
|
|
||||||
//use input::keyboard::{async_input, input as stdin};
|
|
||||||
|
|
||||||
use std::{thread, time, };
|
|
||||||
use std::sync::mpsc;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
input::keyboard::async_input::async_reading_on_alternate_screen();
|
|
||||||
}
|
|
20
examples/some_types/mod.rs
Normal file
20
examples/some_types/mod.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
extern crate crossterm;
|
||||||
|
|
||||||
|
use crossterm::{Crossterm, Screen};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
/// use the `Crossterm` to get an instance to the cursor module | demonstration.
|
||||||
|
pub fn use_crossterm_cursor()
|
||||||
|
{
|
||||||
|
let screen = Screen::new();
|
||||||
|
|
||||||
|
// Create the crossterm type to access different modules.
|
||||||
|
let crossterm = Crossterm::new();
|
||||||
|
|
||||||
|
// pass a reference to the current screen.
|
||||||
|
let cursor = crossterm.cursor(&screen);
|
||||||
|
let color = crossterm.color(&screen);
|
||||||
|
let terminal = crossterm.terminal(&screen);
|
||||||
|
|
||||||
|
// perform some actions with the instances above.
|
||||||
|
}
|
@ -1,18 +1,18 @@
|
|||||||
extern crate crossterm;
|
extern crate crossterm;
|
||||||
|
|
||||||
use crossterm::style::Color;
|
use crossterm::style::{Color, style};
|
||||||
use crossterm::terminal::{self, ClearType};
|
use crossterm::terminal::{self, ClearType};
|
||||||
use crossterm::Crossterm;
|
use crossterm::{Crossterm, Screen};
|
||||||
|
|
||||||
use std::io::{stdout, Write};
|
use std::io::{stdout, Write};
|
||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
fn print_wait_screen(crossterm: &mut Crossterm) {
|
fn print_wait_screen(screen: &Screen) {
|
||||||
let mut terminal = crossterm.terminal();
|
let crossterm = Crossterm::new();
|
||||||
let mut cursor = crossterm.cursor();
|
let terminal = crossterm.terminal(&screen);
|
||||||
|
let cursor = crossterm.cursor(&screen);
|
||||||
|
|
||||||
terminal.clear(ClearType::All);
|
terminal.clear(ClearType::All);
|
||||||
|
|
||||||
cursor.goto(0, 0);
|
cursor.goto(0, 0);
|
||||||
cursor.hide();
|
cursor.hide();
|
||||||
|
|
||||||
@ -25,49 +25,21 @@ fn print_wait_screen(crossterm: &mut Crossterm) {
|
|||||||
// print some progress example.
|
// print some progress example.
|
||||||
for i in 1..5 {
|
for i in 1..5 {
|
||||||
// print the current counter at the line of `Seconds to Go: {counter}`
|
// print the current counter at the line of `Seconds to Go: {counter}`
|
||||||
cursor
|
cursor.goto(10, 2);
|
||||||
.goto(10, 2)
|
style(format!("{} of the 5 items processed", i)).with(Color::Red).on(Color::Blue).paint(&screen);
|
||||||
.print(crossterm.paint(format!("{} of the 5 items processed", i)).with(Color::Red).on(Color::Blue));
|
|
||||||
|
|
||||||
// 1 second delay
|
// 1 second delay
|
||||||
thread::sleep(time::Duration::from_secs(1));
|
thread::sleep(time::Duration::from_secs(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout().flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// print wait screen on alternate screen, then swich back.
|
/// print wait screen on alternate screen, then swich back.
|
||||||
pub fn print_wait_screen_on_alternate_window() {
|
pub fn print_wait_screen_on_alternate_window() {
|
||||||
|
|
||||||
let mut term = Crossterm::new();
|
let screen = Screen::default();
|
||||||
term.to_alternate_screen();
|
|
||||||
|
|
||||||
term.write(b"test");
|
|
||||||
print_wait_screen(&mut term);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// some stress test switch from and to alternate screen.
|
|
||||||
pub fn switch_between_main_and_alternate_screen() {
|
|
||||||
|
|
||||||
|
if let Ok(alternate) = screen.enable_alternate_modes(false)
|
||||||
{
|
{
|
||||||
let mut term = Crossterm::new();
|
print_wait_screen(&alternate.screen);
|
||||||
let mut cursor = term.cursor();
|
}
|
||||||
|
|
||||||
// create new alternate screen instance and switch to the alternate screen.
|
|
||||||
let alternate = term.to_alternate_screen();
|
|
||||||
|
|
||||||
{ cursor.goto(0, 0); }
|
|
||||||
write!(term, "we are at the alternate screen!");
|
|
||||||
thread::sleep(time::Duration::from_secs(3));
|
|
||||||
|
|
||||||
term.to_main_screen();
|
|
||||||
write!(term, "we are at the alternate screen!");
|
|
||||||
thread::sleep(time::Duration::from_secs(3));
|
|
||||||
|
|
||||||
term.to_alternate_screen();
|
|
||||||
write!(term, "we are at the alternate screen!");
|
|
||||||
thread::sleep(time::Duration::from_secs(3));
|
|
||||||
} // <- Crossterm goes out of scope.
|
|
||||||
|
|
||||||
println!("Whe are back at the main screen");
|
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,33 @@
|
|||||||
extern crate crossterm;
|
extern crate crossterm;
|
||||||
|
|
||||||
use crossterm::Crossterm;
|
use crossterm::{Crossterm, Screen};
|
||||||
|
|
||||||
use crossterm::terminal::{self, ClearType};
|
use crossterm::terminal::{self, ClearType};
|
||||||
|
use crossterm::style::{style, Color};
|
||||||
|
|
||||||
use std::io::{stdout, Write};
|
use std::io::{stdout, Write};
|
||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
// raw screen is not working correctly currently
|
fn print_wait_screen(screen: &Screen) {
|
||||||
fn print_wait_screen(crossterm: &mut Crossterm) {
|
let crossterm = Crossterm::new();
|
||||||
let terminal = crossterm.terminal();
|
let terminal = crossterm.terminal(&screen);
|
||||||
let mut cursor = crossterm.cursor();
|
let cursor = crossterm.cursor(&screen);
|
||||||
|
|
||||||
terminal.clear(ClearType::All);
|
terminal.clear(ClearType::All);
|
||||||
|
cursor.goto(0, 0);
|
||||||
|
cursor.hide();
|
||||||
|
|
||||||
cursor.goto(0, 0).print("Welcome to the wait screen.");
|
terminal.write(
|
||||||
cursor
|
"Welcome to the wait screen.\n\
|
||||||
.goto(0, 1)
|
Please wait a few seconds until we arrive back at the main screen.\n\
|
||||||
.print("Please wait a few seconds until we arrive back at the main screen.");
|
Progress: ",
|
||||||
cursor.goto(0, 2).print("Progress: ");
|
);
|
||||||
|
|
||||||
// print some progress example.
|
// print some progress example.
|
||||||
for i in 1..5 {
|
for i in 1..5 {
|
||||||
// print the current counter at the line of `Seconds to Go: {counter}`
|
// print the current counter at the line of `Seconds to Go: {counter}`
|
||||||
cursor
|
cursor.goto(10, 2);
|
||||||
.goto(10, 2)
|
style(format!("{} of the 5 items processed", i)).with(Color::Red).on(Color::Blue).paint(&screen);
|
||||||
.print(format!("{} of the 5 items processed", i));
|
screen.stdout.flush();
|
||||||
|
|
||||||
// 1 second delay
|
// 1 second delay
|
||||||
thread::sleep(time::Duration::from_secs(1));
|
thread::sleep(time::Duration::from_secs(1));
|
||||||
@ -33,21 +35,11 @@ fn print_wait_screen(crossterm: &mut Crossterm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_wait_screen_on_alternate_window() {
|
pub fn print_wait_screen_on_alternate_window() {
|
||||||
let mut term = Crossterm::new();
|
let screen = Screen::default();
|
||||||
|
|
||||||
// create scope. If this scope ends the screen will be switched back to mainscreen.
|
if let Ok(alternate) = screen.enable_alternate_modes(true)
|
||||||
// because `AlternateScreen` switches back to main screen when going out of scope.
|
|
||||||
{
|
{
|
||||||
// create new alternate screen instance this call is also switching the screen to alternate screen.
|
print_wait_screen(&alternate.screen);
|
||||||
// then convert the output of the program to raw mode.
|
|
||||||
// then print the wait screen on the alternate screen in raw mode.
|
|
||||||
term.to_alternate_screen();
|
|
||||||
term.enable_raw_mode();
|
|
||||||
|
|
||||||
// Print the wait screen.
|
|
||||||
print_wait_screen(&mut term);
|
|
||||||
|
|
||||||
term.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Whe are back at the main screen");
|
println!("Whe are back at the main screen");
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
extern crate crossterm;
|
extern crate crossterm;
|
||||||
|
|
||||||
use crossterm::terminal::ClearType;
|
use crossterm::terminal::{ClearType, terminal};
|
||||||
use crossterm::Crossterm;
|
use crossterm::{Crossterm, Screen};
|
||||||
|
|
||||||
fn print_test_data() {
|
fn print_test_data() {
|
||||||
for i in 0..100 {
|
for i in 0..100 {
|
||||||
@ -15,8 +15,7 @@ fn print_test_data() {
|
|||||||
|
|
||||||
/// Clear all lines in terminal | demonstration
|
/// Clear all lines in terminal | demonstration
|
||||||
pub fn clear_all_lines() {
|
pub fn clear_all_lines() {
|
||||||
let term = Crossterm::new();
|
let mut terminal = terminal(&Screen::default());
|
||||||
let mut terminal = term.terminal();
|
|
||||||
|
|
||||||
print_test_data();
|
print_test_data();
|
||||||
|
|
||||||
@ -26,13 +25,14 @@ pub fn clear_all_lines() {
|
|||||||
|
|
||||||
/// Clear all lines from cursor position X:4, Y:4 down | demonstration
|
/// Clear all lines from cursor position X:4, Y:4 down | demonstration
|
||||||
pub fn clear_from_cursor_down() {
|
pub fn clear_from_cursor_down() {
|
||||||
let term = Crossterm::new();
|
let screen = Screen::default();
|
||||||
let mut terminal = term.terminal();
|
let crossterm = Crossterm::new();
|
||||||
|
let mut terminal = crossterm.terminal(&screen);
|
||||||
|
|
||||||
print_test_data();
|
print_test_data();
|
||||||
|
|
||||||
// Set terminal cursor position (see example for more info).
|
// Set terminal cursor position (see example for more info).
|
||||||
term.cursor().goto(4, 8);
|
crossterm.cursor(&screen).goto(4, 8);
|
||||||
|
|
||||||
// Clear all cells from current cursor position down.
|
// Clear all cells from current cursor position down.
|
||||||
terminal.clear(ClearType::FromCursorDown);
|
terminal.clear(ClearType::FromCursorDown);
|
||||||
@ -40,13 +40,14 @@ pub fn clear_from_cursor_down() {
|
|||||||
|
|
||||||
/// Clear all lines from cursor position X:4, Y:4 up | demonstration
|
/// Clear all lines from cursor position X:4, Y:4 up | demonstration
|
||||||
pub fn clear_from_cursor_up() {
|
pub fn clear_from_cursor_up() {
|
||||||
let term = Crossterm::new();
|
let screen = Screen::default();
|
||||||
let mut terminal = term.terminal();
|
let crossterm = Crossterm::new();
|
||||||
|
let mut terminal = crossterm.terminal(&screen);
|
||||||
|
|
||||||
print_test_data();
|
print_test_data();
|
||||||
|
|
||||||
// Set terminal cursor position (see example for more info).
|
// Set terminal cursor position (see example for more info).
|
||||||
term.cursor().goto(4, 4);
|
crossterm.cursor(&screen).goto(4, 4);
|
||||||
|
|
||||||
// Clear all cells from current cursor position down.
|
// Clear all cells from current cursor position down.
|
||||||
terminal.clear(ClearType::FromCursorUp);
|
terminal.clear(ClearType::FromCursorUp);
|
||||||
@ -54,13 +55,14 @@ pub fn clear_from_cursor_up() {
|
|||||||
|
|
||||||
/// Clear all lines from cursor position X:4, Y:4 up | demonstration
|
/// Clear all lines from cursor position X:4, Y:4 up | demonstration
|
||||||
pub fn clear_current_line() {
|
pub fn clear_current_line() {
|
||||||
let term = Crossterm::new();
|
let screen = Screen::default();
|
||||||
let mut terminal = term.terminal();
|
let crossterm = Crossterm::new();
|
||||||
|
let mut terminal = crossterm.terminal(&screen);
|
||||||
|
|
||||||
print_test_data();
|
print_test_data();
|
||||||
|
|
||||||
// Set terminal cursor position (see example for more info).
|
// Set terminal cursor position (see example for more info).
|
||||||
term.cursor().goto(4, 4);
|
crossterm.cursor(&screen).goto(4, 4);
|
||||||
|
|
||||||
// Clear current line cells.
|
// Clear current line cells.
|
||||||
terminal.clear(ClearType::CurrentLine);
|
terminal.clear(ClearType::CurrentLine);
|
||||||
@ -68,13 +70,14 @@ pub fn clear_current_line() {
|
|||||||
|
|
||||||
/// Clear all lines from cursor position X:4, Y:7 up | demonstration
|
/// Clear all lines from cursor position X:4, Y:7 up | demonstration
|
||||||
pub fn clear_until_new_line() {
|
pub fn clear_until_new_line() {
|
||||||
let term = Crossterm::new();
|
let screen = Screen::default();
|
||||||
let mut terminal = term.terminal();
|
let crossterm = Crossterm::new();
|
||||||
|
let mut terminal = crossterm.terminal(&screen);
|
||||||
|
|
||||||
print_test_data();
|
print_test_data();
|
||||||
|
|
||||||
// Set terminal cursor position (see example for more info).
|
// Set terminal cursor position (see example for more info).
|
||||||
term.cursor().goto(4, 20);
|
crossterm.cursor(&screen).goto(4, 20);
|
||||||
|
|
||||||
// Clear all the cells until next line.
|
// Clear all the cells until next line.
|
||||||
terminal.clear(ClearType::UntilNewLine);
|
terminal.clear(ClearType::UntilNewLine);
|
||||||
@ -82,8 +85,7 @@ pub fn clear_until_new_line() {
|
|||||||
|
|
||||||
/// Print the the current terminal size | demonstration.
|
/// Print the the current terminal size | demonstration.
|
||||||
pub fn print_terminal_size() {
|
pub fn print_terminal_size() {
|
||||||
let term = Crossterm::new();
|
let mut terminal = terminal(&Screen::default());
|
||||||
let mut terminal = term.terminal();
|
|
||||||
|
|
||||||
// Get terminal size
|
// Get terminal size
|
||||||
let (width, height) = terminal.terminal_size();
|
let (width, height) = terminal.terminal_size();
|
||||||
@ -94,16 +96,14 @@ pub fn print_terminal_size() {
|
|||||||
|
|
||||||
/// Set the terminal size to width 10, height: 10 | demonstration.
|
/// Set the terminal size to width 10, height: 10 | demonstration.
|
||||||
pub fn set_terminal_size() {
|
pub fn set_terminal_size() {
|
||||||
let term = Crossterm::new();
|
let mut terminal = terminal(&Screen::default());
|
||||||
let mut terminal = term.terminal();
|
|
||||||
|
|
||||||
terminal.set_size(10, 10);
|
terminal.set_size(10, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scroll down 10 lines | demonstration.
|
/// Scroll down 10 lines | demonstration.
|
||||||
pub fn scroll_down() {
|
pub fn scroll_down() {
|
||||||
let term = Crossterm::new();
|
let mut terminal = terminal(&Screen::default());
|
||||||
let mut terminal = term.terminal();
|
|
||||||
|
|
||||||
print_test_data();
|
print_test_data();
|
||||||
|
|
||||||
@ -113,8 +113,7 @@ pub fn scroll_down() {
|
|||||||
|
|
||||||
/// Scroll down 10 lines | demonstration.
|
/// Scroll down 10 lines | demonstration.
|
||||||
pub fn scroll_up() {
|
pub fn scroll_up() {
|
||||||
let term = Crossterm::new();
|
let mut terminal = terminal(&Screen::default());
|
||||||
let mut terminal = term.terminal();
|
|
||||||
|
|
||||||
print_test_data();
|
print_test_data();
|
||||||
|
|
||||||
@ -124,8 +123,7 @@ pub fn scroll_up() {
|
|||||||
|
|
||||||
/// Resize the terminal to X: 10, Y: 10 | demonstration.
|
/// Resize the terminal to X: 10, Y: 10 | demonstration.
|
||||||
pub fn resize_terminal() {
|
pub fn resize_terminal() {
|
||||||
let term = Crossterm::new();
|
let mut terminal = terminal(&Screen::default());
|
||||||
let mut terminal = term.terminal();
|
|
||||||
|
|
||||||
// Get terminal size
|
// Get terminal size
|
||||||
terminal.set_size(10, 10);
|
terminal.set_size(10, 10);
|
||||||
@ -133,7 +131,6 @@ pub fn resize_terminal() {
|
|||||||
|
|
||||||
/// exit the current proccess.
|
/// exit the current proccess.
|
||||||
pub fn exit() {
|
pub fn exit() {
|
||||||
let term = Crossterm::new();
|
let mut terminal = terminal(&Screen::default());
|
||||||
let mut terminal = term.terminal();
|
|
||||||
terminal.exit();
|
terminal.exit();
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,8 @@ pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T> {
|
|||||||
// Try to enable ansi on windows if not than use WINAPI.
|
// Try to enable ansi on windows if not than use WINAPI.
|
||||||
does_support = try_enable_ansi_support();
|
does_support = try_enable_ansi_support();
|
||||||
|
|
||||||
// does_support = false;
|
// uncomment this line when you want to use the winapi implementation.
|
||||||
|
does_support = false;
|
||||||
if !does_support {
|
if !does_support {
|
||||||
term = Some(winapi_impl);
|
term = Some(winapi_impl);
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,6 @@ impl AlternateScreen {
|
|||||||
self.command.disable(&self.screen.stdout)?;
|
self.command.disable(&self.screen.stdout)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_raw_modes(&self) -> io::Result<RawScreen>
|
|
||||||
{
|
|
||||||
return self.screen.enable_raw_modes();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for AlternateScreen
|
impl Drop for AlternateScreen
|
||||||
|
@ -13,48 +13,34 @@
|
|||||||
//! With these modes you can easier design the terminal screen.
|
//! With these modes you can easier design the terminal screen.
|
||||||
|
|
||||||
use super::commands::*;
|
use super::commands::*;
|
||||||
use super::{functions, Screen};
|
use super::{functions, Screen, Stdout};
|
||||||
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
/// A wrapper for the raw terminal state. Which can be used to write to.
|
/// A wrapper for the raw terminal state. Which can be used to write to.
|
||||||
pub struct RawScreen
|
pub struct RawScreen;
|
||||||
{
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
|
||||||
command: unix_command::RawModeCommand,
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
command: win_commands::RawModeCommand,
|
|
||||||
|
|
||||||
pub screen: Screen,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RawScreen {
|
impl RawScreen {
|
||||||
pub fn into_raw_mode(screen: Screen) -> io::Result<RawScreen>
|
pub fn into_raw_mode() -> io::Result<()>
|
||||||
{
|
{
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let command = unix_command::RawModeCommand::new();
|
let mut command = unix_command::RawModeCommand::new();
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let command = win_commands::RawModeCommand::new();
|
let mut command = win_commands::RawModeCommand::new();
|
||||||
|
|
||||||
Ok(RawScreen { command: command, screen})
|
command.enable()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_raw_modes(&self) -> io::Result<()>
|
pub fn disable_raw_modes() -> io::Result<()>
|
||||||
{
|
{
|
||||||
self.command.disable()?;
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
let mut command = unix_command::RawModeCommand::new();
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let mut command = win_commands::RawModeCommand::new();
|
||||||
|
|
||||||
|
command.disable()?;
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for RawScreen
|
|
||||||
{
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.disable_raw_modes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
/////// Trait withs contains a method for switching into raw mode.
|
|
||||||
////pub trait IntoRawMode: Write + Sized {
|
|
||||||
//// fn into_raw_mode(&self, context: Rc<Context>) -> io::Result<RawTerminal>;
|
|
||||||
////}
|
|
||||||
|
@ -21,9 +21,15 @@ pub struct Screen
|
|||||||
|
|
||||||
impl Screen
|
impl Screen
|
||||||
{
|
{
|
||||||
pub fn new() -> Screen
|
pub fn new(raw_mode: bool) -> Screen
|
||||||
{
|
{
|
||||||
return Screen { stdout: Arc::new(Stdout::new(false)), buffer: Vec::new() };
|
if raw_mode
|
||||||
|
{
|
||||||
|
RawScreen::into_raw_mode();;
|
||||||
|
return Screen { stdout: Arc::new(Stdout::new(true)), buffer: Vec::new() };
|
||||||
|
}
|
||||||
|
|
||||||
|
return Screen::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from(stdout: Stdout) -> Screen
|
pub fn from(stdout: Stdout) -> Screen
|
||||||
@ -31,19 +37,41 @@ impl Screen
|
|||||||
return Screen { stdout: Arc::new(stdout), buffer: Vec::new() };
|
return Screen { stdout: Arc::new(stdout), buffer: Vec::new() };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_raw_modes(&self) -> Result<RawScreen> {
|
pub fn enable_raw_modes(&self) -> Result<()> {
|
||||||
let mut screen = Screen::from(Stdout::new(true));
|
RawScreen::into_raw_mode()?;
|
||||||
let raw_screen = RawScreen::into_raw_mode(screen)?;
|
return Ok(())
|
||||||
return Ok(raw_screen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_alternate_modes(&self) -> Result<AlternateScreen> {
|
pub fn enable_alternate_modes(&self, raw_mode: bool) -> Result<AlternateScreen> {
|
||||||
let mut stdout = Stdout::new(true);
|
let mut stdout = Stdout::new(raw_mode);
|
||||||
|
|
||||||
|
if raw_mode
|
||||||
|
{
|
||||||
|
RawScreen::into_raw_mode();
|
||||||
|
}
|
||||||
|
|
||||||
let alternate_screen = AlternateScreen::to_alternate_screen(stdout)?;
|
let alternate_screen = AlternateScreen::to_alternate_screen(stdout)?;
|
||||||
return Ok(alternate_screen);
|
return Ok(alternate_screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Screen
|
||||||
|
{
|
||||||
|
fn default() -> Self {
|
||||||
|
return Screen { stdout: Arc::new(Stdout::new(false)), buffer: Vec::new() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Screen
|
||||||
|
{
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if self.stdout.is_in_raw_mode
|
||||||
|
{
|
||||||
|
RawScreen::disable_raw_modes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Write for Screen
|
impl Write for Screen
|
||||||
{
|
{
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||||
|
@ -11,6 +11,8 @@ use winapi::um::winnt::HANDLE;
|
|||||||
use winapi::um::winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE};
|
use winapi::um::winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE};
|
||||||
|
|
||||||
use super::{handle, kernel, Empty, Stdout};
|
use super::{handle, kernel, Empty, Stdout};
|
||||||
|
|
||||||
|
use std::sync::{Once, ONCE_INIT};
|
||||||
use std::io::{self, ErrorKind, Result};
|
use std::io::{self, ErrorKind, Result};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -106,3 +108,15 @@ pub fn set_active_screen_buffer(new_buffer: HANDLE) -> Result<()> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GET_ORIGINAL_CONSOLE_COLOR: Once = ONCE_INIT;
|
||||||
|
static mut original_console_color: u16 = 0;
|
||||||
|
|
||||||
|
pub fn get_original_console_color() -> u16 {
|
||||||
|
GET_ORIGINAL_CONSOLE_COLOR.call_once(|| {
|
||||||
|
let handle = handle::get_output_handle().unwrap();
|
||||||
|
let csbi = get_csbi_by_handle(&handle).unwrap();
|
||||||
|
unsafe { original_console_color = csbi.wAttributes as u16 };
|
||||||
|
});
|
||||||
|
return unsafe { original_console_color };
|
||||||
|
}
|
||||||
|
@ -160,53 +160,6 @@ impl TerminalCursor {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print an value at the current cursor position.
|
|
||||||
///
|
|
||||||
/// This method prints an value with `print!()` and clears the buffer afterwards.
|
|
||||||
/// Rust's standard output is line-buffered. So your text gets sent to the console one line at a time.
|
|
||||||
/// If you set the curosr position and try to `print!()` at that position and do not clear the buffer, than the character will not be printed at that position.
|
|
||||||
/// But will be printed when the next `println()` will be done.
|
|
||||||
///
|
|
||||||
/// With this method you can print any displayable value at a certain position and the output buffer will be cleared afterwards.
|
|
||||||
///
|
|
||||||
/// For more information see the cursor example in /examples/cursor
|
|
||||||
///
|
|
||||||
/// #Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
///
|
|
||||||
/// extern crate crossterm;
|
|
||||||
///
|
|
||||||
/// use self::crossterm::Context;
|
|
||||||
/// use self::crossterm::cursor;
|
|
||||||
///
|
|
||||||
/// use std;
|
|
||||||
/// use std::io::Write;
|
|
||||||
///
|
|
||||||
/// let crossterm = Crossterm::new();
|
|
||||||
/// let cursor = crossterm.cursor();
|
|
||||||
///
|
|
||||||
/// // of course we can just do this.
|
|
||||||
/// cursor.goto(10,10);
|
|
||||||
/// print!("@");
|
|
||||||
/// std::io::stdout().flush();
|
|
||||||
///
|
|
||||||
/// // but now we can chain the methods so it looks cleaner and it automatically flushes the buffer.
|
|
||||||
/// cursor::cursor(&context)
|
|
||||||
/// .goto(10,10)
|
|
||||||
/// .print("@");
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
pub fn print<D: Display>(&mut self, value: D) -> &mut TerminalCursor {
|
|
||||||
use std::fmt::Write;
|
|
||||||
let mut string = String::new();
|
|
||||||
write!(string, "{}", value).unwrap();
|
|
||||||
|
|
||||||
&self.screen.write_string(string);
|
|
||||||
&self.screen.flush();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Save cursor position for recall later.
|
/// Save cursor position for recall later.
|
||||||
///
|
///
|
||||||
/// Note that this position is stored program based not per instance of the `Cursor` struct.
|
/// Note that this position is stored program based not per instance of the `Cursor` struct.
|
||||||
|
@ -15,6 +15,7 @@ use self::winapi_color::WinApiColor;
|
|||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
pub use self::color::TerminalColor;
|
pub use self::color::TerminalColor;
|
||||||
pub use self::objectstyle::ObjectStyle;
|
pub use self::objectstyle::ObjectStyle;
|
||||||
@ -40,6 +41,12 @@ pub trait ITerminalColor {
|
|||||||
fn color_value(&self, color: Color, color_type: ColorType) -> String;
|
fn color_value(&self, color: Color, color_type: ColorType) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn style<D>(val: D) -> StyledObject<D>
|
||||||
|
where
|
||||||
|
D: Display, {
|
||||||
|
ObjectStyle::new().apply_to(val)
|
||||||
|
}
|
||||||
|
|
||||||
/// Attributes that could be applied on some text.
|
/// Attributes that could be applied on some text.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
|
||||||
pub enum Attribute {
|
pub enum Attribute {
|
||||||
|
@ -11,11 +11,14 @@ use winapi::um::wincon;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// This struct is an windows implementation for color related actions.
|
/// This struct is an windows implementation for color related actions.
|
||||||
pub struct WinApiColor;
|
pub struct WinApiColor
|
||||||
|
{
|
||||||
|
original_color: u16
|
||||||
|
}
|
||||||
|
|
||||||
impl WinApiColor {
|
impl WinApiColor {
|
||||||
pub fn new() -> WinApiColor {
|
pub fn new() -> WinApiColor {
|
||||||
WinApiColor {}
|
WinApiColor { original_color: csbi::get_original_console_color()}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,8 +66,7 @@ impl ITerminalColor for WinApiColor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&self, stdout: &Arc<Stdout>) {
|
fn reset(&self, stdout: &Arc<Stdout>) {
|
||||||
self.set_bg(Color::Black, stdout);
|
kernel::set_console_text_attribute(self.original_color, stdout);
|
||||||
self.set_fg(Color::White, stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This will get the winapi color value from the Color and ColorType struct
|
/// This will get the winapi color value from the Color and ColorType struct
|
||||||
|
@ -52,7 +52,6 @@ impl Stdout {
|
|||||||
Stdout { screen_manager , is_in_raw_mode}
|
Stdout { screen_manager , is_in_raw_mode}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Write String to the current screen.
|
/// Write String to the current screen.
|
||||||
pub fn write_string(&self, string: String) -> io::Result<usize> {
|
pub fn write_string(&self, string: String) -> io::Result<usize> {
|
||||||
self.screen_manager.write_str(string.as_str())
|
self.screen_manager.write_str(string.as_str())
|
||||||
|
Loading…
Reference in New Issue
Block a user