88 lines
3.3 KiB
Rust
88 lines
3.3 KiB
Rust
//! This module provides one place to work with the screen.
|
|
//!
|
|
//! In Rust we can call `stdout()` to get an handle to the current default console handle.
|
|
//! For example when in unix systems you want to print something to the main screen you can use the following code:
|
|
//!
|
|
//! ```
|
|
//! write!(std::io::stdout(), "{}", "some text").
|
|
//! ```
|
|
//!
|
|
//! But things change when we are in alternate screen modes.
|
|
//! We can not simply use `stdout()` to get a handle to the alternate screen, since this call returns the current default console handle (mainscreen).
|
|
//!
|
|
//! Instead we need to store an handle to the screen output.
|
|
//! This handle could be used to put into alternate screen modes and back into main screen modes.
|
|
//! Through this stored handle Crossterm can execute its command on the current screen whether it be alternate screen or main screen.
|
|
//!
|
|
//! For unix systems we store the handle gotten from `stdout()` for windows systems that are not supporting ANSI escape codes we store WinApi `HANDLE` struct witch will provide access to the current screen.
|
|
//!
|
|
//! This is the reason why this module exits: it is to provide access to the current terminal screen whether it will be the alternate screen and main screen.
|
|
|
|
use super::*;
|
|
|
|
use std::any::Any;
|
|
use std::default::Default;
|
|
use screen::RawScreen;
|
|
|
|
/// Struct that is an handle to an terminal screen.
|
|
/// This handle could be used to write to the current screen
|
|
///
|
|
/// For unix and windows 10 `stdout()` will be used for handle when on windows systems with versions lower than 10 WinApi `HANDLE` will be used.
|
|
pub struct TerminalOutput {
|
|
stdout: Box<IStdout + Send + Sync>,
|
|
pub is_in_raw_mode:bool,
|
|
}
|
|
|
|
impl TerminalOutput {
|
|
/// Create new screen write instance whereon screen related actions can be performed.
|
|
pub fn new(raw_mode: bool) -> Self {
|
|
#[cfg(target_os = "windows")]
|
|
let stdout: Box<IStdout + Send + Sync> = functions::get_module::<Box<IStdout + Send + Sync>>(
|
|
Box::from(WinApiOutput::new()),
|
|
Box::from(AnsiOutput::new()),
|
|
).unwrap();
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
let stdout = Box::from(AnsiOutput::new()) as Box<IStdout + Send + Sync>;
|
|
|
|
TerminalOutput { stdout , is_in_raw_mode: raw_mode}
|
|
}
|
|
|
|
/// Write String to the current screen.
|
|
pub fn write_string(&self, string: String) -> io::Result<usize> {
|
|
self.stdout.write_str(string.as_str())
|
|
}
|
|
|
|
/// Flush the current screen.
|
|
pub fn flush(&self) -> io::Result<()> {
|
|
self.stdout.flush()
|
|
}
|
|
|
|
/// Write &str to the current screen.
|
|
pub fn write_str(&self, string: &str) -> io::Result<usize> {
|
|
self.stdout.write_str(string)
|
|
}
|
|
|
|
/// Write buffer to the screen
|
|
pub fn write_buf(&self, buf: &[u8]) -> io::Result<usize> {
|
|
self.stdout.write(buf)
|
|
}
|
|
}
|
|
|
|
impl Default for TerminalOutput
|
|
{
|
|
/// Get the default handle to the current screen.
|
|
fn default() -> Self {
|
|
#[cfg(target_os = "windows")]
|
|
let stdout = functions::get_module::<Box<IStdout + Send + Sync>>(
|
|
Box::from(WinApiOutput::new()),
|
|
Box::from(AnsiOutput::new()),
|
|
).unwrap();
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
let stdout = Box::from(AnsiOutput::new()) as Box<IStdout + Send + Sync>;
|
|
|
|
TerminalOutput { stdout , is_in_raw_mode: false}
|
|
}
|
|
}
|