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}