diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-02-13 11:30:04 -0500 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-02-13 11:30:04 -0500 |
commit | 44062708b711eac060a4d14e20d502a018c11180 (patch) | |
tree | ac24333e82a730bec4842107c147557cded91222 /src/ui/widgets | |
parent | 35b15cdea61aa7bc36de1700d66b13a8545b6004 (diff) |
clean up long/multiline textfields
- now make use of cursor instead of trying to set the style
of selected text to REVERSED
Diffstat (limited to 'src/ui/widgets')
-rw-r--r-- | src/ui/widgets/tui_text.rs | 126 | ||||
-rw-r--r-- | src/ui/widgets/tui_worker.rs | 4 |
2 files changed, 43 insertions, 87 deletions
diff --git a/src/ui/widgets/tui_text.rs b/src/ui/widgets/tui_text.rs index 6d726c5..326ca6f 100644 --- a/src/ui/widgets/tui_text.rs +++ b/src/ui/widgets/tui_text.rs @@ -5,15 +5,7 @@ use tui::widgets::Widget; use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; #[derive(Clone, Debug)] -struct IndexInfo { - pub index: usize, - pub x: usize, - pub y: usize, - pub c: char, -} - -#[derive(Clone, Debug)] -struct LineInfo { +pub struct LineInfo { pub start: usize, pub end: usize, pub width: usize, @@ -24,93 +16,61 @@ pub struct TuiMultilineText<'a> { _width: usize, _lines: Vec<LineInfo>, _style: Style, - _cursor_style: Style, - _index_info: Option<IndexInfo>, } impl<'a> TuiMultilineText<'a> { - pub fn new(s: &'a str, area_width: usize, index: Option<usize>) -> Self { + pub fn new(s: &'a str, area_width: usize) -> Self { + // TODO: This is a very hacky way of doing it and I would like + // to clean this up more + + let default_style = Style::default().fg(Color::Reset).bg(Color::Reset); + let cursor_style = Style::default() + .fg(Color::White) + .add_modifier(Modifier::REVERSED); + + let s_width = s.width(); + if s_width < area_width { + return Self { + _s: s, + _lines: vec![LineInfo { start: 0, end: s.len(), width: s_width }], + _width: area_width, + _style: default_style, + }; + } + let filter = |(i, c): (usize, char)| { let w = c.width()?; Some((i, c, w)) }; - // TODO: This is a very hacky way of doing it and I would like - // to clean this up more + let mut lines = Vec::with_capacity(s.len() / area_width); - let mut lines = Vec::with_capacity(s.len() / area_width + 1); let mut start = 0; - let mut end = 0; let mut line_width = 0; - for (i, c, w) in s.char_indices().filter_map(filter) { - end = i + c.len_utf8(); if line_width + w < area_width { line_width += w; continue; } lines.push(LineInfo { start, - end, - width: line_width, - }); - start = end; - line_width = 0; - } - if start < end { - lines.push(LineInfo { - start, - end: end, + end: i, width: line_width, }); + line_width = w; + start = i; } + lines.push(LineInfo { + start, + end: s.len(), + width: s[start..s.len()].width(), + }); - let mut index_info = None; - if let Some(idx) = index { - let (row, line_info) = lines - .iter() - .enumerate() - .find(|(_, li)| li.start <= idx && li.end > idx) - .unwrap(); - - let mut s_width = 0; - let substr = &s[line_info.start..line_info.end]; - for (i, c, w) in substr.char_indices().filter_map(filter) { - if line_info.start + i <= idx { - s_width += w; - continue; - } - index_info = Some(IndexInfo { - index: idx, - x: s_width, - y: row, - c: c, - }); - break; - } - - if let None = index_info { - let s_width = substr.width(); - index_info = Some(IndexInfo { - index: idx, - x: s_width % area_width, - y: row + s_width / area_width, - c: ' ', - }); - } - } - - let default_style = Style::default().fg(Color::Reset).bg(Color::Reset); - let cursor_style = Style::default() - .fg(Color::White) - .add_modifier(Modifier::REVERSED); Self { _s: s, _lines: lines, _width: area_width, _style: default_style, - _cursor_style: cursor_style, - _index_info: index_info, } } @@ -118,19 +78,22 @@ impl<'a> TuiMultilineText<'a> { self._width } - pub fn len(&self) -> usize { - match self._index_info.as_ref() { - Some(index_info) if index_info.y >= self._lines.len() => index_info.y + 1, - _ => self._lines.len(), + pub fn height(&self) -> usize { + if self._lines[self._lines.len() - 1].width >= self.width() { + return self.len() + 1; } + self.len() + } + pub fn len(&self) -> usize { + self._lines.len() } - pub fn style(&mut self, style: Style) { - self._style = style; + pub fn iter(&self) -> impl Iterator<Item = &LineInfo> { + self._lines.iter() } - pub fn cursor_style(&mut self, style: Style) { - self._cursor_style = style; + pub fn style(&mut self, style: Style) { + self._style = style; } } @@ -153,14 +116,5 @@ impl<'a> Widget for TuiMultilineText<'a> { &self._s[line_info.start..line_info.end], self._style, ); - - if let Some(index_info) = self._index_info { - buf.set_string( - area_left + index_info.x as u16, - area_top + index_info.y as u16, - index_info.c.to_string(), - self._cursor_style, - ); - } } } diff --git a/src/ui/widgets/tui_worker.rs b/src/ui/widgets/tui_worker.rs index cc76cf6..3033bb1 100644 --- a/src/ui/widgets/tui_worker.rs +++ b/src/ui/widgets/tui_worker.rs @@ -32,6 +32,8 @@ impl<'a> Widget for TuiWorker<'a> { }; TuiTopBar::new(self.context, curr_tab.pwd()).render(rect, buf); + // TODO: could be styled better + match self.context.worker_ref() { Some(io_obs) => { if let Some(progress) = io_obs.progress.as_ref() { @@ -59,7 +61,7 @@ impl<'a> Widget for TuiWorker<'a> { for (i, worker) in self.context.worker_iter().enumerate() { let op_str = match worker.kind() { FileOp::Copy => "Copy", - FileOp::Cut => "Cut", + FileOp::Cut => "Move", }; let msg = format!( "{:02} {} {} items {:?} -> {:?}", |