summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2021-09-05 19:05:20 +0200
committerCanop <cano.petrole@gmail.com>2021-09-05 19:05:20 +0200
commitc2848b6bd433a4e623456ecf217d0cf9843bd491 (patch)
tree096077182d2a94cbff707a47f9bb79f8f396de3e /src
parent1c321d4f287b3752dea62fa250ccc54cb16e8f7c (diff)
upgrade termimad to 0.16
Diffstat (limited to 'src')
-rw-r--r--src/browser/browser_state.rs10
-rw-r--r--src/command/panel_input.rs17
-rw-r--r--src/display/displayable_tree.rs11
-rw-r--r--src/filesystems/filesystems_state.rs2
-rw-r--r--src/help/help_content.rs1
-rw-r--r--src/help/help_state.rs18
-rw-r--r--src/hex/hex_view.rs7
-rw-r--r--src/stage/stage_state.rs5
-rw-r--r--src/syntactic/syntactic_view.rs2
-rw-r--r--src/tree/tree.rs104
10 files changed, 98 insertions, 79 deletions
diff --git a/src/browser/browser_state.rs b/src/browser/browser_state.rs
index dccb3b5..34a19c5 100644
--- a/src/browser/browser_state.rs
+++ b/src/browser/browser_state.rs
@@ -86,8 +86,8 @@ impl BrowserState {
self.tree.root()
}
- pub fn page_height(screen: Screen) -> i32 {
- i32::from(screen.height) - 2
+ pub fn page_height(screen: Screen) -> usize {
+ screen.height as usize - 2 // br shouldn't be displayed when the screen is smaller
}
/// return a reference to the currently displayed tree, which
@@ -243,7 +243,7 @@ impl PanelState for BrowserState {
_screen: Screen,
_con: &AppContext,
) -> Result<CmdResult, ProgramError> {
- self.displayed_tree_mut().try_select_y(y as i32);
+ self.displayed_tree_mut().try_select_y(y as usize);
Ok(CmdResult::Keep)
}
@@ -373,14 +373,14 @@ impl PanelState for BrowserState {
}
Internal::page_down => {
let tree = self.displayed_tree_mut();
- if !tree.try_scroll(page_height, page_height) {
+ if !tree.try_scroll(page_height as i32, page_height) {
tree.try_select_last(page_height);
}
CmdResult::Keep
}
Internal::page_up => {
let tree = self.displayed_tree_mut();
- if !tree.try_scroll(-page_height, page_height) {
+ if !tree.try_scroll(page_height as i32 * -1, page_height) {
tree.try_select_first();
}
CmdResult::Keep
diff --git a/src/command/panel_input.rs b/src/command/panel_input.rs
index ff0c9cd..ff98b32 100644
--- a/src/command/panel_input.rs
+++ b/src/command/panel_input.rs
@@ -16,8 +16,7 @@ use {
termimad::{Area, Event, InputField},
};
-/// wrap the input of a panel,
-/// receive events and make commands
+/// Wrap the input of a panel, receive events and make commands
pub struct PanelInput {
pub input_field: InputField,
tab_cycle_count: usize,
@@ -35,7 +34,7 @@ impl PanelInput {
}
pub fn set_content(&mut self, content: &str) {
- self.input_field.set_content(content);
+ self.input_field.set_str(content);
}
pub fn get_content(&self) -> String {
@@ -51,14 +50,14 @@ impl PanelInput {
panel_skin: &PanelSkin,
) -> Result<(), ProgramError> {
self.input_field.set_normal_style(panel_skin.styles.input.clone());
- self.input_field.focused = active && mode == Mode::Input;
+ self.input_field.set_focus(active && mode == Mode::Input);
if mode == Mode::Command && active {
queue!(w, cursor::MoveTo(area.left, area.top))?;
panel_skin.styles.mode_command_mark.queue_str(w, "C")?;
area.width -= 1;
area.left += 1;
}
- self.input_field.area = area;
+ self.input_field.set_area(area);
self.input_field.display_on(w)?;
Ok(())
}
@@ -95,7 +94,7 @@ impl PanelInput {
if self.input_field.get_content().is_empty() {
false
} else {
- self.input_field.set_content("");
+ self.input_field.clear();
true
}
}
@@ -189,7 +188,7 @@ impl PanelInput {
self.tab_cycle_count = 0;
if let Some(raw) = self.input_before_cycle.take() {
// we cancel the tab cycling
- self.input_field.set_content(&raw);
+ self.input_field.set_str(&raw);
self.input_before_cycle = None;
return Command::from_raw(raw, false);
} else if con.modal && mode == Mode::Input {
@@ -200,7 +199,7 @@ impl PanelInput {
};
} else {
// general back command
- self.input_field.set_content("");
+ self.input_field.clear();
let internal = Internal::back;
return Command::Internal {
internal,
@@ -247,7 +246,7 @@ impl PanelInput {
.as_ref()
.map_or(raw, |s| s.to_string());
raw.push_str(&added);
- self.input_field.set_content(&raw);
+ self.input_field.set_str(&raw);
return Command::from_raw(raw, false);
} else {
return Command::None;
diff --git a/src/display/displayable_tree.rs b/src/display/displayable_tree.rs
index 7e5fd35..6bd5b72 100644
--- a/src/display/displayable_tree.rs
+++ b/src/display/displayable_tree.rs
@@ -25,7 +25,7 @@ use {
file_size,
git2::Status,
std::io::Write,
- termimad::{CompoundStyle, ProgressBar},
+ termimad::{Area, CompoundStyle, ProgressBar},
};
/// A tree wrapper which can be used either
@@ -451,7 +451,12 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> {
let tree = self.tree;
let total_size = tree.total_sum();
let scrollbar = if self.in_app {
- self.area.scrollbar(tree.scroll, tree.lines.len() as i32 - 1)
+ termimad::compute_scrollbar(
+ tree.scroll,
+ tree.lines.len() - 1, // the root line isn't scrolled
+ self.area.height - 1, // the scrollbar doesn't cover the first line
+ self.area.top + 1,
+ )
} else {
None
};
@@ -602,7 +607,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> {
}
self.extend_line_bg(cw, selected)?;
self.skin.queue_reset(f)?;
- if self.in_app && y > 0 {
+ if self.in_app {
if let Some((sctop, scbottom)) = scrollbar {
f.queue(cursor::MoveTo(self.area.left + self.area.width - 1, y))?;
let style = if sctop <= y && y <= scbottom {
diff --git a/src/filesystems/filesystems_state.rs b/src/filesystems/filesystems_state.rs
index 328b87f..3082b18 100644
--- a/src/filesystems/filesystems_state.rs
+++ b/src/filesystems/filesystems_state.rs
@@ -237,7 +237,7 @@ impl PanelState for FilesystemState {
} else {
(self.mounts.as_slice(), self.selection_idx)
};
- let scrollbar = area.scrollbar(self.scroll as i32, mounts.len() as i32);
+ let scrollbar = area.scrollbar(self.scroll, mounts.len());
//- style preparation
let styles = &disc.panel_skin.styles;
let selection_bg = styles.selected_line.get_bg()
diff --git a/src/help/help_content.rs b/src/help/help_content.rs
index 25419de..672aeb5 100644
--- a/src/help/help_content.rs
+++ b/src/help/help_content.rs
@@ -68,6 +68,7 @@ ${features-text}
${features
* **${feature-name}:** ${feature-description}
}
+
"#;
/// build a markdown expander which will need to be
diff --git a/src/help/help_state.rs b/src/help/help_state.rs
index d96cc2f..1f5800e 100644
--- a/src/help/help_state.rs
+++ b/src/help/help_state.rs
@@ -17,7 +17,7 @@ use {
/// an application state dedicated to help
pub struct HelpState {
- pub scroll: i32, // scroll position
+ pub scroll: usize,
pub text_area: Area,
dirty: bool, // background must be cleared
pattern: Pattern,
@@ -205,7 +205,12 @@ impl PanelState for HelpState {
CmdResult::Keep
}
line_up | line_up_no_cycle => {
- self.scroll -= get_arg(input_invocation, internal_exec, 1);
+ let dy = get_arg(input_invocation, internal_exec, 1);
+ self.scroll = if self.scroll > dy {
+ self.scroll - dy
+ } else {
+ 0
+ };
CmdResult::Keep
}
open_stay => match open::that(&Conf::default_location()) {
@@ -222,11 +227,16 @@ impl PanelState for HelpState {
))
}
page_down => {
- self.scroll += self.text_area.height as i32;
+ self.scroll += self.text_area.height as usize;
CmdResult::Keep
}
page_up => {
- self.scroll -= self.text_area.height as i32;
+ let height = self.text_area.height as usize;
+ self.scroll = if self.scroll > height {
+ self.scroll - self.text_area.height as usize
+ } else {
+ 0
+ };
CmdResult::Keep
}
_ => self.on_internal_generic(
diff --git a/src/hex/hex_view.rs b/src/hex/hex_view.rs
index 8a7141a..40c072d 100644
--- a/src/hex/hex_view.rs
+++ b/src/hex/hex_view.rs
@@ -145,7 +145,7 @@ impl HexView {
margin_around_adresses = true;
//rem -= 2;
}
- let scrollbar = area.scrollbar(self.scroll as i32, self.line_count() as i32);
+ let scrollbar = area.scrollbar(self.scroll, self.line_count());
let scrollbar_fg = styles.scrollbar_thumb.get_fg()
.or_else(|| styles.preview.get_fg())
.unwrap_or(Color::White);
@@ -201,7 +201,7 @@ impl HexView {
}
}
cw.fill(&styles.default, &SPACE_FILLING)?;
- if is_thumb(y, scrollbar) {
+ if is_thumb(y as u16 + area.top, scrollbar) {
w.queue(SetForegroundColor(scrollbar_fg))?;
w.queue(Print('▐'))?;
} else {
@@ -237,9 +237,8 @@ impl HexView {
}
}
-fn is_thumb(y: usize, scrollbar: Option<(u16, u16)>) -> bool {
+fn is_thumb(y: u16, scrollbar: Option<(u16, u16)>) -> bool {
if let Some((sctop, scbottom)) = scrollbar {
- let y = y as u16;
if sctop <= y && y <= scbottom {
return true;
}
diff --git a/src/stage/stage_state.rs b/src/stage/stage_state.rs
index b734f85..90551ce 100644
--- a/src/stage/stage_state.rs
+++ b/src/stage/stage_state.rs
@@ -304,10 +304,7 @@ impl PanelState for StageState {
self.page_height = list_area.height as usize;
let pattern = &self.filtered_stage.pattern().pattern;
let pattern_object = pattern.object();
- let scrollbar = list_area.scrollbar(
- self.scroll as i32,
- self.filtered_stage.len() as i32,
- );
+ let scrollbar = list_area.scrollbar(self.scroll, self.filtered_stage.len());
for idx in 0..self.page_height {
let y = list_area.top + idx as u16;
let stage_idx = idx + self.scroll;
diff --git a/src/syntactic/syntactic_view.rs b/src/syntactic/syntactic_view.rs
index 2a38466..ba0063e 100644
--- a/src/syntactic/syntactic_view.rs
+++ b/src/syntactic/syntactic_view.rs
@@ -314,7 +314,7 @@ impl SyntacticView {
.unwrap_or(Color::AnsiValue(240));
let match_bg = styles.preview_match.get_bg().unwrap_or(Color::AnsiValue(28));
let code_width = area.width as usize - 1; // 1 char left for scrollbar
- let scrollbar = area.scrollbar(self.scroll as i32, self.lines.len() as i32);
+ let scrollbar = area.scrollbar(self.scroll, self.lines.len());
let scrollbar_fg = styles.scrollbar_thumb.get_fg()
.or_else(|| styles.preview.get_fg())
.unwrap_or(Color::White);
diff --git a/src/tree/tree.rs b/src/tree/tree.rs
index 253eeb1..346573c 100644
--- a/src/tree/tree.rs
+++ b/src/tree/tree.rs
@@ -25,7 +25,7 @@ pub struct Tree {
pub lines: Box<[TreeLine]>,
pub selection: usize, // there's always a selection (starts with root, which is 0)
pub options: TreeOptions,
- pub scroll: i32, // the number of lines at the top hidden because of scrolling
+ pub scroll: usize, // the number of lines at the top hidden because of scrolling
pub nb_gitignored: u32, // number of times a gitignore pattern excluded a file
pub total_search: bool, // whether the search was made on all children
pub git_status: ComputationResult<TreeGitStatus>,
@@ -60,7 +60,7 @@ impl Tree {
self.selection = 0;
}
}
- self.make_selection_visible(page_height as i32);
+ self.make_selection_visible(page_height);
Ok(())
}
@@ -144,70 +144,74 @@ impl Tree {
/// select another line
///
/// For example the following one if dy is 1.
- pub fn move_selection(&mut self, dy: i32, page_height: i32, cycle: bool) {
- // FIXME may not work well if dy is too big
- let l = self.lines.len() as i32;
+ pub fn move_selection(&mut self, dy: i32, page_height: usize, cycle: bool) {
+ let l = self.lines.len();
+ // we find the new line to select
loop {
- if !cycle {
- let s = dy + (self.selection as i32);
- if s < 0 || s >= l {
+ if dy < 0 {
+ let ady = (-dy) as usize;
+ if !cycle && self.selection < ady {
+ break;
+ }
+ self.selection = (self.selection + l - ady) % l;
+ } else {
+ let dy = dy as usize;
+ if !cycle && self.selection + dy > l {
break;
}
+ self.selection = (self.selection + dy) % l;
}
- self.selection = (self.selection + (l + dy) as usize) % self.lines.len();
if self.lines[self.selection].is_selectable() {
break;
}
}
// we adjust the scroll
- let sel = self.selection as i32;
if l > page_height {
- if dy < 0 {
- if sel == l - 1 {
- // cycling
- self.scroll = l - page_height;
- } else if sel < self.scroll + 5 {
- self.scroll = (self.scroll + 2 * dy).max(0);
- }
- } else {
- if sel == 0 {
- // cycling brought us back to top
- self.scroll = 0;
- } else if sel > self.scroll + page_height - 5 {
- self.scroll = (self.scroll + 2 * dy).min(l - page_height);
- }
+ if self.selection < 3 {
+ self.scroll = 0;
+ } else if self.selection < self.scroll + 3 {
+ self.scroll = self.selection - 3;
+ } else if self.selection + 3 > l {
+ self.scroll = l - page_height;
+ } else if self.selection + 3 > self.scroll + page_height {
+ self.scroll = self.selection + 3 - page_height;
}
}
}
- /// scroll the desired amount and return true, or return false if it's
+ /// Scroll the desired amount and return true, or return false if it's
/// already at end or the tree fits the page
- pub fn try_scroll(&mut self, dy: i32, page_height: i32) -> bool {
- let lines_len = self.lines.len() as i32;
- if lines_len <= page_height {
+ pub fn try_scroll(&mut self, dy: i32, page_height: usize) -> bool {
+ if self.lines.len() <= page_height {
return false;
}
if dy < 0 { // scroll up
if self.scroll == 0 {
return false;
+ } else {
+ let ady = -dy as usize;
+ if ady < self.scroll {
+ self.scroll -= ady;
+ } else {
+ self.scroll = 0;
+ }
}
- self.scroll = (self.scroll + dy).max(0);
} else { // scroll down
- let max = lines_len - page_height;
+ let max = self.lines.len() - page_height;
if self.scroll >= max {
return false;
}
- self.scroll = (self.scroll + dy).min(max);
+ self.scroll = (self.scroll + dy as usize).min(max);
}
self.select_visible_line(page_height);
true
}
- /// try to select a line (works if y+scroll falls on a selectable line)
- pub fn try_select_y(&mut self, y: i32) -> bool {
+ /// try to select a line by index of visible line
+ /// (works if y+scroll falls on a selectable line)
+ pub fn try_select_y(&mut self, y: usize) -> bool {
let y = y + self.scroll;
- if y >= 0 && y < self.lines.len() as i32 {
- let y = y as usize;
+ if y < self.lines.len() {
if self.lines[y].is_selectable() {
self.selection = y;
return true;
@@ -216,13 +220,12 @@ impl Tree {
false
}
/// fix the selection so that it's a selectable visible line
- fn select_visible_line(&mut self, page_height: i32) {
- let sel = self.selection as i32;
- if sel < self.scroll || sel >= self.scroll + page_height {
- self.selection = self.scroll as usize;
+ fn select_visible_line(&mut self, page_height: usize) {
+ if self.selection < self.scroll || self.selection >= self.scroll + page_height {
+ self.selection = self.scroll;
let l = self.lines.len();
loop {
- self.selection = (self.selection + ((l as i32) + 1) as usize) % l;
+ self.selection = (self.selection + l + 1) % l;
if self.lines[self.selection].is_selectable() {
break;
}
@@ -230,14 +233,19 @@ impl Tree {
}
}
- pub fn make_selection_visible(&mut self, page_height: i32) {
- let sel = self.selection as i32;
- let l = self.lines.len() as i32;
- if sel < self.scroll {
- self.scroll = (self.selection as i32 - 2).max(0);
- } else if l > page_height && sel >= self.scroll + page_height {
- self.scroll = (self.selection as i32 - page_height + 2) as i32;
+ pub fn make_selection_visible(&mut self, page_height: usize) {
+ debug!("make_selection_visible len={} page_height={} scroll={} sel={}",
+ self.lines.len(), page_height, self.scroll, self.selection);
+ if page_height >= self.lines.len() || self.selection < 3 {
+ self.scroll = 0;
+ } else if self.selection < self.scroll {
+ self.scroll = self.selection - 2;
+ } else if self.selection > self.lines.len() - 2 {
+ self.scroll = self.lines.len() - page_height;
+ } else if self.selection >= self.scroll + page_height {
+ self.scroll = self.selection + 2 - page_height;
}
+ debug!(" -> scroll={}", self.scroll);
}
pub fn selected_line(&self) -> &TreeLine {
&self.lines[self.selection]
@@ -289,7 +297,7 @@ impl Tree {
}
false
}
- pub fn try_select_last(&mut self, page_height: i32) -> bool {
+ pub fn try_select_last(&mut self, page_height: usize) -> bool {
for idx in (0..self.lines.len()).rev() {
let line = &self.lines[idx];
if line.is_selectable() {