mirror of https://git.meli.delivery/meli/meli
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
7.8 KiB
Rust
268 lines
7.8 KiB
Rust
use std::fmt;
|
|
use cells::{Color, Cell, CellBuffer, CellAccessor};
|
|
use position::Pos;
|
|
|
|
/// The upper and lower boundary char.
|
|
const HORZ_BOUNDARY: char = '─';
|
|
/// The left and right boundary char.
|
|
const VERT_BOUNDARY: char = '│';
|
|
|
|
/// The top-left corner
|
|
const TOP_LEFT_CORNER: char = '┌';
|
|
/// The top-right corner
|
|
const TOP_RIGHT_CORNER: char = '┐';
|
|
/// The bottom-left corner
|
|
const BOTTOM_LEFT_CORNER: char = '└';
|
|
/// The bottom-right corner
|
|
const BOTTOM_RIGHT_CORNER: char = '┘';
|
|
|
|
const LIGHT_VERTICAL_AND_RIGHT: char = '├';
|
|
|
|
const LIGHT_VERTICAL_AND_LEFT: char = '┤';
|
|
|
|
const LIGHT_DOWN_AND_HORIZONTAL: char = '┬';
|
|
|
|
const LIGHT_UP_AND_HORIZONTAL: char = '┴';
|
|
|
|
pub struct Entity {
|
|
//queue: VecDeque,
|
|
pub component: Box<Component>, // more than one?
|
|
}
|
|
|
|
impl fmt::Debug for Entity {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "Entity", )
|
|
}
|
|
}
|
|
|
|
pub trait Component {
|
|
fn draw(&mut self, upper_left: Pos, bottom_right: Pos, grid: &mut CellBuffer);
|
|
fn process_event(&mut self);
|
|
}
|
|
|
|
|
|
///A simple box with borders and no content.
|
|
pub struct BoxPanel {
|
|
}
|
|
|
|
impl Component for BoxPanel {
|
|
fn draw(&mut self, upper_left: Pos, bottom_right: Pos, grid: &mut CellBuffer) {
|
|
grid[upper_left].set_ch('u');
|
|
grid[bottom_right].set_ch('b');
|
|
let width = bottom_right.0 - upper_left.0;
|
|
let height = bottom_right.1 - upper_left.1;
|
|
|
|
grid[upper_left].set_ch('┌');
|
|
grid[(upper_left.0, bottom_right.1)].set_ch(BOTTOM_LEFT_CORNER);
|
|
grid[(bottom_right.0, upper_left.1)].set_ch('┐');
|
|
grid[bottom_right].set_ch('┘');
|
|
for i in upper_left.1 + 1..bottom_right.1 {
|
|
grid[(upper_left.0, i)].set_ch('│');
|
|
grid[(upper_left.0 + width, i)].set_ch('│');
|
|
}
|
|
for i in upper_left.0+1..bottom_right.0 {
|
|
grid[(i, upper_left.1)].set_ch('─');
|
|
grid[(i, upper_left.1 + height)].set_ch('─');
|
|
}
|
|
|
|
let width = bottom_right.0 - upper_left.0;
|
|
let height = bottom_right.1 - upper_left.1;
|
|
}
|
|
fn process_event(&mut self) {
|
|
unimplemented!();
|
|
}
|
|
}
|
|
|
|
/// A horizontally split in half container.
|
|
pub struct HSplit {
|
|
top: Entity,
|
|
bottom: Entity,
|
|
ratio: usize, // bottom/whole height * 100
|
|
}
|
|
|
|
impl HSplit {
|
|
pub fn new(top: Entity, bottom: Entity, ratio: usize) -> Self {
|
|
HSplit {
|
|
top: top,
|
|
bottom: bottom,
|
|
ratio: ratio,
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl Component for HSplit {
|
|
fn draw(&mut self, upper_left: Pos, bottom_right: Pos, grid: &mut CellBuffer) {
|
|
//eprintln!("grid {:?}", grid);
|
|
grid[upper_left].set_ch('u');
|
|
let (a,b) = upper_left;
|
|
grid[(a+1,b)].set_ch('h');
|
|
let width = bottom_right.0 - upper_left.0;
|
|
let height = bottom_right.1 - upper_left.1;
|
|
|
|
let total_rows = bottom_right.1 - upper_left.1;
|
|
let bottom_entity_height = (self.ratio*total_rows )/100;
|
|
let mid = upper_left.1 + total_rows - bottom_entity_height;
|
|
|
|
for i in upper_left.0..bottom_right.0+1 {
|
|
grid[(i, mid)].set_ch('─');
|
|
}
|
|
let _ = self.top.component.draw(upper_left, (bottom_right.0, upper_left.1 + mid-1), grid);
|
|
let _ = self.bottom.component.draw((upper_left.0, upper_left.1 + mid), bottom_right, grid);
|
|
grid[bottom_right].set_ch('b');
|
|
}
|
|
fn process_event(&mut self) {
|
|
unimplemented!();
|
|
}
|
|
}
|
|
|
|
/// A horizontally split in half container.
|
|
pub struct VSplit {
|
|
left: Entity,
|
|
right: Entity,
|
|
ratio: usize, // right/(container width) * 100
|
|
}
|
|
|
|
impl VSplit {
|
|
pub fn new(left: Entity, right: Entity, ratio: usize) -> Self {
|
|
VSplit {
|
|
left: left,
|
|
right: right,
|
|
ratio: ratio,
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl Component for VSplit {
|
|
fn draw(&mut self, upper_left: Pos, bottom_right: Pos, grid: &mut CellBuffer) {
|
|
|
|
eprintln!("Upper left is {:?} and bottom_right is {:?}", upper_left, bottom_right);
|
|
let width = bottom_right.0 - upper_left.0;
|
|
let height = bottom_right.1 - upper_left.1;
|
|
|
|
let total_cols = bottom_right.0 - upper_left.0;
|
|
let right_entity_width = (self.ratio*total_cols )/100;
|
|
let mid = bottom_right.0 - right_entity_width;
|
|
eprintln!("total_cols {:?}, right_entity_width: {:?}, mid: {:?}",total_cols, right_entity_width, mid);
|
|
if (upper_left.1> 1) {
|
|
let c = grid.get(mid, upper_left.1-1).map(|a| a.ch()).unwrap_or_else(|| ' ');
|
|
match c {
|
|
HORZ_BOUNDARY => {
|
|
grid[(mid, upper_left.1-1)].set_ch(LIGHT_DOWN_AND_HORIZONTAL);
|
|
},
|
|
_ => {},
|
|
}
|
|
}
|
|
|
|
for i in upper_left.1..bottom_right.1 {
|
|
grid[(mid, i)].set_ch(VERT_BOUNDARY);
|
|
}
|
|
if (bottom_right.1> 1) {
|
|
let c = grid.get(mid, bottom_right.1-1).map(|a| a.ch()).unwrap_or_else(|| ' ');
|
|
match c {
|
|
HORZ_BOUNDARY => {
|
|
grid[(mid, bottom_right.1+1)].set_ch(LIGHT_UP_AND_HORIZONTAL);
|
|
},
|
|
_ => {},
|
|
}
|
|
}
|
|
let _ = self.left.component.draw(upper_left, (mid-1, bottom_right.1), grid);
|
|
let _ = self.right.component.draw((mid+1, upper_left.1), bottom_right, grid);
|
|
}
|
|
fn process_event(&mut self) {
|
|
unimplemented!();
|
|
}
|
|
}
|
|
|
|
/// A box with a text content.
|
|
pub struct TextBox {
|
|
content: String,
|
|
}
|
|
|
|
impl TextBox {
|
|
pub fn new(s: String) -> Self {
|
|
TextBox {
|
|
content: s,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Component for TextBox {
|
|
fn draw(&mut self, upper_left: Pos, bottom_right: Pos, grid: &mut CellBuffer) {
|
|
let mut x = upper_left.0;
|
|
let mut y = upper_left.1;
|
|
for c in self.content.chars() {
|
|
grid[(x,y)].set_ch(c);
|
|
//eprintln!("printed {} in ({}, {})", c, x, y);
|
|
x += 1;
|
|
if x == bottom_right.0 + 1 {
|
|
x = upper_left.0;
|
|
}
|
|
|
|
if y == bottom_right.1 {
|
|
break;
|
|
}
|
|
}
|
|
//eprintln!("Upper left is {:?} and bottom_right is {:?}", upper_left, bottom_right);
|
|
let width = bottom_right.0 - upper_left.0;
|
|
let height = bottom_right.1 - upper_left.1;
|
|
}
|
|
fn process_event(&mut self) {
|
|
unimplemented!();
|
|
}
|
|
}
|
|
|
|
const max_width: usize = 500;
|
|
|
|
pub struct MailListing {
|
|
cursor_pos: usize,
|
|
length: usize,
|
|
// sorting
|
|
content: CellBuffer,
|
|
unfocused: bool,
|
|
// content (2-d vec of bytes) or Cells?
|
|
// current view on top of content
|
|
// active or not? for key events
|
|
|
|
}
|
|
|
|
impl MailListing {
|
|
pub fn new(length: usize) -> Self {
|
|
MailListing {
|
|
cursor_pos: 0,
|
|
length: length,
|
|
content: CellBuffer::new(max_width, length+1, Cell::with_char(' ')),
|
|
unfocused: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Component for MailListing {
|
|
fn draw(&mut self, upper_left: Pos, bottom_right: Pos, grid: &mut CellBuffer) {
|
|
let mut height = 0;
|
|
let mut stripe = false;
|
|
for y in upper_left.1..bottom_right.1 {
|
|
if height == self.length {
|
|
/* for loop */
|
|
for _y in y..bottom_right.1 {
|
|
for x in upper_left.0..bottom_right.0 {
|
|
grid[(x,y)].set_ch(' ');
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
for x in upper_left.0..bottom_right.0 {
|
|
//grid[(x,y)].set_ch(self.content[(x-upper_left.0+1, y-upper_left.1+1)].ch());
|
|
grid[(x,y)].set_ch(if stripe { 't' } else { 'f'} );
|
|
grid[(x,y)].set_bg(if stripe { Color::Byte(246) } else {Color::Default });
|
|
}
|
|
stripe = if stripe { false } else { true };
|
|
height +1 ;
|
|
}
|
|
}
|
|
fn process_event(&mut self) {
|
|
unimplemented!();
|
|
}
|
|
}
|