#[derive(Clone, Debug, Default)]
pub struct SelectionEndpoint {
pub(crate) node_or_parent: Option<usize>,
pub offset: usize,
pub(crate) sibling_index: Option<usize>,
}
impl SelectionEndpoint {
fn new(node: usize, offset: usize) -> Self {
Self {
node_or_parent: Some(node),
offset,
sibling_index: None,
}
}
pub fn is_some(&self) -> bool {
self.node_or_parent.is_some()
}
pub fn clear(&mut self) {
self.node_or_parent = None;
self.offset = 0;
self.sibling_index = None;
}
pub fn resolve_node_id(
&self,
lookup_fn: impl FnOnce(usize, usize) -> Option<usize>,
) -> Option<usize> {
match (self.node_or_parent, self.sibling_index) {
(Some(node), None) => Some(node),
(Some(parent), Some(idx)) => lookup_fn(parent, idx),
_ => None,
}
}
pub fn set_node(&mut self, node: usize, offset: usize) {
self.node_or_parent = Some(node);
self.offset = offset;
self.sibling_index = None;
}
pub fn set_anonymous(&mut self, parent: usize, sibling_index: usize, offset: usize) {
self.node_or_parent = Some(parent);
self.offset = offset;
self.sibling_index = Some(sibling_index);
}
}
#[derive(Clone, Debug, Default)]
pub struct TextSelection {
pub anchor: SelectionEndpoint,
pub focus: SelectionEndpoint,
}
impl TextSelection {
pub fn new(
anchor_node: usize,
anchor_offset: usize,
focus_node: usize,
focus_offset: usize,
) -> Self {
Self {
anchor: SelectionEndpoint::new(anchor_node, anchor_offset),
focus: SelectionEndpoint::new(focus_node, focus_offset),
}
}
pub fn is_active(&self) -> bool {
self.anchor.is_some()
&& self.focus.is_some()
&& (self.anchor.node_or_parent != self.focus.node_or_parent
|| self.anchor.sibling_index != self.focus.sibling_index
|| self.anchor.offset != self.focus.offset)
}
pub fn clear(&mut self) {
self.anchor.clear();
self.focus.clear();
}
pub fn set_focus(&mut self, node: usize, offset: usize) {
self.focus.set_node(node, offset);
}
}