Track mouse drag IDs

This commit is contained in:
Joshua Barretto 2025-09-25 10:25:51 +01:00
parent 4d50159122
commit df378b46de
3 changed files with 30 additions and 26 deletions

View file

@ -17,20 +17,20 @@ pub enum Dir {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Action { pub enum Action {
Char(char), // Insert a character Char(char), // Insert a character
Indent(bool), // Indent (indent vs deindent) Indent(bool), // Indent (indent vs deindent)
Move(Dir, Dist, bool, bool), // Move the cursor (dir, dist, retain_base, word) Move(Dir, Dist, bool, bool), // Move the cursor (dir, dist, retain_base, word)
Pan(Dir, Dist), // Pan the view window Pan(Dir, Dist), // Pan the view window
PaneMove(Dir), // Move panes PaneMove(Dir), // Move panes
PaneOpen(Dir), // Create a new pane PaneOpen(Dir), // Create a new pane
PaneClose, // Close the current pane PaneClose, // Close the current pane
Cancel, // Cancels the current action Cancel, // Cancels the current action
Continue, // Continue past an info-only element (like a help screen) Continue, // Continue past an info-only element (like a help screen)
Go, // Search, accept, or select the current option Go, // Search, accept, or select the current option
Yes, // A binary confirmation is answered 'yes' Yes, // A binary confirmation is answered 'yes'
No, // A binary confirmation is answered 'no' No, // A binary confirmation is answered 'no'
Quit, // Quit the application Quit, // Quit the application
OpenPrompt, // Open the command prompt OpenPrompt, // Open the command prompt
Show(Option<String>, String), // Display an optionally titled informational text box to the user Show(Option<String>, String), // Display an optionally titled informational text box to the user
OpenSwitcher, // Open the buffer switcher OpenSwitcher, // Open the buffer switcher
OpenOpener(PathBuf), // Open the file opener OpenOpener(PathBuf), // Open the file opener
@ -45,7 +45,7 @@ pub enum Action {
SelectToken, // Fully select the token under the cursor SelectToken, // Fully select the token under the cursor
SelectAll, // Fully select the entire input SelectAll, // Fully select the entire input
Save, // Save the current buffer Save, // Save the current buffer
Mouse(MouseAction, [isize; 2], bool), // (action, pos, is_ctrl) Mouse(MouseAction, [isize; 2], bool, usize), // (action, pos, is_ctrl, drag_id)
Undo, Undo,
Redo, Redo,
Copy, Copy,
@ -495,7 +495,7 @@ impl RawEvent {
} }
} }
pub fn to_mouse(&self, area: Area) -> Option<Action> { pub fn to_mouse(&self, area: Area, drag_id_counter: &mut usize) -> Option<Action> {
let TerminalEvent::Mouse(ev) = self.0 else { let TerminalEvent::Mouse(ev) = self.0 else {
return None; return None;
}; };
@ -504,12 +504,15 @@ impl RawEvent {
let action = match ev.kind { let action = match ev.kind {
MouseEventKind::ScrollUp => MouseAction::ScrollUp, MouseEventKind::ScrollUp => MouseAction::ScrollUp,
MouseEventKind::ScrollDown => MouseAction::ScrollDown, MouseEventKind::ScrollDown => MouseAction::ScrollDown,
MouseEventKind::Down(MouseButton::Left) => MouseAction::Click, MouseEventKind::Down(MouseButton::Left) => {
*drag_id_counter += 1;
MouseAction::Click
}
MouseEventKind::Drag(MouseButton::Left) => MouseAction::Drag, MouseEventKind::Drag(MouseButton::Left) => MouseAction::Drag,
_ => return None, _ => return None,
}; };
let is_ctrl = ev.modifiers == KeyModifiers::CONTROL; let is_ctrl = ev.modifiers == KeyModifiers::CONTROL;
Some(Action::Mouse(action, pos, is_ctrl)) Some(Action::Mouse(action, pos, is_ctrl, *drag_id_counter))
} else { } else {
None None
} }

View file

@ -67,7 +67,6 @@ impl Input {
.or_else(|| e.to_select_token()) .or_else(|| e.to_select_token())
.or_else(|| e.to_select_all()) .or_else(|| e.to_select_all())
.or_else(|| e.to_indent()) .or_else(|| e.to_indent())
.or_else(|| e.to_mouse(self.last_area))
.or_else(|| e.to_edit()) .or_else(|| e.to_edit())
}) { }) {
Some(Action::Char(c)) => { Some(Action::Char(c)) => {
@ -130,7 +129,7 @@ impl Input {
buffer.select_all_cursor(cursor_id); buffer.select_all_cursor(cursor_id);
Ok(Resp::handled(None)) Ok(Resp::handled(None))
} }
Some(Action::Mouse(MouseAction::Click, pos, false)) => { Some(Action::Mouse(MouseAction::Click, pos, false, _)) => {
let pos = [self.focus[0] + pos[0], self.focus[1] + pos[1]]; let pos = [self.focus[0] + pos[0], self.focus[1] + pos[1]];
// If we're already in the right place, select the token instead // If we're already in the right place, select the token instead
if let Some(cursor) = buffer.cursors.get(cursor_id) if let Some(cursor) = buffer.cursors.get(cursor_id)
@ -144,8 +143,8 @@ impl Input {
Ok(Resp::handled(None)) Ok(Resp::handled(None))
} }
Some( Some(
Action::Mouse(MouseAction::Drag, pos, false) Action::Mouse(MouseAction::Drag, pos, false, _)
| Action::Mouse(MouseAction::Click, pos, true), | Action::Mouse(MouseAction::Click, pos, true, _),
) => { ) => {
buffer.goto_cursor( buffer.goto_cursor(
cursor_id, cursor_id,

View file

@ -15,6 +15,7 @@ pub struct Panes {
selected: usize, selected: usize,
panes: Vec<Pane>, panes: Vec<Pane>,
last_area: Area, last_area: Area,
drag_id_counter: usize,
} }
impl Panes { impl Panes {
@ -29,6 +30,7 @@ impl Panes {
}) })
.collect(), .collect(),
last_area: Default::default(), last_area: Default::default(),
drag_id_counter: 0,
} }
} }
@ -44,7 +46,7 @@ impl Element for Panes {
.map(Action::PaneMove) .map(Action::PaneMove)
.or_else(|| e.to_pane_open().map(Action::PaneOpen)) .or_else(|| e.to_pane_open().map(Action::PaneOpen))
.or_else(|| e.to_pane_close()) .or_else(|| e.to_pane_close())
.or_else(|| e.to_mouse(self.last_area)) .or_else(|| e.to_mouse(self.last_area, &mut self.drag_id_counter))
}) { }) {
Some(Action::PaneMove(Dir::Left)) => { Some(Action::PaneMove(Dir::Left)) => {
self.selected = (self.selected + self.panes.len() - 1) % self.panes.len(); self.selected = (self.selected + self.panes.len() - 1) % self.panes.len();
@ -86,14 +88,14 @@ impl Element for Panes {
self.selected = new_idx; self.selected = new_idx;
Ok(Resp::handled(None)) Ok(Resp::handled(None))
} }
Some(Action::Mouse(action, pos, _)) => { Some(ref action @ Action::Mouse(ref m_action, pos, _, _)) => {
for (i, pane) in self.panes.iter_mut().enumerate() { for (i, pane) in self.panes.iter_mut().enumerate() {
if pane.last_area.contains(pos).is_some() { if pane.last_area.contains(pos).is_some() {
if matches!(action, MouseAction::Click) { if matches!(m_action, MouseAction::Click) {
self.selected = i; self.selected = i;
} }
match &mut pane.kind { match &mut pane.kind {
PaneKind::Doc(doc) => return doc.handle(state, event), PaneKind::Doc(doc) => return doc.handle(state, action.clone().into()),
PaneKind::Empty => {} PaneKind::Empty => {}
} }
} }