refactor: extract block state helper
This commit is contained in:
@@ -3,7 +3,12 @@
|
||||
//! 本模块只承接拖拽命中所需的窄 helper,不处理 Leptos signal,
|
||||
//! 也不分发 editor command;调用方负责保留编辑器状态编排。
|
||||
|
||||
use crate::editor_runtime::block_hover_state::{DropIndicatorState, DropPlacement};
|
||||
use crate::{
|
||||
editor_runtime::block_hover_state::{
|
||||
block_label_for_element, DropIndicatorState, DropPlacement, HoveredBlockState,
|
||||
},
|
||||
editor_root_element, editor_stage_element,
|
||||
};
|
||||
use web_sys::{window, Element, EventTarget};
|
||||
|
||||
pub(crate) struct HandleCorridorGeometry {
|
||||
@@ -124,6 +129,78 @@ pub(crate) fn drop_indicator_from_block_rects(
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn block_state_from_index(index: usize) -> Option<HoveredBlockState> {
|
||||
let root = editor_root_element()?;
|
||||
let stage = editor_stage_element()?;
|
||||
let block = root.children().item(index as u32)?;
|
||||
let block_rect = block.get_bounding_client_rect();
|
||||
let stage_rect = stage.get_bounding_client_rect();
|
||||
let block_height = if block_rect.height() > 0.0 {
|
||||
block_rect.height()
|
||||
} else {
|
||||
28.0
|
||||
};
|
||||
|
||||
Some(HoveredBlockState {
|
||||
index,
|
||||
label: block_label_for_element(&block),
|
||||
top: block_rect.top() - stage_rect.top(),
|
||||
height: block_height,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn pointer_in_handle_corridor(
|
||||
client_x: i32,
|
||||
client_y: i32,
|
||||
block: &HoveredBlockState,
|
||||
handle_selector: &str,
|
||||
handle_left_fallback: f64,
|
||||
handle_width: f64,
|
||||
) -> bool {
|
||||
let Some(stage) = editor_stage_element() else {
|
||||
return false;
|
||||
};
|
||||
let Some(root) = editor_root_element() else {
|
||||
return false;
|
||||
};
|
||||
let Some(block_element) = root.children().item(block.index as u32) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let stage_rect = stage.get_bounding_client_rect();
|
||||
let block_rect = block_element.get_bounding_client_rect();
|
||||
let handle_rect = window()
|
||||
.and_then(|win| win.document())
|
||||
.and_then(|document| document.query_selector(handle_selector).ok().flatten())
|
||||
.map(|handle| handle.get_bounding_client_rect());
|
||||
|
||||
let block_left = block_rect.left() - stage_rect.left();
|
||||
let block_top = block_rect.top() - stage_rect.top();
|
||||
let block_bottom = block_rect.bottom() - stage_rect.top();
|
||||
let handle_left = handle_rect
|
||||
.as_ref()
|
||||
.map(|rect| rect.left() - stage_rect.left())
|
||||
.unwrap_or(handle_left_fallback);
|
||||
let handle_right = handle_rect
|
||||
.as_ref()
|
||||
.map(|rect| rect.right() - stage_rect.left())
|
||||
.unwrap_or_else(|| handle_left + handle_width);
|
||||
|
||||
pointer_in_handle_corridor_geometry(
|
||||
client_x,
|
||||
client_y,
|
||||
&HandleCorridorGeometry {
|
||||
stage_left: stage_rect.left(),
|
||||
stage_top: stage_rect.top(),
|
||||
block_left,
|
||||
block_top,
|
||||
block_bottom,
|
||||
handle_left,
|
||||
handle_right,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn top_level_block_index(root: &Element, block: &Element) -> Option<usize> {
|
||||
let children = root.children();
|
||||
(0..children.length()).find_map(|index| {
|
||||
|
||||
Reference in New Issue
Block a user