fixed input and cursor with new implementation
This commit is contained in:
parent
d7387ed227
commit
26472359bc
@ -25,4 +25,12 @@ use crossterm::Terminal;
|
|||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let term = Terminal::new();
|
||||||
|
let mut cursor = term.cursor();
|
||||||
|
cursor.goto(10,10);
|
||||||
|
cursor.print("test");
|
||||||
|
|
||||||
|
let stdin = term.input();
|
||||||
|
let line = stdin.read_line();
|
||||||
|
println!("{:?}", line)
|
||||||
}
|
}
|
||||||
|
@ -4,95 +4,63 @@
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use shared::functions;
|
use shared::functions;
|
||||||
use Context;
|
use {Context,ScreenManager};
|
||||||
|
|
||||||
/// This struct is an ansi implementation for cursor related actions.
|
/// This struct is an ansi implementation for cursor related actions.
|
||||||
pub struct AnsiCursor {
|
pub struct AnsiCursor;
|
||||||
context: Rc<Context>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AnsiCursor {
|
impl AnsiCursor {
|
||||||
pub fn new(context: Rc<Context>) -> Box<AnsiCursor> {
|
pub fn new() -> Box<AnsiCursor> {
|
||||||
Box::from(AnsiCursor { context })
|
Box::from(AnsiCursor { })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ITerminalCursor for AnsiCursor {
|
impl ITerminalCursor for AnsiCursor {
|
||||||
fn goto(&self, x: u16, y: u16) {
|
fn goto(&self, x: u16, y: u16, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_string(format!(csi!("{};{}H"), y + 1, x + 1));
|
||||||
{
|
|
||||||
screen.write_string(format!(csi!("{};{}H"), y + 1, x + 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos(&self) -> (u16, u16) {
|
fn pos(&self, screen_manager: &ScreenManager) -> (u16, u16) {
|
||||||
functions::get_cursor_position(self.context.clone())
|
functions::get_cursor_position(screen_manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_up(&self, count: u16) {
|
fn move_up(&self, count: u16, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_string(format!(csi!("{}A"), count));
|
||||||
{
|
|
||||||
screen.write_string(format!(csi!("{}A"), count));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_right(&self, count: u16) {
|
fn move_right(&self, count: u16, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_string(format!(csi!("{}C"), count));
|
||||||
{
|
|
||||||
screen.write_string(format!(csi!("{}C"), count));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_down(&self, count: u16) {
|
fn move_down(&self, count: u16, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_string(format!(csi!("{}B"), count));
|
||||||
{
|
|
||||||
screen.write_string(format!(csi!("{}B"), count));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_left(&self, count: u16) {
|
fn move_left(&self, count: u16, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_string(format!(csi!("{}D"), count));
|
||||||
{
|
|
||||||
screen.write_string(format!(csi!("{}D"), count));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_position(&self) {
|
fn save_position(&self, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_str(csi!("s"));
|
||||||
{
|
|
||||||
screen.write_str(csi!("s"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_position(&self) {
|
fn reset_position(&self, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_str(csi!("u"));
|
||||||
{
|
|
||||||
screen.write_str(csi!("u"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hide(&self) {
|
fn hide(&self, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_str(csi!("?25l"));
|
||||||
{
|
|
||||||
screen.write_str(csi!("?25l"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&self) {
|
fn show(&self, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
screen_manager.write_str(csi!("?25h"));
|
||||||
{
|
|
||||||
screen.write_str(csi!("?25h"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blink(&self, blink: bool) {
|
fn blink(&self, blink: bool, screen_manager: &ScreenManager) {
|
||||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
if blink {
|
||||||
{
|
screen_manager.write_str(csi!("?12h"));
|
||||||
if blink {
|
} else {
|
||||||
screen.write_str(csi!("?12h"));
|
screen_manager.write_str(csi!("?12l"));
|
||||||
} else {
|
|
||||||
screen.write_str(csi!("?12l"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,25 +13,25 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
/// Struct that stores an specific platform implementation for cursor related actions.
|
/// Struct that stores an specific platform implementation for cursor related actions.
|
||||||
pub struct TerminalCursor<'cursor> {
|
pub struct TerminalCursor<'cursor> {
|
||||||
context: &'cursor ScreenManager,
|
screen_manager: &'cursor ScreenManager,
|
||||||
terminal_cursor: Box<ITerminalCursor>,
|
terminal_cursor: Box<ITerminalCursor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cursor> TerminalCursor<'cursor> {
|
impl<'cursor> TerminalCursor<'cursor> {
|
||||||
/// Create new cursor instance whereon cursor related actions can be performed.
|
/// Create new cursor instance whereon cursor related actions can be performed.
|
||||||
pub fn new(context: &'cursor ScreenManager) -> TerminalCursor<'cursor> {
|
pub fn new(screen_manager: &'cursor ScreenManager) -> TerminalCursor<'cursor> {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let cursor = functions::get_module::<Box<ITerminalCursor>>(
|
let cursor = functions::get_module::<Box<ITerminalCursor>>(
|
||||||
WinApiCursor::new(context.screen_manager.clone()),
|
WinApiCursor::new(),
|
||||||
AnsiCursor::new(context.clone()),
|
AnsiCursor::new(),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let cursor = AnsiCursor::new(context.clone()) as Box<ITerminalCursor>;
|
let cursor = AnsiCursor::new() as Box<ITerminalCursor>;
|
||||||
|
|
||||||
TerminalCursor {
|
TerminalCursor {
|
||||||
terminal_cursor: cursor,
|
terminal_cursor: cursor,
|
||||||
context,
|
screen_manager: screen_manager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,8 +56,8 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn goto(&mut self, x: u16, y: u16) -> &mut TerminalCursor {
|
pub fn goto(&mut self, x: u16, y: u16) -> &mut TerminalCursor<'cursor> {
|
||||||
self.terminal_cursor.goto(x, y);
|
self.terminal_cursor.goto(x, y, &self.screen_manager);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn pos(&self) -> (u16, u16) {
|
pub fn pos(&self) -> (u16, u16) {
|
||||||
self.terminal_cursor.pos()
|
self.terminal_cursor.pos(&self.screen_manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move the current cursor position `n` times up.
|
/// Move the current cursor position `n` times up.
|
||||||
@ -107,8 +107,8 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor {
|
pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor<'cursor> {
|
||||||
self.terminal_cursor.move_up(count);
|
self.terminal_cursor.move_up(count, &self.screen_manager);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,8 +131,8 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
/// cursor.move_right(3);
|
/// cursor.move_right(3);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor {
|
pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor<'cursor> {
|
||||||
self.terminal_cursor.move_right(count);
|
self.terminal_cursor.move_right(count, &self.screen_manager);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,8 +157,8 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor {
|
pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor<'cursor> {
|
||||||
self.terminal_cursor.move_down(count);
|
self.terminal_cursor.move_down(count, &self.screen_manager);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,8 +183,8 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor {
|
pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor<'cursor> {
|
||||||
self.terminal_cursor.move_left(count);
|
self.terminal_cursor.move_left(count, &self.screen_manager);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,19 +224,13 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
/// .print("@");
|
/// .print("@");
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn print<D: Display>(&mut self, value: D) -> &mut TerminalCursor {
|
pub fn print<D: Display>(&mut self, value: D) -> &mut TerminalCursor<'cursor> {
|
||||||
{
|
use std::fmt::Write;
|
||||||
use std::fmt::Write;
|
let mut string = String::new();
|
||||||
let mut string = String::new();
|
write!(string, "{}", value).unwrap();
|
||||||
write!(string, "{}", value).unwrap();
|
|
||||||
|
|
||||||
let mut mutex = &self.context.screen_manager;
|
&self.screen_manager.write_string(string);
|
||||||
{
|
&self.screen_manager.flush();
|
||||||
let mut screen_manager = mutex.lock().unwrap();
|
|
||||||
screen_manager.write_string(string);
|
|
||||||
screen_manager.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +251,7 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn save_position(&self) {
|
pub fn save_position(&self) {
|
||||||
self.terminal_cursor.save_position();
|
self.terminal_cursor.save_position(&self.screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return to saved cursor position
|
/// Return to saved cursor position
|
||||||
@ -277,7 +271,7 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn reset_position(&self) {
|
pub fn reset_position(&self) {
|
||||||
self.terminal_cursor.reset_position();
|
self.terminal_cursor.reset_position(&self.screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hide de cursor in the console.
|
/// Hide de cursor in the console.
|
||||||
@ -295,7 +289,7 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn hide(&self) {
|
pub fn hide(&self) {
|
||||||
self.terminal_cursor.hide();
|
self.terminal_cursor.hide(&self.screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show the cursor in the console.
|
/// Show the cursor in the console.
|
||||||
@ -313,7 +307,7 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn show(&self) {
|
pub fn show(&self) {
|
||||||
self.terminal_cursor.show();
|
self.terminal_cursor.show(&self.screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable or disable blinking of the terminal.
|
/// Enable or disable blinking of the terminal.
|
||||||
@ -335,37 +329,37 @@ impl<'cursor> TerminalCursor<'cursor> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn blink(&self, blink: bool) {
|
pub fn blink(&self, blink: bool) {
|
||||||
self.terminal_cursor.blink(blink);
|
self.terminal_cursor.blink(blink, &self.screen_manager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an TerminalCursor implementation whereon cursor related actions can be performed.
|
// Get an TerminalCursor implementation whereon cursor related actions can be performed.
|
||||||
///
|
//
|
||||||
/// Check `/examples/version/cursor` in the libary for more spesific examples.
|
// Check `/examples/version/cursor` in the libary for more spesific examples.
|
||||||
///
|
//
|
||||||
/// #Example
|
// #Example
|
||||||
///
|
//
|
||||||
/// ```rust
|
// ```rust
|
||||||
///
|
//
|
||||||
/// extern crate crossterm;
|
// extern crate crossterm;
|
||||||
/// use self::crossterm::Context;
|
// use self::crossterm::Context;
|
||||||
/// use self::crossterm::cursor;
|
// use self::crossterm::cursor;
|
||||||
///
|
//
|
||||||
/// let context = Context::new();
|
// let context = Context::new();
|
||||||
///
|
//
|
||||||
/// // Get cursor and goto pos X: 5, Y: 10
|
// // Get cursor and goto pos X: 5, Y: 10
|
||||||
/// let mut cursor = cursor::cursor(&context);
|
// let mut cursor = cursor::cursor(&context);
|
||||||
/// cursor.goto(5,10);
|
// cursor.goto(5,10);
|
||||||
///
|
//
|
||||||
/// cursor.show();
|
// cursor.show();
|
||||||
/// cursor.hide();
|
// cursor.hide();
|
||||||
/// cursor.blink();
|
// cursor.blink();
|
||||||
/// cursor.move_left(2);
|
// cursor.move_left(2);
|
||||||
///
|
//
|
||||||
/// //Or you can do it in one line.
|
// //Or you can do it in one line.
|
||||||
/// cursor::cursor(&context).goto(5,10);
|
// cursor::cursor(&context).goto(5,10);
|
||||||
///
|
//
|
||||||
/// ```
|
// ```
|
||||||
pub fn cursor(context: &Rc<Context>) -> Box<TerminalCursor> {
|
//pub fn cursor(context: &ScreenManager) -> Box<TerminalCursor> {
|
||||||
Box::from(TerminalCursor::new(context.clone()))
|
// Box::from(TerminalCursor::new(context.clone()))
|
||||||
}
|
//}
|
||||||
|
@ -17,8 +17,8 @@ use self::ansi_cursor::AnsiCursor;
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use self::winapi_cursor::WinApiCursor;
|
use self::winapi_cursor::WinApiCursor;
|
||||||
|
|
||||||
pub use self::cursor::{cursor, TerminalCursor};
|
pub use self::cursor::{TerminalCursor};
|
||||||
|
use ScreenManager;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
///! This trait defines the actions that can be preformed with the terminal cursor.
|
///! This trait defines the actions that can be preformed with the terminal cursor.
|
||||||
|
@ -20,47 +20,47 @@ impl WinApiCursor {
|
|||||||
|
|
||||||
impl ITerminalCursor for WinApiCursor {
|
impl ITerminalCursor for WinApiCursor {
|
||||||
fn goto(&self, x: u16, y: u16, screen_manager: &ScreenManager) {
|
fn goto(&self, x: u16, y: u16, screen_manager: &ScreenManager) {
|
||||||
cursor::set_console_cursor_position(x as i16, y as i16, &self.screen_manager);
|
cursor::set_console_cursor_position(x as i16, y as i16, screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos(&self, screen_manager: &ScreenManager) -> (u16, u16) {
|
fn pos(&self, screen_manager: &ScreenManager) -> (u16, u16) {
|
||||||
cursor::pos(&self.screen_manager)
|
cursor::pos(screen_manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_up(&self, count: u16, screen_manager: &ScreenManager) {
|
fn move_up(&self, count: u16, screen_manager: &ScreenManager) {
|
||||||
let (xpos, ypos) = self.pos();
|
let (xpos, ypos) = self.pos(screen_manager);
|
||||||
self.goto(xpos, ypos - count);
|
self.goto(xpos, ypos - count, screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_right(&self, count: u16, screen_manager: &ScreenManager) {
|
fn move_right(&self, count: u16, screen_manager: &ScreenManager) {
|
||||||
let (xpos, ypos) = self.pos();
|
let (xpos, ypos) = self.pos(screen_manager);
|
||||||
self.goto(xpos + count, ypos);
|
self.goto(xpos + count, ypos, screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_down(&self, count: u16, screen_manager: &ScreenManager) {
|
fn move_down(&self, count: u16, screen_manager: &ScreenManager) {
|
||||||
let (xpos, ypos) = self.pos();
|
let (xpos, ypos) = self.pos(screen_manager);
|
||||||
self.goto(xpos, ypos + count);
|
self.goto(xpos, ypos + count, screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_left(&self, count: u16, screen_manager: &ScreenManager) {
|
fn move_left(&self, count: u16, screen_manager: &ScreenManager) {
|
||||||
let (xpos, ypos) = self.pos();
|
let (xpos, ypos) = self.pos(screen_manager);
|
||||||
self.goto(xpos - count, ypos);
|
self.goto(xpos - count, ypos, screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_position(&self, screen_manager: &ScreenManager) {
|
fn save_position(&self, screen_manager: &ScreenManager) {
|
||||||
cursor::save_cursor_pos(&self.screen_manager);
|
cursor::save_cursor_pos(screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_position(&self, screen_manager: &ScreenManager) {
|
fn reset_position(&self, screen_manager: &ScreenManager) {
|
||||||
cursor::reset_to_saved_position(&self.screen_manager);
|
cursor::reset_to_saved_position(screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hide(&self, screen_manager: &ScreenManager) {
|
fn hide(&self, screen_manager: &ScreenManager) {
|
||||||
cursor::cursor_visibility(false, &self.screen_manager);
|
cursor::cursor_visibility(false, screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&self, screen_manager: &ScreenManager) {
|
fn show(&self, screen_manager: &ScreenManager) {
|
||||||
cursor::cursor_visibility(true, &self.screen_manager);
|
cursor::cursor_visibility(true, screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blink(&self, blink: bool, screen_manager: &ScreenManager) {}
|
fn blink(&self, blink: bool, screen_manager: &ScreenManager) {}
|
||||||
|
@ -2,48 +2,44 @@ use std::io;
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use Context;
|
use {Context, ScreenManager };
|
||||||
|
|
||||||
pub struct TerminalInput {
|
pub struct TerminalInput<'terminal> {
|
||||||
context: Rc<Context>,
|
|
||||||
terminal_input: Box<ITerminalInput>,
|
terminal_input: Box<ITerminalInput>,
|
||||||
|
screen_manager: &'terminal ScreenManager
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalInput {
|
impl<'terminal> TerminalInput<'terminal> {
|
||||||
pub fn new(context: Rc<Context>) -> TerminalInput {
|
pub fn new(screen_manager: &'terminal ScreenManager) -> TerminalInput<'terminal> {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let input = Box::from(WindowsInput::new(context.clone()));
|
let input = Box::from(WindowsInput::new());
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let input = Box::from(UnixInput::new());
|
let input = Box::from(UnixInput::new());
|
||||||
|
|
||||||
TerminalInput {
|
TerminalInput {
|
||||||
terminal_input: input,
|
terminal_input: input,
|
||||||
context,
|
screen_manager: screen_manager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_line(&self) -> io::Result<String> {
|
pub fn read_line(&self) -> io::Result<String> {
|
||||||
self.terminal_input.read_line()
|
self.terminal_input.read_line(&self.screen_manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_char(&self) -> io::Result<char> {
|
pub fn read_char(&self) -> io::Result<char> {
|
||||||
return self.terminal_input.read_char();
|
return self.terminal_input.read_char(&self.screen_manager);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_key(&self) -> io::Result<Key> {
|
|
||||||
self.terminal_input.read_pressed_key()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_async(&self) -> AsyncReader {
|
pub fn read_async(&self) -> AsyncReader {
|
||||||
self.terminal_input.read_async()
|
self.terminal_input.read_async(&self.screen_manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_until_async(&self, delimiter: u8) -> AsyncReader {
|
pub fn read_until_async(&self, delimiter: u8) -> AsyncReader {
|
||||||
self.terminal_input.read_until_async(delimiter)
|
self.terminal_input.read_until_async(delimiter,&self.screen_manager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input(context: &Rc<Context>) -> Box<TerminalInput> {
|
pub fn input(screen_manager: &ScreenManager) -> TerminalInput {
|
||||||
return Box::from(TerminalInput::new(context.clone()));
|
return TerminalInput::new(screen_manager)
|
||||||
}
|
}
|
||||||
|
@ -13,18 +13,18 @@ use self::unix_input::UnixInput;
|
|||||||
mod unix_input;
|
mod unix_input;
|
||||||
|
|
||||||
pub use self::input::{input, TerminalInput};
|
pub use self::input::{input, TerminalInput};
|
||||||
|
use ScreenManager;
|
||||||
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
trait ITerminalInput {
|
trait ITerminalInput {
|
||||||
fn read_line(&self) -> io::Result<String>;
|
fn read_line(&self, screen_manger: &ScreenManager) -> io::Result<String>;
|
||||||
|
|
||||||
fn read_char(&self) -> io::Result<char>;
|
fn read_char(&self, screen_manger: &ScreenManager) -> io::Result<char>;
|
||||||
fn read_pressed_key(&self) -> io::Result<Key>;
|
|
||||||
|
|
||||||
fn read_async(&self) -> AsyncReader;
|
fn read_async(&self, screen_manger: &ScreenManager) -> AsyncReader;
|
||||||
fn read_until_async(&self, delimiter: u8) -> AsyncReader;
|
fn read_until_async(&self, delimiter: u8, screen_manger: &ScreenManager) -> AsyncReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AsyncReader {
|
pub struct AsyncReader {
|
||||||
|
@ -8,7 +8,7 @@ use std::thread;
|
|||||||
use super::super::kernel::unix_kernel::terminal::{get_tty, read_char};
|
use super::super::kernel::unix_kernel::terminal::{get_tty, read_char};
|
||||||
use super::super::terminal::terminal;
|
use super::super::terminal::terminal;
|
||||||
use super::{AsyncReader, ITerminalInput, Key};
|
use super::{AsyncReader, ITerminalInput, Key};
|
||||||
|
use ScreenManager;
|
||||||
pub struct UnixInput;
|
pub struct UnixInput;
|
||||||
|
|
||||||
impl UnixInput {
|
impl UnixInput {
|
||||||
@ -18,7 +18,7 @@ impl UnixInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ITerminalInput for UnixInput {
|
impl ITerminalInput for UnixInput {
|
||||||
fn read_line(&self) -> io::Result<String> {
|
fn read_line(&self, screen_manger: &ScreenManager) -> io::Result<String> {
|
||||||
let mut rv = String::new();
|
let mut rv = String::new();
|
||||||
io::stdin().read_line(&mut rv)?;
|
io::stdin().read_line(&mut rv)?;
|
||||||
let len = rv.trim_right_matches(&['\r', '\n'][..]).len();
|
let len = rv.trim_right_matches(&['\r', '\n'][..]).len();
|
||||||
@ -26,15 +26,11 @@ impl ITerminalInput for UnixInput {
|
|||||||
Ok(rv)
|
Ok(rv)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_char(&self) -> io::Result<char> {
|
fn read_char(&self, screen_manger: &ScreenManager) -> io::Result<char> {
|
||||||
read_char()
|
read_char()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_pressed_key(&self) -> io::Result<Key> {
|
fn read_async(&self, screen_manger: &ScreenManager) -> AsyncReader {
|
||||||
Ok(Key::Unknown)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_async(&self) -> AsyncReader {
|
|
||||||
let (send, recv) = mpsc::channel();
|
let (send, recv) = mpsc::channel();
|
||||||
|
|
||||||
thread::spawn(move || for i in get_tty().unwrap().bytes() {
|
thread::spawn(move || for i in get_tty().unwrap().bytes() {
|
||||||
@ -46,7 +42,7 @@ impl ITerminalInput for UnixInput {
|
|||||||
AsyncReader { recv: recv }
|
AsyncReader { recv: recv }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_until_async(&self, delimiter: u8) -> AsyncReader {
|
fn read_until_async(&self, delimiter: u8, screen_manger: &ScreenManager) -> AsyncReader {
|
||||||
let (send, recv) = mpsc::channel();
|
let (send, recv) = mpsc::channel();
|
||||||
|
|
||||||
thread::spawn(move || for i in get_tty().unwrap().bytes() {
|
thread::spawn(move || for i in get_tty().unwrap().bytes() {
|
||||||
|
@ -9,36 +9,23 @@ use super::{AsyncReader, ITerminalInput, Key};
|
|||||||
use winapi::um::winnt::INT;
|
use winapi::um::winnt::INT;
|
||||||
use winapi::um::winuser;
|
use winapi::um::winuser;
|
||||||
|
|
||||||
use super::super::terminal::terminal;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use Context;
|
use ScreenManager;
|
||||||
|
|
||||||
pub struct WindowsInput {
|
pub struct WindowsInput;
|
||||||
context: Rc<Context>,
|
|
||||||
pub display_input: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WindowsInput {
|
impl WindowsInput {
|
||||||
pub fn new(context: Rc<Context>) -> WindowsInput {
|
pub fn new() -> WindowsInput {
|
||||||
WindowsInput {
|
WindowsInput {}
|
||||||
context,
|
|
||||||
display_input: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ITerminalInput for WindowsInput {
|
impl ITerminalInput for WindowsInput {
|
||||||
fn read_line(&self) -> io::Result<String> {
|
fn read_line(&self,screen_manger: &ScreenManager) -> io::Result<String> {
|
||||||
let term = terminal(&self.context);
|
|
||||||
let mut chars: Vec<char> = Vec::new();
|
let mut chars: Vec<char> = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut is_raw_screen = false;
|
let is_raw_screen = screen_manger.is_raw_screen();
|
||||||
{
|
|
||||||
let mutex = &self.context.screen_manager;
|
|
||||||
let screen = mutex.lock().unwrap();
|
|
||||||
is_raw_screen = screen.is_raw_screen();
|
|
||||||
}
|
|
||||||
|
|
||||||
// _getwch is without echo and _getwche is with echo
|
// _getwch is without echo and _getwche is with echo
|
||||||
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
|
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
|
||||||
@ -63,15 +50,8 @@ impl ITerminalInput for WindowsInput {
|
|||||||
return Ok(chars.into_iter().collect());
|
return Ok(chars.into_iter().collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_char(&self) -> io::Result<char> {
|
fn read_char(&self, screen_manger: &ScreenManager) -> io::Result<char> {
|
||||||
let term = terminal(&self.context);
|
let is_raw_screen = screen_manger.is_raw_screen();
|
||||||
|
|
||||||
let mut is_raw_screen = false;
|
|
||||||
{
|
|
||||||
let mutex = &self.context.screen_manager;
|
|
||||||
let screen = mutex.lock().unwrap();
|
|
||||||
is_raw_screen = screen.is_raw_screen();
|
|
||||||
}
|
|
||||||
|
|
||||||
// _getwch is without echo and _getwche is with echo
|
// _getwch is without echo and _getwche is with echo
|
||||||
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
|
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
|
||||||
@ -86,9 +66,6 @@ impl ITerminalInput for WindowsInput {
|
|||||||
|
|
||||||
match char::from_u32(pressed_char as u32) {
|
match char::from_u32(pressed_char as u32) {
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
if self.display_input {
|
|
||||||
term.write(c);
|
|
||||||
}
|
|
||||||
return Ok(c);
|
return Ok(c);
|
||||||
}
|
}
|
||||||
None => Err(io::Error::new(
|
None => Err(io::Error::new(
|
||||||
@ -98,41 +75,11 @@ impl ITerminalInput for WindowsInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_pressed_key(&self) -> io::Result<Key> {
|
fn read_async(&self,screen_manger: &ScreenManager) -> AsyncReader {
|
||||||
use Context;
|
|
||||||
let context = Context::new();
|
|
||||||
|
|
||||||
let buf: [u8; 1024] = unsafe { ::std::mem::zeroed() };
|
|
||||||
// reading::read(&mut buf, &context.screen_manager);
|
|
||||||
|
|
||||||
Ok(Key::Unknown)
|
|
||||||
// let pressed_char = unsafe { _getwch() };
|
|
||||||
//
|
|
||||||
// // if 0 or 0xe0 we need to listen again because the next key will be an special key
|
|
||||||
// if pressed_char == 0 || pressed_char == 0xe0 {
|
|
||||||
// let special_key: i32 = unsafe { _getwch() };
|
|
||||||
// println!("spkey {}",special_key);
|
|
||||||
// return Ok(key_from_key_code(0x26));
|
|
||||||
// } else {
|
|
||||||
// match char::from_u32(pressed_char as u32)
|
|
||||||
// {
|
|
||||||
// Some(c) => return Ok(Key::Char(c)),
|
|
||||||
// None => { panic!("Some error needs to be returned") }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_async(&self) -> AsyncReader {
|
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
let mut is_raw_screen = false;
|
let is_raw_screen = screen_manger.is_raw_screen();
|
||||||
|
|
||||||
{
|
|
||||||
let mutex = &self.context.screen_manager;
|
|
||||||
let screen = mutex.lock().unwrap();
|
|
||||||
is_raw_screen = screen.is_raw_screen();
|
|
||||||
}
|
|
||||||
// panic!("is raw screen: {} ", is_raw_screen);
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
|
|
||||||
@ -155,15 +102,10 @@ impl ITerminalInput for WindowsInput {
|
|||||||
AsyncReader { recv: rx }
|
AsyncReader { recv: rx }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_until_async(&self, delimiter: u8) -> AsyncReader {
|
fn read_until_async(&self, delimiter: u8,screen_manger: &ScreenManager) -> AsyncReader {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
let mut is_raw_screen = false;
|
let is_raw_screen = screen_manger.is_raw_screen();
|
||||||
{
|
|
||||||
let mutex =&self.context.screen_manager;
|
|
||||||
let screen = mutex.lock().unwrap();
|
|
||||||
is_raw_screen = screen.is_raw_screen();
|
|
||||||
}
|
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
|
@ -16,7 +16,7 @@ use std::sync::Mutex;
|
|||||||
use ScreenManager;
|
use ScreenManager;
|
||||||
|
|
||||||
/// Create a new console screen buffer info struct.
|
/// Create a new console screen buffer info struct.
|
||||||
pub fn get_csbi(screen_manager: &Rc<Mutex<ScreenManager>>) -> Result<CONSOLE_SCREEN_BUFFER_INFO> {
|
pub fn get_csbi(screen_manager: &ScreenManager) -> Result<CONSOLE_SCREEN_BUFFER_INFO> {
|
||||||
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
|
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
|
||||||
let success;
|
let success;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ pub fn get_csbi(screen_manager: &Rc<Mutex<ScreenManager>>) -> Result<CONSOLE_SCR
|
|||||||
|
|
||||||
/// Get buffer info and handle of the current screen.
|
/// Get buffer info and handle of the current screen.
|
||||||
pub fn get_csbi_and_handle(
|
pub fn get_csbi_and_handle(
|
||||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
screen_manager: &ScreenManager,
|
||||||
) -> Result<(CONSOLE_SCREEN_BUFFER_INFO, HANDLE)> {
|
) -> Result<(CONSOLE_SCREEN_BUFFER_INFO, HANDLE)> {
|
||||||
let handle = handle::get_current_handle(screen_manager)?;
|
let handle = handle::get_current_handle(screen_manager)?;
|
||||||
let csbi = get_csbi_by_handle(&handle)?;
|
let csbi = get_csbi_by_handle(&handle)?;
|
||||||
@ -63,7 +63,7 @@ pub fn get_csbi_by_handle(handle: &HANDLE) -> Result<CONSOLE_SCREEN_BUFFER_INFO>
|
|||||||
/// Set the console screen buffer size
|
/// Set the console screen buffer size
|
||||||
pub fn set_console_screen_buffer_size(
|
pub fn set_console_screen_buffer_size(
|
||||||
size: COORD,
|
size: COORD,
|
||||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
screen_manager: &ScreenManager,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let handle = handle::get_current_handle(screen_manager).unwrap();
|
let handle = handle::get_current_handle(screen_manager).unwrap();
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ use std::sync::Mutex;
|
|||||||
static mut SAVED_CURSOR_POS: (u16, u16) = (0, 0);
|
static mut SAVED_CURSOR_POS: (u16, u16) = (0, 0);
|
||||||
|
|
||||||
/// Reset to saved cursor position
|
/// Reset to saved cursor position
|
||||||
pub fn reset_to_saved_position(screen_manager: &Rc<Mutex<ScreenManager>>) {
|
pub fn reset_to_saved_position(screen_manager: &ScreenManager) {
|
||||||
unsafe {
|
unsafe {
|
||||||
set_console_cursor_position(
|
set_console_cursor_position(
|
||||||
SAVED_CURSOR_POS.0 as i16,
|
SAVED_CURSOR_POS.0 as i16,
|
||||||
@ -27,7 +27,7 @@ pub fn reset_to_saved_position(screen_manager: &Rc<Mutex<ScreenManager>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Save current cursor position to recall later.
|
/// Save current cursor position to recall later.
|
||||||
pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) {
|
pub fn save_cursor_pos(screen_manager: &ScreenManager) {
|
||||||
let position = pos(screen_manager);
|
let position = pos(screen_manager);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -36,7 +36,7 @@ pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// get the current cursor position.
|
/// get the current cursor position.
|
||||||
pub fn pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
pub fn pos(screen_manager: &ScreenManager) -> (u16, u16) {
|
||||||
|
|
||||||
let handle = handle::get_output_handle().unwrap();
|
let handle = handle::get_output_handle().unwrap();
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ pub fn pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn absolute_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
pub fn absolute_cursor_pos(screen_manager: &ScreenManager) -> (u16, u16) {
|
||||||
|
|
||||||
let handle = handle::get_output_handle().unwrap();
|
let handle = handle::get_output_handle().unwrap();
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ pub fn absolute_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the cursor position to the given x and y. Note that this is 0 based.
|
/// Set the cursor position to the given x and y. Note that this is 0 based.
|
||||||
pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<ScreenManager>>) {
|
pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &ScreenManager) {
|
||||||
if x < 0 || x >= <i16>::max_value() {
|
if x < 0 || x >= <i16>::max_value() {
|
||||||
panic!(
|
panic!(
|
||||||
"Argument Out of Range Exception when setting cursor position to X: {}",
|
"Argument Out of Range Exception when setting cursor position to X: {}",
|
||||||
@ -91,7 +91,7 @@ pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<Scr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// change the cursor visibility.
|
/// change the cursor visibility.
|
||||||
pub fn cursor_visibility(visable: bool, screen_manager: &Rc<Mutex<ScreenManager>>) -> Result<()> {
|
pub fn cursor_visibility(visable: bool, screen_manager: &ScreenManager) -> Result<()> {
|
||||||
let handle = handle::get_current_handle(screen_manager).unwrap();
|
let handle = handle::get_current_handle(screen_manager).unwrap();
|
||||||
|
|
||||||
let cursor_info = CONSOLE_CURSOR_INFO {
|
let cursor_info = CONSOLE_CURSOR_INFO {
|
||||||
|
@ -6,27 +6,23 @@ use winapi::um::winnt::HANDLE;
|
|||||||
use std::io::{self, ErrorKind, Result};
|
use std::io::{self, ErrorKind, Result};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use super::super::super::manager::{ScreenManager, WinApiScreenManager};
|
use super::super::super::manager::{ScreenManager, WinApiScreenManager};
|
||||||
|
|
||||||
/// Get the global stored handle whits provides access to the current screen.
|
/// Get the global stored handle whits provides access to the current screen.
|
||||||
pub fn get_current_handle(screen_manager: &Rc<Mutex<ScreenManager>>) -> Result<HANDLE> {
|
pub fn get_current_handle(screen_manager: &ScreenManager) -> Result<HANDLE> {
|
||||||
let mut mutex = screen_manager;
|
let mut mutex = screen_manager;
|
||||||
|
|
||||||
let handle: Result<HANDLE>;
|
let handle: Result<HANDLE>;
|
||||||
|
|
||||||
let mut screen_manager = mutex.lock().unwrap();
|
let winapi_screen_manager: &WinApiScreenManager = match screen_manager
|
||||||
{
|
|
||||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
|
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_mut::<WinApiScreenManager>()
|
.downcast_ref::<WinApiScreenManager>()
|
||||||
{
|
{
|
||||||
Some(win_api) => win_api,
|
Some(win_api) => win_api,
|
||||||
None => return Err(io::Error::new(io::ErrorKind::Other,"Could not convert to winapi screen manager, this could happen when the user has an ANSI screen manager and is calling the platform specific operations 'get_cursor_pos' or 'get_terminal_size'"))
|
None => return Err(io::Error::new(io::ErrorKind::Other,"Could not convert to winapi screen manager, this could happen when the user has an ANSI screen manager and is calling the platform specific operations 'get_cursor_pos' or 'get_terminal_size'"))
|
||||||
};
|
};
|
||||||
|
|
||||||
handle = Ok(*winapi_screen_manager.get_handle());
|
handle = Ok(*winapi_screen_manager.get_handle());
|
||||||
}
|
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Change the console text attribute.
|
/// Change the console text attribute.
|
||||||
pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenManager>>) -> bool {
|
pub fn set_console_text_attribute(value: u16, screen_manager: &ScreenManager) -> bool {
|
||||||
let handle = handle::get_current_handle(screen_manager).unwrap();
|
let handle = handle::get_current_handle(screen_manager).unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -49,7 +49,7 @@ pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenMa
|
|||||||
pub fn set_console_info(
|
pub fn set_console_info(
|
||||||
absolute: bool,
|
absolute: bool,
|
||||||
rect: &SMALL_RECT,
|
rect: &SMALL_RECT,
|
||||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
screen_manager: &ScreenManager,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let handle = handle::get_current_handle(screen_manager).unwrap();
|
let handle = handle::get_current_handle(screen_manager).unwrap();
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ pub fn is_true(value: i32) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///// Get the original color of the terminal.
|
///// Get the original color of the terminal.
|
||||||
//pub fn get_original_console_color(screen_manager: &Rc<Mutex<ScreenManager>>) -> u16 {
|
//pub fn get_original_console_color(screen_manager: &ScreenManager) -> u16 {
|
||||||
// let console_buffer_info = csbi::get_console_screen_buffer_info(screen_manager);
|
// let console_buffer_info = csbi::get_console_screen_buffer_info(screen_manager);
|
||||||
// console_buffer_info.wAttributes as u16
|
// console_buffer_info.wAttributes as u16
|
||||||
//}
|
//}
|
||||||
|
@ -5,7 +5,7 @@ use ScreenManager;
|
|||||||
use super::{csbi, handle};
|
use super::{csbi, handle};
|
||||||
|
|
||||||
/// Get the terminal size
|
/// Get the terminal size
|
||||||
pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
pub fn terminal_size(screen_manager: &ScreenManager) -> (u16, u16) {
|
||||||
|
|
||||||
let handle = handle::get_output_handle().unwrap();
|
let handle = handle::get_output_handle().unwrap();
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
pub fn buffer_size(screen_manager: &ScreenManager) -> (u16, u16) {
|
||||||
|
|
||||||
let handle = handle::get_output_handle().unwrap();
|
let handle = handle::get_output_handle().unwrap();
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ pub fn fill_console_output_character(
|
|||||||
cells_written: &mut u32,
|
cells_written: &mut u32,
|
||||||
start_location: COORD,
|
start_location: COORD,
|
||||||
cells_to_write: u32,
|
cells_to_write: u32,
|
||||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
screen_manager: &ScreenManager,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let handle = handle::get_current_handle(screen_manager).unwrap();
|
let handle = handle::get_current_handle(screen_manager).unwrap();
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ pub fn fill_console_output_attribute(
|
|||||||
cells_written: &mut u32,
|
cells_written: &mut u32,
|
||||||
start_location: COORD,
|
start_location: COORD,
|
||||||
cells_to_write: u32,
|
cells_to_write: u32,
|
||||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
screen_manager: &ScreenManager,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// Get the position of the current console window
|
// Get the position of the current console window
|
||||||
|
|
||||||
|
@ -11,11 +11,11 @@ mod state;
|
|||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod manager;
|
pub mod manager;
|
||||||
pub mod style;
|
//pub mod style;
|
||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
|
|
||||||
pub use shared::Terminal::Terminal;
|
pub use shared::Terminal::Terminal;
|
||||||
pub use shared::crossterm::Crossterm;
|
//pub use shared::crossterm::Crossterm;
|
||||||
pub use shared::raw;
|
pub use shared::raw;
|
||||||
pub use shared::screen;
|
pub use shared::screen;
|
||||||
pub use state::context::Context;
|
pub use state::context::Context;
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
|
use std::sync::Mutex;
|
||||||
use super::IScreenManager;
|
use super::IScreenManager;
|
||||||
|
use std::str::from_utf8;
|
||||||
|
|
||||||
pub struct AnsiScreenManager {
|
pub struct AnsiScreenManager {
|
||||||
is_alternate_screen: bool,
|
is_alternate_screen: bool,
|
||||||
is_raw_screen: bool,
|
is_raw_screen: bool,
|
||||||
output: Box<Write>,
|
output: Mutex<Box<Write>>
|
||||||
input: Box<Read>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IScreenManager for AnsiScreenManager {
|
impl IScreenManager for AnsiScreenManager {
|
||||||
@ -31,41 +31,37 @@ impl IScreenManager for AnsiScreenManager {
|
|||||||
self.is_alternate_screen
|
self.is_alternate_screen
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string(&mut self, string: String) -> io::Result<usize> {
|
fn write_str(&self, string: &str) -> io::Result<usize> {
|
||||||
write!(self.output, "{}", string)?;
|
{
|
||||||
|
let mx = &self.output;
|
||||||
|
|
||||||
|
let mut output = mx.lock().unwrap();
|
||||||
|
write!(output, "{}", string)?;
|
||||||
|
}
|
||||||
self.flush();
|
self.flush();
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_str(&mut self, string: &str) -> io::Result<usize> {
|
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
write!(self.output, "{}", string)?;
|
{
|
||||||
self.flush();
|
let mx = &self.output;
|
||||||
|
let mut output = mx.lock().unwrap();
|
||||||
|
output.write(buf)?;
|
||||||
|
}
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn read_line(&mut self) -> io::Result<String>
|
fn flush(&self) -> io::Result<()> {
|
||||||
// {
|
let mx = &self.output;
|
||||||
// let mut rv = String::new();
|
let mut output = mx.lock().unwrap();
|
||||||
// self.input.read_line(&mut rv)?;
|
output.flush()
|
||||||
// let len = rv.trim_right_matches(&['\r', '\n'][..]).len();
|
|
||||||
// rv.truncate(len);
|
|
||||||
// Ok(rv)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn read_char(&mut self) -> io::Result<String>
|
|
||||||
// {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
self.output.write(buf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn as_any(&self) -> &Any {
|
||||||
self.output.flush()
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&mut self) -> &mut Any {
|
fn as_any_mut(&mut self) -> &mut Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,8 +69,7 @@ impl IScreenManager for AnsiScreenManager {
|
|||||||
impl AnsiScreenManager {
|
impl AnsiScreenManager {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
AnsiScreenManager {
|
AnsiScreenManager {
|
||||||
input: (Box::from(io::stdin()) as Box<Read>),
|
output: Mutex::new(Box::from(io::stdout()) as Box<Write>),
|
||||||
output: (Box::from(io::stdout()) as Box<Write>),
|
|
||||||
is_alternate_screen: false,
|
is_alternate_screen: false,
|
||||||
is_raw_screen: false,
|
is_raw_screen: false,
|
||||||
}
|
}
|
||||||
|
@ -52,27 +52,26 @@ impl ScreenManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write an ANSI code as String.
|
/// Write an ANSI code as String.
|
||||||
pub fn write_string(&mut self, string: String) -> io::Result<usize> {
|
pub fn write_string(&self, string: String) -> io::Result<usize> {
|
||||||
self.screen_manager.write_string(string)
|
self.screen_manager.write_str(string.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn flush(&self) -> io::Result<()>
|
||||||
|
{
|
||||||
|
self.screen_manager.flush()
|
||||||
|
}
|
||||||
/// Write an ANSI code as &str
|
/// Write an ANSI code as &str
|
||||||
pub fn write_str(&mut self, string: &str) -> io::Result<usize> {
|
pub fn write_str(&self, string: &str) -> io::Result<usize> {
|
||||||
self.screen_manager.write_str(string)
|
self.screen_manager.write_str(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can be used to get an specific implementation used for the current platform.
|
/// Can be used to get an specific implementation used for the current platform.
|
||||||
pub fn as_any(&mut self) -> &mut Any {
|
pub fn as_any(&self) -> &Any {
|
||||||
self.screen_manager.as_any()
|
self.screen_manager.as_any()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Write for ScreenManager {
|
/// Can be used to get an specific implementation used for the current platform.
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
pub fn as_any_mut(&mut self) -> &mut Any {
|
||||||
self.screen_manager.write(buf)
|
self.screen_manager.as_any_mut()
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
|
||||||
self.screen_manager.flush()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,14 +39,14 @@ pub trait IScreenManager {
|
|||||||
fn is_raw_screen(&self) -> bool;
|
fn is_raw_screen(&self) -> bool;
|
||||||
fn is_alternate_screen(&self) -> bool;
|
fn is_alternate_screen(&self) -> bool;
|
||||||
|
|
||||||
/// Write ansi code as String to the current stdout.
|
|
||||||
fn write_string(&mut self, string: String) -> io::Result<usize>;
|
|
||||||
/// Write a &str to the current stdout.
|
/// Write a &str to the current stdout.
|
||||||
fn write_str(&mut self, string: &str) -> io::Result<usize>;
|
fn write_str(&self, string: &str) -> io::Result<usize>;
|
||||||
/// Write [u8] buffer to console.
|
/// Write [u8] buffer to console.
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
|
fn write(&self, buf: &[u8]) -> io::Result<usize>;
|
||||||
/// Flush the current output.
|
/// Flush the current output.
|
||||||
fn flush(&mut self) -> io::Result<()>;
|
fn flush(&self) -> io::Result<()>;
|
||||||
/// Can be used to convert to an specific IScreenManager implementation.
|
/// Can be used to convert to an specific IScreenManager implementation.
|
||||||
fn as_any(&mut self) -> &mut Any;
|
fn as_any(&self) -> &Any;
|
||||||
|
/// Can be used to convert to an specific mutable IScreenManager implementation.
|
||||||
|
fn as_any_mut(&mut self) -> &mut Any;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ pub struct WinApiScreenManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IScreenManager for WinApiScreenManager {
|
impl IScreenManager for WinApiScreenManager {
|
||||||
|
|
||||||
fn set_is_raw_screen(&mut self, value: bool) {
|
fn set_is_raw_screen(&mut self, value: bool) {
|
||||||
self.is_raw_screen = value;
|
self.is_raw_screen = value;
|
||||||
}
|
}
|
||||||
@ -31,16 +30,11 @@ impl IScreenManager for WinApiScreenManager {
|
|||||||
self.is_alternate_screen
|
self.is_alternate_screen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_str(&self, string: &str) -> io::Result<usize> {
|
||||||
fn write_string(&mut self, string: String) -> io::Result<usize> {
|
|
||||||
self.write(string.as_bytes())
|
self.write(string.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_str(&mut self, string: &str) -> io::Result<usize> {
|
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.write(string.as_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
if self.is_alternate_screen {
|
if self.is_alternate_screen {
|
||||||
writing::write_char_buffer(&self.alternate_handle, buf)
|
writing::write_char_buffer(&self.alternate_handle, buf)
|
||||||
} else {
|
} else {
|
||||||
@ -48,11 +42,15 @@ impl IScreenManager for WinApiScreenManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&self) -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&mut self) -> &mut Any {
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_mut(&mut self) -> &mut Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +74,7 @@ impl WinApiScreenManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// get the current screen handle.
|
/// get the current screen handle.
|
||||||
pub fn get_handle(&mut self) -> &HANDLE {
|
pub fn get_handle(&self) -> &HANDLE {
|
||||||
if self.is_alternate_screen {
|
if self.is_alternate_screen {
|
||||||
return &self.alternate_handle;
|
return &self.alternate_handle;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,6 +2,12 @@ use {StateManager, ScreenManager};
|
|||||||
use super::super::state::commands::*;
|
use super::super::state::commands::*;
|
||||||
use super::raw::RawTerminal;
|
use super::raw::RawTerminal;
|
||||||
use super::screen::AlternateScreen;
|
use super::screen::AlternateScreen;
|
||||||
|
|
||||||
|
use super::super::cursor;
|
||||||
|
use super::super::input;
|
||||||
|
use super::super::terminal;
|
||||||
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use std::io::Result;
|
use std::io::Result;
|
||||||
@ -93,6 +99,18 @@ impl Terminal{
|
|||||||
|
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cursor(&self) -> cursor::TerminalCursor {
|
||||||
|
cursor::TerminalCursor::new(&self.active_screen)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn input(&self) -> input::TerminalInput {
|
||||||
|
return input::TerminalInput::new(&self.active_screen)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn terminal(&self) -> input::TerminalInput {
|
||||||
|
return input::TerminalInput::new(&self.active_screen)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Terminal
|
impl Drop for Terminal
|
||||||
|
@ -1,183 +1,183 @@
|
|||||||
//! This module provides easy access to the functionalities of crossterm.
|
////! This module provides easy access to the functionalities of crossterm.
|
||||||
//! since `crossterm version 0.3.0` an `Context` type is introduced (check that documentation for more info why this type is introduced).
|
////! since `crossterm version 0.3.0` an `Context` type is introduced (check that documentation for more info why this type is introduced).
|
||||||
//!
|
////!
|
||||||
//! You have to provide this `Context` to the modules: `cursor::cursor(), color::color(), terminal::terminal()`.
|
////! You have to provide this `Context` to the modules: `cursor::cursor(), color::color(), terminal::terminal()`.
|
||||||
//!
|
////!
|
||||||
//! use crossterm::Context;
|
////! use crossterm::Context;
|
||||||
//! use crossterm::cursor;
|
////! use crossterm::cursor;
|
||||||
//! use crossterm::color;
|
////! use crossterm::color;
|
||||||
//! use crossterm::terminal;
|
////! use crossterm::terminal;
|
||||||
//!
|
////!
|
||||||
//! let context = Context::new();
|
////! let context = Context::new();
|
||||||
//! let cursor = cursor::cursor(&context)
|
////! let cursor = cursor::cursor(&context)
|
||||||
//! let terminal = terminal::terminal(&context);
|
////! let terminal = terminal::terminal(&context);
|
||||||
//! let color = terminal::color(&context);
|
////! let color = terminal::color(&context);
|
||||||
//!
|
////!
|
||||||
//! Because it can seem a little odd to constantly create an Context and provide it to these modules.
|
////! Because it can seem a little odd to constantly create an Context and provide it to these modules.
|
||||||
//! You can better use `Crossterm` for accessing these modules.
|
////! You can better use `Crossterm` for accessing these modules.
|
||||||
//! `Crossterm` handles the Context internally so jo do not have to bother about it, for example:
|
////! `Crossterm` handles the Context internally so jo do not have to bother about it, for example:
|
||||||
//!
|
////!
|
||||||
//! let crossterm = Crossterm::new();
|
////! let crossterm = Crossterm::new();
|
||||||
//! let color = crossterm.color();
|
////! let color = crossterm.color();
|
||||||
//! let cursor = crossterm.cursor();
|
////! let cursor = crossterm.cursor();
|
||||||
//! let terminal = crossterm.terminal();
|
////! let terminal = crossterm.terminal();
|
||||||
|
//
|
||||||
use super::super::cursor;
|
//use super::super::cursor;
|
||||||
use super::super::input::input;
|
//use super::super::input::input;
|
||||||
use super::super::style;
|
//use super::super::style;
|
||||||
use super::super::terminal::terminal;
|
//use super::super::terminal::terminal;
|
||||||
|
//
|
||||||
use Context;
|
//use Context;
|
||||||
|
//
|
||||||
use std::convert::From;
|
//use std::convert::From;
|
||||||
use std::fmt::Display;
|
//use std::fmt::Display;
|
||||||
use std::mem;
|
//use std::mem;
|
||||||
use std::rc::Rc;
|
//use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
//use std::sync::Arc;
|
||||||
|
//
|
||||||
/// Because it can seem a little odd to constantly create an `Context` and provide it to modules like: `cursor, color and terminal`.
|
///// Because it can seem a little odd to constantly create an `Context` and provide it to modules like: `cursor, color and terminal`.
|
||||||
/// You can better use `Crossterm` for accessing these modules.
|
///// You can better use `Crossterm` for accessing these modules.
|
||||||
/// `Crossterm` handles the Context internally so jo do not have to bother about it, for example:
|
///// `Crossterm` handles the Context internally so jo do not have to bother about it, for example:
|
||||||
///
|
/////
|
||||||
/// Check `/examples/Crossterm 0.3.0/program_examples/first_depth_search` in the library for more specific examples.
|
///// Check `/examples/Crossterm 0.3.0/program_examples/first_depth_search` in the library for more specific examples.
|
||||||
///
|
/////
|
||||||
/// let crossterm = Crossterm::new();
|
///// let crossterm = Crossterm::new();
|
||||||
/// let color = crossterm.color();
|
///// let color = crossterm.color();
|
||||||
/// let cursor = crossterm.cursor();
|
///// let cursor = crossterm.cursor();
|
||||||
/// let terminal = crossterm.terminal();
|
///// let terminal = crossterm.terminal();
|
||||||
pub struct Crossterm {
|
pub struct Crossterm {
|
||||||
context: Rc<Context>,
|
// context: Rc<Context>,
|
||||||
}
|
|
||||||
|
|
||||||
/// Create `Crossterm` instance from `Context`
|
|
||||||
impl From<Rc<Context>> for Crossterm {
|
|
||||||
fn from(context: Rc<Context>) -> Self {
|
|
||||||
return Crossterm { context: context };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Crossterm {
|
|
||||||
pub fn new() -> Crossterm {
|
|
||||||
return Crossterm {
|
|
||||||
context: Context::new(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get an Terminal implementation whereon terminal related actions can be performed.
|
|
||||||
///
|
|
||||||
/// #Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
///
|
|
||||||
/// extern crate crossterm;
|
|
||||||
/// use crossterm::Crossterm;
|
|
||||||
/// use crossterm::terminal;
|
|
||||||
///
|
|
||||||
/// let crossterm = Crossterm::new();
|
|
||||||
/// let mut terminal = crossterm.terminal();
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
pub fn terminal(&self) -> terminal::Terminal {
|
|
||||||
return terminal::Terminal::new(self.context.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get an TerminalCursor implementation whereon cursor related actions can be performed.
|
|
||||||
///
|
|
||||||
/// #Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
///
|
|
||||||
/// extern crate crossterm;
|
|
||||||
/// use crossterm::Crossterm;
|
|
||||||
/// use crossterm::terminal;
|
|
||||||
///
|
|
||||||
/// let crossterm = Crossterm::new();
|
|
||||||
/// let mut cursor = crossterm.cursor();
|
|
||||||
///
|
|
||||||
/// // move cursor to x: 5 and y:10
|
|
||||||
/// cursor.goto(5,10);
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
pub fn cursor(&self) -> cursor::TerminalCursor {
|
|
||||||
return cursor::TerminalCursor::new(self.context.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get an Color implementation whereon color related actions can be performed.
|
|
||||||
///
|
|
||||||
/// Check `/examples/version/color` in the library for more specific examples.
|
|
||||||
///
|
|
||||||
/// #Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
///
|
|
||||||
/// extern crate crossterm;
|
|
||||||
/// use crossterm::Crossterm;
|
|
||||||
/// use crossterm::terminal;
|
|
||||||
///
|
|
||||||
/// let crossterm = Crossterm::new();
|
|
||||||
/// let mut terminal_color = crossterm.color();
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
pub fn color(&self) -> style::TerminalColor {
|
|
||||||
return style::TerminalColor::new(self.context.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn input(&self) -> input::TerminalInput {
|
|
||||||
return input::TerminalInput::new(self.context.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wraps an displayable object so it can be formatted with colors and attributes.
|
|
||||||
///
|
|
||||||
/// Check `/examples/color` in the library for more specific examples.
|
|
||||||
///
|
|
||||||
/// #Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// extern crate crossterm;
|
|
||||||
///
|
|
||||||
/// use self::crossterm::style::{paint,Color};
|
|
||||||
/// use self::crossterm::Crossterm;
|
|
||||||
///
|
|
||||||
/// fn main()
|
|
||||||
/// {
|
|
||||||
/// let crossterm = Crossterm::new();
|
|
||||||
/// // Create an styledobject object from the text 'Unstyled font'
|
|
||||||
/// // Currently it has the default foreground color and background color.
|
|
||||||
/// println!("{}",crossterm.paint("Unstyled font"));
|
|
||||||
///
|
|
||||||
/// // Create an displayable object from the text 'Colored font',
|
|
||||||
/// // Paint this with the `Red` foreground color and `Blue` background color.
|
|
||||||
/// // Print the result.
|
|
||||||
/// let styledobject = crossterm.paint("Colored font").with(Color::Red).on(Color::Blue);
|
|
||||||
/// println!("{}", styledobject);
|
|
||||||
///
|
|
||||||
/// // Or all in one line
|
|
||||||
/// println!("{}", crossterm.paint("Colored font").with(Color::Red).on(Color::Blue));
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn paint<'a, D: Display>(&'a self, value: D) -> style::StyledObject<D> {
|
|
||||||
self.terminal().paint(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write any displayable value to the current screen weather it will be the main screen or alternate screen.
|
|
||||||
///
|
|
||||||
/// #Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
///
|
|
||||||
/// extern crate crossterm;
|
|
||||||
/// use crossterm::Crossterm;
|
|
||||||
///
|
|
||||||
/// let mut crossterm = Crossterm::new();
|
|
||||||
/// crossterm.write("Some text \n Some text on new line.");
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
pub fn write<D: Display>(&self, value: D) {
|
|
||||||
self.terminal().write(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get an copy of the context that `Crossterm` uses internally.
|
|
||||||
pub fn context(&self) -> Rc<Context> {
|
|
||||||
self.context.clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
///// Create `Crossterm` instance from `Context`
|
||||||
|
//impl From<Rc<Context>> for Crossterm {
|
||||||
|
// fn from(context: Rc<Context>) -> Self {
|
||||||
|
// return Crossterm { context: context };
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//impl Crossterm {
|
||||||
|
// pub fn new() -> Crossterm {
|
||||||
|
// return Crossterm {
|
||||||
|
// context: Context::new(),
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /// Get an Terminal implementation whereon terminal related actions can be performed.
|
||||||
|
// ///
|
||||||
|
// /// #Example
|
||||||
|
// ///
|
||||||
|
// /// ```rust
|
||||||
|
// ///
|
||||||
|
// /// extern crate crossterm;
|
||||||
|
// /// use crossterm::Crossterm;
|
||||||
|
// /// use crossterm::terminal;
|
||||||
|
// ///
|
||||||
|
// /// let crossterm = Crossterm::new();
|
||||||
|
// /// let mut terminal = crossterm.terminal();
|
||||||
|
// ///
|
||||||
|
// /// ```
|
||||||
|
// pub fn terminal(&self) -> terminal::Terminal {
|
||||||
|
// return terminal::Terminal::new(self.context.clone());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /// Get an TerminalCursor implementation whereon cursor related actions can be performed.
|
||||||
|
// ///
|
||||||
|
// /// #Example
|
||||||
|
// ///
|
||||||
|
// /// ```rust
|
||||||
|
// ///
|
||||||
|
// /// extern crate crossterm;
|
||||||
|
// /// use crossterm::Crossterm;
|
||||||
|
// /// use crossterm::terminal;
|
||||||
|
// ///
|
||||||
|
// /// let crossterm = Crossterm::new();
|
||||||
|
// /// let mut cursor = crossterm.cursor();
|
||||||
|
// ///
|
||||||
|
// /// // move cursor to x: 5 and y:10
|
||||||
|
// /// cursor.goto(5,10);
|
||||||
|
// ///
|
||||||
|
// /// ```
|
||||||
|
// pub fn cursor(&self) -> cursor::TerminalCursor {
|
||||||
|
// return cursor::TerminalCursor::new(self.context.clone());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /// Get an Color implementation whereon color related actions can be performed.
|
||||||
|
// ///
|
||||||
|
// /// Check `/examples/version/color` in the library for more specific examples.
|
||||||
|
// ///
|
||||||
|
// /// #Example
|
||||||
|
// ///
|
||||||
|
// /// ```rust
|
||||||
|
// ///
|
||||||
|
// /// extern crate crossterm;
|
||||||
|
// /// use crossterm::Crossterm;
|
||||||
|
// /// use crossterm::terminal;
|
||||||
|
// ///
|
||||||
|
// /// let crossterm = Crossterm::new();
|
||||||
|
// /// let mut terminal_color = crossterm.color();
|
||||||
|
// ///
|
||||||
|
// /// ```
|
||||||
|
// pub fn color(&self) -> style::TerminalColor {
|
||||||
|
// return style::TerminalColor::new(self.context.clone());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn input(&self) -> input::TerminalInput {
|
||||||
|
// return input::TerminalInput::new(self.context.clone());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /// Wraps an displayable object so it can be formatted with colors and attributes.
|
||||||
|
// ///
|
||||||
|
// /// Check `/examples/color` in the library for more specific examples.
|
||||||
|
// ///
|
||||||
|
// /// #Example
|
||||||
|
// ///
|
||||||
|
// /// ```rust
|
||||||
|
// /// extern crate crossterm;
|
||||||
|
// ///
|
||||||
|
// /// use self::crossterm::style::{paint,Color};
|
||||||
|
// /// use self::crossterm::Crossterm;
|
||||||
|
// ///
|
||||||
|
// /// fn main()
|
||||||
|
// /// {
|
||||||
|
// /// let crossterm = Crossterm::new();
|
||||||
|
// /// // Create an styledobject object from the text 'Unstyled font'
|
||||||
|
// /// // Currently it has the default foreground color and background color.
|
||||||
|
// /// println!("{}",crossterm.paint("Unstyled font"));
|
||||||
|
// ///
|
||||||
|
// /// // Create an displayable object from the text 'Colored font',
|
||||||
|
// /// // Paint this with the `Red` foreground color and `Blue` background color.
|
||||||
|
// /// // Print the result.
|
||||||
|
// /// let styledobject = crossterm.paint("Colored font").with(Color::Red).on(Color::Blue);
|
||||||
|
// /// println!("{}", styledobject);
|
||||||
|
// ///
|
||||||
|
// /// // Or all in one line
|
||||||
|
// /// println!("{}", crossterm.paint("Colored font").with(Color::Red).on(Color::Blue));
|
||||||
|
// /// }
|
||||||
|
// /// ```
|
||||||
|
// pub fn paint<'a, D: Display>(&'a self, value: D) -> style::StyledObject<D> {
|
||||||
|
// self.terminal().paint(value)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /// Write any displayable value to the current screen weather it will be the main screen or alternate screen.
|
||||||
|
// ///
|
||||||
|
// /// #Example
|
||||||
|
// ///
|
||||||
|
// /// ```rust
|
||||||
|
// ///
|
||||||
|
// /// extern crate crossterm;
|
||||||
|
// /// use crossterm::Crossterm;
|
||||||
|
// ///
|
||||||
|
// /// let mut crossterm = Crossterm::new();
|
||||||
|
// /// crossterm.write("Some text \n Some text on new line.");
|
||||||
|
// ///
|
||||||
|
// /// ```
|
||||||
|
// pub fn write<D: Display>(&self, value: D) {
|
||||||
|
// self.terminal().write(value)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /// Get an copy of the context that `Crossterm` uses internally.
|
||||||
|
// pub fn context(&self) -> Rc<Context> {
|
||||||
|
// self.context.clone()
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
@ -15,7 +15,7 @@ use kernel::windows_kernel::cursor::{pos, absolute_cursor_pos};
|
|||||||
use kernel::unix_kernel::terminal::{exit, pos, terminal_size};
|
use kernel::unix_kernel::terminal::{exit, pos, terminal_size};
|
||||||
|
|
||||||
/// Get the terminal size based on the current platform.
|
/// Get the terminal size based on the current platform.
|
||||||
pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
pub fn get_terminal_size(screen_manager: &ScreenManager) -> (u16, u16) {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
return terminal_size();
|
return terminal_size();
|
||||||
|
|
||||||
@ -24,12 +24,12 @@ pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the cursor position based on the current platform.
|
/// Get the cursor position based on the current platform.
|
||||||
pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16) {
|
pub fn get_cursor_position(screen_manager: &ScreenManager) -> (u16, u16) {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
return pos(context.clone());
|
return pos(screen_manager);
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
return pos(&context.screen_manager);
|
return pos(screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// exit the current terminal.
|
/// exit the current terminal.
|
||||||
|
@ -147,16 +147,13 @@ impl IAlternateScreenCommand for ToAlternateScreenBufferCommand {
|
|||||||
// Make the new screen buffer the active screen buffer.
|
// Make the new screen buffer the active screen buffer.
|
||||||
csbi::set_active_screen_buffer(new_handle)?;
|
csbi::set_active_screen_buffer(new_handle)?;
|
||||||
|
|
||||||
let b: &mut WinApiScreenManager = match screen_manager
|
match screen_manager
|
||||||
.as_any()
|
.as_any_mut()
|
||||||
.downcast_mut::<WinApiScreenManager>()
|
.downcast_mut::<WinApiScreenManager>()
|
||||||
{
|
{
|
||||||
Some(b) => b,
|
Some(b) => b.set_alternate_handle(new_handle),
|
||||||
None => return Err(Error::new(ErrorKind::Other,"Invalid cast exception")),
|
None => return Err(Error::new(ErrorKind::Other,"Invalid cast exception")),
|
||||||
};
|
};
|
||||||
|
|
||||||
b.set_alternate_handle(new_handle);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user