text.rs

  1use gpui::{
  2    color::Color,
  3    fonts::{Properties, Weight},
  4    text_layout::RunStyle,
  5    DebugContext, Element as _, MeasurementContext, Quad,
  6};
  7use log::LevelFilter;
  8use pathfinder_geometry::rect::RectF;
  9use simplelog::SimpleLogger;
 10use std::ops::Range;
 11
 12fn main() {
 13    SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
 14
 15    gpui::App::new(()).unwrap().run(|cx| {
 16        cx.platform().activate(true);
 17        cx.add_window(Default::default(), |_| TextView);
 18    });
 19}
 20
 21struct TextView;
 22struct TextElement;
 23
 24impl gpui::Entity for TextView {
 25    type Event = ();
 26}
 27
 28impl gpui::View for TextView {
 29    fn ui_name() -> &'static str {
 30        "View"
 31    }
 32
 33    fn render(&mut self, _: &mut gpui::RenderContext<Self>) -> gpui::ElementBox {
 34        TextElement.boxed()
 35    }
 36}
 37
 38impl gpui::Element for TextElement {
 39    type LayoutState = ();
 40
 41    type PaintState = ();
 42
 43    fn layout(
 44        &mut self,
 45        constraint: gpui::SizeConstraint,
 46        _: &mut gpui::LayoutContext,
 47    ) -> (pathfinder_geometry::vector::Vector2F, Self::LayoutState) {
 48        (constraint.max, ())
 49    }
 50
 51    fn paint(
 52        &mut self,
 53        bounds: RectF,
 54        visible_bounds: RectF,
 55        _: &mut Self::LayoutState,
 56        cx: &mut gpui::PaintContext,
 57    ) -> Self::PaintState {
 58        let font_size = 12.;
 59        let family = cx.font_cache.load_family(&["SF Pro Display"]).unwrap();
 60        let normal = RunStyle {
 61            font_id: cx
 62                .font_cache
 63                .select_font(family, &Default::default())
 64                .unwrap(),
 65            color: Color::default(),
 66            underline: Default::default(),
 67        };
 68        let bold = RunStyle {
 69            font_id: cx
 70                .font_cache
 71                .select_font(
 72                    family,
 73                    &Properties {
 74                        weight: Weight::BOLD,
 75                        ..Default::default()
 76                    },
 77                )
 78                .unwrap(),
 79            color: Color::default(),
 80            underline: Default::default(),
 81        };
 82
 83        let text = "Hello world!";
 84        let line = cx.text_layout_cache.layout_str(
 85            text,
 86            font_size,
 87            &[
 88                (1, normal),
 89                (1, bold),
 90                (1, normal),
 91                (1, bold),
 92                (text.len() - 4, normal),
 93            ],
 94        );
 95
 96        cx.scene.push_quad(Quad {
 97            bounds,
 98            background: Some(Color::white()),
 99            ..Default::default()
100        });
101        line.paint(bounds.origin(), visible_bounds, bounds.height(), cx);
102    }
103
104    fn rect_for_text_range(
105        &self,
106        _: Range<usize>,
107        _: RectF,
108        _: RectF,
109        _: &Self::LayoutState,
110        _: &Self::PaintState,
111        _: &MeasurementContext,
112    ) -> Option<RectF> {
113        None
114    }
115
116    fn debug(
117        &self,
118        _: RectF,
119        _: &Self::LayoutState,
120        _: &Self::PaintState,
121        _: &DebugContext,
122    ) -> gpui::json::Value {
123        todo!()
124    }
125}