handle long lines in status/footer

This commit is contained in:
rabite 2019-03-20 13:58:59 +01:00
parent c2297ab494
commit 9a711bbe96
6 changed files with 53 additions and 20 deletions

View File

@ -60,6 +60,10 @@ impl Coordinates {
(self.position.0).1 = y;
}
pub fn xsize_u(&self) -> usize {
self.size.size_u().0
}
pub fn xsize(&self) -> u16 {
self.size.xsize()
}
@ -115,7 +119,7 @@ impl Size {
}
pub fn size_u(&self) -> (usize, usize) {
let (xsize, ysize) = self.0;
(xsize as usize, ysize as usize)
((xsize-1) as usize, (ysize-1) as usize)
}
pub fn xsize(&self) -> u16 {
(self.0).0
@ -131,7 +135,7 @@ impl Position {
}
pub fn position_u(&self) -> (usize, usize) {
let (xpos, ypos) = self.0;
(xpos as usize, ypos as usize)
((xpos-1) as usize, (ypos-1) as usize)
}
pub fn x(&self) -> u16 {
(self.0).0

View File

@ -69,9 +69,14 @@ pub enum HError {
WidgetUndefinedKeyError{key: Key},
#[fail(display = "Terminal has been resized!")]
TerminalResizedError,
#[fail(display = "{}", _0)]
Log(String)
}
impl HError {
pub fn log(log: String) -> HResult<()> {
Err(HError::Log(log))
}
pub fn quit() -> HResult<()> {
Err(HError::Quit)
}

View File

@ -44,15 +44,21 @@ impl Foldable for LogEntry {
impl From<&HError> for LogEntry {
fn from(from: &HError) -> LogEntry {
let time: DateTime<Local> = Local::now();
let logcolor = match from {
HError::Log(_) => term::normal_color(),
_ => term::color_red()
};
let description = format!("{}{}{}: {}",
term::color_green(),
time.format("%F %R"),
term::color_red(),
logcolor,
from).lines().take(1).collect();
let mut content = format!("{}{}{}: {}\n",
term::color_green(),
time.format("%F %R"),
term::color_red(),
logcolor,
from);
@ -93,7 +99,7 @@ impl FoldableWidgetExt for ListView<Vec<LogEntry>> {
fn render_header(&self) -> HResult<String> {
let (xsize, _) = self.core.coordinates.size_u();
let current = self.current_fold().unwrap_or(0);
let current = self.current_fold().map(|n| n+1).unwrap_or(0);
let num = self.content.len();
let hint = format!("{} / {}", current, num);
let hint_xpos = xsize - hint.len();
@ -118,12 +124,17 @@ impl FoldableWidgetExt for ListView<Vec<LogEntry>> {
let hint_xpos = xsize - line_hint.len();
let hint_ypos = ysize + ypos + 1;
let footer = format!("LogEntry: {}{}{}{}{}",
description,
let sized_description = term::sized_string_u(&description,
xsize
- (line_hint.len()+2));
let footer = format!("{}{}{}{}{}",
sized_description,
term::reset(),
term::status_bg(),
term::goto_xy_u(hint_xpos, hint_ypos),
line_hint);
Ok(footer)
} else { Ok("No log entries".to_string()) }
}

View File

@ -12,6 +12,7 @@ use crate::listview::{Listable, ListView};
use crate::textview::TextView;
use crate::widget::{Widget, Events, WidgetCore};
use crate::coordinates::Coordinates;
use crate::dirty::Dirtyable;
use crate::hbox::HBox;
use crate::preview::WillBeWidget;
use crate::fail::{HResult, HError, ErrorLog};
@ -90,12 +91,11 @@ impl Process {
format!("{}{}", term::color_red(), proc_status)
};
let status = format!("Process: {}:{} exited {}{}{} with status: {}",
let status = format!("Process: {}:{} exited {}{} with status: {}",
cmd,
pid,
color_success,
term::reset(),
term::status_bg(),
term::normal_color(),
color_status);
sender.send(Events::Status(status))?;
}
@ -113,6 +113,10 @@ impl Listable for ListView<Vec<Process>> {
self.render_proc(proc).unwrap()
}).collect()
}
fn on_refresh(&mut self) -> HResult<()> {
self.core.set_dirty();
Ok(())
}
}
impl ListView<Vec<Process>> {
@ -385,6 +389,7 @@ impl Widget for ProcView {
fn render_footer(&self) -> HResult<String> {
let listview = self.get_listview();
let selection = listview.get_selection();
let xsize = self.core.coordinates.xsize_u();
if let Some(proc) = listview.content.get(selection) {
let cmd = &proc.cmd;
@ -409,7 +414,7 @@ impl Widget for ProcView {
}
} else { "wtf".to_string() };
let procinfo = format!("Process: {}:{} exited {}{}{} with status: {}",
let procinfo = format!("{}:{} exited {}{}{} with status: {}",
cmd,
pid,
color_success,
@ -419,7 +424,7 @@ impl Widget for ProcView {
procinfo
} else { "still running".to_string() };
let footer = format!("{}: {}", cmd, procinfo);
let footer = term::sized_string_u(&procinfo, xsize);
Ok(footer)
} else { Ok("No proccesses".to_string()) }

View File

@ -163,9 +163,13 @@ fn is_ansi(ansi_pos: &Vec<(usize, usize)>, char_pos: &usize) -> bool {
fn ansi_len_at(ansi_pos: &Vec<(usize, usize)>, char_pos: &usize) -> usize {
ansi_pos.iter().fold(0, |len, (start, end)| {
if char_pos >= end {
len + (end-start)
} else { len }
if char_pos >= start && char_pos <= end {
len + (char_pos - start)
} else if char_pos >= end {
len + (end - start)
} else {
len
}
})
}
@ -174,18 +178,19 @@ pub fn sized_string_u(string: &str, xsize: usize) -> String {
(m.start(), m.end())
}).collect();
let sized = string.chars().enumerate().fold("".to_string(), |acc, (i, ch)| {
let sized = string.chars().fold(String::new(), |acc, ch| {
let width: usize = unicode_width::UnicodeWidthStr::width_cjk(acc.as_str());
let ansi_len = ansi_len_at(&ansi_pos, &i);
let ansi_len = ansi_len_at(&ansi_pos, &acc.len());
let unprinted = acc.len() - width;
if width >= xsize as usize + ansi_len {
if width + unprinted >= xsize + ansi_len + 1{
acc
} else {
acc + &ch.to_string()
}
});
let ansi_len = ansi_len_at(&ansi_pos, &(sized.len().saturating_sub(1)));
let ansi_len = ansi_len_at(&ansi_pos, &sized.len());
let padded = format!("{:padding$}", sized, padding=xsize + ansi_len + 1);
padded
}

View File

@ -373,9 +373,12 @@ pub trait Widget {
}
fn show_status(&self, status: &str) -> HResult<()> {
let xsize = self.get_core()?.coordinates.xsize_u();
let sized_status = term::sized_string_u(status, xsize);
HError::log(status.to_string()).log();
{
let mut status_content = self.get_core()?.status_bar_content.lock()?;
*status_content = Some(status.to_string());
*status_content = Some(sized_status);
}
self.draw_status()?;
Ok(())