mirror of
https://codeberg.org/unspeaker/perch.git
synced 2025-12-06 09:36:42 +01:00
add value bar
This commit is contained in:
parent
2ebf2c6cef
commit
41b6a0cd57
6 changed files with 64 additions and 39 deletions
14
src/keys.rs
14
src/keys.rs
|
|
@ -35,7 +35,7 @@ impl Handle<TuiIn> for Taggart {
|
|||
press!(Left) => { self.column = self.column.saturating_sub(1); },
|
||||
press!(Right) => { self.column = self.column + 1; },
|
||||
press!(Enter) => { self.edit_begin() },
|
||||
press!(Char(' ')) => { open(&self.paths[self.cursor].path)?; }
|
||||
press!(Char(' ')) => { open(&self.entries[self.cursor].path)?; }
|
||||
press!(Char(']')) => { self.columns.0[self.column].width += 1; }
|
||||
press!(Char('[')) => { self.columns.0[self.column].width =
|
||||
self.columns.0[self.column].width.saturating_sub(1).max(5); }
|
||||
|
|
@ -57,8 +57,10 @@ impl Handle<TuiIn> for Taggart {
|
|||
if self.cursor > x_max {
|
||||
self.offset += self.cursor - x_max;
|
||||
}
|
||||
if self.cursor >= self.paths.len() {
|
||||
self.cursor = self.paths.len().saturating_sub(1)
|
||||
if self.offset > self.display.h() {
|
||||
}
|
||||
if self.cursor >= self.entries.len() {
|
||||
self.cursor = self.entries.len().saturating_sub(1)
|
||||
}
|
||||
if self.column + 1 > self.columns.0.len() {
|
||||
self.column = self.columns.0.len().saturating_sub(1)
|
||||
|
|
@ -72,7 +74,7 @@ impl Taggart {
|
|||
if let Some(column) = self.columns.0.get(self.column)
|
||||
&& column.setter.is_some()
|
||||
{
|
||||
let value = (column.getter)(&self.paths[self.cursor]);
|
||||
let value = (column.getter)(&self.entries[self.cursor]);
|
||||
let value = format!("{}", value.unwrap_or_default());
|
||||
self.editing = Some((value.len(), value));
|
||||
}
|
||||
|
|
@ -84,9 +86,9 @@ impl Taggart {
|
|||
if let Some((_edit_index, value)) = &self.editing
|
||||
&& let Some(column) = self.columns.0.get(self.column)
|
||||
&& let Some(setter) = &column.setter
|
||||
&& self.paths.get_mut(self.cursor).is_some()
|
||||
&& self.entries.get_mut(self.cursor).is_some()
|
||||
{
|
||||
setter(self.paths.as_mut_slice(), self.cursor, value)
|
||||
setter(self.entries.as_mut_slice(), self.cursor, value)
|
||||
}
|
||||
self.editing = None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ mod metadata; pub use self::metadata::*;
|
|||
|
||||
pub struct Taggart {
|
||||
pub _root: PathBuf,
|
||||
pub paths: Vec<Entry>,
|
||||
pub entries: Vec<Entry>,
|
||||
pub cursor: usize,
|
||||
pub offset: usize,
|
||||
pub column: usize,
|
||||
|
|
@ -16,7 +16,7 @@ pub struct Taggart {
|
|||
}
|
||||
|
||||
impl Taggart {
|
||||
pub fn new (root: &impl AsRef<Path>, paths: Vec<Entry>) -> Usually<Self> {
|
||||
pub fn new (root: &impl AsRef<Path>, entries: Vec<Entry>) -> Usually<Self> {
|
||||
Ok(Self {
|
||||
_root: root.as_ref().into(),
|
||||
cursor: 0,
|
||||
|
|
@ -25,12 +25,12 @@ impl Taggart {
|
|||
display: Measure::new(),
|
||||
editing: None,
|
||||
columns: Columns::default(),
|
||||
paths,
|
||||
entries,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn paths_under (
|
||||
pub(crate) fn entries_under (
|
||||
entries: &mut [Entry], index: usize
|
||||
) -> Option<Vec<Arc<RwLock<Metadata>>>> {
|
||||
let path = if let Some(Entry { path, info, .. }) = entries.get(index)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ pub struct Column<T, G, S> {
|
|||
pub width: usize,
|
||||
pub getter: G,
|
||||
pub setter: Option<S>,
|
||||
//pub styler: Option<U>,
|
||||
}
|
||||
|
||||
impl<T> Column<T, fn(&T)->Option<Arc<str>>, fn(&mut [T], usize, &str)> {
|
||||
|
|
@ -33,7 +34,7 @@ impl<T> Column<T, fn(&T)->Option<Arc<str>>, fn(&mut [T], usize, &str)> {
|
|||
macro_rules! setter {
|
||||
($method:ident) => {
|
||||
|entries: &mut [Entry], index: usize, value: &str|{
|
||||
if let Some(entries) = paths_under(entries, index) {
|
||||
if let Some(entries) = entries_under(entries, index) {
|
||||
for entry in entries.iter() {
|
||||
entry.write().unwrap().$method(&value);
|
||||
}
|
||||
|
|
|
|||
68
src/view.rs
68
src/view.rs
|
|
@ -2,8 +2,7 @@ use crate::*;
|
|||
pub(crate) use tengri::tui::ratatui::style::Color;//, Style}, prelude::Stylize};
|
||||
pub(crate) use pad::PadStr;
|
||||
|
||||
mod status; pub use self::status::*;
|
||||
mod table; pub use self::table::*;
|
||||
mod table; pub use self::table::*;
|
||||
|
||||
impl Taggart {
|
||||
pub(crate) const FG_BROWSE: Color = Color::Rgb(255, 192, 0);
|
||||
|
|
@ -14,27 +13,58 @@ impl Taggart {
|
|||
|
||||
impl Content<TuiOut> for Taggart {
|
||||
fn content (&self) -> impl Render<TuiOut> {
|
||||
let sizer = Fill::xy(&self.display);
|
||||
let size = format!("{}x{}", self.display.w(), self.display.h());
|
||||
let titlebar = status_bar(Align::w(self.columns.header()));
|
||||
let size_bar = status_bar(Fill::x(Bsp::a(
|
||||
Fill::x(Align::w(Tui::bold(true, if self.editing.is_some() {
|
||||
Bsp::e(
|
||||
Tui::bg(Self::BG_EDIT, Tui::fg(Self::FG_EDIT, " EDIT ")),
|
||||
" Esc: cancel, Enter: set value"
|
||||
let size = format!("{}x{}", self.display.w(), self.display.h());
|
||||
let sizer = Fill::xy(&self.display);
|
||||
let titlebar = status_bar(
|
||||
Color::Rgb(0, 0, 0),
|
||||
Color::Rgb(192, 192, 192),
|
||||
Align::w(self.columns.header())
|
||||
);
|
||||
let value_bar = status_bar(
|
||||
Color::Rgb(192, 192, 192),
|
||||
Color::Rgb(0, 0, 0),
|
||||
Fill::x(Align::w(format!(" {}/{} ", self.cursor + 1, self.entries.len())))
|
||||
);
|
||||
let mode_bar = status_bar(
|
||||
Color::Rgb(0, 0, 0),
|
||||
Color::Rgb(192, 192, 192),
|
||||
Fill::x(Bsp::a(
|
||||
Fill::x(Align::w(Tui::bold(true, if self.editing.is_some() {
|
||||
Bsp::e(
|
||||
Tui::bg(Self::BG_EDIT, Tui::fg(Self::FG_EDIT, " EDIT ")),
|
||||
" Esc: cancel, Enter: set value"
|
||||
)
|
||||
} else {
|
||||
Bsp::e(
|
||||
Tui::bg(Self::BG_BROWSE, Tui::fg(Self::FG_BROWSE, " BROWSE ")),
|
||||
" Q: exit, Arrows: select, Space: open, Enter: edit"
|
||||
)
|
||||
}))),
|
||||
Fill::x(Align::e(size)),
|
||||
))
|
||||
);
|
||||
Bsp::n(
|
||||
value_bar,
|
||||
Bsp::n(
|
||||
mode_bar,
|
||||
Bsp::s(
|
||||
titlebar,
|
||||
Bsp::b(
|
||||
sizer,
|
||||
Fill::xy(TreeTable(self))
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Bsp::e(
|
||||
Tui::bg(Self::BG_BROWSE, Tui::fg(Self::FG_BROWSE, " BROWSE ")),
|
||||
" Q: exit, Arrows: select, Space: open, Enter: edit"
|
||||
)
|
||||
}))),
|
||||
Fill::x(Align::e(size)),
|
||||
)));
|
||||
Bsp::n(size_bar, Bsp::s(titlebar, Bsp::b(sizer, Fill::xy(TreeTable(self)))))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status_bar (
|
||||
fg: Color, bg: Color, content: impl Content<TuiOut>
|
||||
) -> impl Content<TuiOut> {
|
||||
Fixed::y(1, Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, content))))
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
pub const ICON_DIRECTORY: &'static str = "";
|
||||
pub const ICON_IMAGE: &'static str = "";
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
pub fn status_bar (content: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
||||
Fixed::y(
|
||||
1,
|
||||
Fill::x(Tui::bold(true, Tui::fg_bg(Color::Rgb(0,0,0), Color::Rgb(255,255,255), content)))
|
||||
)
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ impl<'a> TreeTable<'a> {
|
|||
let row_index_scrolled = row_index + self.0.offset;
|
||||
let selected = self.0.cursor == row_index_scrolled;
|
||||
let mut column_x = area.x();
|
||||
if let Some(entry) = self.0.paths.get(row_index_scrolled) {
|
||||
if let Some(entry) = self.0.entries.get(row_index_scrolled) {
|
||||
for (index, _fragment) in entry.path.iter().enumerate() {
|
||||
if index == entry.depth - 1 {
|
||||
let _cursor = if selected { ">" } else { " " };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue