mirror of
https://github.com/chylex/Bark-Browser.git
synced 2025-01-06 07:42:50 +01:00
Move custom slab-tree node logic into included sources
This commit is contained in:
parent
dace27d259
commit
63b56de63f
lib/slab-tree/src/node
src/component/filesystem
action/movement
render
tree
@ -22,6 +22,38 @@ impl<'a, T> NodeRef<'a, T> {
|
||||
pub fn next_sibling_id(&self) -> Option<NodeId> {
|
||||
self.next_sibling().map(|node| node.node_id())
|
||||
}
|
||||
|
||||
pub fn last_descendant_or_self(&self) -> NodeRef<'a, T> {
|
||||
let mut node = NodeRef::new(self.node_id(), self.tree);
|
||||
|
||||
while let Some(id) = node.get_self_as_node().relatives.last_child {
|
||||
node = NodeRef::new(id, self.tree);
|
||||
}
|
||||
|
||||
node
|
||||
}
|
||||
|
||||
pub fn above(&self) -> Option<NodeRef<T>> {
|
||||
if let Some(prev_sibling) = self.prev_sibling() {
|
||||
Some(prev_sibling.last_descendant_or_self())
|
||||
} else {
|
||||
self.parent()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn above_id(&self) -> Option<NodeId> {
|
||||
self.above().map(|node| node.node_id())
|
||||
}
|
||||
|
||||
pub fn below(&self) -> Option<NodeRef<T>> {
|
||||
self.first_child()
|
||||
.or_else(|| self.next_sibling())
|
||||
.or_else(|| self.ancestors().find_map(|ancestor| ancestor.next_sibling_id()).map(|id| NodeRef::new(id, self.tree)))
|
||||
}
|
||||
|
||||
pub fn below_id(&self) -> Option<NodeId> {
|
||||
self.below().map(|node| node.node_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> NodeMut<'a, T> {
|
||||
|
@ -11,8 +11,8 @@ use crate::NodeId;
|
||||
/// An immutable reference to a given `Node`'s data and its relatives.
|
||||
///
|
||||
pub struct NodeRef<'a, T> {
|
||||
node_id: NodeId,
|
||||
tree: &'a Tree<T>,
|
||||
pub(super) node_id: NodeId,
|
||||
pub(super) tree: &'a Tree<T>,
|
||||
}
|
||||
|
||||
impl<'a, T> NodeRef<'a, T> {
|
||||
@ -276,7 +276,7 @@ impl<'a, T> NodeRef<'a, T> {
|
||||
LevelOrder::new(self, self.tree)
|
||||
}
|
||||
|
||||
fn get_self_as_node(&self) -> &Node<T> {
|
||||
pub(super) fn get_self_as_node(&self) -> &Node<T> {
|
||||
if let Some(node) = self.tree.get_node(self.node_id) {
|
||||
&node
|
||||
} else {
|
||||
|
@ -2,13 +2,13 @@ use slab_tree::{NodeId, NodeRef};
|
||||
|
||||
use crate::component::filesystem::action::movement::{MovementAction, perform_movement_with_count_from_register, SimpleMovementAction};
|
||||
use crate::component::filesystem::FsLayer;
|
||||
use crate::component::filesystem::tree::{FsTree, FsTreeView, FsTreeViewNode};
|
||||
use crate::component::filesystem::tree::{FsTree, FsTreeViewNode};
|
||||
use crate::state::Environment;
|
||||
|
||||
pub struct MoveToNextSibling;
|
||||
|
||||
impl SimpleMovementAction for MoveToNextSibling {
|
||||
fn get_target(_view: &FsTreeView, selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
fn get_target(selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
selected_node.next_sibling_id()
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@ impl SimpleMovementAction for MoveToNextSibling {
|
||||
pub struct MoveToPreviousSibling;
|
||||
|
||||
impl SimpleMovementAction for MoveToPreviousSibling {
|
||||
fn get_target(_view: &FsTreeView, selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
fn get_target(selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
selected_node.prev_sibling_id()
|
||||
}
|
||||
}
|
||||
@ -24,7 +24,7 @@ impl SimpleMovementAction for MoveToPreviousSibling {
|
||||
pub struct MoveBetweenFirstAndLastSibling;
|
||||
|
||||
impl SimpleMovementAction for MoveBetweenFirstAndLastSibling {
|
||||
fn get_target(_view: &FsTreeView, selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
fn get_target(selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
if selected_node.next_sibling().is_none() {
|
||||
selected_node.parent().and_then(|node| node.first_child_id())
|
||||
} else {
|
||||
@ -36,7 +36,7 @@ impl SimpleMovementAction for MoveBetweenFirstAndLastSibling {
|
||||
pub struct MoveToParent;
|
||||
|
||||
impl SimpleMovementAction for MoveToParent {
|
||||
fn get_target(_view: &FsTreeView, selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
fn get_target(selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
selected_node.parent_id()
|
||||
}
|
||||
}
|
||||
@ -51,8 +51,8 @@ impl MovementAction for MoveOrTraverseUpParent {
|
||||
|
||||
impl MoveOrTraverseUpParent {
|
||||
fn get_target(tree: &mut FsTree, node_id: NodeId) -> Option<NodeId> {
|
||||
if let Some(node) = tree.view.get(node_id) {
|
||||
let target_node_id = <MoveToParent as SimpleMovementAction>::get_target(&tree.view, &node);
|
||||
if let Some(node) = tree.get_view_node(node_id) {
|
||||
let target_node_id = <MoveToParent as SimpleMovementAction>::get_target(&node);
|
||||
if target_node_id.is_some() {
|
||||
return target_node_id;
|
||||
} else if let Some(target_node_id) = tree.traverse_up_root() {
|
||||
|
@ -2,15 +2,15 @@ use slab_tree::{NodeId, NodeRef};
|
||||
|
||||
use crate::component::filesystem::action::movement::{get_simple_movement_target, MovementAction, MoveToParent, perform_movement_with_count_from, SimpleMovementAction};
|
||||
use crate::component::filesystem::FsLayer;
|
||||
use crate::component::filesystem::tree::{FsTree, FsTreeView, FsTreeViewNode};
|
||||
use crate::component::filesystem::tree::{FsTree, FsTreeViewNode};
|
||||
use crate::state::Environment;
|
||||
|
||||
/// Moves up `count` lines (1 line by default).
|
||||
pub struct MoveUp;
|
||||
|
||||
impl SimpleMovementAction for MoveUp {
|
||||
fn get_target(tree: &FsTreeView, selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
tree.get_node_above(selected_node)
|
||||
fn get_target(selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
selected_node.above_id()
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,8 +18,8 @@ impl SimpleMovementAction for MoveUp {
|
||||
pub struct MoveDown;
|
||||
|
||||
impl SimpleMovementAction for MoveDown {
|
||||
fn get_target(tree: &FsTreeView, selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> {
|
||||
tree.get_node_below(selected_node)
|
||||
fn get_target(selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> {
|
||||
selected_node.below_id()
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ impl MoveToFirst {
|
||||
fn get_target(tree: &mut FsTree) -> NodeId where Self: Sized {
|
||||
let mut target_node_id = tree.selected_view_node_id;
|
||||
|
||||
while let Some(node_id) = tree.view.get(target_node_id).and_then(|node| <MoveToParent as SimpleMovementAction>::get_target(&tree.view, &node)) {
|
||||
while let Some(node_id) = tree.get_view_node(target_node_id).and_then(|node| <MoveToParent as SimpleMovementAction>::get_target(&node)) {
|
||||
target_node_id = node_id;
|
||||
}
|
||||
|
||||
@ -50,8 +50,8 @@ pub struct MoveToLast;
|
||||
impl MovementAction for MoveToLast {
|
||||
fn get_target(&self, layer: &mut FsLayer, _environment: &Environment) -> Option<NodeId> where Self: Sized {
|
||||
let first_node_id = MoveToFirst::get_target(&mut layer.tree);
|
||||
let last_node_id = layer.tree.view.get_last_descendant_or_self(first_node_id);
|
||||
Some(last_node_id)
|
||||
let last_node_id = layer.tree.get_view_node(first_node_id).map(|node| node.last_descendant_or_self().node_id());
|
||||
last_node_id
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use slab_tree::{NodeId, NodeRef};
|
||||
|
||||
use crate::component::filesystem::FsLayer;
|
||||
use crate::component::filesystem::tree::{FsTree, FsTreeView, FsTreeViewNode};
|
||||
use crate::component::filesystem::tree::{FsTree, FsTreeViewNode};
|
||||
use crate::state::action::{Action, ActionResult};
|
||||
use crate::state::Environment;
|
||||
|
||||
@ -56,7 +56,7 @@ fn perform_movement_with_count_from<F>(tree: &mut FsTree, count: Option<usize>,
|
||||
}
|
||||
|
||||
pub trait SimpleMovementAction {
|
||||
fn get_target(view: &FsTreeView, selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized;
|
||||
fn get_target(selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized;
|
||||
}
|
||||
|
||||
impl<T: SimpleMovementAction> MovementAction for T {
|
||||
@ -66,5 +66,5 @@ impl<T: SimpleMovementAction> MovementAction for T {
|
||||
}
|
||||
|
||||
fn get_simple_movement_target<T: SimpleMovementAction>(tree: &mut FsTree, node_id: NodeId) -> Option<NodeId> {
|
||||
tree.view.get(node_id).and_then(|node| T::get_target(&tree.view, &node))
|
||||
tree.get_view_node(node_id).and_then(|node| T::get_target(&node))
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::marker::PhantomData;
|
||||
use slab_tree::{NodeId, NodeRef};
|
||||
|
||||
use crate::component::filesystem::action::movement::SimpleMovementAction;
|
||||
use crate::component::filesystem::tree::{FsTreeView, FsTreeViewNode};
|
||||
use crate::component::filesystem::tree::FsTreeViewNode;
|
||||
|
||||
/// A movement action with fallback.
|
||||
pub struct MovementWithFallback<A: SimpleMovementAction, F: SimpleMovementAction>(PhantomData<A>, PhantomData<F>);
|
||||
@ -21,7 +21,7 @@ impl<A: SimpleMovementAction, F: SimpleMovementAction> MovementWithFallbackFacto
|
||||
}
|
||||
|
||||
impl<A: SimpleMovementAction, F: SimpleMovementAction> SimpleMovementAction for MovementWithFallback<A, F> {
|
||||
fn get_target(view: &FsTreeView, selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
A::get_target(view, selected_node).or_else(|| F::get_target(view, selected_node))
|
||||
fn get_target(selected_node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> where Self: Sized {
|
||||
A::get_target(selected_node).or_else(|| F::get_target(selected_node))
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use ratatui::widgets::{Clear, Widget};
|
||||
use slab_tree::{NodeId, NodeRef};
|
||||
|
||||
use crate::component::filesystem::{ColumnWidths, FsLayer};
|
||||
use crate::component::filesystem::tree::{FsTree, FsTreeView, FsTreeViewNode};
|
||||
use crate::component::filesystem::tree::{FsTree, FsTreeViewNode};
|
||||
use crate::file::{FileEntry, FileKind, FileOwnerNameCache};
|
||||
use crate::state::view::Frame;
|
||||
|
||||
@ -37,7 +37,7 @@ fn get_or_update_column_widths(layer: &mut FsLayer, cols: u16) -> ColumnWidths {
|
||||
let mut user: usize = 0;
|
||||
let mut group: usize = 0;
|
||||
|
||||
for node in &layer.tree.view {
|
||||
for node in layer.tree.view_iter() {
|
||||
let entry = layer.tree.get_entry(&node).unwrap_or_else(|| FileEntry::dummy_as_ref());
|
||||
|
||||
name = max(name, get_node_level(&node).saturating_add(Span::from(entry.name().str()).width()));
|
||||
@ -63,7 +63,7 @@ fn collect_displayed_rows(tree: &FsTree, selected_node_id: NodeId, terminal_rows
|
||||
let mut displayed_rows = Vec::with_capacity(terminal_rows);
|
||||
let mut cursor_y: u16 = 0;
|
||||
|
||||
if let Some(middle_node) = tree.selected_node().or_else(|| tree.view.root()) {
|
||||
if let Some(middle_node) = tree.selected_node().or_else(|| tree.view_root_node()) {
|
||||
let middle_node_id = middle_node.node_id();
|
||||
|
||||
displayed_rows.push(NodeRow::from(&middle_node, tree, middle_node_id == selected_node_id));
|
||||
@ -72,7 +72,7 @@ fn collect_displayed_rows(tree: &FsTree, selected_node_id: NodeId, terminal_rows
|
||||
let mut cursor_down_id = Some(middle_node_id);
|
||||
|
||||
while displayed_rows.len() < terminal_rows {
|
||||
if let Some(next_node_up) = move_cursor(tree, &mut cursor_up_id, FsTreeView::get_node_above) {
|
||||
if let Some(next_node_up) = move_cursor(tree, &mut cursor_up_id, |node| node.above_id()) {
|
||||
displayed_rows.insert(0, NodeRow::from(&next_node_up, tree, false));
|
||||
cursor_y = cursor_y.saturating_add(1);
|
||||
}
|
||||
@ -81,7 +81,7 @@ fn collect_displayed_rows(tree: &FsTree, selected_node_id: NodeId, terminal_rows
|
||||
break;
|
||||
}
|
||||
|
||||
if let Some(next_node_down) = move_cursor(tree, &mut cursor_down_id, FsTreeView::get_node_below) {
|
||||
if let Some(next_node_down) = move_cursor(tree, &mut cursor_down_id, |node| node.below_id()) {
|
||||
displayed_rows.push(NodeRow::from(&next_node_down, tree, false));
|
||||
}
|
||||
|
||||
@ -94,12 +94,11 @@ fn collect_displayed_rows(tree: &FsTree, selected_node_id: NodeId, terminal_rows
|
||||
(displayed_rows, cursor_y)
|
||||
}
|
||||
|
||||
fn move_cursor<'a, F>(tree: &'a FsTree, cursor: &mut Option<NodeId>, func: F) -> Option<NodeRef<'a, FsTreeViewNode>> where F: FnOnce(&FsTreeView, &NodeRef<FsTreeViewNode>) -> Option<NodeId> {
|
||||
let view = &tree.view;
|
||||
fn move_cursor<'a, F>(tree: &'a FsTree, cursor: &mut Option<NodeId>, func: F) -> Option<NodeRef<'a, FsTreeViewNode>> where F: FnOnce(NodeRef<FsTreeViewNode>) -> Option<NodeId> {
|
||||
let next_node = cursor
|
||||
.and_then(|id| view.get(id))
|
||||
.and_then(|node| func(view, &node))
|
||||
.and_then(|id| view.get(id));
|
||||
.and_then(|id| tree.get_view_node(id))
|
||||
.and_then(func)
|
||||
.and_then(|id| tree.get_view_node(id));
|
||||
|
||||
*cursor = next_node.as_ref().map(NodeRef::node_id);
|
||||
|
||||
|
@ -2,6 +2,7 @@ use std::path::Path;
|
||||
|
||||
use slab_tree::{NodeId, NodeRef};
|
||||
|
||||
use crate::component::filesystem::tree::view::FsTreeViewIterator;
|
||||
use crate::file::FileEntry;
|
||||
|
||||
pub use self::model::FsTreeModel;
|
||||
@ -14,7 +15,7 @@ mod view;
|
||||
|
||||
pub struct FsTree {
|
||||
model: FsTreeModel,
|
||||
pub view: FsTreeView,
|
||||
view: FsTreeView,
|
||||
pub selected_view_node_id: NodeId,
|
||||
structure_version: u32,
|
||||
}
|
||||
@ -44,6 +45,14 @@ impl FsTree {
|
||||
return self.view.get(self.selected_view_node_id);
|
||||
}
|
||||
|
||||
pub fn view_root_node(&self) -> Option<NodeRef<FsTreeViewNode>> {
|
||||
self.view.root()
|
||||
}
|
||||
|
||||
pub fn view_iter(&self) -> FsTreeViewIterator {
|
||||
self.view.into_iter()
|
||||
}
|
||||
|
||||
pub fn get_view_node(&self, view_node_id: NodeId) -> Option<NodeRef<FsTreeViewNode>> {
|
||||
self.view.get(view_node_id)
|
||||
}
|
||||
@ -105,7 +114,7 @@ impl FsTree {
|
||||
let view = &mut self.view;
|
||||
|
||||
if self.selected_view_node_id == view_node_id {
|
||||
self.selected_view_node_id = view.get_node_below_id(view_node_id).or_else(|| view.get_node_above_id(view_node_id)).unwrap_or_else(|| view.root_id());
|
||||
self.selected_view_node_id = view.get(view_node_id).and_then(|node| node.below_id().or_else(|| node.above_id())).unwrap_or_else(|| view.root_id());
|
||||
}
|
||||
|
||||
if let Some(view_node) = view.remove(view_node_id) {
|
||||
|
@ -1,47 +0,0 @@
|
||||
use slab_tree::{NodeId, NodeRef};
|
||||
|
||||
use crate::component::filesystem::tree::{FsTreeView, FsTreeViewNode};
|
||||
|
||||
impl FsTreeView {
|
||||
pub fn get_node_above(&self, node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> {
|
||||
if let Some(prev_sibling_id) = node.prev_sibling_id() {
|
||||
Some(self.get_last_descendant_or_self(prev_sibling_id))
|
||||
} else {
|
||||
node.parent_id()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_self)]
|
||||
pub fn get_node_below(&self, node: &NodeRef<FsTreeViewNode>) -> Option<NodeId> {
|
||||
if let Some(next_id) = node.first_child_id() {
|
||||
Some(next_id)
|
||||
} else if let Some(next_id) = node.next_sibling_id() {
|
||||
Some(next_id)
|
||||
} else {
|
||||
for ancestor in node.ancestors() {
|
||||
if let Some(next_id) = ancestor.next_sibling_id() {
|
||||
return Some(next_id);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_node_above_id(&self, node_id: NodeId) -> Option<NodeId> {
|
||||
self.get(node_id).and_then(|node| self.get_node_above(&node))
|
||||
}
|
||||
|
||||
pub fn get_node_below_id(&self, node_id: NodeId) -> Option<NodeId> {
|
||||
self.get(node_id).and_then(|node| self.get_node_below(&node))
|
||||
}
|
||||
|
||||
pub fn get_last_descendant_or_self(&self, id: NodeId) -> NodeId {
|
||||
let mut id = id;
|
||||
|
||||
while let Some(node_id) = self.get(id).and_then(|node| node.last_child_id()) {
|
||||
id = node_id;
|
||||
}
|
||||
|
||||
id
|
||||
}
|
||||
}
|
@ -2,7 +2,8 @@ use slab_tree::{NodeId, NodeMut, NodeRef, RemoveBehavior, Tree};
|
||||
|
||||
use crate::component::filesystem::tree::FsTreeModel;
|
||||
|
||||
mod above_below;
|
||||
pub use self::iterator::FsTreeViewIterator;
|
||||
|
||||
mod expand_collapse;
|
||||
mod iterator;
|
||||
mod refresh;
|
||||
|
@ -4,13 +4,13 @@ use crate::component::filesystem::tree::{FsTreeModel, FsTreeView, FsTreeViewNode
|
||||
|
||||
impl FsTreeView {
|
||||
pub fn traverse_up_root(&mut self, model: &mut FsTreeModel) -> Option<NodeId> {
|
||||
let old_moodel_root_id = model.root_id();
|
||||
let old_model_root_id = model.root_id();
|
||||
|
||||
if let Some(new_model_root_id) = model.traverse_up_root() {
|
||||
self.set_root(new_model_root_id);
|
||||
|
||||
if let Some(mut new_view_root) = self.get_mut(self.root_id) {
|
||||
Self::resolve_new_root_children(&mut new_view_root, model, old_moodel_root_id, new_model_root_id);
|
||||
Self::resolve_new_root_children(&mut new_view_root, model, old_model_root_id, new_model_root_id);
|
||||
Some(self.root_id)
|
||||
} else {
|
||||
None
|
||||
|
Loading…
Reference in New Issue
Block a user