Skip to main content

gpui_kit/
lib.rs

1//! GPUI Kit: one dependency for building desktop applications with GPUI.
2//!
3//! GPUI itself is published as a family of `gpui-pre-*` crates that move
4//! together. This crate depends on the matching set for you, so an
5//! application lists `gpui-kit` alone. `use gpui_kit::*;` is GPUI, and each
6//! layer is reachable by name:
7//!
8//! | Path            | Crate             | Feature          |
9//! | --------------- | ----------------- | ---------------- |
10//! | `gpui_kit::*`   | `gpui`            | always           |
11//! | [`platform`]    | `gpui_platform`   | always           |
12//! | [`base`]        | `gpui-base`       | always           |
13//! | [`component`]   | `gpui-component`  | `component` (on) |
14//! | [`assets`]      | `gpui-kit-assets` | `assets` (on)    |
15//!
16//! [`application`] opens the platform and [`init`] initializes the enabled
17//! layers:
18//!
19//! ```no_run
20//! use gpui_kit::*;
21//!
22//! actions!(hello, [Quit]);
23//!
24//! struct Hello;
25//!
26//! impl Render for Hello {
27//!     fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
28//!         div().child("Hello, World!")
29//!     }
30//! }
31//!
32//! fn main() {
33//!     gpui_kit::application().run(|cx| {
34//!         gpui_kit::init(cx);
35//!         cx.spawn(async move |cx| {
36//!             cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| Hello))
37//!                 .expect("failed to open window");
38//!         })
39//!         .detach();
40//!     });
41//! }
42//! ```
43//!
44//! See [`component`] for the same program with the styled component library.
45
46/// Defines unit actions without requiring consumers to depend on GPUI under the
47/// crate name `gpui`.
48///
49/// GPUI's original macro spells its derive as `gpui::Action`, which does not
50/// resolve when GPUI is consumed solely through this facade.
51#[macro_export]
52macro_rules! actions {
53    ($namespace:path, [ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
54        $(
55            #[derive(
56                ::std::clone::Clone,
57                ::std::cmp::PartialEq,
58                ::std::default::Default,
59                ::std::fmt::Debug,
60                $crate::Action
61            )]
62            #[action(namespace = $namespace)]
63            $(#[$attr])*
64            pub struct $name;
65        )*
66    };
67    ([ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
68        $(
69            #[derive(
70                ::std::clone::Clone,
71                ::std::cmp::PartialEq,
72                ::std::default::Default,
73                ::std::fmt::Debug,
74                $crate::Action
75            )]
76            $(#[$attr])*
77            pub struct $name;
78        )*
79    };
80}
81
82// Everything in GPUI itself, so `use gpui_kit::*;` is enough to get started.
83// With the `test-support` feature the glob also carries GPUI's `test`
84// attribute, so a test module imports explicitly (or adds
85// `use core::prelude::v1::test;`) to keep the built-in `#[test]`.
86pub use ::gpui::*;
87
88// The crate name, so code that keeps `gpui::…` paths still resolves after
89// `use gpui_kit::*;`. `gpui_kit::*` is the documented way.
90#[doc(hidden)]
91pub use ::gpui;
92
93pub use ::gpui_base as base;
94pub use ::gpui_platform as platform;
95#[cfg(target_family = "wasm")]
96pub use ::gpui_web as web;
97
98/// The styled component library.
99///
100/// ```no_run
101/// use gpui_kit::component::button::*;
102/// use gpui_kit::component::Root;
103/// use gpui_kit::*;
104///
105/// struct Hello;
106///
107/// impl Render for Hello {
108///     fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
109///         div().child(Button::new("ok").primary().label("Let's Go!"))
110///     }
111/// }
112///
113/// fn main() {
114///     gpui_kit::application().run(|cx| {
115///         gpui_kit::init(cx);
116///         cx.spawn(async move |cx| {
117///             cx.open_window(WindowOptions::default(), |window, cx| {
118///                 let view = cx.new(|_| Hello);
119///                 cx.new(|cx| Root::new(view, window, cx))
120///             })
121///             .expect("failed to open window");
122///         })
123///         .detach();
124///     });
125/// }
126/// ```
127#[cfg(feature = "component")]
128pub use ::gpui_component as component;
129#[cfg(feature = "assets")]
130pub use ::gpui_kit_assets as assets;
131
132pub use ::gpui_platform::application;
133
134/// Initializes every enabled layer. Call it once, before using anything else.
135///
136/// With the `component` feature (on by default) this is
137/// `gpui_component::init`, which also initializes `gpui-base`; otherwise it
138/// is `gpui_base::init`.
139pub fn init(cx: &mut App) {
140    #[cfg(feature = "component")]
141    gpui_component::init(cx);
142    #[cfg(not(feature = "component"))]
143    gpui_base::init(cx);
144}