example_editor_info.rs

 1//! `EditorInfo` โ€” a read-only View over an `ExampleEditor` entity.
 2//!
 3//! Demonstrates zero-wiring reactivity: just return the entity from `entity()`,
 4//! read from it in `render()`, and caching + invalidation happen automatically.
 5//! No observers, no subscriptions, no manual `cx.notify()`.
 6
 7use gpui::{App, Entity, IntoViewElement, Window, div, hsla, prelude::*, px};
 8
 9use crate::example_editor::ExampleEditor;
10
11#[derive(Hash, IntoViewElement)]
12pub struct EditorInfo {
13    editor: Entity<ExampleEditor>,
14}
15
16impl EditorInfo {
17    pub fn new(editor: Entity<ExampleEditor>) -> Self {
18        Self { editor }
19    }
20}
21
22impl gpui::View for EditorInfo {
23    type Entity = ExampleEditor;
24
25    fn entity(&self) -> Option<Entity<ExampleEditor>> {
26        Some(self.editor.clone())
27    }
28
29    fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
30        let editor = self.editor.read(cx);
31        let char_count = editor.content.len();
32        let cursor = editor.cursor;
33        let is_focused = editor.focus_handle.is_focused(window);
34
35        div()
36            .flex()
37            .gap(px(8.))
38            .text_xs()
39            .text_color(hsla(0., 0., 0.45, 1.))
40            .child(format!("{char_count} chars"))
41            .child("ยท")
42            .child(format!("cursor {cursor}"))
43            .child("ยท")
44            .child(if is_focused { "focused" } else { "unfocused" })
45    }
46}