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}