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!(Left) => { self.column = self.column.saturating_sub(1); },
|
||||||
press!(Right) => { self.column = self.column + 1; },
|
press!(Right) => { self.column = self.column + 1; },
|
||||||
press!(Enter) => { self.edit_begin() },
|
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 += 1; }
|
||||||
press!(Char('[')) => { self.columns.0[self.column].width =
|
press!(Char('[')) => { self.columns.0[self.column].width =
|
||||||
self.columns.0[self.column].width.saturating_sub(1).max(5); }
|
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 {
|
if self.cursor > x_max {
|
||||||
self.offset += self.cursor - x_max;
|
self.offset += self.cursor - x_max;
|
||||||
}
|
}
|
||||||
if self.cursor >= self.paths.len() {
|
if self.offset > self.display.h() {
|
||||||
self.cursor = self.paths.len().saturating_sub(1)
|
}
|
||||||
|
if self.cursor >= self.entries.len() {
|
||||||
|
self.cursor = self.entries.len().saturating_sub(1)
|
||||||
}
|
}
|
||||||
if self.column + 1 > self.columns.0.len() {
|
if self.column + 1 > self.columns.0.len() {
|
||||||
self.column = self.columns.0.len().saturating_sub(1)
|
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)
|
if let Some(column) = self.columns.0.get(self.column)
|
||||||
&& column.setter.is_some()
|
&& 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());
|
let value = format!("{}", value.unwrap_or_default());
|
||||||
self.editing = Some((value.len(), value));
|
self.editing = Some((value.len(), value));
|
||||||
}
|
}
|
||||||
|
|
@ -84,9 +86,9 @@ impl Taggart {
|
||||||
if let Some((_edit_index, value)) = &self.editing
|
if let Some((_edit_index, value)) = &self.editing
|
||||||
&& let Some(column) = self.columns.0.get(self.column)
|
&& let Some(column) = self.columns.0.get(self.column)
|
||||||
&& let Some(setter) = &column.setter
|
&& 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;
|
self.editing = None;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ mod metadata; pub use self::metadata::*;
|
||||||
|
|
||||||
pub struct Taggart {
|
pub struct Taggart {
|
||||||
pub _root: PathBuf,
|
pub _root: PathBuf,
|
||||||
pub paths: Vec<Entry>,
|
pub entries: Vec<Entry>,
|
||||||
pub cursor: usize,
|
pub cursor: usize,
|
||||||
pub offset: usize,
|
pub offset: usize,
|
||||||
pub column: usize,
|
pub column: usize,
|
||||||
|
|
@ -16,7 +16,7 @@ pub struct Taggart {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
Ok(Self {
|
||||||
_root: root.as_ref().into(),
|
_root: root.as_ref().into(),
|
||||||
cursor: 0,
|
cursor: 0,
|
||||||
|
|
@ -25,12 +25,12 @@ impl Taggart {
|
||||||
display: Measure::new(),
|
display: Measure::new(),
|
||||||
editing: None,
|
editing: None,
|
||||||
columns: Columns::default(),
|
columns: Columns::default(),
|
||||||
paths,
|
entries,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn paths_under (
|
pub(crate) fn entries_under (
|
||||||
entries: &mut [Entry], index: usize
|
entries: &mut [Entry], index: usize
|
||||||
) -> Option<Vec<Arc<RwLock<Metadata>>>> {
|
) -> Option<Vec<Arc<RwLock<Metadata>>>> {
|
||||||
let path = if let Some(Entry { path, info, .. }) = entries.get(index)
|
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 width: usize,
|
||||||
pub getter: G,
|
pub getter: G,
|
||||||
pub setter: Option<S>,
|
pub setter: Option<S>,
|
||||||
|
//pub styler: Option<U>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Column<T, fn(&T)->Option<Arc<str>>, fn(&mut [T], usize, &str)> {
|
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 {
|
macro_rules! setter {
|
||||||
($method:ident) => {
|
($method:ident) => {
|
||||||
|entries: &mut [Entry], index: usize, value: &str|{
|
|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() {
|
for entry in entries.iter() {
|
||||||
entry.write().unwrap().$method(&value);
|
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 tengri::tui::ratatui::style::Color;//, Style}, prelude::Stylize};
|
||||||
pub(crate) use pad::PadStr;
|
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 {
|
impl Taggart {
|
||||||
pub(crate) const FG_BROWSE: Color = Color::Rgb(255, 192, 0);
|
pub(crate) const FG_BROWSE: Color = Color::Rgb(255, 192, 0);
|
||||||
|
|
@ -14,27 +13,58 @@ impl Taggart {
|
||||||
|
|
||||||
impl Content<TuiOut> for Taggart {
|
impl Content<TuiOut> for Taggart {
|
||||||
fn content (&self) -> impl Render<TuiOut> {
|
fn content (&self) -> impl Render<TuiOut> {
|
||||||
let sizer = Fill::xy(&self.display);
|
let size = format!("{}x{}", self.display.w(), self.display.h());
|
||||||
let size = format!("{}x{}", self.display.w(), self.display.h());
|
let sizer = Fill::xy(&self.display);
|
||||||
let titlebar = status_bar(Align::w(self.columns.header()));
|
let titlebar = status_bar(
|
||||||
let size_bar = status_bar(Fill::x(Bsp::a(
|
Color::Rgb(0, 0, 0),
|
||||||
Fill::x(Align::w(Tui::bold(true, if self.editing.is_some() {
|
Color::Rgb(192, 192, 192),
|
||||||
Bsp::e(
|
Align::w(self.columns.header())
|
||||||
Tui::bg(Self::BG_EDIT, Tui::fg(Self::FG_EDIT, " EDIT ")),
|
);
|
||||||
" Esc: cancel, Enter: set value"
|
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 {
|
impl Entry {
|
||||||
pub const ICON_DIRECTORY: &'static str = "";
|
pub const ICON_DIRECTORY: &'static str = "";
|
||||||
pub const ICON_IMAGE: &'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 row_index_scrolled = row_index + self.0.offset;
|
||||||
let selected = self.0.cursor == row_index_scrolled;
|
let selected = self.0.cursor == row_index_scrolled;
|
||||||
let mut column_x = area.x();
|
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() {
|
for (index, _fragment) in entry.path.iter().enumerate() {
|
||||||
if index == entry.depth - 1 {
|
if index == entry.depth - 1 {
|
||||||
let _cursor = if selected { ">" } else { " " };
|
let _cursor = if selected { ">" } else { " " };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue