Maked windows compilable and worked on the screen manager for windows.

This commit is contained in:
TimonPost 2018-06-18 22:10:41 +02:00
parent e48b952604
commit bb2067ed7b
19 changed files with 635 additions and 667 deletions

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
use super::*; use super::*;
use Context; use Context;
use super::super::shared::functions;
use std::fmt::Display; use std::fmt::Display;
use std::io::Write; use std::io::Write;
@ -20,7 +21,7 @@ impl <'context> TerminalCursor<'context>
/// 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: &'context Context) -> TerminalCursor<'context> { pub fn new(context: &'context Context) -> TerminalCursor<'context> {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let cursor = functions::get_module::<Box<ITerminalCursor>>(WinApiCursor::new(), AnsiCursor::new()); let cursor = functions::get_module::<Box<ITerminalCursor>>(WinApiCursor::new(), AnsiCursor::new(), context);
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
let cursor = Some(AnsiCursor::new() as Box<ITerminalCursor>); let cursor = Some(AnsiCursor::new() as Box<ITerminalCursor>);

View File

@ -26,23 +26,23 @@ impl ITerminalCursor for WinApiCursor {
} }
fn move_up(&self, count: u16, context: &Context) { fn move_up(&self, count: u16, context: &Context) {
let (xpos,ypos) = self.pos(); let (xpos,ypos) = self.pos(context);
self.goto(xpos, ypos - count); self.goto(xpos, ypos - count, context);
} }
fn move_right(&self, count: u16, context: &Context) { fn move_right(&self, count: u16, context: &Context) {
let (xpos,ypos) = self.pos(); let (xpos,ypos) = self.pos(context);
self.goto(xpos + count, ypos); self.goto(xpos + count, ypos, context);
} }
fn move_down(&self, count: u16, context: &Context) { fn move_down(&self, count: u16, context: &Context) {
let (xpos,ypos) = self.pos(); let (xpos,ypos) = self.pos(context);
self.goto(xpos, ypos + count); self.goto(xpos, ypos + count,context);
} }
fn move_left(&self, count: u16, context: &Context) { fn move_left(&self, count: u16, context: &Context) {
let (xpos,ypos) = self.pos(); let (xpos,ypos) = self.pos(context);
self.goto(xpos - count, ypos); self.goto(xpos - count, ypos,context);
} }
fn save_position(&mut self, context: &Context) fn save_position(&mut self, context: &Context)

View File

@ -1,6 +1,6 @@
//! This module handles the enabling `ANSI escape codes` for windows terminals. //! This module handles the enabling `ANSI escape codes` for windows terminals.
use StateManager; use {Context, StateManager};
use state::commands::ICommand; use state::commands::ICommand;
static mut HAS_BEEN_TRYED_TO_ENABLE: bool = false; static mut HAS_BEEN_TRYED_TO_ENABLE: bool = false;
@ -8,11 +8,11 @@ static mut IS_ANSI_ON_WINDOWS_ENABLED: Option<bool> = None;
static mut DOES_WINDOWS_SUPPORT_ANSI: Option<bool> = None; static mut DOES_WINDOWS_SUPPORT_ANSI: Option<bool> = None;
/// Try enable `ANSI escape codes` and return the result. /// Try enable `ANSI escape codes` and return the result.
pub fn try_enable_ansi_support() -> bool pub fn try_enable_ansi_support(context: &Context) -> bool
{ {
use state::commands::win_commands::EnableAnsiCommand; use state::commands::win_commands::EnableAnsiCommand;
let mut command = EnableAnsiCommand::new(); let mut command = EnableAnsiCommand::new();
let success = command.execute(); let success = command.execute(&context);
set_is_windows_ansi_supportable(success); set_is_windows_ansi_supportable(success);
set_ansi_enabled(success); set_ansi_enabled(success);

View File

@ -6,15 +6,17 @@ use std::io::{self, Write};
use super::IScreenManager; use super::IScreenManager;
pub struct AnsiScreenManager<Output:Write> pub struct AnsiScreenManager
{ {
pub is_alternate_screen: bool, pub is_alternate_screen: bool,
output: Output, output: Box<Write>,
} }
impl<Output :Write> IScreenManager<Output> for AnsiScreenManager<Output> impl IScreenManager for AnsiScreenManager
{ {
fn stdout(&mut self) -> &mut Output type Output = Box<Write>;
fn stdout(&mut self) -> &mut Self::Output
{ {
return &mut self.output return &mut self.output
} }
@ -37,7 +39,7 @@ impl<Output :Write> IScreenManager<Output> for AnsiScreenManager<Output>
} }
} }
impl AnsiScreenManager<Box<Write>> { impl AnsiScreenManager {
pub fn new() -> Self { pub fn new() -> Self {
AnsiScreenManager { AnsiScreenManager {
output: (Box::from(io::stdout()) as Box<Write>), output: (Box::from(io::stdout()) as Box<Write>),
@ -46,7 +48,7 @@ impl AnsiScreenManager<Box<Write>> {
} }
} }
impl<Output:Write> Write for AnsiScreenManager<Output> impl Write for AnsiScreenManager
{ {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.output.write(buf) self.output.write(buf)

View File

@ -9,7 +9,7 @@ use std::io::Write;
/// Struct that stores an specific platform implementation for screen related actions. /// Struct that stores an specific platform implementation for screen related actions.
pub struct ScreenManager pub struct ScreenManager
{ {
screen_manager: Box<IScreenManager<Box<Write>>> screen_manager: Box<IScreenManager<Output=Box<Write>>>
} }
impl ScreenManager impl ScreenManager

View File

@ -13,10 +13,12 @@ use self::ansi_manager::AnsiScreenManager;
pub use self::manager::{ ScreenManager }; pub use self::manager::{ ScreenManager };
pub trait IScreenManager<Output> pub trait IScreenManager
{ {
type Output;
/// get the stdout of the screen. This can be used to write to the /// get the stdout of the screen. This can be used to write to the
fn stdout(&mut self) -> &mut Output; fn stdout(&mut self) -> &mut Self::Output;
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool); fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool);
/// Write ansi code as String to the current stdout. /// Write ansi code as String to the current stdout.
fn write_ansi(&mut self, string: String); fn write_ansi(&mut self, string: String);

View File

@ -1,4 +1,56 @@
use super::IScreenManager;
use kernel::windows_kernel::kernel;
use winapi::um::winnt::HANDLE;
pub struct WinApiScreenManager pub struct WinApiScreenManager
{ {
pub is_alternate_screen: bool,
output: Box<HANDLE>,
}
} impl IScreenManager for WinApiScreenManager where
{
type Output = HANDLE;
fn stdout(&mut self) -> &mut Self::Output
{
return &mut self.output
}
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool)
{
self.is_alternate_screen = is_alternate_screen;
}
fn write_ansi(&mut self, string: String)
{
// write!(self.output, "{}", string);
// self.flush();
}
fn write_ansi_str(&mut self, string: &str)
{
// write!(self.output, "{}", string);
// self.flush();
}
}
impl WinApiScreenManager {
pub fn new() -> Self {
WinApiScreenManager {
output: (Box::from(kernel::get_output_handle())),
is_alternate_screen: false
}
}
}
//impl<Output:Write> Write for AnsiScreenManager<Output>
//{
// fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
// self.output.write(buf)
// }
//
// fn flush(&mut self) -> io::Result<()> {
// self.stdout().flush()
// }
//}

View File

@ -31,7 +31,7 @@ pub fn get_cursor_position(screen: &Context) -> (u16, u16)
#[cfg(windows)] #[cfg(windows)]
/// Get an module specific implementation based on the current platform. /// Get an module specific implementation based on the current platform.
pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T> pub fn get_module<T>(winapi_impl: T, unix_impl: T, context: &Context) -> Option<T>
{ {
let mut term: Option<T> = None; let mut term: Option<T> = None;
let mut does_support = true; let mut does_support = true;
@ -41,7 +41,7 @@ pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T>
use kernel::windows_kernel::ansi_support::try_enable_ansi_support; use kernel::windows_kernel::ansi_support::try_enable_ansi_support;
// Try to enable ansi on windows if not than use WINAPI. // Try to enable ansi on windows if not than use WINAPI.
does_support = try_enable_ansi_support(); does_support = try_enable_ansi_support(&context);
if !does_support if !does_support
{ {

View File

@ -2,7 +2,7 @@
use Context; use Context;
use state::commands::*; use state::commands::*;
use super::functions;
use std::io::{self, Write}; use std::io::{self, Write};
pub struct AlternateScreen<'context> { pub struct AlternateScreen<'context> {
@ -14,20 +14,20 @@ impl<'context> AlternateScreen<'context> {
/// By calling this method the current screen will be changed to the alternate screen. /// By calling this method the current screen will be changed to the alternate screen.
/// And you get back an handle for that screen. /// And you get back an handle for that screen.
pub fn from(context: &'context Context) -> Self { pub fn from(context: &'context Context) -> Self {
get_to_alternate_screen_command().execute(&context); get_to_alternate_screen_command(context).execute(&context);
AlternateScreen { context: context } AlternateScreen { context: context }
} }
/// Change the current screen to the mainscreen. /// Change the current screen to the mainscreen.
pub fn to_main(&self) pub fn to_main(&self)
{ {
get_to_alternate_screen_command().undo(&self.context); get_to_alternate_screen_command(&self.context).undo(&self.context);
} }
/// Change the current screen to alternate screen. /// Change the current screen to alternate screen.
pub fn to_alternate(&self) pub fn to_alternate(&self)
{ {
get_to_alternate_screen_command().execute(&self.context); get_to_alternate_screen_command(&self.context).execute(&self.context);
} }
} }
@ -51,15 +51,15 @@ impl<'context> Drop for AlternateScreen<'context>
{ {
fn drop(&mut self) fn drop(&mut self)
{ {
get_to_alternate_screen_command().undo(&self.context); get_to_alternate_screen_command(&self.context).undo(&self.context);
} }
} }
// Get the alternate screen command to enable and disable alternate screen based on the current platform // Get the alternate screen command to enable and disable alternate screen based on the current platform
fn get_to_alternate_screen_command() -> Box<ICommand> fn get_to_alternate_screen_command(context: &Context) -> Box<ICommand>
{ {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let command = functions::get_module::<Box<ICommand>>(win_commands::ToAlternateScreenBufferCommand::new(), shared_commands::ToAlternateScreenBufferCommand::new()).unwrap(); let command = functions::get_module::<Box<ICommand>>(win_commands::ToAlternateScreenBufferCommand::new(), shared_commands::ToAlternateScreenBufferCommand::new(), context).unwrap();
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
let command = shared_commands::ToAlternateScreenBufferCommand::new(); let command = shared_commands::ToAlternateScreenBufferCommand::new();

View File

@ -1,7 +1,7 @@
//! This module contains the commands that can be used for windows systems. //! This module contains the commands that can be used for windows systems.
use super::{ICommand, IStateCommand}; use super::{ICommand, IStateCommand};
use super::super::StateManager; use { StateManager, Context };
use kernel::windows_kernel::{kernel, ansi_support}; use kernel::windows_kernel::{kernel, ansi_support};
use winapi::shared::minwindef::DWORD; use winapi::shared::minwindef::DWORD;
@ -23,18 +23,16 @@ pub struct EnableAnsiCommand
impl ICommand for EnableAnsiCommand impl ICommand for EnableAnsiCommand
{ {
fn new() -> Box<EnableAnsiCommand> { fn new() -> Box<EnableAnsiCommand> {
let key = super::generate_key();
let command = EnableAnsiCommand { mask: ENABLE_VIRTUAL_TERMINAL_PROCESSING }; let command = EnableAnsiCommand { mask: ENABLE_VIRTUAL_TERMINAL_PROCESSING };
Box::from(command) Box::from(command)
} }
fn execute(&mut self) -> bool fn execute(&mut self, context: &Context) -> bool
{ {
// we need to check whether we tried to enable ansi before. If we have we can just return if that had succeeded. // we need to check whether we tried to enable ansi before. If we have we can just return if that had succeeded.
if ansi_support::has_been_tried_to_enable_ansi() && ansi_support::ansi_enabled() if ansi_support::has_been_tried_to_enable_ansi() && ansi_support::ansi_enabled()
{ {
return ansi_support::windows_supportable(); return ansi_support::windows_supportable();
} else { } else {
let output_handle = kernel::get_output_handle(); let output_handle = kernel::get_output_handle();
@ -56,7 +54,7 @@ impl ICommand for EnableAnsiCommand
} }
} }
fn undo(&mut self) -> bool fn undo(&mut self, context: &Context) -> bool
{ {
if ansi_support::ansi_enabled() if ansi_support::ansi_enabled()
{ {
@ -86,23 +84,28 @@ impl ICommand for EnableAnsiCommand
pub struct EnableRawModeCommand pub struct EnableRawModeCommand
{ {
mask: DWORD, mask: DWORD,
key: i16 key: u16
}
impl EnableRawModeCommand
{
pub fn new(state_manager: &Mutex<StateManager>) -> u16 {
use self::wincon::{ENABLE_LINE_INPUT,ENABLE_PROCESSED_INPUT, ENABLE_PROCESSED_OUTPUT, ENABLE_WRAP_AT_EOL_OUTPUT, ENABLE_ECHO_INPUT};
let mut state = state_manager.lock().unwrap();
{
let key = state.get_changes_count();
let command = EnableRawModeCommand { mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT, key: key };
state.register_change(Box::from(command), key);
key
}
}
} }
impl IStateCommand for EnableRawModeCommand impl IStateCommand for EnableRawModeCommand
{ {
fn new(state: &mut StateManager) -> (Box<EnableRawModeCommand>, i16) { fn execute(&mut self, context: &Context) -> bool
use self::wincon::{ENABLE_LINE_INPUT,ENABLE_PROCESSED_INPUT, ENABLE_PROCESSED_OUTPUT, ENABLE_WRAP_AT_EOL_OUTPUT, ENABLE_ECHO_INPUT};
let key = super::generate_key();
let command = EnableRawModeCommand { mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT, key: key };
let rc = Rc::new(command);
state.register_change(rc.clone(), key);
(rc.clone(),key)
}
fn execute(&mut self, terminal: &Terminal) -> bool
{ {
use self::wincon::{ENABLE_LINE_INPUT,ENABLE_PROCESSED_INPUT, ENABLE_ECHO_INPUT}; use self::wincon::{ENABLE_LINE_INPUT,ENABLE_PROCESSED_INPUT, ENABLE_ECHO_INPUT};
@ -124,7 +127,7 @@ impl IStateCommand for EnableRawModeCommand
true true
} }
fn undo(&mut self, terminal: &Terminal) -> bool fn undo(&mut self, context: &Context) -> bool
{ {
let output_handle = kernel::get_output_handle(); let output_handle = kernel::get_output_handle();
@ -157,7 +160,7 @@ impl ICommand for ToAlternateScreenBufferCommand
Box::from(ToAlternateScreenBufferCommand {}) Box::from(ToAlternateScreenBufferCommand {})
} }
fn execute(&mut self, state: &StateManager) -> bool fn execute(&mut self, context: &Context) -> bool
{ {
let mut chi_buffer: [CHAR_INFO;160] = unsafe {mem::zeroed() }; let mut chi_buffer: [CHAR_INFO;160] = unsafe {mem::zeroed() };
@ -211,7 +214,7 @@ impl ICommand for ToAlternateScreenBufferCommand
true true
} }
fn undo(&mut self, state: &StateManager) -> bool fn undo(&mut self, context: &Context) -> bool
{ {
let handle = kernel::get_output_handle(); let handle = kernel::get_output_handle();
kernel::set_active_screen_buffer(handle); kernel::set_active_screen_buffer(handle);

View File

@ -78,7 +78,7 @@ impl Context
where where
D: fmt::Display, D: fmt::Display,
{ {
style::ObjectStyle::new().apply_to(val, self.screen_manager.clone()) style::ObjectStyle::new().apply_to(val, &self)
} }
} }

View File

@ -50,6 +50,11 @@ impl StateManager
return Rc::new(Mutex::new(Box::new(EmptyCommand))) return Rc::new(Mutex::new(Box::new(EmptyCommand)))
} }
pub fn get_changes_count(&self) -> u16
{
return self.changed_states.len() as u16
}
} }

View File

@ -1,12 +1,13 @@
//! With this module you can perform actions that are color related. //! With this module you can perform actions that are color related.
//! Like styling the font, foreground color and background. //! Like styling the font, foreground color and background.
use {ScreenManager, Context};
use super::*; use super::*;
use style::Color; use style::Color;
use std::io; use std::io;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex; use std::sync::Mutex;
use super::super::super::shared::functions;
/// 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 {
@ -16,14 +17,14 @@ pub struct TerminalColor {
impl TerminalColor { impl TerminalColor {
/// Create new instance whereon color related actions can be performed. /// Create new instance whereon color related actions can be performed.
pub fn new(screen_manager: Rc<Mutex<ScreenManager>> ) -> TerminalColor { pub fn new(context: &Context ) -> TerminalColor {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let color = functions::get_module::<Box<ITerminalColor>>(WinApiColor::new(), AnsiColor::new()); let color = functions::get_module::<Box<ITerminalColor>>(WinApiColor::new(), AnsiColor::new(), context);
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
let color = Some(AnsiColor::new() as Box<ITerminalColor>); let color = Some(AnsiColor::new() as Box<ITerminalColor>);
TerminalColor { color: color, screen_manager: screen_manager.clone() } TerminalColor { color: color, screen_manager: context.screen_manager.clone() }
} }
/// Set the foreground color to the given color. /// Set the foreground color to the given color.
@ -126,6 +127,6 @@ impl TerminalColor {
/// ///
/// Check `/examples/version/color` in the libary for more specific examples. /// Check `/examples/version/color` in the libary for more specific examples.
/// ///
pub fn color(screen_manager: Rc<Mutex<ScreenManager>>) -> Box<TerminalColor> { pub fn color(context: &Context) -> Box<TerminalColor> {
Box::from(TerminalColor::new(screen_manager.clone())) Box::from(TerminalColor::new(context))
} }

View File

@ -1,8 +1,11 @@
use Construct;
use super::ITerminalColor; use super::ITerminalColor;
use super::super::{ColorType, Color}; use super::super::{ColorType, Color};
use winapi::um::wincon; use winapi::um::wincon;
use kernel::windows_kernel::kernel; use kernel::windows_kernel::kernel;
use ScreenManager;
use std::sync::Mutex;
use std::rc::Rc;
/// This struct is an windows implementation for color related actions. /// This struct is an windows implementation for color related actions.
#[derive(Debug)] #[derive(Debug)]
@ -10,8 +13,8 @@ pub struct WinApiColor {
original_console_color: u16, original_console_color: u16,
} }
impl Construct for WinApiColor { impl WinApiColor {
fn new() -> Box<WinApiColor> { pub fn new() -> Box<WinApiColor> {
Box::from(WinApiColor { Box::from(WinApiColor {
original_console_color: kernel::get_original_console_color(), original_console_color: kernel::get_original_console_color(),
}) })
@ -20,7 +23,7 @@ impl Construct for WinApiColor {
impl ITerminalColor for WinApiColor { impl ITerminalColor for WinApiColor {
fn set_fg(&self, fg_color: Color) { fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
let color_value = &self.color_value(fg_color, ColorType::Foreground); let color_value = &self.color_value(fg_color, ColorType::Foreground);
let csbi = kernel::get_console_screen_buffer_info(); let csbi = kernel::get_console_screen_buffer_info();
@ -41,7 +44,7 @@ impl ITerminalColor for WinApiColor {
kernel::set_console_text_attribute(color); kernel::set_console_text_attribute(color);
} }
fn set_bg(&self, bg_color: Color) { fn set_bg(&self, bg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
let color_value = &self.color_value(bg_color, ColorType::Background); let color_value = &self.color_value(bg_color, ColorType::Background);
let csbi = kernel::get_console_screen_buffer_info(); let csbi = kernel::get_console_screen_buffer_info();
@ -61,7 +64,7 @@ impl ITerminalColor for WinApiColor {
kernel::set_console_text_attribute(color); kernel::set_console_text_attribute(color);
} }
fn reset(&self) { fn reset(&self, screen_manager: Rc<Mutex<ScreenManager>>) {
kernel::set_console_text_attribute(self.original_console_color); kernel::set_console_text_attribute(self.original_console_color);
} }

View File

@ -2,7 +2,7 @@
use std::fmt::Display; use std::fmt::Display;
use style::{Color, StyledObject}; use style::{Color, StyledObject};
use ScreenManager; use { ScreenManager, Context };
use std::sync::Mutex; use std::sync::Mutex;
use std::rc::Rc; use std::rc::Rc;
@ -32,13 +32,13 @@ impl Default for ObjectStyle {
impl ObjectStyle { impl ObjectStyle {
/// Apply an `StyledObject` to the passed displayable object. /// Apply an `StyledObject` to the passed displayable object.
pub fn apply_to<D>(&self, val: D, screen: Rc<Mutex<ScreenManager>>) -> StyledObject<D> pub fn apply_to<'a, D>(&self, val: D, context: &'a Context) -> StyledObject<'a, D>
where where
D: Display, D: Display,
{ {
StyledObject { StyledObject {
object_style: self.clone(), object_style: self.clone(),
screen_manager: screen, context: context,
content: val, content: val,
} }
} }

View File

@ -4,7 +4,7 @@ use std::fmt;
use std::io::Write; use std::io::Write;
use std::sync::Mutex; use std::sync::Mutex;
use std::rc::Rc; use std::rc::Rc;
use ScreenManager; use { ScreenManager, Context};
#[cfg(unix)] #[cfg(unix)]
use super::super::Attribute; use super::super::Attribute;
@ -12,13 +12,13 @@ use super::super::Attribute;
use style::{Color, ObjectStyle}; use style::{Color, ObjectStyle};
/// Struct that contains both the style and the content wits can be styled. /// Struct that contains both the style and the content wits can be styled.
pub struct StyledObject<D> { pub struct StyledObject<'a, D> {
pub object_style: ObjectStyle, pub object_style: ObjectStyle,
pub content: D, pub content: D,
pub screen_manager: Rc<Mutex<ScreenManager>> pub context: &'a Context
} }
impl<D> StyledObject<D> { impl<'a, D> StyledObject<'a,D> {
/// Set the foreground of the styled object to the passed `Color` /// Set the foreground of the styled object to the passed `Color`
/// ///
/// #Example /// #Example
@ -39,7 +39,7 @@ impl<D> StyledObject<D> {
/// println!("{}", paint("I am colored green").with(Color::Green)); /// println!("{}", paint("I am colored green").with(Color::Green));
/// ///
/// ``` /// ```
pub fn with(mut self, foreground_color: Color) -> StyledObject<D> { pub fn with(mut self, foreground_color: Color) -> StyledObject<'a,D> {
self.object_style = self.object_style.fg(foreground_color); self.object_style = self.object_style.fg(foreground_color);
self self
} }
@ -64,7 +64,7 @@ impl<D> StyledObject<D> {
/// println!("{}", paint("I am colored green").on(Color::Green)) /// println!("{}", paint("I am colored green").on(Color::Green))
/// ///
/// ``` /// ```
pub fn on(mut self, background_color: Color) -> StyledObject<D> { pub fn on(mut self, background_color: Color) -> StyledObject<'a,D> {
self.object_style = self.object_style.bg(background_color); self.object_style = self.object_style.bg(background_color);
self self
} }
@ -82,7 +82,7 @@ impl<D> StyledObject<D> {
/// ///
/// ``` /// ```
#[cfg(unix)] #[cfg(unix)]
pub fn attr(mut self, attr: Attribute) -> StyledObject<D> pub fn attr(mut self, attr: Attribute) -> StyledObject<'a,D>
{ {
&self.object_style.add_attr(attr); &self.object_style.add_attr(attr);
self self
@ -113,10 +113,10 @@ impl<D> StyledObject<D> {
macro_rules! impl_fmt macro_rules! impl_fmt
{ {
($name:ident) => { ($name:ident) => {
impl<D: fmt::$name> fmt::$name for StyledObject<D> { impl<'a, D: fmt::$name> fmt::$name for StyledObject<'a, D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{ {
let mut colored_terminal = super::super::color(self.screen_manager.clone()); let mut colored_terminal = super::super::color(&self.context);
let mut reset = true; let mut reset = true;
if let Some(bg) = self.object_style.bg_color if let Some(bg) = self.object_style.bg_color
@ -138,7 +138,7 @@ macro_rules! impl_fmt
fmt::$name::fmt(&self.content, f)?; fmt::$name::fmt(&self.content, f)?;
let mutex = &self.screen_manager; let mutex = &self.context.screen_manager;
{ {
let mut screen = mutex.lock().unwrap(); let mut screen = mutex.lock().unwrap();
screen.stdout().flush().expect("Flush stdout failed"); screen.stdout().flush().expect("Flush stdout failed");

View File

@ -4,8 +4,9 @@
use super::*; use super::*;
use Context; use Context;
use super::super::style;
use std::fmt; use std::fmt;
use super::super::style;
use super::super::shared::functions;
/// Struct that stores an specific platform implementation for terminal related actions. /// Struct that stores an specific platform implementation for terminal related actions.
pub struct Terminal<'context> { pub struct Terminal<'context> {
@ -17,7 +18,7 @@ impl<'context> Terminal<'context> {
/// Create new terminal instance whereon terminal related actions can be performed. /// Create new terminal instance whereon terminal related actions can be performed.
pub fn new(context: &'context Context) -> Terminal<'context> { pub fn new(context: &'context Context) -> Terminal<'context> {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let terminal = functions::get_module::<Box<ITerminal>>(WinApiTerminal::new(), AnsiTerminal::new()); let terminal = functions::get_module::<Box<ITerminal>>(WinApiTerminal::new(), AnsiTerminal::new(), context);
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
let terminal = Some(AnsiTerminal::new() as Box<ITerminal>); let terminal = Some(AnsiTerminal::new() as Box<ITerminal>);
@ -182,7 +183,7 @@ impl<'context> Terminal<'context> {
where where
D: fmt::Display, D: fmt::Display,
{ {
style::ObjectStyle::new().apply_to(val, self.context.screen_manager.clone()) style::ObjectStyle::new().apply_to(val, &self.context)
} }
} }

View File

@ -1,7 +1,7 @@
//! This is an `WINAPI` specific implementation for terminal related action. //! This is an `WINAPI` specific implementation for terminal related action.
//! This module is used for non supporting `ANSI` windows terminals. //! This module is used for non supporting `ANSI` windows terminals.
use {Construct}; use Context;
use cursor::cursor; use cursor::cursor;
use super::{ClearType, ITerminal}; use super::{ClearType, ITerminal};
use winapi::um::wincon::{SMALL_RECT, COORD, CONSOLE_SCREEN_BUFFER_INFO,}; use winapi::um::wincon::{SMALL_RECT, COORD, CONSOLE_SCREEN_BUFFER_INFO,};
@ -10,37 +10,37 @@ use kernel::windows_kernel::{kernel, terminal};
/// This struct is an windows implementation for terminal related actions. /// This struct is an windows implementation for terminal related actions.
pub struct WinApiTerminal; pub struct WinApiTerminal;
impl Construct for WinApiTerminal { impl WinApiTerminal {
fn new() -> Box<WinApiTerminal> { pub fn new() -> Box<WinApiTerminal> {
Box::from(WinApiTerminal {}) Box::from(WinApiTerminal {})
} }
} }
impl ITerminal for WinApiTerminal { impl ITerminal for WinApiTerminal {
fn clear(&self, clear_type: ClearType) { fn clear(&self, clear_type: ClearType, context: &Context) {
let csbi = kernel::get_console_screen_buffer_info(); let csbi = kernel::get_console_screen_buffer_info();
let pos = cursor().pos(); let pos = cursor(&context).pos();
match clear_type match clear_type
{ {
ClearType::All => clear_entire_screen(csbi), ClearType::All => clear_entire_screen(csbi, &context),
ClearType::FromCursorDown => clear_after_cursor(pos,csbi), ClearType::FromCursorDown => clear_after_cursor(pos,csbi,&context),
ClearType::FromCursorUp => clear_before_cursor(pos, csbi), ClearType::FromCursorUp => clear_before_cursor(pos, csbi, &context),
ClearType::CurrentLine => clear_current_line(pos, csbi), ClearType::CurrentLine => clear_current_line(pos, csbi, &context),
ClearType::UntilNewLine => clear_until_line(pos, csbi), ClearType::UntilNewLine => clear_until_line(pos, csbi,&context),
}; };
} }
fn terminal_size(&self) -> (u16, u16) { fn terminal_size(&self, context: &Context) -> (u16, u16) {
terminal::terminal_size() terminal::terminal_size()
} }
fn scroll_up(&self, count: i16) { fn scroll_up(&self, count: i16, context: &Context) {
// yet to be inplemented // yet to be inplemented
} }
fn scroll_down(&self, count: i16) { fn scroll_down(&self, count: i16, context: &Context) {
let csbi = kernel::get_console_screen_buffer_info(); let csbi = kernel::get_console_screen_buffer_info();
let mut srct_window; let mut srct_window;
@ -60,7 +60,7 @@ impl ITerminal for WinApiTerminal {
} }
/// Set the current terminal size /// Set the current terminal size
fn set_size(&self, width: i16, height: i16) { fn set_size(&self, width: i16, height: i16, context: &Context) {
if width <= 0 if width <= 0
{ {
panic!("Cannot set the terminal width lower than 1"); panic!("Cannot set the terminal width lower than 1");
@ -136,7 +136,7 @@ impl ITerminal for WinApiTerminal {
} }
} }
pub fn clear_after_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO) { pub fn clear_after_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Context) {
let (mut x,mut y) = pos; let (mut x,mut y) = pos;
// if cursor position is at the outer right position // if cursor position is at the outer right position
@ -154,7 +154,7 @@ pub fn clear_after_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO) {
clear(start_location,cells_to_write); clear(start_location,cells_to_write);
} }
pub fn clear_before_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO) { pub fn clear_before_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Context) {
let (xpos,ypos) = pos; let (xpos,ypos) = pos;
// one cell after cursor position // one cell after cursor position
@ -170,7 +170,7 @@ pub fn clear_before_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO) {
clear(start_location, cells_to_write); clear(start_location, cells_to_write);
} }
pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO) { pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Context) {
// position x at start // position x at start
let x = 0; let x = 0;
// position y at start // position y at start
@ -185,10 +185,10 @@ pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO) {
clear( start_location, cells_to_write); clear( start_location, cells_to_write);
// put the cursor back at (0, 0) // put the cursor back at (0, 0)
cursor().goto(0, 0); cursor(&context).goto(0, 0);
} }
pub fn clear_current_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO) pub fn clear_current_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Context)
{ {
// position x at start // position x at start
let x = 0; let x = 0;
@ -204,10 +204,10 @@ pub fn clear_current_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO)
clear(start_location, cells_to_write); clear(start_location, cells_to_write);
// put the cursor back at 1 cell on current row // put the cursor back at 1 cell on current row
cursor().goto(0, y); cursor(&context).goto(0, y);
} }
pub fn clear_until_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO) pub fn clear_until_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Context)
{ {
let (x,y) = pos; let (x,y) = pos;
@ -219,7 +219,7 @@ pub fn clear_until_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO)
clear(start_location, cells_to_write); clear(start_location, cells_to_write);
// put the cursor back at original cursor position // put the cursor back at original cursor position
cursor().goto(x,y); cursor(&context).goto(x,y);
} }
fn clear( fn clear(