Clean up rendering a bit
This commit is contained in:
parent
d6d8397683
commit
01ec2c67c1
3 changed files with 95 additions and 79 deletions
|
|
@ -1,22 +1,15 @@
|
||||||
mod blocks;
|
mod blocks;
|
||||||
mod layout;
|
mod layout;
|
||||||
|
mod render;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use crossterm::event::{KeyCode, KeyEvent};
|
use crossterm::event::{KeyCode, KeyEvent};
|
||||||
use crossterm::style::ContentStyle;
|
|
||||||
use toss::frame::{Frame, Pos, Size};
|
use toss::frame::{Frame, Pos, Size};
|
||||||
|
|
||||||
use crate::store::{Msg, MsgStore};
|
use crate::store::{Msg, MsgStore};
|
||||||
|
|
||||||
use self::blocks::{BlockBody, Blocks};
|
|
||||||
use self::util::{
|
|
||||||
after_indent, style_indent, style_indent_inverted, style_placeholder, style_time,
|
|
||||||
style_time_inverted, INDENT, INDENT_WIDTH, PLACEHOLDER, TIME_EMPTY, TIME_FORMAT, TIME_WIDTH,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::Cursor;
|
use super::Cursor;
|
||||||
|
|
||||||
pub struct TreeView<M: Msg> {
|
pub struct TreeView<M: Msg> {
|
||||||
|
|
@ -33,74 +26,6 @@ impl<M: Msg> TreeView<M> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_time(frame: &mut Frame, x: i32, y: i32, time: Option<DateTime<Utc>>, cursor: bool) {
|
|
||||||
let pos = Pos::new(x, y);
|
|
||||||
|
|
||||||
let style = if cursor {
|
|
||||||
style_time_inverted()
|
|
||||||
} else {
|
|
||||||
style_time()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(time) = time {
|
|
||||||
let time = format!("{}", time.format(TIME_FORMAT));
|
|
||||||
frame.write(pos, &time, style);
|
|
||||||
} else {
|
|
||||||
frame.write(pos, TIME_EMPTY, style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_indent(frame: &mut Frame, x: i32, y: i32, indent: usize, cursor: bool) {
|
|
||||||
for i in 0..indent {
|
|
||||||
let pos = Pos::new(x + after_indent(i), y);
|
|
||||||
|
|
||||||
let style = if cursor {
|
|
||||||
style_indent_inverted()
|
|
||||||
} else {
|
|
||||||
style_indent()
|
|
||||||
};
|
|
||||||
|
|
||||||
frame.write(pos, INDENT, style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_layout(&mut self, frame: &mut Frame, pos: Pos, size: Size, layout: &Blocks<M::Id>) {
|
|
||||||
for block in &layout.blocks {
|
|
||||||
// Draw rest of block
|
|
||||||
match &block.body {
|
|
||||||
BlockBody::Msg(msg) => {
|
|
||||||
let nick_width = frame.width(&msg.nick) as i32;
|
|
||||||
for (i, line) in msg.lines.iter().enumerate() {
|
|
||||||
let y = pos.y + block.line + i as i32;
|
|
||||||
if y < 0 || y >= size.height as i32 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::render_indent(frame, pos.x, y, block.indent, block.cursor);
|
|
||||||
let after_indent =
|
|
||||||
pos.x + (TIME_WIDTH + INDENT_WIDTH * block.indent) as i32;
|
|
||||||
if i == 0 {
|
|
||||||
Self::render_time(frame, pos.x, y, block.time, block.cursor);
|
|
||||||
let nick = format!("[{}]", msg.nick);
|
|
||||||
frame.write(Pos::new(after_indent, y), &nick, ContentStyle::default());
|
|
||||||
} else {
|
|
||||||
Self::render_time(frame, pos.x, y, None, block.cursor);
|
|
||||||
}
|
|
||||||
let msg_x = after_indent + 1 + nick_width + 2;
|
|
||||||
frame.write(Pos::new(msg_x, y), line, ContentStyle::default());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlockBody::Placeholder => {
|
|
||||||
let y = pos.y + block.line;
|
|
||||||
Self::render_time(frame, pos.x, y, block.time, block.cursor);
|
|
||||||
Self::render_indent(frame, pos.x, y, block.indent, block.cursor);
|
|
||||||
let pos = Pos::new(pos.x + after_indent(block.indent), y);
|
|
||||||
frame.write(pos, PLACEHOLDER, style_placeholder());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn move_to_prev_msg<S: MsgStore<M>>(
|
async fn move_to_prev_msg<S: MsgStore<M>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
store: &mut S,
|
store: &mut S,
|
||||||
|
|
@ -168,7 +93,7 @@ impl<M: Msg> TreeView<M> {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
size: Size,
|
size: Size,
|
||||||
) {
|
) {
|
||||||
let layout = self.layout(room, store, cursor, frame, size).await;
|
let blocks = self.layout_blocks(room, store, cursor, frame, size).await;
|
||||||
self.render_layout(frame, pos, size, &layout);
|
Self::render_blocks(frame, pos, size, &blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ impl<M: Msg> TreeView<M> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn layout<S: MsgStore<M>>(
|
pub async fn layout_blocks<S: MsgStore<M>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
room: &str,
|
room: &str,
|
||||||
store: &S,
|
store: &S,
|
||||||
|
|
|
||||||
91
cove-tui/src/chat/tree/render.rs
Normal file
91
cove-tui/src/chat/tree/render.rs
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use crossterm::style::ContentStyle;
|
||||||
|
use toss::frame::{Frame, Pos, Size};
|
||||||
|
|
||||||
|
use crate::store::Msg;
|
||||||
|
|
||||||
|
use super::blocks::{Block, BlockBody, Blocks};
|
||||||
|
use super::util::{
|
||||||
|
self, style_indent, style_indent_inverted, style_placeholder, style_time, style_time_inverted,
|
||||||
|
INDENT, PLACEHOLDER, TIME_EMPTY, TIME_FORMAT,
|
||||||
|
};
|
||||||
|
use super::TreeView;
|
||||||
|
|
||||||
|
fn render_time(frame: &mut Frame, x: i32, y: i32, cursor: bool, time: Option<DateTime<Utc>>) {
|
||||||
|
let pos = Pos::new(x, y);
|
||||||
|
|
||||||
|
let style = if cursor {
|
||||||
|
style_time_inverted()
|
||||||
|
} else {
|
||||||
|
style_time()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(time) = time {
|
||||||
|
let time = format!("{}", time.format(TIME_FORMAT));
|
||||||
|
frame.write(pos, &time, style);
|
||||||
|
} else {
|
||||||
|
frame.write(pos, TIME_EMPTY, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_indent(frame: &mut Frame, x: i32, y: i32, cursor: bool, indent: usize) {
|
||||||
|
for i in 0..indent {
|
||||||
|
let pos = Pos::new(x + util::after_indent(i), y);
|
||||||
|
|
||||||
|
let style = if cursor {
|
||||||
|
style_indent_inverted()
|
||||||
|
} else {
|
||||||
|
style_indent()
|
||||||
|
};
|
||||||
|
|
||||||
|
frame.write(pos, INDENT, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_nick(frame: &mut Frame, x: i32, y: i32, indent: usize, nick: &str) {
|
||||||
|
let nick_pos = Pos::new(x + util::after_indent(indent), y);
|
||||||
|
let nick = format!("[{}]", nick);
|
||||||
|
frame.write(nick_pos, &nick, ContentStyle::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_block<M: Msg>(frame: &mut Frame, pos: Pos, size: Size, block: &Block<M::Id>) {
|
||||||
|
match &block.body {
|
||||||
|
BlockBody::Msg(msg) => {
|
||||||
|
let after_nick = util::after_nick(frame, block.indent, &msg.nick);
|
||||||
|
|
||||||
|
for (i, line) in msg.lines.iter().enumerate() {
|
||||||
|
let y = pos.y + block.line + i as i32;
|
||||||
|
if y < 0 || y >= size.height as i32 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
render_indent(frame, pos.x, y, block.cursor, block.indent);
|
||||||
|
|
||||||
|
if i == 0 {
|
||||||
|
render_time(frame, pos.x, y, block.cursor, block.time);
|
||||||
|
render_nick(frame, pos.x, y, block.indent, &msg.nick);
|
||||||
|
} else {
|
||||||
|
render_time(frame, pos.x, y, block.cursor, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let line_pos = Pos::new(pos.x + after_nick, y);
|
||||||
|
frame.write(line_pos, line, ContentStyle::default());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BlockBody::Placeholder => {
|
||||||
|
let y = pos.y + block.line;
|
||||||
|
render_time(frame, pos.x, y, block.cursor, block.time);
|
||||||
|
render_indent(frame, pos.x, y, block.cursor, block.indent);
|
||||||
|
let pos = Pos::new(pos.x + util::after_indent(block.indent), y);
|
||||||
|
frame.write(pos, PLACEHOLDER, style_placeholder());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: Msg> TreeView<M> {
|
||||||
|
pub fn render_blocks(frame: &mut Frame, pos: Pos, size: Size, layout: &Blocks<M::Id>) {
|
||||||
|
for block in &layout.blocks {
|
||||||
|
render_block::<M>(frame, pos, size, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue