1use super::*;
4
5impl Editor {
6 pub(super) fn checkbox_at(&self, at: gpui::Point<gpui::Pixels>) -> Option<usize> {
11 let ix = self.layouts.block_at(at)?;
12 self.layouts
13 .checkbox_bounds(ix)
14 .is_some_and(|bounds| bounds.contains(&at))
15 .then_some(ix)
16 }
17
18 pub(super) fn append_tail(&mut self, cx: &mut Context<Self>) -> bool {
23 let Some(last) = self.doc.blocks.len().checked_sub(1) else {
24 return false;
25 };
26 if !self.blocks() {
27 return false;
28 }
29 if self.doc.blocks[last].parts().last() == Some(&Part::Body) {
30 return false;
31 }
32 self.edit(EditKind::Structure, cx, |this| {
33 this.doc
34 .blocks
35 .push(markdown::Block::new(BlockKind::Paragraph(Text::default())));
36 let ix = this.doc.blocks.len() - 1;
37 this.selection = Selection::at(Cursor::new(ix, Part::Body, 0).clamp(&this.doc));
38 vec![]
39 });
40 true
41 }
42
43 pub fn press(
51 &mut self,
52 position: gpui::Point<gpui::Pixels>,
53 click_count: usize,
54 modifiers: gpui::Modifiers,
55 window: &mut Window,
56 cx: &mut Context<Self>,
57 ) {
58 if window.default_prevented() {
59 return;
60 }
61 window.prevent_default();
62 self.pressed(position, click_count, modifiers, window, cx);
63 }
64
65 pub(super) fn in_drag(&self) -> bool {
68 self.dragging || self.lifted.is_some() || self.resizing.is_some()
69 }
70
71 pub(super) fn drag_to(&mut self, position: gpui::Point<gpui::Pixels>, cx: &mut Context<Self>) {
73 if let Some((from, _)) = self.lifted {
75 if let Some(to) = self.layouts.block_at(position) {
76 self.lifted = Some((from, to));
77 cx.notify();
78 }
79 return;
80 }
81 if let Some((ix, _)) = self.resizing {
84 if let Some(width) = self.dragged_width(ix, position.x) {
85 self.resizing = Some((ix, Some(width)));
86 cx.notify();
87 }
88 return;
89 }
90 if self.dragging
91 && let Some(hit) = self.layouts.hit(position)
92 {
93 self.selection = self.selection.extend_to(hit).clamp(&self.doc);
94 cx.notify();
95 }
96 }
97
98 pub(super) fn pressed(
99 &mut self,
100 position: gpui::Point<gpui::Pixels>,
101 click_count: usize,
102 modifiers: gpui::Modifiers,
103 window: &mut Window,
104 cx: &mut Context<Self>,
105 ) {
106 ui::popover::close_popup(self, cx, |this| &mut this.block_menu);
107 ui::popover::close_popup(self, cx, |this| &mut this.language_menu);
108 self.pasted = None;
109 self.focus_handle.clone().focus(window, cx);
110 if let Some(ix) = self.checkbox_at(position) {
114 self.toggle_task(ix, cx);
115 return;
116 }
117 if self.tail_click(position, cx) {
118 return;
119 }
120 let Some(hit) = self.layouts.hit(position) else {
121 return cx.notify();
122 };
123 self.selection = match click_count {
124 _ if modifiers.shift => self.selection.extend_to(hit),
127 1 => Selection::at(hit),
128 2 => Selection::new(hit.word_left(&self.doc), hit.word_right(&self.doc)),
129 _ => Selection::new(hit.home(), hit.end(&self.doc)),
130 }
131 .clamp(&self.doc);
132 self.dragging = click_count == 1 && !modifiers.shift;
133 self.history.interrupt();
134 self.caret_moved();
135 if let Some(id) = self.anchor_at(position) {
138 cx.emit(EditorEvent::AnchorActivated(id));
139 }
140 cx.notify();
141 }
142
143 pub(super) fn tail_click(
147 &mut self,
148 at: gpui::Point<gpui::Pixels>,
149 cx: &mut Context<Self>,
150 ) -> bool {
151 let Some(last) = self.doc.blocks.len().checked_sub(1) else {
152 return false;
153 };
154 let Some(bounds) = self.layouts.block_bounds(last) else {
155 return false;
156 };
157 at.y > bounds.origin.y + bounds.size.height && self.append_tail(cx)
158 }
159}