use std;
use log;
use pancurses;
use easycurses;
use env_logger;
#[cfg(target_os = "linux")]
use ncurses;
#[cfg(target_os = "windows")]
use pdcurses;
use curses_utils::*;
const LOG_LEVEL : log::LevelFilter = log::LevelFilter::Trace;
const LOG_FILENAME : &str = "example.log";
fn main() {
use easycurses::{Color, ColorPair, Input};
{ let log_file = Box::new (std::fs::File::create (LOG_FILENAME).unwrap());
env_logger::Builder::new()
.filter_level (LOG_LEVEL)
.parse_default_env()
.target (env_logger::Target::Pipe (log_file))
.init();
println!("logging output to {LOG_FILENAME:?}");
log::info!("example log begin");
}
let mut curses = Curses::default();
let image = {
let colors = image_color_pair_load_bmp24 ("red.bmp", "example.bmp");
let chars = image_ascii_load ("example.txt");
image_chtype (&colors, &chars)
};
let image2 = image_color_halftone_load_bmp24 ("halftone.bmp");
curses.log_info();
let mut iter : u64 = 0;
let draw = |curses : &mut Curses, iter : &mut u64| {
use pancurses::ToChtype;
let (attrs, colors) = curses.win().attrget();
log::trace!("window colors: {colors:?}");
let clear_color = color_pair (colors as pancurses::chtype);
curses.clear();
let bg_ch = match *iter % 4 {
0 => '|'.to_chtype(),
1 => '/'.to_chtype(),
2 => '-'.to_chtype(),
3 => '\\'.to_chtype(),
_ => unreachable!()
};
pancurses_ok!(curses.win().bkgd (bg_ch | attrs | clear_color));
curses.set_color_pair (ColorPair::new (Color::Black, Color::White));
pancurses_ok!(curses.draw_box ('#'.to_chtype(), (5,5), (8,11)));
let rect_color : pancurses::chtype =
color_pair_attr (Color::Red, Color::White);
let fill_color : pancurses::chtype =
color_pair_attr (Color::White, Color::Green);
curses.draw_rect ('O'.to_chtype() | rect_color, ' '.to_chtype() | fill_color,
(10,5), (15,15), 1, 2);
pancurses_ok!(curses.win().attrset (attrs));
let (row, col) = curses.print_centered ("Welcome\n \
'q' or 'Q' to quit\n \
'B' to toggle bold\n \
'd' to toggle dim\n \
'r' for red background\n \
'g' for green background\n \
'b' for blue background\n \
'c' for cyan background\n \
'y' for yellow background\n \
'm' for magenta background\n \
'k' for black background\n \
'w' for white background\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", None, None);
{ use pancurses::*;
curses.move_rc (row + 13, col);
if !curses.print ("test test test test") {
log::warn!("print failed! (row, col): {:?}", (row + 13, col));
}
let fill_color : chtype = color_pair_attr (Color::White, Color::Blue);
curses.draw_rect (
' '.to_chtype() | fill_color,
' '.to_chtype() | fill_color,
(row + 13, col),
(row + 24, col + 23), 0,0);
curses.win().bkgdset (' '.to_chtype() | fill_color);
let mut i = 14;
macro_rules! display {
($e:expr) => {
curses.move_rc (row + i, col + 1);
let result = curses.print (
format!("{:20} {}", [stringify!($e), ":"].concat(), $e));
if !result {
log::warn!("print failed! (row, col): {:?}", (row + i, col + 1));
}
i += 1;
}
}
macro_rules! bits {
($e:expr) => {
curses.move_rc (row + i, col + 1);
let result = curses.print (
format!("{:20} {:032b}", [stringify!($e), ":"].concat(), $e));
if !result {
log::warn!("print failed! (row, col): {:?}", (row + i, col + 1));
}
i += 1;
}
}
bits!(0xFF00_FF00u32);
bits!(attrs);
bits!(colors);
bits!(b'a');
bits!('a'.to_chtype());
bits!(COLOR_BLUE);
bits!(ATTRIBUTE_MASK);
bits!(A_NORMAL);
bits!(A_BLINK);
bits!(A_BOLD);
bits!(A_CHARTEXT);
bits!(A_COLOR);
bits!(A_DIM);
bits!(A_ITALIC);
#[cfg(target_os = "linux")]
{
display!(ncurses::LINES());
display!(ncurses::COLS());
}
#[cfg(target_os = "windows")]
#[allow(static_mut_refs)]
unsafe {
display!(pdcurses::LINES);
display!(pdcurses::COLS);
}
assert!(i >= 0);
curses.win().bkgdset (' '.to_chtype() | attrs);
}
const SHIFTL : i32 = 7;
let mut i = -4;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_ULCORNER())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_LLCORNER())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_URCORNER())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_LRCORNER())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_RTEE())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_LTEE())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_BTEE())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_TTEE())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_HLINE())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_VLINE())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_PLUS())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_S1())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_S3())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_S7())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_S9())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_CKBOARD())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_DIAMOND())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_DEGREE())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_BULLET())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_LARROW())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_RARROW())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_DARROW())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_UARROW())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_BOARD())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_LANTERN())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_BLOCK())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_LEQUAL())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_GEQUAL())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_NEQUAL())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_PI())); i += 1;
curses.move_rc (row + i, col.saturating_sub (SHIFTL));
pancurses_warn_ok!(curses.win().addch (pancurses::ACS_STERLING()));
curses.draw_image_chtype ((8, 36), &image);
curses.draw_image_chtype ((20, 36), &image2);
pancurses_ok!(curses.draw_border_default());
#[cfg(target_os = "linux")]
let (lines, cols) = (ncurses::LINES(), ncurses::COLS());
#[cfg(target_os = "windows")]
let (lines, cols) = unsafe { (pdcurses::LINES, pdcurses::COLS) };
let s = "bottom line";
#[expect(clippy::cast_possible_truncation)]
#[expect(clippy::cast_possible_wrap)]
curses.move_rc (lines-1, cols - s.len() as i32 - 1);
assert!(curses.print (s));
pancurses_ok!(curses.win().mvaddch (lines-1, cols-2,
b'F' as pancurses::chtype));
pancurses_ok!(curses.win()
.mvchgat (lines-1, cols-1, 1, b'a' as pancurses::chtype, 5));
assert!(curses.refresh());
*iter += 1;
};
draw (&mut curses, &mut iter);
while let Some (input) = curses.getch_wait() {
log::debug!("input: {input:?}");
let (attrs, _color) = curses.win().attrget();
match input {
Input::Character ('B') => {
if attrs & pancurses::A_BOLD > 0 {
curses.set_bold (false);
} else {
curses.set_bold (true);
}
}
Input::Character ('d') => {
if attrs & pancurses::A_DIM > 0 {
curses.win().attroff (pancurses::A_DIM);
} else {
curses.win().attron (pancurses::A_DIM);
}
}
Input::Character ('q') |
Input::Character ('Q') => break,
Input::Character ('r') =>
curses.set_color_pair (ColorPair::new (Color::White, Color::Red)),
Input::Character ('g') =>
curses.set_color_pair (ColorPair::new (Color::White, Color::Green)),
Input::Character ('b') =>
curses.set_color_pair (ColorPair::new (Color::White, Color::Blue)),
Input::Character ('c') =>
curses.set_color_pair (ColorPair::new (Color::White, Color::Cyan)),
Input::Character ('y') =>
curses.set_color_pair (ColorPair::new (Color::White, Color::Yellow)),
Input::Character ('m') =>
curses.set_color_pair (ColorPair::new (Color::White, Color::Magenta)),
Input::Character ('k') =>
curses.set_color_pair (ColorPair::new (Color::White, Color::Black)),
Input::Character ('w') =>
curses.set_color_pair (ColorPair::new (Color::Black, Color::White)),
_ => {}
}
draw (&mut curses, &mut iter);
}
log::info!("example log end");
}