summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2024-02-28 21:02:22 +0100
committerqkzk <qu3nt1n@gmail.com>2024-02-28 21:02:22 +0100
commit87b925b74e3bfee741c9d8d9833dd6c63607a33c (patch)
tree04eb7811c75751881f6570b8de4e2727e3957454
parent6b28a0e82db0ecb84c1f64544b27ac566efc7ec4 (diff)
WIP: fix position of first line element. Can't click on right pane elems anymore :(
-rw-r--r--development.md6
-rw-r--r--src/app/header_footer.rs53
-rw-r--r--src/common/utils.rs32
3 files changed, 58 insertions, 33 deletions
diff --git a/development.md b/development.md
index d3d8810..7d4c8a1 100644
--- a/development.md
+++ b/development.md
@@ -894,7 +894,6 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
- [x] setting second pane as preview should enable dual pane at the same time
- [x] FIX: leaving mount mode with enter when device is mounted should move to it
- [x] FIX: clicking footer row execute directory actions, even in flagged display mode
-- [ ] FIX: leaving flagged file should reset the window correctly. Can't reproduce...
- [x] display all specific binds for every mode.
- [ ] search, display nb of matches, completion + flag on the fly
@@ -935,9 +934,14 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
- [x] open multiple files
- [x] FIX: too many open files. pdf opened by Poppler...new_from_file aren't closed properly.
Open manually and and use Poppler...new_from_data.
+- [x] FIX: in dual pane mode, right aligned elements aren't displayed.
+- [ ] Right pane search & filter click don't match on correct position.
+- [ ] FIX: while filter + search, matching and going forward is buggy
+ - [ ] is it a problem ?
## TODO
+- [ ] FIX: leaving flagged file should reset the window correctly. Can't reproduce...
- [ ] use the new mpsc event parser to read commands from stdin or RPC
- [ ] [opener file kind](./src/io/opener.rs): move associations to a config file
- [ ] open a shell while hiding fm, restore after leaving
diff --git a/src/app/header_footer.rs b/src/app/header_footer.rs
index 0eb430f..7a88b3f 100644
--- a/src/app/header_footer.rs
+++ b/src/app/header_footer.rs
@@ -1,12 +1,13 @@
mod inner {
use anyhow::{Context, Result};
- use unicode_segmentation::UnicodeSegmentation;
use crate::app::{Status, Tab};
use crate::common::{
- HELP_FIRST_SENTENCE, HELP_SECOND_SENTENCE, LOG_FIRST_SENTENCE, LOG_SECOND_SENTENCE,
+ UtfWidth, HELP_FIRST_SENTENCE, HELP_SECOND_SENTENCE, LOG_FIRST_SENTENCE,
+ LOG_SECOND_SENTENCE,
};
use crate::event::ActionMap;
+ use crate::io::MIN_WIDTH_FOR_DUAL_PANE;
use crate::modes::{
shorten_path, ColoredText, Content, Display, FileInfo, FilterKind, Preview, Search,
Selectable, TextKind,
@@ -26,6 +27,7 @@ mod inner {
pub struct ClickableString {
text: String,
action: ActionMap,
+ width: usize,
left: usize,
right: usize,
}
@@ -36,47 +38,32 @@ mod inner {
/// If left aligned, the text size will be added to `col` and the text will span from col to col + width.
/// otherwise, the text will spawn from col - width to col.
fn new(text: String, align: HorizontalAlign, action: ActionMap, col: usize) -> Self {
- let size = Self::size(&text);
- let left: usize;
- let right: usize;
- match align {
- HorizontalAlign::Left => {
- left = col;
- right = col + size;
- }
- HorizontalAlign::Right => {
- right = col;
- left = col - size;
- }
- }
+ let width = text.utf_width();
+ let (left, right) = match align {
+ HorizontalAlign::Left => (col, col + width),
+ HorizontalAlign::Right => (col - width - 3, col - 3),
+ };
Self {
text,
action,
+ width,
left,
right,
}
}
- fn size(text: &str) -> usize {
- text.graphemes(true)
- .map(|s| s.to_string())
- .collect::<Vec<String>>()
- .len()
- }
-
- fn width(&self) -> usize {
- self.right - self.left
- }
-
/// Text content of the element.
pub fn text(&self) -> &str {
self.text.as_str()
}
- /// Starting col where the text should be drawn on the canvas.
pub fn col(&self) -> usize {
self.left
}
+
+ pub fn width(&self) -> usize {
+ self.width
+ }
}
/// A line of element that can be clicked on.
@@ -119,7 +106,12 @@ mod inner {
impl Header {
/// Creates a new header
pub fn new(status: &Status, tab: &Tab) -> Result<Self> {
- let (width, _) = status.internal_settings.term_size()?;
+ let full_width = status.internal_settings.term_size()?.0;
+ let width = if status.display_settings.dual() && full_width >= MIN_WIDTH_FOR_DUAL_PANE {
+ full_width / 2
+ } else {
+ full_width
+ };
let elems = Self::make_elems(tab, width)?;
Ok(Self { elems, width })
@@ -279,10 +271,7 @@ mod inner {
/// Pad every string of `raw_strings` with enough space to fill a line.
fn make_padded_strings(raw_strings: &[String], total_width: usize) -> Vec<String> {
- let used_width: usize = raw_strings
- .iter()
- .map(|s| s.graphemes(true).collect::<Vec<&str>>().len())
- .sum();
+ let used_width: usize = raw_strings.iter().map(|s| s.utf_width()).sum();
let available_width = total_width.checked_sub(used_width).unwrap_or_default();
let margin_width = available_width / (2 * raw_strings.len());
let margin = " ".repeat(margin_width);
diff --git a/src/common/utils.rs b/src/common/utils.rs
index 5b81871..dd504a0 100644
--- a/src/common/utils.rs
+++ b/src/common/utils.rs
@@ -9,6 +9,7 @@ use copypasta::{ClipboardContext, ClipboardProvider};
use rand::Rng;
use sysinfo::{Disk, DiskExt};
use tuikit::term::Term;
+use unicode_segmentation::UnicodeSegmentation;
use crate::common::{CALC_PDF_PATH, THUMBNAIL_PATH};
use crate::log_info;
@@ -287,3 +288,34 @@ where
std::fs::rename(old_path, &new_path)?;
Ok(new_path)
}
+
+/// This trait `UtfWidth` is defined with a single
+/// method `utf_width()` that returns the width of
+/// a string in Unicode code points.
+/// The implementation for `String` and `&str`
+/// types are provided which calculate the
+/// width. of the original string in graphemes.
+/// This method allows for easy calculation of
+/// the horizontal space required for displaying
+/// a given text, which can be useful for layout purposes.
+pub trait UtfWidth {
+ fn utf_width(&self) -> usize;
+}
+
+impl UtfWidth for String {
+ fn utf_width(&self) -> usize {
+ self.graphemes(true)
+ .map(|s| s.to_string())
+ .collect::<Vec<String>>()
+ .len()
+ }
+}
+
+impl UtfWidth for &str {
+ fn utf_width(&self) -> usize {
+ self.graphemes(true)
+ .map(|s| s.to_string())
+ .collect::<Vec<String>>()
+ .len()
+ }
+}