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"
|
||||
|
||||
[[example]]
|
||||
name = "simple"
|
||||
path = "examples/simple.rs"
|
||||
name = "examples"
|
||||
path = "examples/examples.rs"
|
||||
|
||||
[[example]]
|
||||
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)
|
||||
- crossterm_type (this is about the struct `Crossterm`)
|
||||
- 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.
|
||||
//!
|
||||
|
||||
extern crate crossterm;
|
||||
|
||||
use self::crossterm::style::Color;
|
||||
use self::crossterm::terminal;
|
||||
use self::crossterm::Context;
|
||||
use self::crossterm::style::{Color, style, color};
|
||||
use self::crossterm::{terminal, Screen};
|
||||
|
||||
/// print some red font | demonstration.
|
||||
pub fn paint_foreground() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(&context);
|
||||
|
||||
let screen = Screen::default();
|
||||
// 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");
|
||||
// Call the method `with()` on the object given by `paint()` and pass in any Color from the Color enum.
|
||||
styledobject = styledobject.with(Color::Red);
|
||||
// Print the object to the console and see the result.
|
||||
println!("{}", styledobject);
|
||||
// Call the method `with()` on the object given by `style()` and pass in any Color from the Color enum.
|
||||
let mut styledobject = style("Red foreground").with(Color::Red);
|
||||
|
||||
// Crossterm provides method chaining so that the above points can be inlined.
|
||||
println!("{}", terminal.paint("Red font").with(Color::Red));
|
||||
// Print the object to the given screen and.
|
||||
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.
|
||||
pub fn paint_background() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(&context);
|
||||
|
||||
let screen = Screen::default();
|
||||
// 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 background color");
|
||||
// Call the method `on()` on the object given by `paint()` and pass in an Color from the Color enum.
|
||||
styledobject = styledobject.on(Color::Red);
|
||||
// Print the object to the console and check see the result
|
||||
println!("{}", styledobject);
|
||||
// Call the method `on()` on the object given by `style()` and pass in any Color from the Color enum.
|
||||
let mut styledobject = style("Red background color").on(Color::Red);
|
||||
|
||||
// Crossterm provides method chaining so that the above points can be inlined.
|
||||
println!("{}", terminal.paint("Red background color").on(Color::Red));
|
||||
}
|
||||
// Print the object to the given screen and.
|
||||
styledobject.paint(&screen);
|
||||
|
||||
/// print font with fore- background color | demonstration.
|
||||
pub fn paint_foreground_and_background() {
|
||||
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)
|
||||
);
|
||||
// Crossterm provides method chaining for coloring so that the above points can be inlined.
|
||||
style(format!("Red background color : \t {}", "■")).with(Color::Red).paint(&screen);
|
||||
}
|
||||
|
||||
/// Print all available foreground colors | demonstration.
|
||||
pub fn print_all_foreground_colors() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(&context);
|
||||
let screen = Screen::default();
|
||||
|
||||
println!("Black : \t {}", terminal.paint("■").with(Color::Black));
|
||||
println!("Red : \t\t {}", terminal.paint("■").with(Color::Red));
|
||||
println!(
|
||||
"Dark Red: \t {}",
|
||||
terminal.paint("■").with(Color::DarkRed)
|
||||
);
|
||||
println!("Green : \t {}", terminal.paint("■").with(Color::Green));
|
||||
println!(
|
||||
"Dark Green : \t {}",
|
||||
terminal.paint("■").with(Color::DarkGreen)
|
||||
);
|
||||
println!("Yellow : \t {}", terminal.paint("■").with(Color::Yellow));
|
||||
println!(
|
||||
"Dark Yellow : \t {}",
|
||||
terminal.paint("■").with(Color::DarkYellow)
|
||||
);
|
||||
println!("Blue : \t\t {}", terminal.paint("■").with(Color::Blue));
|
||||
println!(
|
||||
"Dark Blue : \t {}",
|
||||
terminal.paint("■").with(Color::DarkBlue)
|
||||
);
|
||||
println!(
|
||||
"Magenta : \t {}",
|
||||
terminal.paint("■").with(Color::Magenta)
|
||||
);
|
||||
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));
|
||||
style(format!("Black : \t\t {} \n", "■")).with(Color::Black).paint(&screen);
|
||||
style(format!("Red : \t\t {} \n", "■")).with(Color::Red).paint(&screen);
|
||||
style(format!("Cyan : \t\t {} \n", "■")).with(Color::Cyan).paint(&screen);
|
||||
style(format!("DarkCyan : \t {} \n", "■")).with(Color::DarkCyan).paint(&screen);
|
||||
style(format!("DarkRed : \t {} \n", "■")).with(Color::DarkRed).paint(&screen);
|
||||
style(format!("Green : \t {} \n", "■")).with(Color::Green).paint(&screen);
|
||||
style(format!("DarkGreen : \t {} \n", "■")).with(Color::DarkGreen).paint(&screen);
|
||||
style(format!("Blue : \t\t {} \n", "■")).with(Color::Blue).paint(&screen);
|
||||
style(format!("DarkBlue : \t {} \n", "■")).with(Color::DarkBlue).paint(&screen);
|
||||
style(format!("Magenta : \t {} \n", "■")).with(Color::Magenta).paint(&screen);
|
||||
style(format!("DarkMagenta : \t {} \n", "■")).with(Color::DarkMagenta).paint(&screen);
|
||||
style(format!("Yellow : \t {} \n", "■")).with(Color::Yellow).paint(&screen);
|
||||
style(format!("DarkYellow : \t {} \n", "■")).with(Color::DarkYellow).paint(&screen);
|
||||
style(format!("Grey : \t\t {} \n", "■")).with(Color::Grey).paint(&screen);
|
||||
style(format!("White : \t {} \n", "■")).with(Color::White).paint(&screen);
|
||||
|
||||
#[cfg(unix)]
|
||||
style("RGB color (10,10,10) ").with(Color::Rgb {
|
||||
r: 10,
|
||||
g: 10,
|
||||
b: 10
|
||||
}).paint(&screen);
|
||||
|
||||
#[cfg(unix)]
|
||||
style("RGB color (10,10,10) ").with(Color::AnsiValue(50)).paint(&screen);
|
||||
}
|
||||
|
||||
/// Print all available foreground colors | demonstration.
|
||||
pub fn print_all_background_colors() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(&context);
|
||||
let screen = Screen::default();
|
||||
|
||||
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)]
|
||||
println!(
|
||||
"RGB (10,10,10): \t {}",
|
||||
terminal.paint(" ").on(Color::Rgb {
|
||||
r: 10,
|
||||
g: 10,
|
||||
b: 10
|
||||
})
|
||||
);
|
||||
style("RGB color (10,10,10) ").on(Color::Rgb {
|
||||
r: 10,
|
||||
g: 10,
|
||||
b: 10
|
||||
}).paint(&screen);
|
||||
|
||||
#[cfg(unix)]
|
||||
println!(
|
||||
"RGB (10,10,10): \t {}",
|
||||
terminal.paint(" ").on(Color::AnsiValue(50))
|
||||
);
|
||||
style("RGB color (10,10,10) ").on(Color::AnsiValue(50)).paint(&screen);
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
pub fn print_font_with_attributes() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(&context);
|
||||
|
||||
println!("{}", terminal.paint("Normal text"));
|
||||
println!("{}", terminal.paint("Bold text").bold());
|
||||
println!("{}", terminal.paint("Italic text").italic());
|
||||
println!("{}", terminal.paint("Slow blinking text").slow_blink());
|
||||
println!("{}", terminal.paint("Rapid blinking text").rapid_blink());
|
||||
println!("{}", terminal.paint("Hidden text").hidden());
|
||||
println!("{}", terminal.paint("Underlined text").underlined());
|
||||
println!("{}", terminal.paint("Reversed color").reverse());
|
||||
println!("{}", terminal.paint("Dim text color").dim());
|
||||
println!("{}", terminal.paint("Crossed out font").crossed_out());
|
||||
let screen = Screen::default();
|
||||
style("Normal text").paint(&screen);
|
||||
style("Bold text").bold().paint(&screen);
|
||||
style("Italic text").italic().paint(&screen);
|
||||
style("Slow blinking text").slow().paint(&screen);
|
||||
style("Rapid blinking text").rapid().paint(&screen);
|
||||
style("Hidden text").hidden().paint(&screen);
|
||||
style("Underlined text").underlined().paint(&screen);
|
||||
style("Reversed text").reverse().paint(&screen);
|
||||
style("Dim text").dim().paint(&screen);
|
||||
style("Crossed out font").crossed_out().paint(&screen);
|
||||
}
|
||||
|
||||
/// Print all supported rgb colors | demonstration.
|
||||
/// Print all supported RGB colors | demonstration.
|
||||
#[cfg(unix)]
|
||||
pub fn print_supported_colors() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(&context);
|
||||
|
||||
let count = crossterm::style::color(&context)
|
||||
let screen = Screen::default();
|
||||
let count = color(&screen)
|
||||
.get_available_color_count()
|
||||
.unwrap();
|
||||
|
||||
for i in 0..count {
|
||||
println!(
|
||||
"{}",
|
||||
terminal
|
||||
.paint(format!("Color: {}", i))
|
||||
.with(Color::AnsiValue(i as u8))
|
||||
);
|
||||
style(format!("White : \t {}", i)).on(Color::AnsiValue(i as u8)).paint(&screen);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
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.
|
||||
pub fn goto() {
|
||||
let context = Context::new();
|
||||
|
||||
// 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
|
||||
cursor.goto(10, 5);
|
||||
}
|
||||
|
||||
/// get the cursor position
|
||||
pub fn pos() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
let mut cursor = cursor(&context);
|
||||
let mut cursor = cursor(&Screen::default());
|
||||
// get the cursor position.
|
||||
let (x, y) = cursor.pos();
|
||||
}
|
||||
|
||||
/// Move the cursor 3 up | demonstration.
|
||||
pub fn move_up() {
|
||||
let context = Context::new();
|
||||
|
||||
// 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
|
||||
cursor.move_up(10);
|
||||
@ -39,66 +33,55 @@ pub fn move_up() {
|
||||
|
||||
/// Move the cursor 3 to the right | demonstration.
|
||||
pub fn move_right() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
let mut cursor = cursor(&context);
|
||||
let mut cursor = cursor(&Screen::default());
|
||||
// Move the cursor to position 3 times to the right in the terminal
|
||||
cursor.move_right(3);
|
||||
}
|
||||
|
||||
/// Move the cursor 3 down | demonstration.
|
||||
pub fn move_down() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
let mut cursor = cursor(&context);
|
||||
let mut cursor = cursor(&Screen::default());
|
||||
// Move the cursor to position 3 times to the down in the terminal
|
||||
cursor.move_down(3);
|
||||
}
|
||||
|
||||
/// Move the cursor 3 to the left | demonstration.
|
||||
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
|
||||
cursor.move_left(3);
|
||||
}
|
||||
|
||||
/// Print character at X: 10 Y: 5 | demonstration.
|
||||
pub fn print() {
|
||||
let context = Context::new();
|
||||
|
||||
// To print an some displayable content on an certain position.
|
||||
|
||||
// Get the cursor
|
||||
let mut cursor = cursor(&context);
|
||||
// Set the cursor to position X: 10, Y: 5 in the terminal
|
||||
cursor.goto(10, 5);
|
||||
// Print the @ symbol at position X: 10, Y: 5 in the terminal
|
||||
print!("@");
|
||||
// Rust is line buffered inorder to print at an certain position we need to clear the buffer first.
|
||||
use std;
|
||||
use std::io::Write;
|
||||
std::io::stdout().flush();
|
||||
|
||||
/* 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.
|
||||
|
||||
Crossterm provides method chaining so that the above points can be inlined.
|
||||
*/
|
||||
|
||||
cursor.goto(10, 5).print("@");
|
||||
}
|
||||
///// Print character at X: 10 Y: 5 | demonstration.
|
||||
//pub fn print() {
|
||||
// let context = Context::new();
|
||||
//
|
||||
// // To print an some displayable content on an certain position.
|
||||
//
|
||||
// // Get the cursor
|
||||
// let mut cursor = cursor(&context);
|
||||
// // Set the cursor to position X: 10, Y: 5 in the terminal
|
||||
// cursor.goto(10, 5);
|
||||
// // Print the @ symbol at position X: 10, Y: 5 in the terminal
|
||||
// print!("@");
|
||||
// // Rust is line buffered inorder to print at an certain position we need to clear the buffer first.
|
||||
// use std;
|
||||
// use std::io::Write;
|
||||
// std::io::stdout().flush();
|
||||
//
|
||||
// /* 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.
|
||||
//
|
||||
// Crossterm provides method chaining so that the above points can be inlined.
|
||||
// */
|
||||
//
|
||||
// cursor.goto(10, 5).print("@");
|
||||
//}
|
||||
|
||||
/// Save and reset cursor position | demonstration..
|
||||
pub fn safe_and_reset_position() {
|
||||
let context = Context::new();
|
||||
|
||||
let mut cursor = cursor(&context);
|
||||
|
||||
let mut cursor = cursor(&Screen::default());
|
||||
// Goto X: 5 Y: 5
|
||||
cursor.goto(5, 5);
|
||||
// Safe cursor position: X: 5 Y: 5
|
||||
@ -117,25 +100,19 @@ pub fn safe_and_reset_position() {
|
||||
|
||||
/// Hide cursor display | demonstration.
|
||||
pub fn hide_cursor() {
|
||||
let context = Context::new();
|
||||
|
||||
let cursor = cursor(&context);
|
||||
let mut cursor = cursor(&Screen::default());
|
||||
cursor.hide();
|
||||
}
|
||||
|
||||
/// Show cursor display | demonstration.
|
||||
pub fn show_cursor() {
|
||||
let context = Context::new();
|
||||
|
||||
let cursor = cursor(&context);
|
||||
let mut cursor = cursor(&Screen::default());
|
||||
cursor.show();
|
||||
}
|
||||
|
||||
/// Show cursor display, only works on certain terminals.| demonstration
|
||||
pub fn blink_cursor() {
|
||||
let context = Context::new();
|
||||
|
||||
let cursor = cursor(&context);
|
||||
let mut cursor = cursor(&Screen::default());
|
||||
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.
|
||||
pub fn read_async_until() {
|
||||
let screen = Screen::new();
|
||||
// create raw screen
|
||||
let screen = Screen::new(true);
|
||||
let crossterm = Crossterm::new();
|
||||
|
||||
if let Ok(raw) = screen.enable_raw_modes()
|
||||
{
|
||||
// init some modules we use for this demo
|
||||
let input = crossterm.input(&raw.screen);
|
||||
let terminal = crossterm.terminal(&raw.screen);
|
||||
let mut cursor = crossterm.cursor(&raw.screen);
|
||||
// init some modules we use for this demo
|
||||
let input = crossterm.input(&screen);
|
||||
let terminal = crossterm.terminal(&screen);
|
||||
let mut cursor = crossterm.cursor(&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 {
|
||||
terminal.clear(ClearType::All);
|
||||
cursor.goto(1, 1);
|
||||
let a = stdin.next();
|
||||
println!("pressed key: {:?}", a);
|
||||
|
||||
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.");
|
||||
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'\r')) = a {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/// this will read pressed characters async until `x` is typed .
|
||||
pub fn read_async() {
|
||||
let input = input(&Screen::new());
|
||||
let input = input(&Screen::default());
|
||||
|
||||
let mut stdin = input.read_async().bytes();
|
||||
|
||||
@ -66,16 +63,13 @@ pub fn read_async() {
|
||||
}
|
||||
|
||||
pub fn read_async_demo() {
|
||||
let screen = Screen::new();
|
||||
let screen = Screen::new(true);
|
||||
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
|
||||
let input = crossterm.input(&raw.screen);
|
||||
let terminal = crossterm.terminal(&raw.screen);
|
||||
let mut cursor = crossterm.cursor(&raw.screen);
|
||||
let input = crossterm.input(&screen);
|
||||
let terminal = crossterm.terminal(&screen);
|
||||
let mut cursor = crossterm.cursor(&screen);
|
||||
|
||||
// this will setup the async reading.
|
||||
let mut stdin = input.read_async().bytes();
|
||||
@ -106,41 +100,37 @@ pub fn read_async_demo() {
|
||||
pub fn async_reading_on_alternate_screen() {
|
||||
use crossterm::screen::AlternateScreen;
|
||||
|
||||
let screen = Screen::new();
|
||||
let screen = Screen::new(false);
|
||||
let crossterm = Crossterm::new();
|
||||
|
||||
// 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.
|
||||
if let Ok(raw) = alternate.enable_raw_modes()
|
||||
{
|
||||
// init some modules we use for this demo
|
||||
let input = crossterm.input(&raw.screen);
|
||||
let terminal = crossterm.terminal(&raw.screen);
|
||||
let mut cursor = crossterm.cursor(&raw.screen);
|
||||
// init some modules we use for this demo
|
||||
let input = crossterm.input(&alternate.screen);
|
||||
let terminal = crossterm.terminal(&alternate.screen);
|
||||
let mut cursor = crossterm.cursor(&alternate.screen);
|
||||
|
||||
// this will setup the async reading.
|
||||
let mut stdin = input.read_async().bytes();
|
||||
// this will setup the async reading.
|
||||
let mut stdin = input.read_async().bytes();
|
||||
|
||||
// loop until the enter key (\r) is pressed.
|
||||
loop {
|
||||
terminal.clear(ClearType::All);
|
||||
cursor.goto(1, 1);
|
||||
// loop until the enter key (\r) is pressed.
|
||||
loop {
|
||||
terminal.clear(ClearType::All);
|
||||
cursor.goto(1, 1);
|
||||
|
||||
// get the next pressed key
|
||||
let pressed_key = stdin.next();
|
||||
// get the next pressed key
|
||||
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)
|
||||
if let Some(Ok(b'\r')) = pressed_key {
|
||||
break;
|
||||
}
|
||||
|
||||
// wait 200 ms and reset cursor write
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
// check if pressed key is enter (\r)
|
||||
if let Some(Ok(b'\r')) = pressed_key {
|
||||
break;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
pub fn read_char() {
|
||||
let input = input(&Screen::new());
|
||||
let input = input(&Screen::default());
|
||||
|
||||
match input.read_char() {
|
||||
Ok(s) => println!("char typed: {}", s),
|
||||
@ -13,7 +13,7 @@ pub fn read_char() {
|
||||
}
|
||||
|
||||
pub fn read_line() {
|
||||
let input = input(&Screen::new());
|
||||
let input = input(&Screen::default());
|
||||
|
||||
match input.read_line() {
|
||||
Ok(s) => println!("string typed: {}", s),
|
||||
|
@ -7,3 +7,4 @@ The programs are:
|
||||
- First depth search:
|
||||
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.
|
||||
- This is an async logging program to demonstrate asynchronous working with crossterm.
|
@ -26,10 +26,10 @@ fn main()
|
||||
pub fn run()
|
||||
{
|
||||
// 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.
|
||||
terminal(&screen).set_size(110,50);
|
||||
terminal(&screen).set_size(60,110);
|
||||
|
||||
print_welcome_screen(&screen);
|
||||
|
||||
@ -39,7 +39,7 @@ pub fn run()
|
||||
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
|
||||
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.
|
||||
let map_size = Size::new(100, 40);
|
||||
@ -58,41 +58,38 @@ fn start_algorithm(screen: &Screen)
|
||||
fn print_welcome_screen(screen: &Screen)
|
||||
{
|
||||
// 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 cursor = crossterm.cursor(&raw.screen);
|
||||
let input = crossterm.input(&raw.screen);
|
||||
let crossterm = Crossterm::new();
|
||||
let terminal = crossterm.terminal(&screen);
|
||||
let cursor = crossterm.cursor(&screen);
|
||||
let input = crossterm.input(&screen);
|
||||
|
||||
// clear the screen and print the welcome message.
|
||||
terminal.clear(ClearType::All);
|
||||
cursor.goto(0, 0);
|
||||
terminal.write(WELCOME_MESSAGE.join("\n"));
|
||||
// clear the screen and print the welcome message.
|
||||
terminal.clear(ClearType::All);
|
||||
cursor.goto(0, 0);
|
||||
terminal.write(WELCOME_MESSAGE.join("\n"));
|
||||
|
||||
cursor.hide();
|
||||
cursor.goto(0, 10);
|
||||
terminal.write(
|
||||
"The first depth search algorithm will start in: Seconds\n\
|
||||
cursor.hide();
|
||||
cursor.goto(0, 10);
|
||||
terminal.write(
|
||||
"The first depth search algorithm will start in: Seconds\n\
|
||||
Press `q` to abort the program"
|
||||
);
|
||||
);
|
||||
|
||||
let mut stdin = input.read_async().bytes();
|
||||
let mut stdin = input.read_async().bytes();
|
||||
|
||||
// print some progress example.
|
||||
for i in (1..5).rev() {
|
||||
let a = stdin.next();
|
||||
// print some progress example.
|
||||
for i in (1..5).rev() {
|
||||
let a = stdin.next();
|
||||
|
||||
if let Some(Ok(b'q')) = a {
|
||||
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));
|
||||
}
|
||||
if let Some(Ok(b'q')) = a {
|
||||
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));
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
use crossterm::style::Color;
|
||||
use crossterm::style::{Color, style};
|
||||
use crossterm::terminal::{self, ClearType};
|
||||
use crossterm::Crossterm;
|
||||
use crossterm::{Crossterm, Screen};
|
||||
|
||||
use std::io::{stdout, Write};
|
||||
use std::{thread, time};
|
||||
|
||||
fn print_wait_screen(crossterm: &mut Crossterm) {
|
||||
let mut terminal = crossterm.terminal();
|
||||
let mut cursor = crossterm.cursor();
|
||||
fn print_wait_screen(screen: &Screen) {
|
||||
let crossterm = Crossterm::new();
|
||||
let terminal = crossterm.terminal(&screen);
|
||||
let cursor = crossterm.cursor(&screen);
|
||||
|
||||
terminal.clear(ClearType::All);
|
||||
|
||||
cursor.goto(0, 0);
|
||||
cursor.hide();
|
||||
|
||||
@ -25,49 +25,21 @@ fn print_wait_screen(crossterm: &mut Crossterm) {
|
||||
// print some progress example.
|
||||
for i in 1..5 {
|
||||
// print the current counter at the line of `Seconds to Go: {counter}`
|
||||
cursor
|
||||
.goto(10, 2)
|
||||
.print(crossterm.paint(format!("{} of the 5 items processed", i)).with(Color::Red).on(Color::Blue));
|
||||
cursor.goto(10, 2);
|
||||
style(format!("{} of the 5 items processed", i)).with(Color::Red).on(Color::Blue).paint(&screen);
|
||||
|
||||
// 1 second delay
|
||||
thread::sleep(time::Duration::from_secs(1));
|
||||
}
|
||||
|
||||
stdout().flush();
|
||||
}
|
||||
|
||||
/// print wait screen on alternate screen, then swich back.
|
||||
pub fn print_wait_screen_on_alternate_window() {
|
||||
|
||||
let mut term = Crossterm::new();
|
||||
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() {
|
||||
let screen = Screen::default();
|
||||
|
||||
if let Ok(alternate) = screen.enable_alternate_modes(false)
|
||||
{
|
||||
let mut term = Crossterm::new();
|
||||
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");
|
||||
print_wait_screen(&alternate.screen);
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,33 @@
|
||||
extern crate crossterm;
|
||||
|
||||
use crossterm::Crossterm;
|
||||
|
||||
use crossterm::{Crossterm, Screen};
|
||||
use crossterm::terminal::{self, ClearType};
|
||||
use crossterm::style::{style, Color};
|
||||
|
||||
use std::io::{stdout, Write};
|
||||
use std::{thread, time};
|
||||
|
||||
// raw screen is not working correctly currently
|
||||
fn print_wait_screen(crossterm: &mut Crossterm) {
|
||||
let terminal = crossterm.terminal();
|
||||
let mut cursor = crossterm.cursor();
|
||||
fn print_wait_screen(screen: &Screen) {
|
||||
let crossterm = Crossterm::new();
|
||||
let terminal = crossterm.terminal(&screen);
|
||||
let cursor = crossterm.cursor(&screen);
|
||||
|
||||
terminal.clear(ClearType::All);
|
||||
cursor.goto(0, 0);
|
||||
cursor.hide();
|
||||
|
||||
cursor.goto(0, 0).print("Welcome to the wait screen.");
|
||||
cursor
|
||||
.goto(0, 1)
|
||||
.print("Please wait a few seconds until we arrive back at the main screen.");
|
||||
cursor.goto(0, 2).print("Progress: ");
|
||||
terminal.write(
|
||||
"Welcome to the wait screen.\n\
|
||||
Please wait a few seconds until we arrive back at the main screen.\n\
|
||||
Progress: ",
|
||||
);
|
||||
|
||||
// print some progress example.
|
||||
for i in 1..5 {
|
||||
// print the current counter at the line of `Seconds to Go: {counter}`
|
||||
cursor
|
||||
.goto(10, 2)
|
||||
.print(format!("{} of the 5 items processed", i));
|
||||
cursor.goto(10, 2);
|
||||
style(format!("{} of the 5 items processed", i)).with(Color::Red).on(Color::Blue).paint(&screen);
|
||||
screen.stdout.flush();
|
||||
|
||||
// 1 second delay
|
||||
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() {
|
||||
let mut term = Crossterm::new();
|
||||
let screen = Screen::default();
|
||||
|
||||
// create scope. If this scope ends the screen will be switched back to mainscreen.
|
||||
// because `AlternateScreen` switches back to main screen when going out of scope.
|
||||
if let Ok(alternate) = screen.enable_alternate_modes(true)
|
||||
{
|
||||
// create new alternate screen instance this call is also switching the screen to 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();
|
||||
print_wait_screen(&alternate.screen);
|
||||
}
|
||||
|
||||
println!("Whe are back at the main screen");
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
extern crate crossterm;
|
||||
|
||||
use crossterm::terminal::ClearType;
|
||||
use crossterm::Crossterm;
|
||||
use crossterm::terminal::{ClearType, terminal};
|
||||
use crossterm::{Crossterm, Screen};
|
||||
|
||||
fn print_test_data() {
|
||||
for i in 0..100 {
|
||||
@ -15,8 +15,7 @@ fn print_test_data() {
|
||||
|
||||
/// Clear all lines in terminal | demonstration
|
||||
pub fn clear_all_lines() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let mut terminal = terminal(&Screen::default());
|
||||
|
||||
print_test_data();
|
||||
|
||||
@ -26,13 +25,14 @@ pub fn clear_all_lines() {
|
||||
|
||||
/// Clear all lines from cursor position X:4, Y:4 down | demonstration
|
||||
pub fn clear_from_cursor_down() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let screen = Screen::default();
|
||||
let crossterm = Crossterm::new();
|
||||
let mut terminal = crossterm.terminal(&screen);
|
||||
|
||||
print_test_data();
|
||||
|
||||
// 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.
|
||||
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
|
||||
pub fn clear_from_cursor_up() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let screen = Screen::default();
|
||||
let crossterm = Crossterm::new();
|
||||
let mut terminal = crossterm.terminal(&screen);
|
||||
|
||||
print_test_data();
|
||||
|
||||
// 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.
|
||||
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
|
||||
pub fn clear_current_line() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let screen = Screen::default();
|
||||
let crossterm = Crossterm::new();
|
||||
let mut terminal = crossterm.terminal(&screen);
|
||||
|
||||
print_test_data();
|
||||
|
||||
// Set terminal cursor position (see example for more info).
|
||||
term.cursor().goto(4, 4);
|
||||
crossterm.cursor(&screen).goto(4, 4);
|
||||
|
||||
// Clear current line cells.
|
||||
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
|
||||
pub fn clear_until_new_line() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let screen = Screen::default();
|
||||
let crossterm = Crossterm::new();
|
||||
let mut terminal = crossterm.terminal(&screen);
|
||||
|
||||
print_test_data();
|
||||
|
||||
// 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.
|
||||
terminal.clear(ClearType::UntilNewLine);
|
||||
@ -82,8 +85,7 @@ pub fn clear_until_new_line() {
|
||||
|
||||
/// Print the the current terminal size | demonstration.
|
||||
pub fn print_terminal_size() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let mut terminal = terminal(&Screen::default());
|
||||
|
||||
// Get 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.
|
||||
pub fn set_terminal_size() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let mut terminal = terminal(&Screen::default());
|
||||
|
||||
terminal.set_size(10, 10);
|
||||
}
|
||||
|
||||
/// Scroll down 10 lines | demonstration.
|
||||
pub fn scroll_down() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let mut terminal = terminal(&Screen::default());
|
||||
|
||||
print_test_data();
|
||||
|
||||
@ -113,8 +113,7 @@ pub fn scroll_down() {
|
||||
|
||||
/// Scroll down 10 lines | demonstration.
|
||||
pub fn scroll_up() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let mut terminal = terminal(&Screen::default());
|
||||
|
||||
print_test_data();
|
||||
|
||||
@ -124,8 +123,7 @@ pub fn scroll_up() {
|
||||
|
||||
/// Resize the terminal to X: 10, Y: 10 | demonstration.
|
||||
pub fn resize_terminal() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let mut terminal = terminal(&Screen::default());
|
||||
|
||||
// Get terminal size
|
||||
terminal.set_size(10, 10);
|
||||
@ -133,7 +131,6 @@ pub fn resize_terminal() {
|
||||
|
||||
/// exit the current proccess.
|
||||
pub fn exit() {
|
||||
let term = Crossterm::new();
|
||||
let mut terminal = term.terminal();
|
||||
let mut terminal = terminal(&Screen::default());
|
||||
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.
|
||||
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 {
|
||||
term = Some(winapi_impl);
|
||||
}
|
||||
|
@ -61,11 +61,6 @@ impl AlternateScreen {
|
||||
self.command.disable(&self.screen.stdout)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn enable_raw_modes(&self) -> io::Result<RawScreen>
|
||||
{
|
||||
return self.screen.enable_raw_modes();
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AlternateScreen
|
||||
|
@ -13,48 +13,34 @@
|
||||
//! With these modes you can easier design the terminal screen.
|
||||
|
||||
use super::commands::*;
|
||||
use super::{functions, Screen};
|
||||
use super::{functions, Screen, Stdout};
|
||||
|
||||
use std::io::{self, Write};
|
||||
|
||||
/// A wrapper for the raw terminal state. Which can be used to write to.
|
||||
pub struct RawScreen
|
||||
{
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
command: unix_command::RawModeCommand,
|
||||
#[cfg(target_os = "windows")]
|
||||
command: win_commands::RawModeCommand,
|
||||
|
||||
pub screen: Screen,
|
||||
}
|
||||
pub struct 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"))]
|
||||
let command = unix_command::RawModeCommand::new();
|
||||
let mut command = unix_command::RawModeCommand::new();
|
||||
#[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(())
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
@ -31,19 +37,41 @@ impl Screen
|
||||
return Screen { stdout: Arc::new(stdout), buffer: Vec::new() };
|
||||
}
|
||||
|
||||
pub fn enable_raw_modes(&self) -> Result<RawScreen> {
|
||||
let mut screen = Screen::from(Stdout::new(true));
|
||||
let raw_screen = RawScreen::into_raw_mode(screen)?;
|
||||
return Ok(raw_screen)
|
||||
pub fn enable_raw_modes(&self) -> Result<()> {
|
||||
RawScreen::into_raw_mode()?;
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
pub fn enable_alternate_modes(&self) -> Result<AlternateScreen> {
|
||||
let mut stdout = Stdout::new(true);
|
||||
pub fn enable_alternate_modes(&self, raw_mode: bool) -> Result<AlternateScreen> {
|
||||
let mut stdout = Stdout::new(raw_mode);
|
||||
|
||||
if raw_mode
|
||||
{
|
||||
RawScreen::into_raw_mode();
|
||||
}
|
||||
|
||||
let alternate_screen = AlternateScreen::to_alternate_screen(stdout)?;
|
||||
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
|
||||
{
|
||||
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 super::{handle, kernel, Empty, Stdout};
|
||||
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use std::io::{self, ErrorKind, Result};
|
||||
use std::mem::size_of;
|
||||
use std::sync::Arc;
|
||||
@ -106,3 +108,15 @@ pub fn set_active_screen_buffer(new_buffer: HANDLE) -> Result<()> {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// 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::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::fmt::Display;
|
||||
|
||||
pub use self::color::TerminalColor;
|
||||
pub use self::objectstyle::ObjectStyle;
|
||||
@ -40,6 +41,12 @@ pub trait ITerminalColor {
|
||||
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.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
|
||||
pub enum Attribute {
|
||||
|
@ -11,11 +11,14 @@ use winapi::um::wincon;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// This struct is an windows implementation for color related actions.
|
||||
pub struct WinApiColor;
|
||||
pub struct WinApiColor
|
||||
{
|
||||
original_color: u16
|
||||
}
|
||||
|
||||
impl 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>) {
|
||||
self.set_bg(Color::Black, stdout);
|
||||
self.set_fg(Color::White, stdout);
|
||||
kernel::set_console_text_attribute(self.original_color, stdout);
|
||||
}
|
||||
|
||||
/// 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}
|
||||
}
|
||||
|
||||
|
||||
/// Write String to the current screen.
|
||||
pub fn write_string(&self, string: String) -> io::Result<usize> {
|
||||
self.screen_manager.write_str(string.as_str())
|
||||
|
Loading…
Reference in New Issue
Block a user