Make completion documentation scroll & fix accompanying panic from tag

Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
This commit is contained in:
Julia 2023-10-10 10:08:29 -04:00
parent f5af5f7334
commit 801af95a13
3 changed files with 64 additions and 41 deletions

View file

@ -119,7 +119,7 @@ pub const DOCUMENT_HIGHLIGHTS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis
pub const FORMAT_TIMEOUT: Duration = Duration::from_secs(2); pub const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
pub fn render_parsed_markdown( pub fn render_parsed_markdown<Tag: 'static>(
parsed: &language::ParsedMarkdown, parsed: &language::ParsedMarkdown,
editor_style: &EditorStyle, editor_style: &EditorStyle,
cx: &mut ViewContext<Editor>, cx: &mut ViewContext<Editor>,
@ -153,7 +153,7 @@ pub fn render_parsed_markdown(
style: CursorStyle::PointingHand, style: CursorStyle::PointingHand,
}); });
cx.scene().push_mouse_region( cx.scene().push_mouse_region(
MouseRegion::new::<RenderedMarkdown>(view_id, region_id, bounds) MouseRegion::new::<(RenderedMarkdown, Tag)>(view_id, region_id, bounds)
.on_click::<Editor, _>(MouseButton::Left, move |_, _, cx| { .on_click::<Editor, _>(MouseButton::Left, move |_, _, cx| {
cx.platform().open_url(&url) cx.platform().open_url(&url)
}), }),
@ -1247,6 +1247,8 @@ impl CompletionsMenu {
}) })
.with_width_from_item(widest_completion_ix); .with_width_from_item(widest_completion_ix);
enum MultiLineDocumentation {}
Flex::row() Flex::row()
.with_child(list) .with_child(list)
.with_children({ .with_children({
@ -1256,13 +1258,21 @@ impl CompletionsMenu {
let documentation = &completion.documentation; let documentation = &completion.documentation;
match documentation { match documentation {
Some(Documentation::MultiLinePlainText(text)) => { Some(Documentation::MultiLinePlainText(text)) => Some(
Some(Text::new(text.clone(), style.text.clone())) Flex::column()
} .scrollable::<MultiLineDocumentation>(0, None, cx)
.with_child(
Text::new(text.clone(), style.text.clone()).with_soft_wrap(true),
),
),
Some(Documentation::MultiLineMarkdown(parsed)) => { Some(Documentation::MultiLineMarkdown(parsed)) => Some(
Some(render_parsed_markdown(parsed, &style, cx)) Flex::column()
} .scrollable::<MultiLineDocumentation>(0, None, cx)
.with_child(render_parsed_markdown::<MultiLineDocumentation>(
parsed, &style, cx,
)),
),
_ => None, _ => None,
} }

View file

@ -474,8 +474,8 @@ impl InfoPopover {
) -> AnyElement<Editor> { ) -> AnyElement<Editor> {
MouseEventHandler::new::<InfoPopover, _>(0, cx, |_, cx| { MouseEventHandler::new::<InfoPopover, _>(0, cx, |_, cx| {
Flex::column() Flex::column()
.scrollable::<HoverBlock>(1, None, cx) .scrollable::<HoverBlock>(0, None, cx)
.with_child(crate::render_parsed_markdown( .with_child(crate::render_parsed_markdown::<HoverBlock>(
&self.parsed_content, &self.parsed_content,
style, style,
cx, cx,

View file

@ -2,7 +2,8 @@ use std::{any::Any, cell::Cell, f32::INFINITY, ops::Range, rc::Rc};
use crate::{ use crate::{
json::{self, ToJson, Value}, json::{self, ToJson, Value},
AnyElement, Axis, Element, ElementStateHandle, SizeConstraint, Vector2FExt, ViewContext, AnyElement, Axis, Element, ElementStateHandle, SizeConstraint, TypeTag, Vector2FExt,
ViewContext,
}; };
use pathfinder_geometry::{ use pathfinder_geometry::{
rect::RectF, rect::RectF,
@ -10,10 +11,10 @@ use pathfinder_geometry::{
}; };
use serde_json::json; use serde_json::json;
#[derive(Default)]
struct ScrollState { struct ScrollState {
scroll_to: Cell<Option<usize>>, scroll_to: Cell<Option<usize>>,
scroll_position: Cell<f32>, scroll_position: Cell<f32>,
type_tag: TypeTag,
} }
pub struct Flex<V> { pub struct Flex<V> {
@ -66,8 +67,14 @@ impl<V: 'static> Flex<V> {
where where
Tag: 'static, Tag: 'static,
{ {
let scroll_state = cx.default_element_state::<Tag, Rc<ScrollState>>(element_id); let scroll_state = cx.element_state::<Tag, Rc<ScrollState>>(
scroll_state.read(cx).scroll_to.set(scroll_to); element_id,
Rc::new(ScrollState {
scroll_to: Cell::new(scroll_to),
scroll_position: Default::default(),
type_tag: TypeTag::new::<Tag>(),
}),
);
self.scroll_state = Some((scroll_state, cx.handle().id())); self.scroll_state = Some((scroll_state, cx.handle().id()));
self self
} }
@ -276,38 +283,44 @@ impl<V: 'static> Element<V> for Flex<V> {
if let Some((scroll_state, id)) = &self.scroll_state { if let Some((scroll_state, id)) = &self.scroll_state {
let scroll_state = scroll_state.read(cx).clone(); let scroll_state = scroll_state.read(cx).clone();
cx.scene().push_mouse_region( cx.scene().push_mouse_region(
crate::MouseRegion::new::<Self>(*id, 0, bounds) crate::MouseRegion::from_handlers(
.on_scroll({ scroll_state.type_tag,
let axis = self.axis; *id,
move |e, _: &mut V, cx| { 0,
if remaining_space < 0. { bounds,
let scroll_delta = e.delta.raw(); Default::default(),
)
.on_scroll({
let axis = self.axis;
move |e, _: &mut V, cx| {
if remaining_space < 0. {
let scroll_delta = e.delta.raw();
let mut delta = match axis { let mut delta = match axis {
Axis::Horizontal => { Axis::Horizontal => {
if scroll_delta.x().abs() >= scroll_delta.y().abs() { if scroll_delta.x().abs() >= scroll_delta.y().abs() {
scroll_delta.x() scroll_delta.x()
} else { } else {
scroll_delta.y() scroll_delta.y()
}
} }
Axis::Vertical => scroll_delta.y(),
};
if !e.delta.precise() {
delta *= 20.;
} }
Axis::Vertical => scroll_delta.y(),
scroll_state };
.scroll_position if !e.delta.precise() {
.set(scroll_state.scroll_position.get() - delta); delta *= 20.;
cx.notify();
} else {
cx.propagate_event();
} }
scroll_state
.scroll_position
.set(scroll_state.scroll_position.get() - delta);
cx.notify();
} else {
cx.propagate_event();
} }
}) }
.on_move(|_, _: &mut V, _| { /* Capture move events */ }), })
.on_move(|_, _: &mut V, _| { /* Capture move events */ }),
) )
} }