gpui_nav/context.rs
1use gpui::{Context, Render, WeakEntity};
2
3/// A helper context that provides convenient navigation methods to screens.
4///
5/// This struct should be stored in each screen and provides methods to navigate
6/// without directly accessing the app state.
7///
8/// # Type Parameter
9///
10/// `T` - Your app state type (e.g., `AppState`)
11///
12/// # Example
13///
14/// ```rust,ignore
15/// use gpui_nav::ScreenContext;
16///
17/// pub struct MyScreen {
18/// ctx: ScreenContext<AppState>,
19/// // other fields...
20/// }
21///
22/// impl MyScreen {
23/// pub fn new(app_state: WeakEntity<AppState>) -> Self {
24/// Self {
25/// ctx: ScreenContext::new(app_state),
26/// }
27/// }
28/// }
29/// ```
30pub struct ScreenContext<T> {
31 app_state: WeakEntity<T>,
32}
33
34impl<T> ScreenContext<T>
35where
36 T: 'static,
37{
38 /// Creates a new screen context with a reference to the app state.
39 ///
40 /// # Example
41 ///
42 /// ```rust,ignore
43 /// let ctx = ScreenContext::new(cx.weak_entity());
44 /// ```
45 #[must_use]
46 pub fn new(app_state: WeakEntity<T>) -> Self {
47 Self { app_state }
48 }
49
50 /// Returns a clone of the app state weak entity.
51 ///
52 /// Use this when creating new screens that need navigation capabilities.
53 ///
54 /// # Example
55 ///
56 /// ```rust,ignore
57 /// let next_screen = NextScreen::new(self.ctx.app_state());
58 /// ```
59 #[must_use]
60 pub fn app_state(&self) -> WeakEntity<T> {
61 self.app_state.clone()
62 }
63
64 /// Helper method to update the app state.
65 ///
66 /// This is a convenience method that handles the `Result` from `update()`.
67 ///
68 /// # Example
69 ///
70 /// ```rust,ignore
71 /// self.ctx.update(cx, |app, inner_cx| {
72 /// app.navigator().push(NextScreen::new(self.ctx.app_state()), inner_cx);
73 /// });
74 /// ```
75 pub fn update<R>(
76 &self,
77 cx: &mut Context<impl Render>,
78 f: impl FnOnce(&mut T, &mut Context<T>) -> R,
79 ) -> Option<R> {
80 self.app_state.update(cx, f).ok()
81 }
82}
83
84impl<T> Clone for ScreenContext<T> {
85 fn clone(&self) -> Self {
86 Self {
87 app_state: self.app_state.clone(),
88 }
89 }
90}