2018-06-17 04:10:51 +10:00
|
|
|
//! This module contains the logic to style an object that contains some state witch can be styled.
|
2018-03-11 03:33:06 +11:00
|
|
|
|
2018-06-10 07:19:02 +10:00
|
|
|
use std::fmt;
|
2018-01-07 07:31:14 +11:00
|
|
|
use std::io::Write;
|
2018-06-10 05:59:43 +10:00
|
|
|
use std::sync::Mutex;
|
|
|
|
use std::rc::Rc;
|
2018-06-10 07:19:02 +10:00
|
|
|
use ScreenManager;
|
2018-01-28 04:48:49 +11:00
|
|
|
|
2018-03-04 01:40:51 +11:00
|
|
|
#[cfg(unix)]
|
2018-01-26 04:26:08 +11:00
|
|
|
use super::super::Attribute;
|
2018-01-07 07:31:14 +11:00
|
|
|
|
2018-03-11 03:33:06 +11:00
|
|
|
use style::{Color, ObjectStyle};
|
2018-01-04 00:43:54 +11:00
|
|
|
|
2018-03-11 03:33:06 +11:00
|
|
|
/// Struct that contains both the style and the content wits can be styled.
|
2018-01-07 07:31:14 +11:00
|
|
|
pub struct StyledObject<D> {
|
2018-01-04 00:43:54 +11:00
|
|
|
pub object_style: ObjectStyle,
|
2018-01-07 07:31:14 +11:00
|
|
|
pub content: D,
|
2018-06-10 05:59:43 +10:00
|
|
|
pub screen_manager: Rc<Mutex<ScreenManager>>
|
2018-01-04 00:43:54 +11:00
|
|
|
}
|
|
|
|
|
2018-01-07 07:31:14 +11:00
|
|
|
impl<D> StyledObject<D> {
|
2018-01-28 04:26:08 +11:00
|
|
|
/// Set the foreground of the styled object to the passed `Color`
|
2018-01-07 07:31:14 +11:00
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
2018-01-04 00:43:54 +11:00
|
|
|
/// ```rust
|
2018-01-28 04:26:08 +11:00
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use self::crossterm::style::{paint,Color};
|
2018-01-07 07:31:14 +11:00
|
|
|
///
|
2018-01-28 04:26:08 +11:00
|
|
|
/// // create an styled object with the foreground color red.
|
|
|
|
/// let styledobject = paint("I am colored red").with(Color::Red);
|
|
|
|
/// // create an styled object with the foreground color blue.
|
|
|
|
/// let styledobject1 = paint("I am colored blue").with(Color::Blue);
|
|
|
|
///
|
|
|
|
/// // print the styledobject to see the result
|
|
|
|
/// println!("{}", styledobject);
|
|
|
|
/// println!("{}", styledobject1);
|
|
|
|
/// // print an styled object directly.
|
|
|
|
/// println!("{}", paint("I am colored green").with(Color::Green));
|
2018-01-10 06:36:48 +11:00
|
|
|
///
|
2018-01-04 00:43:54 +11:00
|
|
|
/// ```
|
2018-01-07 07:31:14 +11:00
|
|
|
pub fn with(mut self, foreground_color: Color) -> StyledObject<D> {
|
2018-01-04 00:43:54 +11:00
|
|
|
self.object_style = self.object_style.fg(foreground_color);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-01-28 04:26:08 +11:00
|
|
|
/// Set the background of the styled object to the passed `Color`
|
2018-01-07 07:31:14 +11:00
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
2018-01-28 04:26:08 +11:00
|
|
|
/// ```rust
|
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use self::crossterm::style::{paint,Color};
|
2018-01-07 07:31:14 +11:00
|
|
|
///
|
2018-01-28 04:26:08 +11:00
|
|
|
/// // create an styled object with the background color red.
|
|
|
|
/// let styledobject = paint("I am colored red").on(Color::Red);
|
|
|
|
/// // create an styled object with the background color blue.
|
|
|
|
/// let styledobject1 = paint("I am colored blue").on(Color::Blue);
|
|
|
|
///
|
|
|
|
/// // print the styledobjects
|
|
|
|
/// println!("{}", styledobject);
|
|
|
|
/// println!("{}", styledobject1);
|
|
|
|
/// // print an styled object directly.
|
|
|
|
/// println!("{}", paint("I am colored green").on(Color::Green))
|
2018-01-10 06:36:48 +11:00
|
|
|
///
|
2018-01-04 00:43:54 +11:00
|
|
|
/// ```
|
2018-01-07 07:31:14 +11:00
|
|
|
pub fn on(mut self, background_color: Color) -> StyledObject<D> {
|
2018-01-04 00:43:54 +11:00
|
|
|
self.object_style = self.object_style.bg(background_color);
|
|
|
|
self
|
|
|
|
}
|
2018-01-26 04:26:08 +11:00
|
|
|
|
2018-01-28 04:26:08 +11:00
|
|
|
/// Set the attribute of an styled object to the passed `Attribute`
|
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use self::crossterm::style::{paint,Attribute};
|
2018-01-28 04:26:08 +11:00
|
|
|
///
|
|
|
|
/// println!("{}", paint("Bold").attr(Attribute::Bold));
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
#[cfg(unix)]
|
2018-01-26 04:26:08 +11:00
|
|
|
pub fn attr(mut self, attr: Attribute) -> StyledObject<D>
|
|
|
|
{
|
2018-01-28 04:26:08 +11:00
|
|
|
&self.object_style.add_attr(attr);
|
2018-01-26 04:26:08 +11:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-01-28 04:26:08 +11:00
|
|
|
/// Increase the font intensity.
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn bold(self) -> StyledObject<D> { self.attr(Attribute::Bold) }
|
|
|
|
/// Faint (decreased intensity) (Not widely supported).
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn dim(self) -> StyledObject<D> { self.attr(Attribute::Dim) }
|
|
|
|
/// Make the font italic (Not widely supported; Sometimes treated as inverse).
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn italic(self) -> StyledObject<D> { self.attr(Attribute::Italic) }
|
|
|
|
/// Underline font.
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn underlined(self) -> StyledObject<D> { self.attr(Attribute::Underlined) }
|
|
|
|
/// Slow Blink (less than 150 per minute; not widely supported).
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn slow_blink(self) -> StyledObject<D> { self.attr(Attribute::SlowBlink) }
|
|
|
|
/// Rapid Blink (MS-DOS ANSI.SYS; 150+ per minute; not widely supported).
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn rapid_blink(self) -> StyledObject<D> { self.attr(Attribute::RapidBlink) }
|
|
|
|
/// Swap foreground and background colors.
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn reverse(self) -> StyledObject<D> { self.attr(Attribute::Reverse) }
|
|
|
|
/// Hide text (Not widely supported).
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn hidden(self) -> StyledObject<D> { self.attr(Attribute::Hidden) }
|
|
|
|
/// Characters legible, but marked for deletion. Not widely supported.
|
|
|
|
#[cfg(unix)]#[inline(always)] pub fn crossed_out(self) -> StyledObject<D> { self.attr(Attribute::CrossedOut) }
|
2018-01-04 00:43:54 +11:00
|
|
|
}
|
|
|
|
|
2018-01-07 07:31:14 +11:00
|
|
|
/// This is used to make StyledObject able to be displayed.
|
2018-01-10 06:36:48 +11:00
|
|
|
/// This macro will set the styles stored in Styled Object
|
2018-01-07 07:31:14 +11:00
|
|
|
macro_rules! impl_fmt
|
|
|
|
{
|
|
|
|
($name:ident) => {
|
|
|
|
impl<D: fmt::$name> fmt::$name for StyledObject<D> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
|
|
|
{
|
2018-06-10 05:59:43 +10:00
|
|
|
let mut colored_terminal = super::super::color(self.screen_manager.clone());
|
2018-01-07 07:31:14 +11:00
|
|
|
let mut reset = true;
|
|
|
|
|
|
|
|
if let Some(bg) = self.object_style.bg_color
|
|
|
|
{
|
|
|
|
colored_terminal.set_bg(bg);
|
|
|
|
reset = true;
|
|
|
|
}
|
|
|
|
if let Some(fg) = self.object_style.fg_color
|
|
|
|
{
|
|
|
|
colored_terminal.set_fg(fg);
|
|
|
|
reset = true;
|
|
|
|
}
|
2018-01-26 04:26:08 +11:00
|
|
|
|
|
|
|
#[cfg(unix)]
|
2018-01-28 04:26:08 +11:00
|
|
|
for attr in self.object_style.attrs.iter() {
|
|
|
|
write!(f, csi!("{}m"), *attr as i16);
|
2018-01-26 04:26:08 +11:00
|
|
|
reset = true;
|
|
|
|
}
|
|
|
|
|
2018-01-07 07:31:14 +11:00
|
|
|
fmt::$name::fmt(&self.content, f)?;
|
2018-06-10 05:59:43 +10:00
|
|
|
|
2018-06-10 07:19:02 +10:00
|
|
|
let mutex = &self.screen_manager;
|
2018-06-10 05:59:43 +10:00
|
|
|
{
|
|
|
|
let mut screen = mutex.lock().unwrap();
|
|
|
|
screen.stdout().flush().expect("Flush stdout failed");
|
|
|
|
}
|
2018-01-07 07:31:14 +11:00
|
|
|
|
|
|
|
if reset
|
|
|
|
{
|
|
|
|
colored_terminal.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 00:43:54 +11:00
|
|
|
|
2018-01-07 07:31:14 +11:00
|
|
|
impl_fmt!(Debug);
|
|
|
|
impl_fmt!(Display);
|