diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index c8ce37d7e2..efcde2d328 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -154,7 +154,6 @@ pub fn render_parsed_markdown( ); let runs = text_runs_for_highlights(&parsed.text, &editor_style.text, highlights); - // todo!("add the ability to change cursor style for link ranges") let mut links = Vec::new(); let mut link_ranges = Vec::new(); for (range, region) in parsed.region_ranges.iter().zip(&parsed.regions) { diff --git a/crates/gpui2/src/elements/text.rs b/crates/gpui2/src/elements/text.rs index a0715b81a9..d57daca062 100644 --- a/crates/gpui2/src/elements/text.rs +++ b/crates/gpui2/src/elements/text.rs @@ -265,7 +265,9 @@ impl TextState { pub struct InteractiveText { element_id: ElementId, text: StyledText, - click_listener: Option)>>, + click_listener: + Option], InteractiveTextClickEvent, &mut WindowContext<'_>)>>, + clickable_ranges: Vec>, } struct InteractiveTextClickEvent { @@ -284,6 +286,7 @@ impl InteractiveText { element_id: id.into(), text, click_listener: None, + clickable_ranges: Vec::new(), } } @@ -292,7 +295,7 @@ impl InteractiveText { ranges: Vec>, listener: impl Fn(usize, &mut WindowContext<'_>) + 'static, ) -> Self { - self.click_listener = Some(Box::new(move |event, cx| { + self.click_listener = Some(Box::new(move |ranges, event, cx| { for (range_ix, range) in ranges.iter().enumerate() { if range.contains(&event.mouse_down_index) && range.contains(&event.mouse_up_index) { @@ -300,6 +303,7 @@ impl InteractiveText { } } })); + self.clickable_ranges = ranges; self } } @@ -334,6 +338,19 @@ impl Element for InteractiveText { fn paint(self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { if let Some(click_listener) = self.click_listener { + if let Some(ix) = state + .text_state + .index_for_position(bounds, cx.mouse_position()) + { + if self + .clickable_ranges + .iter() + .any(|range| range.contains(&ix)) + { + cx.set_cursor_style(crate::CursorStyle::PointingHand) + } + } + let text_state = state.text_state.clone(); let mouse_down = state.mouse_down_index.clone(); if let Some(mouse_down_index) = mouse_down.get() { @@ -343,6 +360,7 @@ impl Element for InteractiveText { text_state.index_for_position(bounds, event.position) { click_listener( + &self.clickable_ranges, InteractiveTextClickEvent { mouse_down_index, mouse_up_index,