Skip to main content

beamterm_core/gl/
selection.rs

1use std::{cell::RefCell, fmt::Debug, rc::Rc};
2
3use crate::gl::cell_query::CellQuery;
4
5/// Tracks the active text selection in the terminal grid.
6///
7/// Manages the current selection query and provides methods to update or clear
8/// the selection. Uses interior mutability to allow shared access across
9/// multiple components.
10#[derive(Debug, Clone)]
11pub struct SelectionTracker {
12    inner: Rc<RefCell<SelectionTrackerInner>>,
13}
14
15#[derive(Debug, Default)]
16struct SelectionTrackerInner {
17    query: Option<CellQuery>,
18}
19
20impl SelectionTracker {
21    /// Creates a new selection tracker with no active selection.
22    pub(crate) fn new() -> Self {
23        Self {
24            inner: Rc::new(RefCell::new(SelectionTrackerInner::default())),
25        }
26    }
27
28    /// Clears the current selection.
29    ///
30    /// Removes any active selection from the terminal grid.
31    pub fn clear(&self) {
32        *self.inner.borrow_mut() = SelectionTrackerInner::default();
33    }
34
35    /// Returns the current selection query.
36    ///
37    /// # Panics
38    /// Panics if no selection is active. This is internal-only API where
39    /// a selection is guaranteed to exist when called.
40    pub fn query(&self) -> CellQuery {
41        self.get_query()
42            .expect("query to be a value due to internal-only usage")
43    }
44
45    /// Returns the current selection query or `None` if no selection is active.
46    ///
47    /// Safe version that doesn't panic when no selection exists.
48    pub fn get_query(&self) -> Option<CellQuery> {
49        self.inner.borrow().query
50    }
51
52    /// Sets a new selection query.
53    ///
54    /// Replaces any existing selection with the provided query.
55    pub fn set_query(&self, query: CellQuery) {
56        self.inner.borrow_mut().query = Some(query);
57    }
58
59    /// Updates the end position of the current selection.
60    ///
61    /// Used during mouse drag operations to extend the selection.
62    pub fn update_selection_end(&self, end: (u16, u16)) {
63        if let Some(query) = &mut self.inner.borrow_mut().query {
64            *query = query.end(end);
65        }
66    }
67
68    /// Sets the content hash on the current query.
69    ///
70    /// The hash is stored with the query to detect if underlying content changes.
71    pub fn set_content_hash(&self, hash: u64) {
72        if let Some(query) = &mut self.inner.borrow_mut().query {
73            *query = query.with_content_hash(hash);
74        }
75    }
76}