WIP, almost done with tooltips
This commit is contained in:
parent
a686a9f1d2
commit
d2d49633f1
4 changed files with 138 additions and 18 deletions
|
@ -7,15 +7,17 @@ use alacritty_terminal::{
|
|||
use editor::{Cursor, CursorShape, HighlightedRange, HighlightedRangeLine};
|
||||
use gpui::{
|
||||
color::Color,
|
||||
fonts::{Properties, Style::Italic, TextStyle, Underline, Weight},
|
||||
elements::{Overlay, Tooltip},
|
||||
fonts::{HighlightStyle, Properties, Style::Italic, TextStyle, Underline, Weight},
|
||||
geometry::{
|
||||
rect::RectF,
|
||||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
serde_json::json,
|
||||
text_layout::{Line, RunStyle},
|
||||
Element, Event, EventContext, FontCache, KeyDownEvent, ModelContext, MouseButton, MouseRegion,
|
||||
PaintContext, Quad, TextLayoutCache, WeakModelHandle, WeakViewHandle,
|
||||
Axis, Element, ElementBox, Event, EventContext, FontCache, KeyDownEvent, ModelContext,
|
||||
ModifiersChangedEvent, MouseButton, MouseRegion, PaintContext, Quad, SizeConstraint,
|
||||
TextLayoutCache, WeakModelHandle, WeakViewHandle,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use ordered_float::OrderedFloat;
|
||||
|
@ -42,6 +44,7 @@ pub struct LayoutState {
|
|||
size: TerminalSize,
|
||||
mode: TermMode,
|
||||
display_offset: usize,
|
||||
hyperlink_tooltip: Option<ElementBox>,
|
||||
}
|
||||
|
||||
///Helper struct for converting data between alacritty's cursor points, and displayed cursor points
|
||||
|
@ -180,6 +183,7 @@ impl TerminalElement {
|
|||
text_layout_cache: &TextLayoutCache,
|
||||
font_cache: &FontCache,
|
||||
modal: bool,
|
||||
hyperlink: Option<(HighlightStyle, &RangeInclusive<Point>)>,
|
||||
) -> (Vec<LayoutCell>, Vec<LayoutRect>) {
|
||||
let mut cells = vec![];
|
||||
let mut rects = vec![];
|
||||
|
@ -245,6 +249,7 @@ impl TerminalElement {
|
|||
text_style,
|
||||
font_cache,
|
||||
modal,
|
||||
hyperlink,
|
||||
);
|
||||
|
||||
let layout_cell = text_layout_cache.layout_str(
|
||||
|
@ -304,6 +309,7 @@ impl TerminalElement {
|
|||
text_style: &TextStyle,
|
||||
font_cache: &FontCache,
|
||||
modal: bool,
|
||||
hyperlink: Option<(HighlightStyle, &RangeInclusive<Point>)>,
|
||||
) -> RunStyle {
|
||||
let flags = indexed.cell.flags;
|
||||
let fg = convert_color(&fg, &style.colors, modal);
|
||||
|
@ -339,11 +345,25 @@ impl TerminalElement {
|
|||
.select_font(text_style.font_family_id, &properties)
|
||||
.unwrap_or(text_style.font_id);
|
||||
|
||||
RunStyle {
|
||||
let mut result = RunStyle {
|
||||
color: fg,
|
||||
font_id,
|
||||
underline,
|
||||
};
|
||||
|
||||
if let Some((style, range)) = hyperlink {
|
||||
if range.contains(&indexed.point) {
|
||||
if let Some(underline) = style.underline {
|
||||
result.underline = underline;
|
||||
}
|
||||
|
||||
if let Some(color) = style.color {
|
||||
result.color = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn generic_button_handler<E>(
|
||||
|
@ -373,7 +393,7 @@ impl TerminalElement {
|
|||
) {
|
||||
let connection = self.terminal;
|
||||
|
||||
let mut region = MouseRegion::new::<Self>(view_id, view_id, visible_bounds);
|
||||
let mut region = MouseRegion::new::<Self>(view_id, 0, visible_bounds);
|
||||
|
||||
// Terminal Emulator controlled behavior:
|
||||
region = region
|
||||
|
@ -549,6 +569,9 @@ impl Element for TerminalElement {
|
|||
|
||||
//Setup layout information
|
||||
let terminal_theme = settings.theme.terminal.clone(); //TODO: Try to minimize this clone.
|
||||
let link_style = settings.theme.editor.link_definition;
|
||||
let tooltip_style = settings.theme.tooltip.clone();
|
||||
|
||||
let text_style = TerminalElement::make_text_style(font_cache, settings);
|
||||
let selection_color = settings.theme.editor.selection.selection;
|
||||
let match_color = settings.theme.search.match_background;
|
||||
|
@ -571,9 +594,51 @@ impl Element for TerminalElement {
|
|||
};
|
||||
let terminal_handle = self.terminal.upgrade(cx).unwrap();
|
||||
|
||||
terminal_handle.update(cx.app, |terminal, cx| {
|
||||
terminal.set_size(dimensions);
|
||||
terminal.try_sync(cx)
|
||||
let (last_hovered_hyperlink, last_mouse) =
|
||||
terminal_handle.update(cx.app, |terminal, cx| {
|
||||
terminal.set_size(dimensions);
|
||||
terminal.try_sync(cx);
|
||||
(
|
||||
terminal.last_content.last_hovered_hyperlink.clone(),
|
||||
terminal.last_mouse_position,
|
||||
)
|
||||
});
|
||||
|
||||
let view_handle = self.view.clone();
|
||||
let hyperlink_tooltip = last_hovered_hyperlink.and_then(|(uri, _)| {
|
||||
last_mouse.and_then(|last_mouse| {
|
||||
view_handle.upgrade(cx).map(|handle| {
|
||||
let mut tooltip = cx.render(&handle, |_, cx| {
|
||||
// TODO: Use the correct dynamic line height
|
||||
// let mut collapsed_tooltip = Tooltip::render_tooltip(
|
||||
// uri.clone(),
|
||||
// tooltip_style.clone(),
|
||||
// None,
|
||||
// false,
|
||||
// )
|
||||
// .boxed();
|
||||
|
||||
Overlay::new(
|
||||
Tooltip::render_tooltip(uri, tooltip_style, None, false)
|
||||
.constrained()
|
||||
.with_height(text_style.line_height(cx.font_cache()))
|
||||
// .dynamically(move |constraint, cx| {
|
||||
// SizeConstraint::strict_along(
|
||||
// Axis::Vertical,
|
||||
// collapsed_tooltip.layout(constraint, cx).y(),
|
||||
// )
|
||||
// })
|
||||
.boxed(),
|
||||
)
|
||||
.with_fit_mode(gpui::elements::OverlayFitMode::SwitchAnchor)
|
||||
.with_anchor_position(last_mouse)
|
||||
.boxed()
|
||||
});
|
||||
|
||||
tooltip.layout(SizeConstraint::new(Vector2F::zero(), cx.window_size), cx);
|
||||
tooltip
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
let TerminalContent {
|
||||
|
@ -585,7 +650,7 @@ impl Element for TerminalElement {
|
|||
cursor,
|
||||
last_hovered_hyperlink,
|
||||
..
|
||||
} = &terminal_handle.read(cx).last_content;
|
||||
} = { &terminal_handle.read(cx).last_content };
|
||||
|
||||
// searches, highlights to a single range representations
|
||||
let mut relative_highlighted_ranges = Vec::new();
|
||||
|
@ -605,6 +670,9 @@ impl Element for TerminalElement {
|
|||
cx.text_layout_cache,
|
||||
cx.font_cache(),
|
||||
self.modal,
|
||||
last_hovered_hyperlink
|
||||
.as_ref()
|
||||
.map(|(_, range)| (link_style, range)),
|
||||
);
|
||||
|
||||
//Layout cursor. Rectangle is used for IME, so we should lay it out even
|
||||
|
@ -636,10 +704,11 @@ impl Element for TerminalElement {
|
|||
)
|
||||
};
|
||||
|
||||
let focused = self.focused;
|
||||
TerminalElement::shape_cursor(cursor_point, dimensions, &cursor_text).map(
|
||||
move |(cursor_position, block_width)| {
|
||||
let shape = match cursor.shape {
|
||||
AlacCursorShape::Block if !self.focused => CursorShape::Hollow,
|
||||
AlacCursorShape::Block if !focused => CursorShape::Hollow,
|
||||
AlacCursorShape::Block => CursorShape::Block,
|
||||
AlacCursorShape::Underline => CursorShape::Underscore,
|
||||
AlacCursorShape::Beam => CursorShape::Bar,
|
||||
|
@ -672,6 +741,7 @@ impl Element for TerminalElement {
|
|||
relative_highlighted_ranges,
|
||||
mode: *mode,
|
||||
display_offset: *display_offset,
|
||||
hyperlink_tooltip,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -694,7 +764,11 @@ impl Element for TerminalElement {
|
|||
|
||||
cx.scene.push_cursor_region(gpui::CursorRegion {
|
||||
bounds,
|
||||
style: gpui::CursorStyle::IBeam,
|
||||
style: if layout.hyperlink_tooltip.is_some() {
|
||||
gpui::CursorStyle::PointingHand
|
||||
} else {
|
||||
gpui::CursorStyle::IBeam
|
||||
},
|
||||
});
|
||||
|
||||
cx.paint_layer(clip_bounds, |cx| {
|
||||
|
@ -746,6 +820,15 @@ impl Element for TerminalElement {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(element) = &mut layout.hyperlink_tooltip {
|
||||
element.paint(
|
||||
visible_bounds.lower_left()
|
||||
- vec2f(-layout.size.cell_width, layout.size.line_height),
|
||||
visible_bounds,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -784,6 +867,18 @@ impl Element for TerminalElement {
|
|||
})
|
||||
})
|
||||
.unwrap_or(false)
|
||||
} else if let Event::ModifiersChanged(ModifiersChangedEvent { cmd, .. }) = event {
|
||||
self.terminal
|
||||
.upgrade(cx.app)
|
||||
.map(|model_handle| {
|
||||
if model_handle.update(cx.app, |term, _| term.refresh_hyperlink(*cmd)) {
|
||||
cx.notify();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue