Detailed changes
@@ -686,26 +686,9 @@ fn diagnostic_header_renderer(entry: DiagnosticEntry<Point>, path: ProjectPath)
})
.with_tooltip(
entry.diagnostic.group_id,
- Flex::row()
- .with_child(
- Label::new(
- "Jump to diagnostic (".to_string(),
- tooltip_style.text.clone(),
- )
- .boxed(),
- )
- .with_child(
- KeystrokeLabel::new(
- Box::new(editor::OpenExcerpts),
- Default::default(),
- tooltip_style.text.clone(),
- )
- .boxed(),
- )
- .with_child(Label::new(")".to_string(), tooltip_style.text).boxed())
- .contained()
- .with_style(tooltip_style.container)
- .boxed(),
+ "Jump to diagnostic".to_string(),
+ Some(Box::new(editor::OpenExcerpts)),
+ tooltip_style,
cx,
)
.aligned()
@@ -31,7 +31,7 @@ use crate::{
rect::RectF,
vector::{vec2f, Vector2F},
},
- json, DebugContext, Event, EventContext, LayoutContext, PaintContext, RenderContext,
+ json, Action, DebugContext, Event, EventContext, LayoutContext, PaintContext, RenderContext,
SizeConstraint, View,
};
use core::panic;
@@ -160,13 +160,15 @@ pub trait Element {
fn with_tooltip<T: View>(
self,
id: usize,
- tooltip: ElementBox,
+ text: String,
+ action: Option<Box<dyn Action>>,
+ style: TooltipStyle,
cx: &mut RenderContext<T>,
) -> Tooltip
where
Self: 'static + Sized,
{
- Tooltip::new(id, self.boxed(), tooltip, cx)
+ Tooltip::new(id, text, action, style, self.boxed(), cx)
}
}
@@ -1,14 +1,19 @@
-use std::{
- cell::{Cell, RefCell},
- rc::Rc,
- time::Duration,
+use super::{
+ ContainerStyle, Element, ElementBox, Flex, KeystrokeLabel, MouseEventHandler, ParentElement,
+ Text,
};
-
-use super::{Element, ElementBox, MouseEventHandler};
use crate::{
+ fonts::TextStyle,
geometry::{rect::RectF, vector::Vector2F},
json::json,
- ElementStateHandle, LayoutContext, PaintContext, RenderContext, SizeConstraint, Task, View,
+ Action, Axis, ElementStateHandle, LayoutContext, PaintContext, RenderContext, SizeConstraint,
+ Task, View,
+};
+use serde::Deserialize;
+use std::{
+ cell::{Cell, RefCell},
+ rc::Rc,
+ time::Duration,
};
const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(500);
@@ -26,17 +31,53 @@ struct TooltipState {
debounce: RefCell<Option<Task<()>>>,
}
+#[derive(Clone, Deserialize, Default)]
+pub struct TooltipStyle {
+ #[serde(flatten)]
+ container: ContainerStyle,
+ text: TextStyle,
+ keystroke: KeystrokeStyle,
+ max_text_width: f32,
+}
+
+#[derive(Clone, Deserialize, Default)]
+pub struct KeystrokeStyle {
+ #[serde(flatten)]
+ container: ContainerStyle,
+ #[serde(flatten)]
+ text: TextStyle,
+}
+
impl Tooltip {
pub fn new<T: View>(
id: usize,
+ text: String,
+ action: Option<Box<dyn Action>>,
+ style: TooltipStyle,
child: ElementBox,
- tooltip: ElementBox,
cx: &mut RenderContext<T>,
) -> Self {
let state_handle = cx.element_state::<TooltipState, Rc<TooltipState>>(id);
let state = state_handle.read(cx).clone();
let tooltip = if state.visible.get() {
- Some(tooltip)
+ let mut collapsed_tooltip = Self::render_tooltip(
+ text.clone(),
+ style.clone(),
+ action.as_ref().map(|a| a.boxed_clone()),
+ true,
+ )
+ .boxed();
+ Some(
+ Self::render_tooltip(text, style, action, false)
+ .constrained()
+ .dynamically(move |constraint, cx| {
+ SizeConstraint::strict_along(
+ Axis::Vertical,
+ collapsed_tooltip.layout(constraint, cx).y(),
+ )
+ })
+ .boxed(),
+ )
} else {
None
};
@@ -73,6 +114,36 @@ impl Tooltip {
state: state_handle,
}
}
+
+ fn render_tooltip(
+ text: String,
+ style: TooltipStyle,
+ action: Option<Box<dyn Action>>,
+ measure: bool,
+ ) -> impl Element {
+ Flex::row()
+ .with_child({
+ let text = Text::new(text, style.text)
+ .constrained()
+ .with_max_width(style.max_text_width);
+ if measure {
+ text.flex(1., false).boxed()
+ } else {
+ text.flex(1., false).aligned().boxed()
+ }
+ })
+ .with_children(action.map(|action| {
+ let keystroke_label =
+ KeystrokeLabel::new(action, style.keystroke.container, style.keystroke.text);
+ if measure {
+ keystroke_label.boxed()
+ } else {
+ keystroke_label.aligned().boxed()
+ }
+ }))
+ .contained()
+ .with_style(style.container)
+ }
}
impl Element for Tooltip {
@@ -2,7 +2,7 @@ mod theme_registry;
use gpui::{
color::Color,
- elements::{ContainerStyle, ImageStyle, LabelStyle},
+ elements::{ContainerStyle, ImageStyle, LabelStyle, TooltipStyle},
fonts::{HighlightStyle, TextStyle},
Border, MouseState,
};
@@ -31,7 +31,7 @@ pub struct Theme {
pub project_diagnostics: ProjectDiagnostics,
pub breadcrumbs: ContainedText,
pub contact_notification: ContactNotification,
- pub tooltip: ContainedText,
+ pub tooltip: TooltipStyle,
}
#[derive(Deserialize, Default)]
@@ -9,6 +9,14 @@ export default function tooltip(theme: Theme) {
margin: { top: 6, left: 6 },
shadow: shadow(theme),
cornerRadius: 6,
- ...text(theme, "sans", "secondary", { size: "xs", weight: "bold" })
+ text: text(theme, "sans", "secondary", { size: "xs", weight: "bold" }),
+ keystroke: {
+ background: backgroundColor(theme, "on500"),
+ cornerRadius: 4,
+ margin: { left: 6 },
+ padding: { left: 3, right: 3 },
+ ...text(theme, "mono", "muted", { size: "xs", weight: "bold" })
+ },
+ maxTextWidth: 200,
}
}