Added resizing terminal. Styling font with attributes for unix systems inplemented. Windows kernel refactored and cleared out some grammer mistakes. (Windows tested and unix jet to be tested).
This commit is contained in:
parent
34e3ebfbbc
commit
0df9ad1015
File diff suppressed because it is too large
Load Diff
@ -16,5 +16,8 @@ winapi = { version = "0.3", features = ["winbase","winuser","consoleapi","proces
|
|||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "a"
|
||||||
|
path = "./examples/bin.rs"
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,5 +11,8 @@ pub mod cursor;
|
|||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
terminal::resize_terminal();
|
||||||
|
|
||||||
|
print!(paint("asdf").with(Color::Black).on(Color::Red).black().red());
|
||||||
|
println!()
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ pub fn paint_background()
|
|||||||
// This will give you an object back wits can be styled and displayed.
|
// This will give you an object back wits can be styled and displayed.
|
||||||
let mut styledobject = paint("Red background color");
|
let mut styledobject = paint("Red background color");
|
||||||
// Call the method `on()` on the object given by `paint()` and pass in an Color from the Color enum.
|
// Call the method `on()` on the object given by `paint()` and pass in an Color from the Color enum.
|
||||||
styledobject = styledobject.on(Color::Blue);
|
styledobject = styledobject.on(Color::Red);
|
||||||
// Print the object to the console and check see the result
|
// Print the object to the console and check see the result
|
||||||
println!("{}", styledobject);
|
println!("{}", styledobject);
|
||||||
|
|
||||||
|
@ -76,6 +76,18 @@ pub fn print()
|
|||||||
get().goto(10,5).print("@");
|
get().goto(10,5).print("@");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Save cursor position for recall later
|
||||||
|
pub fn safe_position()
|
||||||
|
{
|
||||||
|
get().safe_position();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save cursor position for recall later
|
||||||
|
pub fn reset_position()
|
||||||
|
{
|
||||||
|
get().reset_position();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ pub fn clear_until_new_line()
|
|||||||
print_test_data();
|
print_test_data();
|
||||||
|
|
||||||
// Set terminal cursor position (see example for more info).
|
// Set terminal cursor position (see example for more info).
|
||||||
crossterm_cursor::get().goto(4,4);
|
crossterm_cursor::get().goto(4,7);
|
||||||
|
|
||||||
// Clear all the cells until next line.
|
// Clear all the cells until next line.
|
||||||
terminal.clear(ClearType::UntilNewLine);
|
terminal.clear(ClearType::UntilNewLine);
|
||||||
@ -96,6 +96,14 @@ pub fn print_terminal_size()
|
|||||||
print!("X: {}, y: {}", terminal_size.0, terminal_size.1);
|
print!("X: {}, y: {}", terminal_size.0, terminal_size.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the terminal size to width 10, height: 10.
|
||||||
|
pub fn set_terminal_size()
|
||||||
|
{
|
||||||
|
let mut terminal = get();
|
||||||
|
|
||||||
|
terminal.set_size(10,10);
|
||||||
|
}
|
||||||
|
|
||||||
// scroll down 10 lines
|
// scroll down 10 lines
|
||||||
pub fn scroll_down()
|
pub fn scroll_down()
|
||||||
{
|
{
|
||||||
@ -116,3 +124,12 @@ pub fn scroll_up()
|
|||||||
// Scroll up 10 lines.
|
// Scroll up 10 lines.
|
||||||
let terminal_size = terminal.scroll_up(10);
|
let terminal_size = terminal.scroll_up(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resize the terminal to X: 10, Y: 10
|
||||||
|
pub fn resize_terminal()
|
||||||
|
{
|
||||||
|
// Get terminal
|
||||||
|
let mut terminal = get();
|
||||||
|
// Get terminal size
|
||||||
|
terminal.set_size(2,2);
|
||||||
|
}
|
||||||
|
@ -44,4 +44,16 @@ impl ITerminalCursor for AnsiCursor {
|
|||||||
let mut some_writer = io::stdout();
|
let mut some_writer = io::stdout();
|
||||||
write!(&mut some_writer, csi!("{}D"), count);
|
write!(&mut some_writer, csi!("{}D"), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn safe_position(&self)
|
||||||
|
{
|
||||||
|
let mut some_writer = io::stdout();
|
||||||
|
write!(&mut some_writer, csi!("s"));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset_position(&self)
|
||||||
|
{
|
||||||
|
let mut some_writer = io::stdout();
|
||||||
|
write!(&mut some_writer, csi!("u"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,4 +20,8 @@ pub trait ITerminalCursor {
|
|||||||
fn move_down(&self, count: u16);
|
fn move_down(&self, count: u16);
|
||||||
/// Move the cursor `n` times left.
|
/// Move the cursor `n` times left.
|
||||||
fn move_left(&self, count: u16);
|
fn move_left(&self, count: u16);
|
||||||
|
/// Save cursor position for recall later. Note that this position is stored program based not per instance of the cursor struct.
|
||||||
|
fn safe_position(&mut self);
|
||||||
|
/// Return to saved cursor position
|
||||||
|
fn reset_position(&self);
|
||||||
}
|
}
|
||||||
|
@ -209,6 +209,52 @@ impl TerminalCursor {
|
|||||||
std::io::stdout().flush();
|
std::io::stdout().flush();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Save cursor position for recall later.
|
||||||
|
///
|
||||||
|
/// Note that this position is stored program based not per instance of the `Cursor` struct.
|
||||||
|
///
|
||||||
|
/// #Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
///
|
||||||
|
/// extern crate crossterm;
|
||||||
|
///
|
||||||
|
/// use self::crossterm::crossterm_cursor::get;
|
||||||
|
///
|
||||||
|
/// get().safe_position();
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
pub fn safe_position(&mut self)
|
||||||
|
{
|
||||||
|
&self.init();
|
||||||
|
if let Some(ref mut terminal_cursor) = self.terminal_cursor {
|
||||||
|
terminal_cursor.safe_position();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return to saved cursor position
|
||||||
|
///
|
||||||
|
/// Note that this method reset to the position set by `safe_position()` and that this position is stored program based not per instance of the `Cursor` struct.
|
||||||
|
///
|
||||||
|
/// #Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
///
|
||||||
|
/// extern crate crossterm;
|
||||||
|
///
|
||||||
|
/// use self::crossterm::crossterm_cursor::get;
|
||||||
|
///
|
||||||
|
/// get().reset_position();
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
pub fn reset_position(&mut self)
|
||||||
|
{
|
||||||
|
&self.init();
|
||||||
|
if let Some(ref terminal_cursor) = self.terminal_cursor {
|
||||||
|
terminal_cursor.reset_position();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the concrete ITerminalCursor implementation based on the current operating system.
|
/// Get the concrete ITerminalCursor implementation based on the current operating system.
|
||||||
|
@ -17,34 +17,40 @@ impl ITerminalCursor for WinApiCursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pos(&self) -> (i16, i16) {
|
fn pos(&self) -> (i16, i16) {
|
||||||
(cursor::xpos(), cursor::ypos())
|
cursor::pos()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_up(&self, count: u16) {
|
fn move_up(&self, count: u16) {
|
||||||
let xpos = cursor::xpos();
|
let (xpos,ypos) = cursor::pos();
|
||||||
let ypos = cursor::ypos();
|
|
||||||
|
|
||||||
cursor::set(xpos, ypos - count as i16);
|
cursor::set(xpos, ypos - count as i16);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_right(&self, count: u16) {
|
fn move_right(&self, count: u16) {
|
||||||
let xpos = cursor::xpos();
|
let (xpos,ypos) = cursor::pos();
|
||||||
let ypos = cursor::ypos();
|
|
||||||
|
|
||||||
cursor::set(xpos + count as i16, ypos);
|
cursor::set(xpos + count as i16, ypos);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_down(&self, count: u16) {
|
fn move_down(&self, count: u16) {
|
||||||
let xpos = cursor::xpos();
|
let (xpos,ypos) = cursor::pos();
|
||||||
let ypos = cursor::ypos();
|
|
||||||
|
|
||||||
cursor::set(xpos, ypos + count as i16);
|
cursor::set(xpos, ypos + count as i16);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_left(&self, count: u16) {
|
fn move_left(&self, count: u16) {
|
||||||
let xpos = cursor::xpos();
|
let (xpos,ypos) = cursor::pos();
|
||||||
let ypos = cursor::ypos();
|
|
||||||
|
|
||||||
cursor::set(xpos - count as i16, ypos);
|
cursor::set(xpos - count as i16, ypos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn safe_position(&mut self)
|
||||||
|
{
|
||||||
|
cursor::save_cursor_pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset_position(&self)
|
||||||
|
{
|
||||||
|
cursor::reset_to_saved_position();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
0
src/crossterm_mouse/mod.rs
Normal file
0
src/crossterm_mouse/mod.rs
Normal file
@ -9,7 +9,7 @@
|
|||||||
///! so that the color related actions can be preformed on both unix and windows systems.
|
///! so that the color related actions can be preformed on both unix and windows systems.
|
||||||
///!
|
///!
|
||||||
|
|
||||||
use super::color::{Color, ColorType};
|
use super::super::{Color, ColorType};
|
||||||
|
|
||||||
pub trait ITerminalColor {
|
pub trait ITerminalColor {
|
||||||
/// Set the forground color to the given color.
|
/// Set the forground color to the given color.
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
//! Like styling the font, foreground color and background color.
|
//! Like styling the font, foreground color and background color.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::convert::From;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use Construct;
|
use Construct;
|
||||||
use crossterm_style::{ObjectStyle, StyledObject};
|
use crossterm_style::{ObjectStyle, StyledObject};
|
||||||
@ -14,79 +12,6 @@ use super::ANSIColor;
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use super::WinApiColor;
|
use super::WinApiColor;
|
||||||
|
|
||||||
/// Colors that are available for coloring the termainal font.
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub enum Color {
|
|
||||||
Black,
|
|
||||||
|
|
||||||
Red,
|
|
||||||
DarkRed,
|
|
||||||
|
|
||||||
Green,
|
|
||||||
DarkGreen,
|
|
||||||
|
|
||||||
Yellow,
|
|
||||||
DarkYellow,
|
|
||||||
|
|
||||||
Blue,
|
|
||||||
DarkBlue,
|
|
||||||
|
|
||||||
Magenta,
|
|
||||||
DarkMagenta,
|
|
||||||
|
|
||||||
Cyan,
|
|
||||||
DarkCyan,
|
|
||||||
|
|
||||||
Grey,
|
|
||||||
White,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Color types that can be used to determine if the Color enum is an Fore- or Background Color
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub enum ColorType {
|
|
||||||
Background,
|
|
||||||
Foreground,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a str> for Color {
|
|
||||||
fn from(src: &str) -> Self {
|
|
||||||
src.parse().unwrap_or(Color::White)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for Color {
|
|
||||||
fn from(src: String) -> Self {
|
|
||||||
src.parse().unwrap_or(Color::White)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Color {
|
|
||||||
type Err = ();
|
|
||||||
|
|
||||||
fn from_str(src: &str) -> Result<Self, Self::Err> {
|
|
||||||
let src = src.to_lowercase();
|
|
||||||
|
|
||||||
match src.as_ref() {
|
|
||||||
"black" => Ok(Color::Black),
|
|
||||||
"red" => Ok(Color::Red),
|
|
||||||
"dark_red" => Ok(Color::DarkRed),
|
|
||||||
"green" => Ok(Color::Green),
|
|
||||||
"dark_green" => Ok(Color::DarkGreen),
|
|
||||||
"yellow" => Ok(Color::Yellow),
|
|
||||||
"dark_yellow" => Ok(Color::DarkYellow),
|
|
||||||
"blue" => Ok(Color::Blue),
|
|
||||||
"dark_blue" => Ok(Color::DarkBlue),
|
|
||||||
"magenta" => Ok(Color::Magenta),
|
|
||||||
"dark_magenta" => Ok(Color::DarkMagenta),
|
|
||||||
"cyan" => Ok(Color::Cyan),
|
|
||||||
"dark_cyan" => Ok(Color::DarkCyan),
|
|
||||||
"grey" => Ok(Color::Grey),
|
|
||||||
"white" => Ok(Color::White),
|
|
||||||
_ => Ok(Color::White),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Struct that stores an specific platform implementation for color related actions.
|
/// Struct that stores an specific platform implementation for color related actions.
|
||||||
pub struct TerminalColor {
|
pub struct TerminalColor {
|
||||||
terminal_color: Option<Box<ITerminalColor>>,
|
terminal_color: Option<Box<ITerminalColor>>,
|
||||||
@ -237,3 +162,5 @@ where
|
|||||||
{
|
{
|
||||||
ObjectStyle::new().apply_to(val)
|
ObjectStyle::new().apply_to(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use Construct;
|
use Construct;
|
||||||
use super::color::{ColorType, Color};
|
use super::super::{ColorType, Color};
|
||||||
use super::base_color::ITerminalColor;
|
use super::base_color::ITerminalColor;
|
||||||
use kernel::windows_kernel;
|
use kernel::windows_kernel;
|
||||||
|
|
||||||
|
@ -5,3 +5,91 @@ pub use self::color::color::*;
|
|||||||
|
|
||||||
pub use self::styles::objectstyle::ObjectStyle;
|
pub use self::styles::objectstyle::ObjectStyle;
|
||||||
pub use self::styles::styledobject::StyledObject;
|
pub use self::styles::styledobject::StyledObject;
|
||||||
|
|
||||||
|
use std::convert::From;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
|
||||||
|
pub enum Attribute {
|
||||||
|
Bold = 1,
|
||||||
|
Dim = 2,
|
||||||
|
Italic = 3,
|
||||||
|
Underlined = 4,
|
||||||
|
Blink = 5,
|
||||||
|
Reverse = 7,
|
||||||
|
Hidden = 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Colors that are available for coloring the termainal font.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum Color {
|
||||||
|
Black,
|
||||||
|
|
||||||
|
Red,
|
||||||
|
DarkRed,
|
||||||
|
|
||||||
|
Green,
|
||||||
|
DarkGreen,
|
||||||
|
|
||||||
|
Yellow,
|
||||||
|
DarkYellow,
|
||||||
|
|
||||||
|
Blue,
|
||||||
|
DarkBlue,
|
||||||
|
|
||||||
|
Magenta,
|
||||||
|
DarkMagenta,
|
||||||
|
|
||||||
|
Cyan,
|
||||||
|
DarkCyan,
|
||||||
|
|
||||||
|
Grey,
|
||||||
|
White,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Color types that can be used to determine if the Color enum is an Fore- or Background Color
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum ColorType {
|
||||||
|
Background,
|
||||||
|
Foreground,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a str> for Color {
|
||||||
|
fn from(src: &str) -> Self {
|
||||||
|
src.parse().unwrap_or(Color::White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for Color {
|
||||||
|
fn from(src: String) -> Self {
|
||||||
|
src.parse().unwrap_or(Color::White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Color {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(src: &str) -> Result<Self, Self::Err> {
|
||||||
|
let src = src.to_lowercase();
|
||||||
|
|
||||||
|
match src.as_ref() {
|
||||||
|
"black" => Ok(Color::Black),
|
||||||
|
"red" => Ok(Color::Red),
|
||||||
|
"dark_red" => Ok(Color::DarkRed),
|
||||||
|
"green" => Ok(Color::Green),
|
||||||
|
"dark_green" => Ok(Color::DarkGreen),
|
||||||
|
"yellow" => Ok(Color::Yellow),
|
||||||
|
"dark_yellow" => Ok(Color::DarkYellow),
|
||||||
|
"blue" => Ok(Color::Blue),
|
||||||
|
"dark_blue" => Ok(Color::DarkBlue),
|
||||||
|
"magenta" => Ok(Color::Magenta),
|
||||||
|
"dark_magenta" => Ok(Color::DarkMagenta),
|
||||||
|
"cyan" => Ok(Color::Cyan),
|
||||||
|
"dark_cyan" => Ok(Color::DarkCyan),
|
||||||
|
"grey" => Ok(Color::Grey),
|
||||||
|
"white" => Ok(Color::White),
|
||||||
|
_ => Ok(Color::White),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use crossterm_style::{Color, StyledObject};
|
use crossterm_style::{Color, StyledObject};
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
use super::super::Attribute;
|
||||||
/// Struct that contains the style properties that can be applied to an displayable object.
|
/// Struct that contains the style properties that can be applied to an displayable object.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ObjectStyle {
|
pub struct ObjectStyle {
|
||||||
pub fg_color: Option<Color>,
|
pub fg_color: Option<Color>,
|
||||||
pub bg_color: Option<Color>,
|
pub bg_color: Option<Color>,
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub attrs: Vec<Attribute>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ObjectStyle {
|
impl Default for ObjectStyle {
|
||||||
@ -13,6 +15,8 @@ impl Default for ObjectStyle {
|
|||||||
ObjectStyle {
|
ObjectStyle {
|
||||||
fg_color: Some(Color::White),
|
fg_color: Some(Color::White),
|
||||||
bg_color: Some(Color::Black),
|
bg_color: Some(Color::Black),
|
||||||
|
#[cfg(unix)]
|
||||||
|
attrs: Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,6 +38,8 @@ impl ObjectStyle {
|
|||||||
return ObjectStyle {
|
return ObjectStyle {
|
||||||
fg_color: None,
|
fg_color: None,
|
||||||
bg_color: None,
|
bg_color: None,
|
||||||
|
#[cfg(unix)]
|
||||||
|
attrs: Vec::new()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,4 +54,9 @@ impl ObjectStyle {
|
|||||||
self.fg_color = Some(color);
|
self.fg_color = Some(color);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_attr(mut self, attr: Attribute)
|
||||||
|
{
|
||||||
|
self.attrs.push(attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std;
|
use std;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use super::super::Attribute;
|
||||||
|
|
||||||
use crossterm_style::{Color, ObjectStyle};
|
use crossterm_style::{Color, ObjectStyle};
|
||||||
|
|
||||||
@ -55,6 +56,29 @@ impl<D> StyledObject<D> {
|
|||||||
self.object_style = self.object_style.bg(background_color);
|
self.object_style = self.object_style.bg(background_color);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn attrs(mut self, attrs: Vec<Attribute>) -> StyledObject<D>
|
||||||
|
{
|
||||||
|
for attr in attrs.iter() {
|
||||||
|
self.attr(attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn attr(mut self, attr: Attribute) -> StyledObject<D>
|
||||||
|
{
|
||||||
|
self.object_style.add_attr(attr);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)] pub fn bold(self) -> StyledObject<D> { self.attr(Attribute::Bold) }
|
||||||
|
#[inline(always)] pub fn dim(self) -> StyledObject<D> { self.attr(Attribute::Dim) }
|
||||||
|
#[inline(always)] pub fn italic(self) -> StyledObject<D> { self.attr(Attribute::Italic) }
|
||||||
|
#[inline(always)] pub fn underlined(self) -> StyledObject<D> { self.attr(Attribute::Underlined) }
|
||||||
|
#[inline(always)] pub fn blink(self) -> StyledObject<D> { self.attr(Attribute::Blink) }
|
||||||
|
#[inline(always)] pub fn reverse(self) -> StyledObject<D> { self.attr(Attribute::Reverse) }
|
||||||
|
#[inline(always)] pub fn hidden(self) -> StyledObject<D> { self.attr(Attribute::Hidden) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is used to make StyledObject able to be displayed.
|
/// This is used to make StyledObject able to be displayed.
|
||||||
@ -78,6 +102,13 @@ macro_rules! impl_fmt
|
|||||||
colored_terminal.set_fg(fg);
|
colored_terminal.set_fg(fg);
|
||||||
reset = true;
|
reset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
for attr in &self.object_style.attrs.iter() {
|
||||||
|
write!(f, csi!("{}m"), attr as i16);
|
||||||
|
reset = true;
|
||||||
|
}
|
||||||
|
|
||||||
fmt::$name::fmt(&self.content, f)?;
|
fmt::$name::fmt(&self.content, f)?;
|
||||||
std::io::stdout().flush().expect("Flush stdout failed");
|
std::io::stdout().flush().expect("Flush stdout failed");
|
||||||
|
|
||||||
|
@ -50,4 +50,9 @@ impl ITerminal for UnixTerminal {
|
|||||||
let mut some_writer = io::stdout();
|
let mut some_writer = io::stdout();
|
||||||
write!(&mut some_writer, csi!("{}T"), count);
|
write!(&mut some_writer, csi!("{}T"), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_size(width: i16, height: i16) {
|
||||||
|
let mut some_writer = io::stdout();
|
||||||
|
write!(&mut some_writer, csi!("8;{};{}t"), width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,6 @@ pub trait ITerminal {
|
|||||||
fn scroll_up(&self, count: i16);
|
fn scroll_up(&self, count: i16);
|
||||||
/// Scroll `n` lines down in the current terminal.
|
/// Scroll `n` lines down in the current terminal.
|
||||||
fn scroll_down(&self, count: i16);
|
fn scroll_down(&self, count: i16);
|
||||||
|
/// Resize terminal to the given width and height.
|
||||||
|
fn set_size(&self,width: i16, height: i16);
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,17 @@ impl Terminal {
|
|||||||
terminal.scroll_down(count);
|
terminal.scroll_down(count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the terminal size.
|
||||||
|
pub fn set_size(&mut self, width: i16, height: i16)
|
||||||
|
{
|
||||||
|
&self.init();
|
||||||
|
|
||||||
|
if let Some (ref terminal) = self.terminal
|
||||||
|
{
|
||||||
|
terminal.set_size(width,height);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the concrete ITerminal implementation based on the current operating system.
|
/// Get the concrete ITerminal implementation based on the current operating system.
|
||||||
|
@ -35,4 +35,6 @@ impl ITerminal for WinApiTerminal {
|
|||||||
fn scroll_down(&self, count: i16) {
|
fn scroll_down(&self, count: i16) {
|
||||||
terminal::scroll_down(count as i16);
|
terminal::scroll_down(count as i16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_size(&self, width: i16, height: i16) { terminal::resize_terminal(width,height); }
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
use winapi::shared::ntdef::HANDLE;
|
use super::kernel;
|
||||||
use winapi::um::consoleapi::SetConsoleMode;
|
|
||||||
|
|
||||||
use super::handle;
|
|
||||||
|
|
||||||
/// Enables ansi for windows terminals.
|
/// Enables ansi for windows terminals.
|
||||||
pub fn enable_ansi_support() {
|
pub fn enable_ansi_support() {
|
||||||
let enable_ansi_code: u32 = 7;
|
let enable_ansi_code: u32 = 7;
|
||||||
let output_handle = handle::get_output_handle();
|
kernel::set_console_mode(enable_ansi_code);
|
||||||
set_console_mode(output_handle, enable_ansi_code)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the console mode of the windows terminal.
|
|
||||||
fn set_console_mode(handle: HANDLE, console_mode: u32) {
|
|
||||||
unsafe {
|
|
||||||
SetConsoleMode(handle, console_mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,10 +1,9 @@
|
|||||||
use winapi::um::wincon;
|
use winapi::um::wincon;
|
||||||
use super::{handle, kernel};
|
|
||||||
|
use super::{kernel};
|
||||||
use crossterm_style as style;
|
use crossterm_style as style;
|
||||||
|
|
||||||
use winapi::um::wincon::{SetConsoleTextAttribute};
|
/// This will set the foreground color by the given winapi color.
|
||||||
|
|
||||||
/// This will set the forground color by the given winapi color value parsed to u16.
|
|
||||||
pub fn set_fg_color(fg_color: u16) {
|
pub fn set_fg_color(fg_color: u16) {
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
|
|
||||||
@ -21,10 +20,10 @@ pub fn set_fg_color(fg_color: u16) {
|
|||||||
color = color | wincon::BACKGROUND_INTENSITY as u16;
|
color = color | wincon::BACKGROUND_INTENSITY as u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_console_text_attribute(color);
|
kernel::set_console_text_attribute(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This will set the forground color by the given winapi color value parsed to u16.
|
/// This will set the background color by the given winapi color value.
|
||||||
pub fn set_bg_color(bg_color: u16) {
|
pub fn set_bg_color(bg_color: u16) {
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
// Notice that the color values are stored in wAttribute.
|
// Notice that the color values are stored in wAttribute.
|
||||||
@ -34,21 +33,21 @@ pub fn set_bg_color(bg_color: u16) {
|
|||||||
let fg_color = attrs & 0x0007;
|
let fg_color = attrs & 0x0007;
|
||||||
color = fg_color | bg_color;
|
color = fg_color | bg_color;
|
||||||
|
|
||||||
// foreground intensity is a seperate value in attrs,
|
// foreground intensity is a separate value in attrs,
|
||||||
// wee need to check if this was applied to the current fg color.
|
// wee need to check if this was applied to the current fg color.
|
||||||
if (attrs & wincon::FOREGROUND_INTENSITY as u16) != 0 {
|
if (attrs & wincon::FOREGROUND_INTENSITY as u16) != 0 {
|
||||||
color = color | wincon::FOREGROUND_INTENSITY as u16;
|
color = color | wincon::FOREGROUND_INTENSITY as u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_console_text_attribute(color);
|
kernel::set_console_text_attribute(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This will reset the colors to the value given in u16.
|
/// This will reset the colors to the given winapi color value.
|
||||||
pub fn reset(original_color: u16) {
|
pub fn reset(original_color: u16) {
|
||||||
set_console_text_attribute(original_color);
|
kernel::set_console_text_attribute(original_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This will get the winapi color value from the Color struct
|
/// This will get the winapi color value from the Color and ColorType struct
|
||||||
pub fn winapi_color_val(color: style::Color, color_type: style::ColorType) -> u16 {
|
pub fn winapi_color_val(color: style::Color, color_type: style::ColorType) -> u16 {
|
||||||
use crossterm_style::{Color, ColorType};
|
use crossterm_style::{Color, ColorType};
|
||||||
|
|
||||||
@ -107,12 +106,3 @@ pub fn winapi_color_val(color: style::Color, color_type: style::ColorType) -> u1
|
|||||||
|
|
||||||
winapi_color as u16
|
winapi_color as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This will set the console attributes by the given value
|
|
||||||
fn set_console_text_attribute(value: u16) {
|
|
||||||
let output_handle = handle::get_output_handle();
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
SetConsoleTextAttribute(output_handle, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,53 +1,35 @@
|
|||||||
use winapi::um::wincon::COORD;
|
use super::kernel;
|
||||||
use super::{handle, kernel};
|
|
||||||
use shared::functions;
|
|
||||||
|
|
||||||
use winapi::um::wincon::{SetConsoleCursorPosition};
|
/// This stores the cursor pos, at program level. So it can be recalled later.
|
||||||
|
static mut SAVED_CURSOR_POS:(i16,i16) = (0,0);
|
||||||
|
|
||||||
|
/// Set the current cursor position to X and Y
|
||||||
/// Set the cursor position to an coordinate (x,y).
|
pub fn set(x: i16, y: i16)
|
||||||
pub fn set(x: i16, y: i16) {
|
{
|
||||||
set_cursor_pos(x as i16, y as i16);
|
kernel::set_console_cursor_position(x, y );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current cursor x position.
|
/// Reset to saved cursor position
|
||||||
pub fn xpos() -> i16 {
|
pub fn reset_to_saved_position()
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
{
|
||||||
csbi.dwCursorPosition.X
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the current cursor y position.
|
|
||||||
pub fn ypos() -> i16 {
|
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
|
||||||
csbi.dwCursorPosition.Y
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn move_down(count: u16) {
|
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let output_handle = handle::get_output_handle();
|
kernel::set_console_cursor_position(SAVED_CURSOR_POS.0, SAVED_CURSOR_POS.1);
|
||||||
SetConsoleCursorPosition(
|
|
||||||
output_handle,
|
|
||||||
COORD {
|
|
||||||
X: csbi.dwCursorPosition.X,
|
|
||||||
Y: csbi.dwCursorPosition.Y + count as i16,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the cursor position to an coordinate (x,y).
|
/// Save current cursor position to recall later.
|
||||||
fn set_cursor_pos(x: i16, y: i16) {
|
pub fn save_cursor_pos()
|
||||||
functions::is_cursor_out_of_range(x, y);
|
{
|
||||||
|
let position = pos();
|
||||||
let output_handle = handle::get_output_handle();
|
|
||||||
let position = COORD { X: x, Y: y };
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let success = SetConsoleCursorPosition(output_handle, position);
|
SAVED_CURSOR_POS = (position.0, position.1);
|
||||||
|
|
||||||
if success == 0 {
|
|
||||||
panic!("Cannot set console cursor position");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get current cursor position (X,Y)
|
||||||
|
pub fn pos() -> (i16,i16)
|
||||||
|
{
|
||||||
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
|
( csbi.dwCursorPosition.X , csbi.dwCursorPosition.Y )
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
use winapi::um::winnt;
|
|
||||||
use winapi::um::winbase;
|
|
||||||
use winapi::um::handleapi;
|
|
||||||
|
|
||||||
use winapi::um::processenv::{GetStdHandle};
|
|
||||||
|
|
||||||
// static mut CONSOLE_INPUT_HANDLE:Option<winnt::HANDLE> = None;
|
|
||||||
static mut CONSOLE_OUTPUT_HANDLE: Option<winnt::HANDLE> = None;
|
|
||||||
|
|
||||||
/// Get the std_output_handle of the console
|
|
||||||
pub fn get_output_handle() -> winnt::HANDLE {
|
|
||||||
unsafe {
|
|
||||||
if let Some(handle) = CONSOLE_OUTPUT_HANDLE {
|
|
||||||
handle
|
|
||||||
} else {
|
|
||||||
let handle = GetStdHandle(winbase::STD_OUTPUT_HANDLE);
|
|
||||||
CONSOLE_OUTPUT_HANDLE = Some(handle);
|
|
||||||
handle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks if the console handle is an invalid handle value.
|
|
||||||
pub fn is_valid_handle(handle: &winnt::HANDLE) -> bool {
|
|
||||||
if *handle == handleapi::INVALID_HANDLE_VALUE {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +1,46 @@
|
|||||||
use winapi::um::wincon::{GetConsoleScreenBufferInfo,CONSOLE_SCREEN_BUFFER_INFO};
|
use winapi::um::winnt::HANDLE;
|
||||||
use super::{handle, Empty};
|
use winapi::um::winbase::STD_OUTPUT_HANDLE;
|
||||||
|
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
|
||||||
|
use winapi::um::processenv::{GetStdHandle};
|
||||||
|
use winapi::um::consoleapi::{SetConsoleMode};
|
||||||
|
use winapi::um::wincon::{ SetConsoleWindowInfo, SetConsoleCursorPosition, SetConsoleTextAttribute, SetConsoleScreenBufferSize,
|
||||||
|
GetLargestConsoleWindowSize, GetConsoleScreenBufferInfo,
|
||||||
|
FillConsoleOutputCharacterA, FillConsoleOutputAttribute,
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT, COORD
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{Empty};
|
||||||
|
|
||||||
|
static mut CONSOLE_OUTPUT_HANDLE: Option<HANDLE> = None;
|
||||||
|
|
||||||
|
/// Get the std_output_handle of the console
|
||||||
|
pub fn get_output_handle() -> HANDLE {
|
||||||
|
unsafe {
|
||||||
|
if let Some(handle) = CONSOLE_OUTPUT_HANDLE {
|
||||||
|
handle
|
||||||
|
} else {
|
||||||
|
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
CONSOLE_OUTPUT_HANDLE = Some(handle);
|
||||||
|
handle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if the console handle is an invalid handle value.
|
||||||
|
pub fn is_valid_handle(handle: &HANDLE) -> bool {
|
||||||
|
if *handle == INVALID_HANDLE_VALUE {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get console screen buffer info.
|
/// Get console screen buffer info.
|
||||||
pub fn get_console_screen_buffer_info() -> CONSOLE_SCREEN_BUFFER_INFO {
|
pub fn get_console_screen_buffer_info() -> CONSOLE_SCREEN_BUFFER_INFO {
|
||||||
let output_handle = handle::get_output_handle();
|
let output_handle = get_output_handle();
|
||||||
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
|
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
|
||||||
let success;
|
let success;
|
||||||
|
|
||||||
if handle::is_valid_handle(&output_handle) {
|
|
||||||
return CONSOLE_SCREEN_BUFFER_INFO::empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe { success = GetConsoleScreenBufferInfo(output_handle, &mut csbi) }
|
unsafe { success = GetConsoleScreenBufferInfo(output_handle, &mut csbi) }
|
||||||
|
|
||||||
if success == 0 {
|
if success == 0 {
|
||||||
@ -20,8 +50,129 @@ pub fn get_console_screen_buffer_info() -> CONSOLE_SCREEN_BUFFER_INFO {
|
|||||||
csbi
|
csbi
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current console colors.
|
pub fn get_largest_console_window_size() -> COORD
|
||||||
|
{
|
||||||
|
let output_handle = get_output_handle();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
GetLargestConsoleWindowSize(output_handle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_original_console_color() -> u16 {
|
pub fn get_original_console_color() -> u16 {
|
||||||
let console_buffer_info = get_console_screen_buffer_info();
|
let console_buffer_info = get_console_screen_buffer_info();
|
||||||
console_buffer_info.wAttributes as u16
|
console_buffer_info.wAttributes as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_console_mode(console_mode: u32)
|
||||||
|
{
|
||||||
|
let output_handle = get_output_handle();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
SetConsoleMode(output_handle, console_mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_console_cursor_position(x: i16, y: i16)
|
||||||
|
{
|
||||||
|
if x < 0 || x >= <i16>::max_value() {
|
||||||
|
panic!("X: {}, Argument Out of Range Exception", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
if y < 0 || y >= <i16>::max_value() {
|
||||||
|
panic!("Y: {}, Argument Out of Range Exception", y);
|
||||||
|
}
|
||||||
|
|
||||||
|
let output_handle = get_output_handle();
|
||||||
|
let position = COORD { X: x, Y: y };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let success = SetConsoleCursorPosition(output_handle, position);
|
||||||
|
|
||||||
|
if success == 0 {
|
||||||
|
panic!("Argument out of range.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_console_text_attribute(value: u16)
|
||||||
|
{
|
||||||
|
let output_handle = get_output_handle();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
SetConsoleTextAttribute(output_handle, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_console_info(absolute: bool, rect: &SMALL_RECT) -> bool
|
||||||
|
{
|
||||||
|
|
||||||
|
let output_handle = get_output_handle();
|
||||||
|
|
||||||
|
let absolute = match absolute { true => 1, false => 0, };
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
let success = SetConsoleWindowInfo(output_handle,absolute ,rect);
|
||||||
|
is_true(success)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_console_screen_buffer_size( size: COORD) -> bool
|
||||||
|
{
|
||||||
|
let output_handle = get_output_handle();
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
let success = SetConsoleScreenBufferSize(output_handle, size);
|
||||||
|
is_true(success)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fill_console_output_character(cells_written: &mut u32, start_location: COORD, cells_to_write: u32) -> bool
|
||||||
|
{
|
||||||
|
let output_handle = get_output_handle();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// fill the cells in console with blanks
|
||||||
|
let success = FillConsoleOutputCharacterA (
|
||||||
|
output_handle,
|
||||||
|
' ' as i8,
|
||||||
|
cells_to_write,
|
||||||
|
start_location,
|
||||||
|
cells_written,
|
||||||
|
);
|
||||||
|
is_true(success)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fill_console_output_attribute(cells_written: &mut u32, start_location: COORD, cells_to_write: u32) -> bool
|
||||||
|
{
|
||||||
|
// Get the position of the current console window
|
||||||
|
let csbi = get_console_screen_buffer_info();
|
||||||
|
let output_handle = get_output_handle();
|
||||||
|
|
||||||
|
let mut success;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
success = FillConsoleOutputAttribute (
|
||||||
|
output_handle,
|
||||||
|
csbi.wAttributes,
|
||||||
|
cells_to_write,
|
||||||
|
start_location,
|
||||||
|
cells_written,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
is_true(success)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse integer to an bool
|
||||||
|
fn is_true(value: i32) -> bool
|
||||||
|
{
|
||||||
|
if value == 0{
|
||||||
|
false
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
pub mod color;
|
pub mod color;
|
||||||
pub mod ansi_support;
|
pub mod ansi_support;
|
||||||
pub mod handle;
|
|
||||||
pub mod kernel;
|
pub mod kernel;
|
||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
mod winapi_extentions;
|
mod winapi_extentions;
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use super::{cursor, handle, kernel};
|
use super::{cursor, kernel};
|
||||||
|
use winapi::um::wincon::{SMALL_RECT, COORD};
|
||||||
use winapi;
|
|
||||||
use winapi::shared::ntdef::TRUE;
|
|
||||||
use winapi::um::wincon::{SetConsoleWindowInfo,FillConsoleOutputCharacterA, FillConsoleOutputAttribute, COORD, CONSOLE_SCREEN_BUFFER_INFO};
|
|
||||||
|
|
||||||
/// Get the terminal size (y,x)
|
/// Get the terminal size (y,x)
|
||||||
pub fn terminal_size() -> Option<(u16, u16)> {
|
pub fn terminal_size() -> Option<(u16, u16)> {
|
||||||
@ -16,7 +13,6 @@ pub fn terminal_size() -> Option<(u16, u16)> {
|
|||||||
|
|
||||||
/// Scroll down `n` rows
|
/// Scroll down `n` rows
|
||||||
pub fn scroll_down(rows: i16) {
|
pub fn scroll_down(rows: i16) {
|
||||||
let output_handle = handle::get_output_handle();
|
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
let mut srct_window;
|
let mut srct_window;
|
||||||
|
|
||||||
@ -28,22 +24,16 @@ pub fn scroll_down(rows: i16) {
|
|||||||
srct_window.Top += rows; // move top down
|
srct_window.Top += rows; // move top down
|
||||||
srct_window.Bottom += rows; // move bottom down
|
srct_window.Bottom += rows; // move bottom down
|
||||||
|
|
||||||
unsafe {
|
let success = kernel::set_console_info(true, &mut srct_window);
|
||||||
if SetConsoleWindowInfo(output_handle, TRUE as i32, &mut srct_window) != 1 {
|
if success {
|
||||||
panic!("Something whent wrong when scrolling down");
|
panic!("Something went wrong when scrolling down");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_after_cursor() {
|
pub fn clear_after_cursor() {
|
||||||
let output_handle = handle::get_output_handle();
|
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
|
let (mut x,mut y) = cursor::pos();
|
||||||
// one cell after cursor position
|
|
||||||
let mut x = cursor::xpos() as i16 ;
|
|
||||||
// one at row of cursor position
|
|
||||||
let mut y = cursor::ypos() as i16;
|
|
||||||
|
|
||||||
// if cursor position is at the outer right position
|
// if cursor position is at the outer right position
|
||||||
if x > csbi.dwSize.X
|
if x > csbi.dwSize.X
|
||||||
@ -53,16 +43,16 @@ pub fn clear_after_cursor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// location where to start clearing
|
// location where to start clearing
|
||||||
let start_loaction = COORD { X: x, Y: y };
|
let start_location = COORD { X: x, Y: y };
|
||||||
// get sum cells before cursor
|
// get sum cells before cursor
|
||||||
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
|
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
|
||||||
|
|
||||||
clear(output_handle, csbi, start_loaction,cells_to_write);
|
clear(start_location,cells_to_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_before_cursor() {
|
pub fn clear_before_cursor() {
|
||||||
let output_handle = handle::get_output_handle();
|
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
|
let (xpos,ypos) = cursor::pos();
|
||||||
|
|
||||||
// one cell after cursor position
|
// one cell after cursor position
|
||||||
let x = 0;
|
let x = 0;
|
||||||
@ -70,30 +60,27 @@ pub fn clear_before_cursor() {
|
|||||||
let y = 0;
|
let y = 0;
|
||||||
|
|
||||||
// location where to start clearing
|
// location where to start clearing
|
||||||
let start_loaction = COORD { X: x, Y: y };
|
let start_location = COORD { X: x, Y: y };
|
||||||
// get sum cells before cursor
|
// get sum cells before cursor
|
||||||
let cells_to_write = (csbi.dwSize.X as u32 * cursor::ypos() as u32) + (cursor::xpos()) as u32;
|
let cells_to_write = (csbi.dwSize.X as u32 * ypos as u32) + (xpos as u32 + 1);
|
||||||
|
|
||||||
// println!("{:?}", (csbi.dwSize.X as u32 * (cursor::ypos() - 1) as u32));
|
clear(start_location, cells_to_write);
|
||||||
clear(output_handle, csbi, start_loaction, cells_to_write);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_entire_screen() {
|
pub fn clear_entire_screen() {
|
||||||
let output_handle = handle::get_output_handle();
|
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
|
|
||||||
// position x at start
|
// position x at start
|
||||||
let x = 0;
|
let x = 0;
|
||||||
// position y at start
|
// position y at start
|
||||||
let y = 0;
|
let y = 0;
|
||||||
|
|
||||||
// location where to start clearing
|
// location where to start clearing
|
||||||
let start_loaction = COORD { X: x, Y: y };
|
let start_location = COORD { X: x, Y: y };
|
||||||
// get sum cells before cursor
|
// get sum cells before cursor
|
||||||
|
|
||||||
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
|
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
|
||||||
|
|
||||||
clear(output_handle, csbi, start_loaction, cells_to_write);
|
clear( start_location, cells_to_write);
|
||||||
|
|
||||||
// put the cursor back at (0, 0)
|
// put the cursor back at (0, 0)
|
||||||
cursor::set(0, 0);
|
cursor::set(0, 0);
|
||||||
@ -101,21 +88,19 @@ pub fn clear_entire_screen() {
|
|||||||
|
|
||||||
pub fn clear_current_line()
|
pub fn clear_current_line()
|
||||||
{
|
{
|
||||||
let output_handle = handle::get_output_handle();
|
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
|
|
||||||
// position x at start
|
// position x at start
|
||||||
let x = 0;
|
let x = 0;
|
||||||
// position y at start
|
// position y at start
|
||||||
let y = cursor::ypos();
|
let y = cursor::pos().1;
|
||||||
|
|
||||||
// location where to start clearing
|
// location where to start clearing
|
||||||
let start_loaction = COORD { X: x, Y: y };
|
let start_location = COORD { X: x, Y: y };
|
||||||
// get sum cells before cursor
|
// get sum cells before cursor
|
||||||
|
|
||||||
let cells_to_write = csbi.dwSize.X as u32;
|
let cells_to_write = csbi.dwSize.X as u32;
|
||||||
|
|
||||||
clear(output_handle, csbi, start_loaction, cells_to_write);
|
clear(start_location, cells_to_write);
|
||||||
|
|
||||||
// put the cursor back at (0, 0)
|
// put the cursor back at (0, 0)
|
||||||
cursor::set(x, y);
|
cursor::set(x, y);
|
||||||
@ -123,62 +108,114 @@ pub fn clear_current_line()
|
|||||||
|
|
||||||
pub fn clear_until_line()
|
pub fn clear_until_line()
|
||||||
{
|
{
|
||||||
let output_handle = handle::get_output_handle();
|
|
||||||
let csbi = kernel::get_console_screen_buffer_info();
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
|
let (x,y) = cursor::pos();
|
||||||
// position x at start
|
|
||||||
let x = cursor::xpos();
|
|
||||||
// position y at start
|
|
||||||
let y = cursor::ypos();
|
|
||||||
|
|
||||||
// location where to start clearing
|
// location where to start clearing
|
||||||
let start_loaction = COORD { X: x -1, Y: y };
|
let start_location = COORD { X: x, Y: y };
|
||||||
// get sum cells before cursor
|
// get sum cells before cursor
|
||||||
let cells_to_write = (csbi.dwSize.X - x) as u32 - 1;
|
let cells_to_write = (csbi.dwSize.X - x) as u32;
|
||||||
|
|
||||||
clear(output_handle, csbi, start_loaction, cells_to_write);
|
clear(start_location, cells_to_write);
|
||||||
|
|
||||||
// put the cursor back at (0, 0)
|
// put the cursor back at (0, 0)
|
||||||
cursor::set(x, y);
|
cursor::set(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resize_terminal(width: i16, height: i16)
|
||||||
|
{
|
||||||
|
if width <= 0
|
||||||
|
{
|
||||||
|
panic!("Cannot set the terminal width lower than 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
if height <= 0
|
||||||
|
{
|
||||||
|
panic!("Cannot set the terminal height lower then 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the position of the current console window
|
||||||
|
let csbi = kernel::get_console_screen_buffer_info();
|
||||||
|
let mut success = false;
|
||||||
|
|
||||||
|
// If the buffer is smaller than this new window size, resize the
|
||||||
|
// buffer to be large enough. Include window position.
|
||||||
|
let mut resize_buffer = false;
|
||||||
|
let mut size = COORD { X: csbi.dwSize.X, Y: csbi.dwSize.Y };
|
||||||
|
|
||||||
|
if csbi.dwSize.X < csbi.srWindow.Left + width
|
||||||
|
{
|
||||||
|
if csbi.srWindow.Left >= i16::max_value() - width
|
||||||
|
{
|
||||||
|
panic!("Argument out of range when setting terminal width.");
|
||||||
|
}
|
||||||
|
|
||||||
|
size.X = csbi.srWindow.Left + width;
|
||||||
|
resize_buffer = true;
|
||||||
|
}
|
||||||
|
if csbi.dwSize.Y < csbi.srWindow.Top + height {
|
||||||
|
if csbi.srWindow.Top >= i16::max_value() - height
|
||||||
|
{
|
||||||
|
panic!("Argument out of range when setting terminal height");
|
||||||
|
}
|
||||||
|
|
||||||
|
size.Y = csbi.srWindow.Top + height;
|
||||||
|
resize_buffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if resize_buffer {
|
||||||
|
success = kernel::set_console_screen_buffer_size(size);
|
||||||
|
|
||||||
|
if !success
|
||||||
|
{
|
||||||
|
panic!("Something went wrong when setting screen buffer size.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fsr_window: SMALL_RECT = csbi.srWindow;
|
||||||
|
// Preserve the position, but change the size.
|
||||||
|
fsr_window.Bottom = fsr_window.Top + height;
|
||||||
|
fsr_window.Right = fsr_window.Left + width;
|
||||||
|
|
||||||
|
let success = kernel::set_console_info(true, &fsr_window);
|
||||||
|
|
||||||
|
if success {
|
||||||
|
// If we resized the buffer, un-resize it.
|
||||||
|
if resize_buffer {
|
||||||
|
kernel::set_console_screen_buffer_size(csbi.dwSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
let bounds = kernel::get_largest_console_window_size();
|
||||||
|
|
||||||
|
if width > bounds.X
|
||||||
|
{
|
||||||
|
panic!("Argument width: {} out of range when setting terminal width.", width);
|
||||||
|
}
|
||||||
|
if height > bounds.Y
|
||||||
|
{
|
||||||
|
panic!("Argument height: {} out of range when setting terminal height", height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn clear(
|
fn clear(
|
||||||
handle: winapi::um::winnt::HANDLE,
|
|
||||||
csbi: CONSOLE_SCREEN_BUFFER_INFO,
|
|
||||||
start_loaction: COORD,
|
start_loaction: COORD,
|
||||||
cells_to_write: u32
|
cells_to_write: u32
|
||||||
) {
|
) {
|
||||||
let mut cells_written = 0;
|
let mut cells_written = 0;
|
||||||
let mut success;
|
let mut success = false;
|
||||||
|
|
||||||
unsafe {
|
success = kernel::fill_console_output_character(&mut cells_written,start_loaction,cells_to_write);
|
||||||
// fill the cells in console with blanks
|
|
||||||
success = FillConsoleOutputCharacterA (
|
|
||||||
handle,
|
|
||||||
' ' as i8,
|
|
||||||
cells_to_write,
|
|
||||||
start_loaction,
|
|
||||||
&mut cells_written,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if success == 0 {
|
if !success {
|
||||||
panic!("Couldnot clear screen after cursor");
|
panic!("Could not clear screen after cursor");
|
||||||
}
|
}
|
||||||
|
|
||||||
cells_written = 0;
|
cells_written = 0;
|
||||||
|
|
||||||
unsafe {
|
success = kernel::fill_console_output_attribute(&mut cells_written,start_loaction, cells_to_write);
|
||||||
success = FillConsoleOutputAttribute (
|
|
||||||
handle,
|
|
||||||
csbi.wAttributes,
|
|
||||||
cells_to_write,
|
|
||||||
start_loaction,
|
|
||||||
&mut cells_written,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if success == 0 {
|
if !success {
|
||||||
panic!("Couldnot reset attributes after cursor");
|
panic!("Couldnot reset attributes after cursor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
pub fn is_cursor_out_of_range(x: i16, y: i16) {
|
pub fn is_cursor_out_of_range(x: i16, y: i16) {
|
||||||
if x < 0 || x >= <i16>::max_value() {
|
|
||||||
panic!("Argument Out of Range Exception");
|
|
||||||
}
|
|
||||||
|
|
||||||
if y < 0 || y >= <i16>::max_value() {
|
|
||||||
panic!("Argument Out of Range Exception");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ pub trait Construct {
|
|||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// This trait is used to create an empty instance of an struct.
|
/// This trait is used to create an empty instance of an struct.
|
||||||
pub trait Empty {
|
pub trait Empty {
|
||||||
fn empty() -> Self;
|
fn empty() -> Self;
|
||||||
|
Loading…
Reference in New Issue
Block a user