use crate::app::input::handlers::{self, ScrollableTag};
use crate::core::event::MouseEvent;
use crate::core::node::{NodeKind, NodeTree};
use crate::widgets::internal::scroll_action_from_mouse_n;
pub(crate) fn handle_scroll_wheel_n(
tree: &mut NodeTree,
event: MouseEvent,
scroll_ticks: usize,
fallback_multiplier: u16,
) -> bool {
let Some(hit) = tree.hit_test(event.x as i16, event.y as i16) else {
return false;
};
let mut cur = Some(hit);
while let Some(id) = cur {
if !tree.is_valid(id) {
break;
}
let tag = handlers::classify_scrollable(&tree.node(id).kind);
let parent = tree.node(id).parent;
let scroll_lines = effective_scroll_lines(
&tree.node(id).kind,
scroll_ticks,
fallback_multiplier,
event.mods.shift,
);
let Some(action) = scroll_action_from_mouse_n(event, scroll_lines) else {
return false;
};
let parent_integrated_v_edge = if tag == ScrollableTag::TextArea {
tree.parent_frame_integrated_v_edge(id).unwrap_or(false)
} else {
false
};
let handled = match tag {
ScrollableTag::List => handlers::list_table::handle_list_scroll(tree, id, action),
ScrollableTag::Table => handlers::list_table::handle_table_scroll(tree, id, action),
ScrollableTag::ScrollView => handlers::scroll_view::handle_scroll(tree, id, action),
ScrollableTag::TextArea => {
handlers::text_area::handle_scroll(tree, id, action, parent_integrated_v_edge)
}
ScrollableTag::HexArea => handlers::hex_area::handle_scroll(tree, id, action),
#[cfg(feature = "terminal")]
ScrollableTag::Terminal => handlers::terminal::handle_scroll(tree, id, action),
ScrollableTag::DraggableTabBar => {
handlers::tabs::handle_tab_bar_scroll(tree, id, action)
}
ScrollableTag::DocumentView => handlers::document_view::handle_scroll(tree, id, action),
ScrollableTag::NonScrollable => false,
};
if handled {
return true;
}
cur = parent;
}
false
}
fn effective_scroll_lines(
kind: &NodeKind,
scroll_ticks: usize,
fallback_multiplier: u16,
horizontal: bool,
) -> usize {
let multiplier = match kind {
NodeKind::ScrollView(node) if horizontal => node
.h_scroll_wheel_multiplier
.or(node.scroll_wheel_multiplier)
.unwrap_or(fallback_multiplier),
NodeKind::ScrollView(node) => node.scroll_wheel_multiplier.unwrap_or(fallback_multiplier),
NodeKind::TextArea(node) => node.scroll_wheel_multiplier.unwrap_or(fallback_multiplier),
NodeKind::DocumentView(node) => node.scroll_wheel_multiplier.unwrap_or(fallback_multiplier),
_ => fallback_multiplier,
};
scroll_ticks.saturating_mul(usize::from(multiplier.max(1)))
}