Add API for adding mouse regions within Text

This commit is contained in:
Max Brunsfeld 2023-04-25 17:23:55 -07:00
parent a7145021b6
commit 1bbcff543b
3 changed files with 251 additions and 120 deletions

View file

@ -1,13 +1,12 @@
use gpui::{
color::Color,
fonts::{Properties, Weight},
text_layout::RunStyle,
AnyElement, Element, Quad, SceneBuilder, View, ViewContext,
elements::Text,
fonts::{HighlightStyle, TextStyle},
platform::MouseButton,
AnyElement, Element, MouseRegion,
};
use log::LevelFilter;
use pathfinder_geometry::rect::RectF;
use simplelog::SimpleLogger;
use std::ops::Range;
fn main() {
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
@ -19,7 +18,6 @@ fn main() {
}
struct TextView;
struct TextElement;
impl gpui::Entity for TextView {
type Event = ();
@ -30,104 +28,47 @@ impl gpui::View for TextView {
"View"
}
fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> AnyElement<TextView> {
TextElement.into_any()
}
}
impl<V: View> Element<V> for TextElement {
type LayoutState = ();
type PaintState = ();
fn layout(
&mut self,
constraint: gpui::SizeConstraint,
_: &mut V,
_: &mut ViewContext<V>,
) -> (pathfinder_geometry::vector::Vector2F, Self::LayoutState) {
(constraint.max, ())
}
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
_: &mut V,
cx: &mut ViewContext<V>,
) -> Self::PaintState {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> AnyElement<TextView> {
let font_size = 12.;
let family = cx
.font_cache
.load_family(&["SF Pro Display"], &Default::default())
.load_family(&["Monaco"], &Default::default())
.unwrap();
let normal = RunStyle {
font_id: cx
.font_cache
.select_font(family, &Default::default())
.unwrap(),
color: Color::default(),
underline: Default::default(),
};
let bold = RunStyle {
font_id: cx
.font_cache
.select_font(
family,
&Properties {
weight: Weight::BOLD,
..Default::default()
},
)
.unwrap(),
color: Color::default(),
underline: Default::default(),
};
let font_id = cx
.font_cache
.select_font(family, &Default::default())
.unwrap();
let view_id = cx.view_id();
let text = "Hello world!";
let line = cx.text_layout_cache().layout_str(
text,
font_size,
&[
(1, normal),
(1, bold),
(1, normal),
(1, bold),
(text.len() - 4, normal),
],
);
scene.push_quad(Quad {
bounds,
background: Some(Color::white()),
let underline = HighlightStyle {
underline: Some(gpui::fonts::Underline {
thickness: 1.0.into(),
..Default::default()
}),
..Default::default()
});
line.paint(scene, bounds.origin(), visible_bounds, bounds.height(), cx);
}
};
fn rect_for_text_range(
&self,
_: Range<usize>,
_: RectF,
_: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
_: &V,
_: &ViewContext<V>,
) -> Option<RectF> {
None
}
fn debug(
&self,
_: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
_: &V,
_: &ViewContext<V>,
) -> gpui::json::Value {
todo!()
Text::new(
"The text:\nHello, beautiful world, hello!",
TextStyle {
font_id,
font_size,
color: Color::red(),
font_family_name: "".into(),
font_family_id: family,
underline: Default::default(),
font_properties: Default::default(),
},
)
.with_highlights(vec![(17..26, underline), (34..40, underline)])
.with_mouse_regions(vec![(17..26), (34..40)], move |ix, bounds| {
MouseRegion::new::<Self>(view_id, ix, bounds).on_click::<Self, _>(
MouseButton::Left,
move |_, _, _| {
eprintln!("clicked link {ix}");
},
)
})
.into_any()
}
}