mirror of
https://github.com/gitui-org/gitui
synced 2026-05-24 09:28:21 +00:00
tree view commands (see #714)
This commit is contained in:
parent
0e31d57a33
commit
4591fbb965
3 changed files with 99 additions and 81 deletions
|
|
@ -46,6 +46,11 @@ impl FileTree {
|
||||||
Ok(new_self)
|
Ok(new_self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub const fn is_empty(&self) -> bool {
|
||||||
|
self.items.file_count() == 0
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
pub fn collapse_but_root(&mut self) {
|
pub fn collapse_but_root(&mut self) {
|
||||||
self.items.collapse(0, true);
|
self.items.collapse(0, true);
|
||||||
|
|
@ -67,46 +72,23 @@ impl FileTree {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visual_index_to_absolute(
|
|
||||||
&self,
|
|
||||||
visual_index: usize,
|
|
||||||
) -> Option<usize> {
|
|
||||||
self.items
|
|
||||||
.iterate(0, self.items.len())
|
|
||||||
.enumerate()
|
|
||||||
.find_map(|(i, (abs, _))| {
|
|
||||||
if i == visual_index {
|
|
||||||
Some(abs)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
pub const fn visual_selection(&self) -> Option<&VisualSelection> {
|
pub const fn visual_selection(&self) -> Option<&VisualSelection> {
|
||||||
self.visual_selection.as_ref()
|
self.visual_selection.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_visual_selection(&self) -> Option<VisualSelection> {
|
///
|
||||||
self.selection.map(|selection_absolute| {
|
pub fn collapse_recursive(&mut self) {
|
||||||
let mut count = 0;
|
if let Some(selection) = self.selection {
|
||||||
let mut visual_index = 0;
|
self.items.collapse(selection, true);
|
||||||
for (index, _item) in
|
}
|
||||||
self.items.iterate(0, self.items.len())
|
}
|
||||||
{
|
|
||||||
if selection_absolute == index {
|
|
||||||
visual_index = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
count += 1;
|
///
|
||||||
}
|
pub fn expand_recursive(&mut self) {
|
||||||
|
if let Some(selection) = self.selection {
|
||||||
VisualSelection {
|
self.items.expand(selection, true);
|
||||||
index: visual_index,
|
}
|
||||||
count,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -141,16 +123,41 @@ impl FileTree {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collapse_recursive(&mut self) {
|
fn visual_index_to_absolute(
|
||||||
if let Some(selection) = self.selection {
|
&self,
|
||||||
self.items.collapse(selection, true);
|
visual_index: usize,
|
||||||
}
|
) -> Option<usize> {
|
||||||
|
self.items
|
||||||
|
.iterate(0, self.items.len())
|
||||||
|
.enumerate()
|
||||||
|
.find_map(|(i, (abs, _))| {
|
||||||
|
if i == visual_index {
|
||||||
|
Some(abs)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_recursive(&mut self) {
|
fn calc_visual_selection(&self) -> Option<VisualSelection> {
|
||||||
if let Some(selection) = self.selection {
|
self.selection.map(|selection_absolute| {
|
||||||
self.items.expand(selection, true);
|
let mut count = 0;
|
||||||
}
|
let mut visual_index = 0;
|
||||||
|
for (index, _item) in
|
||||||
|
self.items.iterate(0, self.items.len())
|
||||||
|
{
|
||||||
|
if selection_absolute == index {
|
||||||
|
visual_index = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualSelection {
|
||||||
|
index: visual_index,
|
||||||
|
count,
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn selection_start(current_index: usize) -> Option<usize> {
|
const fn selection_start(current_index: usize) -> Option<usize> {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use super::{
|
||||||
use crate::{
|
use crate::{
|
||||||
keys::SharedKeyConfig,
|
keys::SharedKeyConfig,
|
||||||
queue::Queue,
|
queue::Queue,
|
||||||
strings,
|
strings::{self, order},
|
||||||
ui::{self, style::SharedTheme},
|
ui::{self, style::SharedTheme},
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
@ -109,10 +109,6 @@ impl RevisionFilesComponent {
|
||||||
let path = format!("{}{}{}", indent_str, path_arrow, path);
|
let path = format!("{}{}{}", indent_str, path_arrow, path);
|
||||||
Span::styled(path, theme.file_tree_item(is_path, selected))
|
Span::styled(path, theme.file_tree_item(is_path, selected))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_selection(&mut self, dir: MoveSelection) -> bool {
|
|
||||||
self.tree.move_selection(dir)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawableComponent for RevisionFilesComponent {
|
impl DrawableComponent for RevisionFilesComponent {
|
||||||
|
|
@ -154,13 +150,6 @@ impl DrawableComponent for RevisionFilesComponent {
|
||||||
f,
|
f,
|
||||||
area,
|
area,
|
||||||
&self.title,
|
&self.title,
|
||||||
// &format!(
|
|
||||||
// "{}/{} (height: {}) (top: {})",
|
|
||||||
// selection.index,
|
|
||||||
// selection.count,
|
|
||||||
// tree_height,
|
|
||||||
// self.scroll_top.get()
|
|
||||||
// ),
|
|
||||||
items,
|
items,
|
||||||
true,
|
true,
|
||||||
&self.theme,
|
&self.theme,
|
||||||
|
|
@ -188,6 +177,8 @@ impl Component for RevisionFilesComponent {
|
||||||
)
|
)
|
||||||
.order(1),
|
.order(1),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
tree_nav_cmds(&self.tree, &self.key_config, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
visibility_blocking(self)
|
visibility_blocking(self)
|
||||||
|
|
@ -202,33 +193,8 @@ impl Component for RevisionFilesComponent {
|
||||||
let consumed = if key == self.key_config.exit_popup {
|
let consumed = if key == self.key_config.exit_popup {
|
||||||
self.hide();
|
self.hide();
|
||||||
true
|
true
|
||||||
} else if key == self.key_config.move_down {
|
|
||||||
self.move_selection(MoveSelection::Down)
|
|
||||||
} else if key == self.key_config.move_up {
|
|
||||||
self.move_selection(MoveSelection::Up)
|
|
||||||
} else if key == self.key_config.move_right {
|
|
||||||
self.move_selection(MoveSelection::Right)
|
|
||||||
} else if key == self.key_config.move_left {
|
|
||||||
self.move_selection(MoveSelection::Left)
|
|
||||||
} else if key == self.key_config.home
|
|
||||||
|| key == self.key_config.shift_up
|
|
||||||
{
|
|
||||||
self.move_selection(MoveSelection::Top)
|
|
||||||
} else if key == self.key_config.end
|
|
||||||
|| key == self.key_config.shift_down
|
|
||||||
{
|
|
||||||
self.move_selection(MoveSelection::End)
|
|
||||||
} else if key
|
|
||||||
== self.key_config.tree_collapse_recursive
|
|
||||||
{
|
|
||||||
self.tree.collapse_recursive();
|
|
||||||
true
|
|
||||||
} else if key == self.key_config.tree_expand_recursive
|
|
||||||
{
|
|
||||||
self.tree.expand_recursive();
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
false
|
tree_nav(&mut self.tree, &self.key_config, key)
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(consumed.into());
|
return Ok(consumed.into());
|
||||||
|
|
@ -252,3 +218,48 @@ impl Component for RevisionFilesComponent {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: reuse for other tree usages
|
||||||
|
fn tree_nav_cmds(
|
||||||
|
tree: &FileTree,
|
||||||
|
key_config: &SharedKeyConfig,
|
||||||
|
out: &mut Vec<CommandInfo>,
|
||||||
|
) {
|
||||||
|
out.push(
|
||||||
|
CommandInfo::new(
|
||||||
|
strings::commands::navigate_tree(key_config),
|
||||||
|
!tree.is_empty(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.order(order::NAV),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: reuse for other tree usages
|
||||||
|
fn tree_nav(
|
||||||
|
tree: &mut FileTree,
|
||||||
|
key_config: &SharedKeyConfig,
|
||||||
|
key: crossterm::event::KeyEvent,
|
||||||
|
) -> bool {
|
||||||
|
if key == key_config.move_down {
|
||||||
|
tree.move_selection(MoveSelection::Down)
|
||||||
|
} else if key == key_config.move_up {
|
||||||
|
tree.move_selection(MoveSelection::Up)
|
||||||
|
} else if key == key_config.move_right {
|
||||||
|
tree.move_selection(MoveSelection::Right)
|
||||||
|
} else if key == key_config.move_left {
|
||||||
|
tree.move_selection(MoveSelection::Left)
|
||||||
|
} else if key == key_config.home || key == key_config.shift_up {
|
||||||
|
tree.move_selection(MoveSelection::Top)
|
||||||
|
} else if key == key_config.end || key == key_config.shift_down {
|
||||||
|
tree.move_selection(MoveSelection::End)
|
||||||
|
} else if key == key_config.tree_collapse_recursive {
|
||||||
|
tree.collapse_recursive();
|
||||||
|
true
|
||||||
|
} else if key == key_config.tree_expand_recursive {
|
||||||
|
tree.expand_recursive();
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -351,7 +351,7 @@ pub mod commands {
|
||||||
key_config.get_hint(key_config.move_right),
|
key_config.get_hint(key_config.move_right),
|
||||||
key_config.get_hint(key_config.move_left)
|
key_config.get_hint(key_config.move_left)
|
||||||
),
|
),
|
||||||
"navigate tree view",
|
"navigate tree view, collapse, expand",
|
||||||
CMD_GROUP_GENERAL,
|
CMD_GROUP_GENERAL,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue