1
0
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:
chylex 2023-08-27 14:36:37 +02:00
parent dace27d259
commit 63b56de63f
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
11 changed files with 80 additions and 86 deletions

View File

@ -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> {

View File

@ -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 {

View File

@ -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() {

View File

@ -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
}
}

View File

@ -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))
}

View File

@ -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))
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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
}
}

View File

@ -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;

View File

@ -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