gpui: Update docs to reflect removal of View, ViewContext, WindowContext (#24008)

This PR updates function signatures, docstrings, and gpui's other
documentation to reflect it's new state following the merge of `Model`
and `View` into `Entity` as well as the removal of `WindowContext`.

Release Notes:

- N/A
This commit is contained in:
someone13574 2025-01-31 14:40:42 -05:00 committed by GitHub
parent 027fe1b4b5
commit 0c94bdc8e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 330 additions and 329 deletions

View file

@ -150,7 +150,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
}); });
// Open the project diagnostics view while there are already diagnostics. // Open the project diagnostics view while there are already diagnostics.
let diagnostics = window.build_model(cx, |window, cx| { let diagnostics = window.build_entity(cx, |window, cx| {
ProjectDiagnosticsEditor::new_with_context( ProjectDiagnosticsEditor::new_with_context(
1, 1,
true, true,
@ -485,7 +485,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
let cx = &mut VisualTestContext::from_window(*window, cx); let cx = &mut VisualTestContext::from_window(*window, cx);
let workspace = window.root(cx).unwrap(); let workspace = window.root(cx).unwrap();
let diagnostics = window.build_model(cx, |window, cx| { let diagnostics = window.build_entity(cx, |window, cx| {
ProjectDiagnosticsEditor::new_with_context( ProjectDiagnosticsEditor::new_with_context(
1, 1,
true, true,
@ -763,7 +763,7 @@ async fn test_random_diagnostics(cx: &mut TestAppContext, mut rng: StdRng) {
let cx = &mut VisualTestContext::from_window(*window, cx); let cx = &mut VisualTestContext::from_window(*window, cx);
let workspace = window.root(cx).unwrap(); let workspace = window.root(cx).unwrap();
let mutated_diagnostics = window.build_model(cx, |window, cx| { let mutated_diagnostics = window.build_entity(cx, |window, cx| {
ProjectDiagnosticsEditor::new_with_context( ProjectDiagnosticsEditor::new_with_context(
1, 1,
true, true,
@ -870,7 +870,7 @@ async fn test_random_diagnostics(cx: &mut TestAppContext, mut rng: StdRng) {
cx.run_until_parked(); cx.run_until_parked();
log::info!("constructing reference diagnostics view"); log::info!("constructing reference diagnostics view");
let reference_diagnostics = window.build_model(cx, |window, cx| { let reference_diagnostics = window.build_entity(cx, |window, cx| {
ProjectDiagnosticsEditor::new_with_context( ProjectDiagnosticsEditor::new_with_context(
1, 1,
true, true,

View file

@ -11,7 +11,7 @@ GPUI is still in active development as we work on the Zed code editor and isn't
gpui = { git = "https://github.com/zed-industries/zed" } gpui = { git = "https://github.com/zed-industries/zed" }
``` ```
Everything in GPUI starts with an `App`. You can create one with `App::new()`, and kick off your application by passing a callback to `App::run()`. Inside this callback, you can create a new window with `AppContext::open_window()`, and register your first root view. See [gpui.rs](https://www.gpui.rs/) for a complete example. Everything in GPUI starts with an `Application`. You can create one with `Application::new()`, and kick off your application by passing a callback to `Application::run()`. Inside this callback, you can create a new window with `App::open_window()`, and register your first root view. See [gpui.rs](https://www.gpui.rs/) for a complete example.
### Dependencies ### Dependencies
@ -41,9 +41,9 @@ On macOS, GPUI uses Metal for rendering. In order to use Metal, you need to do t
GPUI offers three different [registers](<https://en.wikipedia.org/wiki/Register_(sociolinguistics)>) depending on your needs: GPUI offers three different [registers](<https://en.wikipedia.org/wiki/Register_(sociolinguistics)>) depending on your needs:
- State management and communication with Models. Whenever you need to store application state that communicates between different parts of your application, you'll want to use GPUI's models. Models are owned by GPUI and are only accessible through an owned smart pointer similar to an `Rc`. See the `app::model_context` module for more information. - State management and communication with `Entity`'s. Whenever you need to store application state that communicates between different parts of your application, you'll want to use GPUI's entities. Entities are owned by GPUI and are only accessible through an owned smart pointer similar to an `Rc`. See the `app::context` module for more information.
- High level, declarative UI with Views. All UI in GPUI starts with a View. A view is simply a model that can be rendered, via the `Render` trait. At the start of each frame, GPUI will call this render method on the root view of a given window. Views build a tree of `elements`, lay them out and style them with a tailwind-style API, and then give them to GPUI to turn into pixels. See the `div` element for an all purpose swiss-army knife of rendering. - High level, declarative UI with views. All UI in GPUI starts with a view. A view is simply an `Entity` that can be rendered, by implementing the `Render` trait. At the start of each frame, GPUI will call this render method on the root view of a given window. Views build a tree of `elements`, lay them out and style them with a tailwind-style API, and then give them to GPUI to turn into pixels. See the `div` element for an all purpose swiss-army knife of rendering.
- Low level, imperative UI with Elements. Elements are the building blocks of UI in GPUI, and they provide a nice wrapper around an imperative API that provides as much flexibility and control as you need. Elements have total control over how they and their child elements are rendered and can be used for making efficient views into large lists, implement custom layouting for a code editor, and anything else you can think of. See the `element` module for more information. - Low level, imperative UI with Elements. Elements are the building blocks of UI in GPUI, and they provide a nice wrapper around an imperative API that provides as much flexibility and control as you need. Elements have total control over how they and their child elements are rendered and can be used for making efficient views into large lists, implement custom layouting for a code editor, and anything else you can think of. See the `element` module for more information.
@ -55,7 +55,7 @@ In addition to the systems above, GPUI provides a range of smaller services that
- Actions are user-defined structs that are used for converting keystrokes into logical operations in your UI. Use this for implementing keyboard shortcuts, such as cmd-q. See the `action` module for more information. - Actions are user-defined structs that are used for converting keystrokes into logical operations in your UI. Use this for implementing keyboard shortcuts, such as cmd-q. See the `action` module for more information.
- Platform services, such as `quit the app` or `open a URL` are available as methods on the `app::AppContext`. - Platform services, such as `quit the app` or `open a URL` are available as methods on the `app::App`.
- An async executor that is integrated with the platform's event loop. See the `executor` module for more information., - An async executor that is integrated with the platform's event loop. See the `executor` module for more information.,

View file

@ -1,41 +1,33 @@
# Contexts # Contexts
GPUI makes extensive use of _context parameters_, typically named `cx` and positioned at the end of the parameter list, unless they're before a final function parameter. A context reference provides access to application state and services. GPUI makes extensive use of _context parameters_ (typically named `cx`) to provide access to application state and services. These contexts are references passed to functions, enabling interaction with global state, windows, entities, and system services.
There are multiple kinds of contexts, and contexts implement the `Deref` trait so that a function taking `&mut AppContext` could be passed a `&mut Window, &mut AppContext` or `&mut ViewContext` instead. ---
``` ## `App`
AppContext
/ \
ModelContext WindowContext
/
ViewContext
```
- The `AppContext` forms the root of the hierarchy The root context granting access to the application's global state. This context owns all entities' data and can be used to read or update the data referenced by an `Entity<T>`.
- `ModelContext` and `WindowContext` both dereference to `AppContext`
- `ViewContext` dereferences to `WindowContext`
## `AppContext`
Provides access to the global application state. All other kinds of contexts ultimately deref to an `AppContext`. You can update a `Model<T>` by passing an `AppContext`, but you can't update a view. For that you need a `WindowContext`...
## `WindowContext`
Provides access to the state of an application window, and also derefs to an `AppContext`, so you can pass a window context reference to any method taking an app context. Obtain this context by calling `WindowHandle::update`.
## `Context<T>` ## `Context<T>`
Available when you create or update a `Model<T>`. It derefs to an `AppContext`, but also contains methods specific to the particular model, such as the ability to notify change observers or emit events. A context provided when interacting with an `Entity<T>`, with additional methods related to that specific entity such as notifying observers and emitting events. This context dereferences into `App`, meaning any function which can take an `App` reference can also take a `Context<T>` reference, allowing you to access the application's global state.
## `ViewContext<V>`
Available when you create or update a `View<V>`. It derefs to a `WindowContext`, but also contains methods specific to the particular view, such as the ability to notify change observers or emit events.
## `AsyncApp` and `AsyncWindowContext` ## `AsyncApp` and `AsyncWindowContext`
Whereas the above contexts are always passed to your code as references, you can call `to_async` on the reference to create an async context, which has a static lifetime and can be held across `await` points in async code. When you interact with `Model`s or `View`s with an async context, the calls become fallible, because the context may outlive the window or even the app itself. Whereas the above contexts are always passed to your code as references, you can call `to_async` on the reference to create an async context, which has a static lifetime and can be held across `await` points in async code. When you interact with entities with an async context, the calls become fallible, because the context may outlive the window or even the app itself.
## `TestAppContext` and `TestVisualContext` ## `TestAppContext`
These are similar to the async contexts above, but they panic if you attempt to access a non-existent app or window, and they also contain other features specific to tests. These are similar to the async contexts above, but they panic if you attempt to access a non-existent app or window, and they also contain other features specific to tests.
---
# Non-Context Core Types
## `Window`
Provides access to the state of an application window. This type has a root view (an `Entity` implementing `Render`) which it can read/update, but since it is not a context, you must pass a `&mut App` (or a context which dereferences to it) to do so, along with other functions interacting with global state. You can obtain a `Window` from an `WindowHandle` by calling `WindowHandle::update`.
## `Entity<T>`
A handle to a structure requiring state. This data is owned by the `App` and can be accessed and modified via references to contexts. If `T` implements `Render`, then the entity is sometimes referred to as a view. Entities can be observed by other entities and windows, allowing a closure to be called when `notify` is called on the entity's `Context`.

View file

@ -37,7 +37,7 @@ fn main() {
// Associate actions using the `actions!` macro (or `impl_actions!` macro) // Associate actions using the `actions!` macro (or `impl_actions!` macro)
actions!(set_menus, [Quit]); actions!(set_menus, [Quit]);
// Define the quit function that is registered with the AppContext // Define the quit function that is registered with the App
fn quit(_: &Quit, cx: &mut App) { fn quit(_: &Quit, cx: &mut App) {
println!("Gracefully quitting the application . . ."); println!("Gracefully quitting the application . . .");
cx.quit(); cx.quit();

View file

@ -46,10 +46,10 @@ mod entity_map;
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
mod test_context; mod test_context;
/// The duration for which futures returned from [AppContext::on_app_context] or [ModelContext::on_app_quit] can run before the application fully quits. /// The duration for which futures returned from [Context::on_app_quit] can run before the application fully quits.
pub const SHUTDOWN_TIMEOUT: Duration = Duration::from_millis(100); pub const SHUTDOWN_TIMEOUT: Duration = Duration::from_millis(100);
/// Temporary(?) wrapper around [`RefCell<AppContext>`] to help us debug any double borrows. /// Temporary(?) wrapper around [`RefCell<App>`] to help us debug any double borrows.
/// Strongly consider removing after stabilization. /// Strongly consider removing after stabilization.
#[doc(hidden)] #[doc(hidden)]
pub struct AppCell { pub struct AppCell {
@ -219,11 +219,11 @@ pub(crate) type KeystrokeObserver =
Box<dyn FnMut(&KeystrokeEvent, &mut Window, &mut App) -> bool + 'static>; Box<dyn FnMut(&KeystrokeEvent, &mut Window, &mut App) -> bool + 'static>;
type QuitHandler = Box<dyn FnOnce(&mut App) -> LocalBoxFuture<'static, ()> + 'static>; type QuitHandler = Box<dyn FnOnce(&mut App) -> LocalBoxFuture<'static, ()> + 'static>;
type ReleaseListener = Box<dyn FnOnce(&mut dyn Any, &mut App) + 'static>; type ReleaseListener = Box<dyn FnOnce(&mut dyn Any, &mut App) + 'static>;
type NewModelListener = Box<dyn FnMut(AnyEntity, &mut Option<&mut Window>, &mut App) + 'static>; type NewEntityListener = Box<dyn FnMut(AnyEntity, &mut Option<&mut Window>, &mut App) + 'static>;
/// Contains the state of the full application, and passed as a reference to a variety of callbacks. /// Contains the state of the full application, and passed as a reference to a variety of callbacks.
/// Other contexts such as [ModelContext], [WindowContext], and [ViewContext] deref to this type, making it the most general context type. /// Other [Context] derefs to this type.
/// You need a reference to an `AppContext` to access the state of a [Model]. /// You need a reference to an `App` to access the state of a [Entity].
pub struct App { pub struct App {
pub(crate) this: Weak<AppCell>, pub(crate) this: Weak<AppCell>,
pub(crate) platform: Rc<dyn Platform>, pub(crate) platform: Rc<dyn Platform>,
@ -241,7 +241,7 @@ pub struct App {
pub(crate) globals_by_type: FxHashMap<TypeId, Box<dyn Any>>, pub(crate) globals_by_type: FxHashMap<TypeId, Box<dyn Any>>,
pub(crate) entities: EntityMap, pub(crate) entities: EntityMap,
pub(crate) window_update_stack: Vec<WindowId>, pub(crate) window_update_stack: Vec<WindowId>,
pub(crate) new_model_observers: SubscriberSet<TypeId, NewModelListener>, pub(crate) new_entity_observers: SubscriberSet<TypeId, NewEntityListener>,
pub(crate) windows: SlotMap<WindowId, Option<Window>>, pub(crate) windows: SlotMap<WindowId, Option<Window>>,
pub(crate) window_handles: FxHashMap<WindowId, AnyWindowHandle>, pub(crate) window_handles: FxHashMap<WindowId, AnyWindowHandle>,
pub(crate) focus_handles: Arc<FocusMap>, pub(crate) focus_handles: Arc<FocusMap>,
@ -305,7 +305,7 @@ impl App {
http_client, http_client,
globals_by_type: FxHashMap::default(), globals_by_type: FxHashMap::default(),
entities, entities,
new_model_observers: SubscriberSet::new(), new_entity_observers: SubscriberSet::new(),
windows: SlotMap::with_key(), windows: SlotMap::with_key(),
window_update_stack: Vec::new(), window_update_stack: Vec::new(),
window_handles: FxHashMap::default(), window_handles: FxHashMap::default(),
@ -359,7 +359,7 @@ impl App {
app app
} }
/// Quit the application gracefully. Handlers registered with [`ModelContext::on_app_quit`] /// Quit the application gracefully. Handlers registered with [`Context::on_app_quit`]
/// will be given 100ms to complete before exiting. /// will be given 100ms to complete before exiting.
pub fn shutdown(&mut self) { pub fn shutdown(&mut self) {
let mut futures = Vec::new(); let mut futures = Vec::new();
@ -426,7 +426,7 @@ impl App {
result result
} }
/// Arrange a callback to be invoked when the given model or view calls `notify` on its respective context. /// Arrange a callback to be invoked when the given entity calls `notify` on its respective context.
pub fn observe<W>( pub fn observe<W>(
&mut self, &mut self,
entity: &Entity<W>, entity: &Entity<W>,
@ -510,7 +510,7 @@ impl App {
) )
} }
/// Arrange for the given callback to be invoked whenever the given model or view emits an event of a given type. /// Arrange for the given callback to be invoked whenever the given entity emits an event of a given type.
/// The callback is provided a handle to the emitting entity and a reference to the emitted event. /// The callback is provided a handle to the emitting entity and a reference to the emitted event.
pub fn subscribe<T, Event>( pub fn subscribe<T, Event>(
&mut self, &mut self,
@ -588,7 +588,7 @@ impl App {
} }
/// Opens a new window with the given option and the root view returned by the given function. /// Opens a new window with the given option and the root view returned by the given function.
/// The function is invoked with a `WindowContext`, which can be used to interact with window-specific /// The function is invoked with a `Window`, which can be used to interact with window-specific
/// functionality. /// functionality.
pub fn open_window<V: 'static + Render>( pub fn open_window<V: 'static + Render>(
&mut self, &mut self,
@ -823,7 +823,7 @@ impl App {
self.pending_effects.push_back(effect); self.pending_effects.push_back(effect);
} }
/// Called at the end of [`AppContext::update`] to complete any side effects /// Called at the end of [`App::update`] to complete any side effects
/// such as notifying observers, emitting events, etc. Effects can themselves /// such as notifying observers, emitting events, etc. Effects can themselves
/// cause effects, so we continue looping until all effects are processed. /// cause effects, so we continue looping until all effects are processed.
fn flush_effects(&mut self) { fn flush_effects(&mut self) {
@ -854,12 +854,12 @@ impl App {
Effect::Defer { callback } => { Effect::Defer { callback } => {
self.apply_defer_effect(callback); self.apply_defer_effect(callback);
} }
Effect::ModelCreated { Effect::EntityCreated {
entity, entity,
tid, tid,
window, window,
} => { } => {
self.apply_model_created_effect(entity, tid, window); self.apply_entity_created_effect(entity, tid, window);
} }
} }
} else { } else {
@ -967,13 +967,13 @@ impl App {
callback(self); callback(self);
} }
fn apply_model_created_effect( fn apply_entity_created_effect(
&mut self, &mut self,
entity: AnyEntity, entity: AnyEntity,
tid: TypeId, tid: TypeId,
window: Option<WindowId>, window: Option<WindowId>,
) { ) {
self.new_model_observers.clone().retain(&tid, |observer| { self.new_entity_observers.clone().retain(&tid, |observer| {
if let Some(id) = window { if let Some(id) = window {
self.update_window_id(id, { self.update_window_id(id, {
let entity = entity.clone(); let entity = entity.clone();
@ -1172,8 +1172,12 @@ impl App {
self.globals_by_type.insert(global_type, lease.global); self.globals_by_type.insert(global_type, lease.global);
} }
pub(crate) fn new_model_observer(&self, key: TypeId, value: NewModelListener) -> Subscription { pub(crate) fn new_entity_observer(
let (subscription, activate) = self.new_model_observers.insert(key, value); &self,
key: TypeId,
value: NewEntityListener,
) -> Subscription {
let (subscription, activate) = self.new_entity_observers.insert(key, value);
activate(); activate();
subscription subscription
} }
@ -1184,18 +1188,18 @@ impl App {
&self, &self,
on_new: impl 'static + Fn(&mut T, Option<&mut Window>, &mut Context<T>), on_new: impl 'static + Fn(&mut T, Option<&mut Window>, &mut Context<T>),
) -> Subscription { ) -> Subscription {
self.new_model_observer( self.new_entity_observer(
TypeId::of::<T>(), TypeId::of::<T>(),
Box::new( Box::new(
move |any_model: AnyEntity, window: &mut Option<&mut Window>, cx: &mut App| { move |any_entity: AnyEntity, window: &mut Option<&mut Window>, cx: &mut App| {
any_model any_entity
.downcast::<T>() .downcast::<T>()
.unwrap() .unwrap()
.update(cx, |model_state, cx| { .update(cx, |entity_state, cx| {
if let Some(window) = window { if let Some(window) = window {
on_new(model_state, Some(window), cx); on_new(entity_state, Some(window), cx);
} else { } else {
on_new(model_state, None, cx); on_new(entity_state, None, cx);
} }
}) })
}, },
@ -1203,7 +1207,7 @@ impl App {
) )
} }
/// Observe the release of a model or view. The callback is invoked after the model or view /// Observe the release of a entity. The callback is invoked after the entity
/// has no more strong references but before it has been dropped. /// has no more strong references but before it has been dropped.
pub fn observe_release<T>( pub fn observe_release<T>(
&self, &self,
@ -1224,7 +1228,7 @@ impl App {
subscription subscription
} }
/// Observe the release of a model or view. The callback is invoked after the model or view /// Observe the release of a entity. The callback is invoked after the entity
/// has no more strong references but before it has been dropped. /// has no more strong references but before it has been dropped.
pub fn observe_release_in<T>( pub fn observe_release_in<T>(
&self, &self,
@ -1573,22 +1577,25 @@ impl AppContext for App {
type Result<T> = T; type Result<T> = T;
/// Build an entity that is owned by the application. The given function will be invoked with /// Build an entity that is owned by the application. The given function will be invoked with
/// a `ModelContext` and must return an object representing the entity. A `Model` handle will be returned, /// a `Context` and must return an object representing the entity. A `Entity` handle will be returned,
/// which can be used to access the entity in a context. /// which can be used to access the entity in a context.
fn new<T: 'static>(&mut self, build_model: impl FnOnce(&mut Context<'_, T>) -> T) -> Entity<T> { fn new<T: 'static>(
&mut self,
build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Entity<T> {
self.update(|cx| { self.update(|cx| {
let slot = cx.entities.reserve(); let slot = cx.entities.reserve();
let model = slot.clone(); let handle = slot.clone();
let entity = build_model(&mut Context::new_context(cx, slot.downgrade())); let entity = build_entity(&mut Context::new_context(cx, slot.downgrade()));
cx.push_effect(Effect::ModelCreated { cx.push_effect(Effect::EntityCreated {
entity: model.clone().into_any(), entity: handle.clone().into_any(),
tid: TypeId::of::<T>(), tid: TypeId::of::<T>(),
window: cx.window_update_stack.last().cloned(), window: cx.window_update_stack.last().cloned(),
}); });
cx.entities.insert(slot, entity); cx.entities.insert(slot, entity);
model handle
}) })
} }
@ -1599,27 +1606,27 @@ impl AppContext for App {
fn insert_entity<T: 'static>( fn insert_entity<T: 'static>(
&mut self, &mut self,
reservation: Reservation<T>, reservation: Reservation<T>,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
self.update(|cx| { self.update(|cx| {
let slot = reservation.0; let slot = reservation.0;
let entity = build_model(&mut Context::new_context(cx, slot.downgrade())); let entity = build_entity(&mut Context::new_context(cx, slot.downgrade()));
cx.entities.insert(slot, entity) cx.entities.insert(slot, entity)
}) })
} }
/// Updates the entity referenced by the given model. The function is passed a mutable reference to the /// Updates the entity referenced by the given handle. The function is passed a mutable reference to the
/// entity along with a `ModelContext` for the entity. /// entity along with a `Context` for the entity.
fn update_entity<T: 'static, R>( fn update_entity<T: 'static, R>(
&mut self, &mut self,
model: &Entity<T>, handle: &Entity<T>,
update: impl FnOnce(&mut T, &mut Context<'_, T>) -> R, update: impl FnOnce(&mut T, &mut Context<'_, T>) -> R,
) -> R { ) -> R {
self.update(|cx| { self.update(|cx| {
let mut entity = cx.entities.lease(model); let mut entity = cx.entities.lease(handle);
let result = update( let result = update(
&mut entity, &mut entity,
&mut Context::new_context(cx, model.downgrade()), &mut Context::new_context(cx, handle.downgrade()),
); );
cx.entities.end_lease(entity); cx.entities.end_lease(entity);
result result
@ -1701,7 +1708,7 @@ pub(crate) enum Effect {
Defer { Defer {
callback: Box<dyn FnOnce(&mut App) + 'static>, callback: Box<dyn FnOnce(&mut App) + 'static>,
}, },
ModelCreated { EntityCreated {
entity: AnyEntity, entity: AnyEntity,
tid: TypeId, tid: TypeId,
window: Option<WindowId>, window: Option<WindowId>,
@ -1718,7 +1725,7 @@ impl std::fmt::Debug for Effect {
write!(f, "NotifyGlobalObservers({:?})", global_type) write!(f, "NotifyGlobalObservers({:?})", global_type)
} }
Effect::Defer { .. } => write!(f, "Defer(..)"), Effect::Defer { .. } => write!(f, "Defer(..)"),
Effect::ModelCreated { entity, .. } => write!(f, "ModelCreated({:?})", entity), Effect::EntityCreated { entity, .. } => write!(f, "EntityCreated({:?})", entity),
} }
} }
} }

View file

@ -10,9 +10,9 @@ use std::{future::Future, rc::Weak};
use super::Context; use super::Context;
/// An async-friendly version of [AppContext] with a static lifetime so it can be held across `await` points in async code. /// An async-friendly version of [App] with a static lifetime so it can be held across `await` points in async code.
/// You're provided with an instance when calling [AppContext::spawn], and you can also create one with [AppContext::to_async]. /// You're provided with an instance when calling [App::spawn], and you can also create one with [App::to_async].
/// Internally, this holds a weak reference to an `AppContext`, so its methods are fallible to protect against cases where the [AppContext] is dropped. /// Internally, this holds a weak reference to an `App`, so its methods are fallible to protect against cases where the [App] is dropped.
#[derive(Clone)] #[derive(Clone)]
pub struct AsyncApp { pub struct AsyncApp {
pub(crate) app: Weak<AppCell>, pub(crate) app: Weak<AppCell>,
@ -25,14 +25,14 @@ impl AppContext for AsyncApp {
fn new<T: 'static>( fn new<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
let app = self let app = self
.app .app
.upgrade() .upgrade()
.ok_or_else(|| anyhow!("app was released"))?; .ok_or_else(|| anyhow!("app was released"))?;
let mut app = app.borrow_mut(); let mut app = app.borrow_mut();
Ok(app.new(build_model)) Ok(app.new(build_entity))
} }
fn reserve_entity<T: 'static>(&mut self) -> Result<Reservation<T>> { fn reserve_entity<T: 'static>(&mut self) -> Result<Reservation<T>> {
@ -47,14 +47,14 @@ impl AppContext for AsyncApp {
fn insert_entity<T: 'static>( fn insert_entity<T: 'static>(
&mut self, &mut self,
reservation: Reservation<T>, reservation: Reservation<T>,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Result<Entity<T>> { ) -> Result<Entity<T>> {
let app = self let app = self
.app .app
.upgrade() .upgrade()
.ok_or_else(|| anyhow!("app was released"))?; .ok_or_else(|| anyhow!("app was released"))?;
let mut app = app.borrow_mut(); let mut app = app.borrow_mut();
Ok(app.insert_entity(reservation, build_model)) Ok(app.insert_entity(reservation, build_entity))
} }
fn update_entity<T: 'static, R>( fn update_entity<T: 'static, R>(
@ -181,7 +181,7 @@ impl AsyncApp {
} }
/// Determine whether global state of the specified type has been assigned. /// Determine whether global state of the specified type has been assigned.
/// Returns an error if the `AppContext` has been dropped. /// Returns an error if the `App` has been dropped.
pub fn has_global<G: Global>(&self) -> Result<bool> { pub fn has_global<G: Global>(&self) -> Result<bool> {
let app = self let app = self
.app .app
@ -194,7 +194,7 @@ impl AsyncApp {
/// Reads the global state of the specified type, passing it to the given callback. /// Reads the global state of the specified type, passing it to the given callback.
/// ///
/// Panics if no global state of the specified type has been assigned. /// Panics if no global state of the specified type has been assigned.
/// Returns an error if the `AppContext` has been dropped. /// Returns an error if the `App` has been dropped.
pub fn read_global<G: Global, R>(&self, read: impl FnOnce(&G, &App) -> R) -> Result<R> { pub fn read_global<G: Global, R>(&self, read: impl FnOnce(&G, &App) -> R) -> Result<R> {
let app = self let app = self
.app .app
@ -209,14 +209,14 @@ impl AsyncApp {
/// Similar to [`AsyncApp::read_global`], but returns an error instead of panicking /// Similar to [`AsyncApp::read_global`], but returns an error instead of panicking
/// if no state of the specified type has been assigned. /// if no state of the specified type has been assigned.
/// ///
/// Returns an error if no state of the specified type has been assigned the `AppContext` has been dropped. /// Returns an error if no state of the specified type has been assigned the `App` has been dropped.
pub fn try_read_global<G: Global, R>(&self, read: impl FnOnce(&G, &App) -> R) -> Option<R> { pub fn try_read_global<G: Global, R>(&self, read: impl FnOnce(&G, &App) -> R) -> Option<R> {
let app = self.app.upgrade()?; let app = self.app.upgrade()?;
let app = app.borrow_mut(); let app = app.borrow_mut();
Some(read(app.try_global()?, &app)) Some(read(app.try_global()?, &app))
} }
/// A convenience method for [AppContext::update_global] /// A convenience method for [App::update_global]
/// for updating the global state of the specified type. /// for updating the global state of the specified type.
pub fn update_global<G: Global, R>( pub fn update_global<G: Global, R>(
&self, &self,
@ -251,13 +251,13 @@ impl AsyncWindowContext {
self.window self.window
} }
/// A convenience method for [`AppContext::update_window`]. /// A convenience method for [`App::update_window`].
pub fn update<R>(&mut self, update: impl FnOnce(&mut Window, &mut App) -> R) -> Result<R> { pub fn update<R>(&mut self, update: impl FnOnce(&mut Window, &mut App) -> R) -> Result<R> {
self.app self.app
.update_window(self.window, |_, window, cx| update(window, cx)) .update_window(self.window, |_, window, cx| update(window, cx))
} }
/// A convenience method for [`AppContext::update_window`]. /// A convenience method for [`App::update_window`].
pub fn update_root<R>( pub fn update_root<R>(
&mut self, &mut self,
update: impl FnOnce(AnyView, &mut Window, &mut App) -> R, update: impl FnOnce(AnyView, &mut Window, &mut App) -> R,
@ -272,7 +272,7 @@ impl AsyncWindowContext {
.ok(); .ok();
} }
/// A convenience method for [`AppContext::global`]. /// A convenience method for [`App::global`].
pub fn read_global<G: Global, R>( pub fn read_global<G: Global, R>(
&mut self, &mut self,
read: impl FnOnce(&G, &Window, &App) -> R, read: impl FnOnce(&G, &Window, &App) -> R,
@ -281,7 +281,7 @@ impl AsyncWindowContext {
.update(self, |_, window, cx| read(cx.global(), window, cx)) .update(self, |_, window, cx| read(cx.global(), window, cx))
} }
/// A convenience method for [`AppContext::update_global`]. /// A convenience method for [`App::update_global`].
/// for updating the global state of the specified type. /// for updating the global state of the specified type.
pub fn update_global<G, R>( pub fn update_global<G, R>(
&mut self, &mut self,
@ -326,11 +326,11 @@ impl AsyncWindowContext {
impl AppContext for AsyncWindowContext { impl AppContext for AsyncWindowContext {
type Result<T> = Result<T>; type Result<T> = Result<T>;
fn new<T>(&mut self, build_model: impl FnOnce(&mut Context<'_, T>) -> T) -> Result<Entity<T>> fn new<T>(&mut self, build_entity: impl FnOnce(&mut Context<'_, T>) -> T) -> Result<Entity<T>>
where where
T: 'static, T: 'static,
{ {
self.window.update(self, |_, _, cx| cx.new(build_model)) self.window.update(self, |_, _, cx| cx.new(build_entity))
} }
fn reserve_entity<T: 'static>(&mut self) -> Result<Reservation<T>> { fn reserve_entity<T: 'static>(&mut self) -> Result<Reservation<T>> {
@ -340,10 +340,10 @@ impl AppContext for AsyncWindowContext {
fn insert_entity<T: 'static>( fn insert_entity<T: 'static>(
&mut self, &mut self,
reservation: Reservation<T>, reservation: Reservation<T>,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
self.window self.window
.update(self, |_, _, cx| cx.insert_entity(reservation, build_model)) .update(self, |_, _, cx| cx.insert_entity(reservation, build_entity))
} }
fn update_entity<T: 'static, R>( fn update_entity<T: 'static, R>(
@ -406,10 +406,10 @@ impl VisualContext for AsyncWindowContext {
fn new_window_entity<T: 'static>( fn new_window_entity<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut Window, &mut Context<T>) -> T, build_entity: impl FnOnce(&mut Window, &mut Context<T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
self.window self.window
.update(self, |_, window, cx| cx.new(|cx| build_model(window, cx))) .update(self, |_, window, cx| cx.new(|cx| build_entity(window, cx)))
} }
fn update_window_entity<T: 'static, R>( fn update_window_entity<T: 'static, R>(
@ -418,7 +418,7 @@ impl VisualContext for AsyncWindowContext {
update: impl FnOnce(&mut T, &mut Window, &mut Context<T>) -> R, update: impl FnOnce(&mut T, &mut Window, &mut Context<T>) -> R,
) -> Self::Result<R> { ) -> Self::Result<R> {
self.window.update(self, |_, window, cx| { self.window.update(self, |_, window, cx| {
view.update(cx, |model, cx| update(model, window, cx)) view.update(cx, |entity, cx| update(entity, window, cx))
}) })
} }

View file

@ -15,39 +15,39 @@ use std::{
use super::{App, AsyncWindowContext, Entity, KeystrokeEvent}; use super::{App, AsyncWindowContext, Entity, KeystrokeEvent};
/// The app context, with specialized behavior for the given model. /// The app context, with specialized behavior for the given entity.
#[derive(Deref, DerefMut)] #[derive(Deref, DerefMut)]
pub struct Context<'a, T> { pub struct Context<'a, T> {
#[deref] #[deref]
#[deref_mut] #[deref_mut]
app: &'a mut App, app: &'a mut App,
model_state: WeakEntity<T>, entity_state: WeakEntity<T>,
} }
impl<'a, T: 'static> Context<'a, T> { impl<'a, T: 'static> Context<'a, T> {
pub(crate) fn new_context(app: &'a mut App, model_state: WeakEntity<T>) -> Self { pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self {
Self { app, model_state } Self { app, entity_state }
} }
/// The entity id of the model backing this context. /// The entity id of the entity backing this context.
pub fn entity_id(&self) -> EntityId { pub fn entity_id(&self) -> EntityId {
self.model_state.entity_id self.entity_state.entity_id
} }
/// Returns a handle to the model belonging to this context. /// Returns a handle to the entity belonging to this context.
pub fn entity(&self) -> Entity<T> { pub fn entity(&self) -> Entity<T> {
self.weak_entity() self.weak_entity()
.upgrade() .upgrade()
.expect("The entity must be alive if we have a model context") .expect("The entity must be alive if we have a entity context")
} }
/// Returns a weak handle to the model belonging to this context. /// Returns a weak handle to the entity belonging to this context.
pub fn weak_entity(&self) -> WeakEntity<T> { pub fn weak_entity(&self) -> WeakEntity<T> {
self.model_state.clone() self.entity_state.clone()
} }
/// Arranges for the given function to be called whenever [`ModelContext::notify`] or /// Arranges for the given function to be called whenever [`Context::notify`] is
/// [`ViewContext::notify`](crate::ViewContext::notify) is called with the given model or view. /// called with the given entity.
pub fn observe<W>( pub fn observe<W>(
&mut self, &mut self,
entity: &Entity<W>, entity: &Entity<W>,
@ -68,7 +68,7 @@ impl<'a, T: 'static> Context<'a, T> {
}) })
} }
/// Subscribe to an event type from another model or view /// Subscribe to an event type from another entity
pub fn subscribe<T2, Evt>( pub fn subscribe<T2, Evt>(
&mut self, &mut self,
entity: &Entity<T2>, entity: &Entity<T2>,
@ -90,13 +90,13 @@ impl<'a, T: 'static> Context<'a, T> {
}) })
} }
/// Register a callback to be invoked when GPUI releases this model. /// Register a callback to be invoked when GPUI releases this entity.
pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription
where where
T: 'static, T: 'static,
{ {
let (subscription, activate) = self.app.release_listeners.insert( let (subscription, activate) = self.app.release_listeners.insert(
self.model_state.entity_id, self.entity_state.entity_id,
Box::new(move |this, cx| { Box::new(move |this, cx| {
let this = this.downcast_mut().expect("invalid entity type"); let this = this.downcast_mut().expect("invalid entity type");
on_release(this, cx); on_release(this, cx);
@ -106,7 +106,7 @@ impl<'a, T: 'static> Context<'a, T> {
subscription subscription
} }
/// Register a callback to be run on the release of another model or view /// Register a callback to be run on the release of another entity
pub fn observe_release<T2>( pub fn observe_release<T2>(
&self, &self,
entity: &Entity<T2>, entity: &Entity<T2>,
@ -175,13 +175,13 @@ impl<'a, T: 'static> Context<'a, T> {
subscription subscription
} }
/// Tell GPUI that this model has changed and observers of it should be notified. /// Tell GPUI that this entity has changed and observers of it should be notified.
pub fn notify(&mut self) { pub fn notify(&mut self) {
self.app.notify(self.model_state.entity_id); self.app.notify(self.entity_state.entity_id);
} }
/// Spawn the future returned by the given function. /// Spawn the future returned by the given function.
/// The function is provided a weak handle to the model owned by this context and a context that can be held across await points. /// The function is provided a weak handle to the entity owned by this context and a context that can be held across await points.
/// The returned task must be held or detached. /// The returned task must be held or detached.
pub fn spawn<Fut, R>(&self, f: impl FnOnce(WeakEntity<T>, AsyncApp) -> Fut) -> Task<R> pub fn spawn<Fut, R>(&self, f: impl FnOnce(WeakEntity<T>, AsyncApp) -> Fut) -> Task<R>
where where
@ -238,7 +238,7 @@ impl<'a, T: 'static> Context<'a, T> {
}); });
} }
/// Observe another model or view for changes to its state, as tracked by [`ModelContext::notify`]. /// Observe another entity for changes to its state, as tracked by [`Context::notify`].
pub fn observe_in<V2>( pub fn observe_in<V2>(
&mut self, &mut self,
observed: &Entity<V2>, observed: &Entity<V2>,
@ -274,9 +274,9 @@ impl<'a, T: 'static> Context<'a, T> {
) )
} }
/// Subscribe to events emitted by another model or view. /// Subscribe to events emitted by another entity.
/// The entity to which you're subscribing must implement the [`EventEmitter`] trait. /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
/// The callback will be invoked with a reference to the current view, a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a view context for the current view. /// The callback will be invoked with a reference to the current view, a handle to the emitting `Entity`, the event, a mutable reference to the `Window`, and the context for the entity.
pub fn subscribe_in<Emitter, Evt>( pub fn subscribe_in<Emitter, Evt>(
&mut self, &mut self,
emitter: &Entity<Emitter>, emitter: &Entity<Emitter>,
@ -329,7 +329,7 @@ impl<'a, T: 'static> Context<'a, T> {
self.app.observe_release_in(&entity, window, on_release) self.app.observe_release_in(&entity, window, on_release)
} }
/// Register a callback to be invoked when the given Model or View is released. /// Register a callback to be invoked when the given Entity is released.
pub fn observe_release_in<T2>( pub fn observe_release_in<T2>(
&self, &self,
observed: &Entity<T2>, observed: &Entity<T2>,
@ -580,7 +580,7 @@ impl<'a, T: 'static> Context<'a, T> {
} }
/// Schedule a future to be run asynchronously. /// Schedule a future to be run asynchronously.
/// The given callback is invoked with a [`WeakModel<V>`] to avoid leaking the view for a long-running process. /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the view for a long-running process.
/// It's also given an [`AsyncWindowContext`], which can be used to access the state of the view across await points. /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the view across await points.
/// The returned future will be polled on the main thread. /// The returned future will be polled on the main thread.
pub fn spawn_in<Fut, R>( pub fn spawn_in<Fut, R>(
@ -655,7 +655,7 @@ impl<'a, T> Context<'a, T> {
Evt: 'static, Evt: 'static,
{ {
self.app.pending_effects.push_back(Effect::Emit { self.app.pending_effects.push_back(Effect::Emit {
emitter: self.model_state.entity_id, emitter: self.entity_state.entity_id,
event_type: TypeId::of::<Evt>(), event_type: TypeId::of::<Evt>(),
event: Box::new(event), event: Box::new(event),
}); });
@ -665,8 +665,11 @@ impl<'a, T> Context<'a, T> {
impl<'a, T> AppContext for Context<'a, T> { impl<'a, T> AppContext for Context<'a, T> {
type Result<U> = U; type Result<U> = U;
fn new<U: 'static>(&mut self, build_model: impl FnOnce(&mut Context<'_, U>) -> U) -> Entity<U> { fn new<U: 'static>(
self.app.new(build_model) &mut self,
build_entity: impl FnOnce(&mut Context<'_, U>) -> U,
) -> Entity<U> {
self.app.new(build_entity)
} }
fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> { fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
@ -676,9 +679,9 @@ impl<'a, T> AppContext for Context<'a, T> {
fn insert_entity<U: 'static>( fn insert_entity<U: 'static>(
&mut self, &mut self,
reservation: Reservation<U>, reservation: Reservation<U>,
build_model: impl FnOnce(&mut Context<'_, U>) -> U, build_entity: impl FnOnce(&mut Context<'_, U>) -> U,
) -> Self::Result<Entity<U>> { ) -> Self::Result<Entity<U>> {
self.app.insert_entity(reservation, build_model) self.app.insert_entity(reservation, build_entity)
} }
fn update_entity<U: 'static, R>( fn update_entity<U: 'static, R>(

View file

@ -25,7 +25,7 @@ use collections::HashMap;
use super::Context; use super::Context;
slotmap::new_key_type! { slotmap::new_key_type! {
/// A unique identifier for a model or view across the application. /// A unique identifier for a entity across the application.
pub struct EntityId; pub struct EntityId;
} }
@ -97,9 +97,9 @@ impl EntityMap {
let mut accessed_entities = self.accessed_entities.borrow_mut(); let mut accessed_entities = self.accessed_entities.borrow_mut();
accessed_entities.insert(slot.entity_id); accessed_entities.insert(slot.entity_id);
let model = slot.0; let handle = slot.0;
self.entities.insert(model.entity_id, Box::new(entity)); self.entities.insert(handle.entity_id, Box::new(entity));
model handle
} }
/// Move an entity to the stack. /// Move an entity to the stack.
@ -127,21 +127,21 @@ impl EntityMap {
.insert(lease.pointer.entity_id, lease.entity.take().unwrap()); .insert(lease.pointer.entity_id, lease.entity.take().unwrap());
} }
pub fn read<T: 'static>(&self, model: &Entity<T>) -> &T { pub fn read<T: 'static>(&self, entity: &Entity<T>) -> &T {
self.assert_valid_context(model); self.assert_valid_context(entity);
let mut accessed_entities = self.accessed_entities.borrow_mut(); let mut accessed_entities = self.accessed_entities.borrow_mut();
accessed_entities.insert(model.entity_id); accessed_entities.insert(entity.entity_id);
self.entities self.entities
.get(model.entity_id) .get(entity.entity_id)
.and_then(|entity| entity.downcast_ref()) .and_then(|entity| entity.downcast_ref())
.unwrap_or_else(|| double_lease_panic::<T>("read")) .unwrap_or_else(|| double_lease_panic::<T>("read"))
} }
fn assert_valid_context(&self, model: &AnyEntity) { fn assert_valid_context(&self, entity: &AnyEntity) {
debug_assert!( debug_assert!(
Weak::ptr_eq(&model.entity_map, &Arc::downgrade(&self.ref_counts)), Weak::ptr_eq(&entity.entity_map, &Arc::downgrade(&self.ref_counts)),
"used a model with the wrong context" "used a entity with the wrong context"
); );
} }
@ -216,7 +216,7 @@ impl<'a, T> Drop for Lease<'a, T> {
#[derive(Deref, DerefMut)] #[derive(Deref, DerefMut)]
pub(crate) struct Slot<T>(Entity<T>); pub(crate) struct Slot<T>(Entity<T>);
/// A dynamically typed reference to a model, which can be downcast into a `Model<T>`. /// A dynamically typed reference to a entity, which can be downcast into a `Entity<T>`.
pub struct AnyEntity { pub struct AnyEntity {
pub(crate) entity_id: EntityId, pub(crate) entity_id: EntityId,
pub(crate) entity_type: TypeId, pub(crate) entity_type: TypeId,
@ -241,17 +241,17 @@ impl AnyEntity {
} }
} }
/// Returns the id associated with this model. /// Returns the id associated with this entity.
pub fn entity_id(&self) -> EntityId { pub fn entity_id(&self) -> EntityId {
self.entity_id self.entity_id
} }
/// Returns the [TypeId] associated with this model. /// Returns the [TypeId] associated with this entity.
pub fn entity_type(&self) -> TypeId { pub fn entity_type(&self) -> TypeId {
self.entity_type self.entity_type
} }
/// Converts this model handle into a weak variant, which does not prevent it from being released. /// Converts this entity handle into a weak variant, which does not prevent it from being released.
pub fn downgrade(&self) -> AnyWeakEntity { pub fn downgrade(&self) -> AnyWeakEntity {
AnyWeakEntity { AnyWeakEntity {
entity_id: self.entity_id, entity_id: self.entity_id,
@ -260,8 +260,8 @@ impl AnyEntity {
} }
} }
/// Converts this model handle into a strongly-typed model handle of the given type. /// Converts this entity handle into a strongly-typed entity handle of the given type.
/// If this model handle is not of the specified type, returns itself as an error variant. /// If this entity handle is not of the specified type, returns itself as an error variant.
pub fn downcast<T: 'static>(self) -> Result<Entity<T>, AnyEntity> { pub fn downcast<T: 'static>(self) -> Result<Entity<T>, AnyEntity> {
if TypeId::of::<T>() == self.entity_type { if TypeId::of::<T>() == self.entity_type {
Ok(Entity { Ok(Entity {
@ -281,9 +281,9 @@ impl Clone for AnyEntity {
let count = entity_map let count = entity_map
.counts .counts
.get(self.entity_id) .get(self.entity_id)
.expect("detected over-release of a model"); .expect("detected over-release of a entity");
let prev_count = count.fetch_add(1, SeqCst); let prev_count = count.fetch_add(1, SeqCst);
assert_ne!(prev_count, 0, "Detected over-release of a model."); assert_ne!(prev_count, 0, "Detected over-release of a entity.");
} }
Self { Self {
@ -311,7 +311,7 @@ impl Drop for AnyEntity {
.get(self.entity_id) .get(self.entity_id)
.expect("detected over-release of a handle."); .expect("detected over-release of a handle.");
let prev_count = count.fetch_sub(1, SeqCst); let prev_count = count.fetch_sub(1, SeqCst);
assert_ne!(prev_count, 0, "Detected over-release of a model."); assert_ne!(prev_count, 0, "Detected over-release of a entity.");
if prev_count == 1 { if prev_count == 1 {
// We were the last reference to this entity, so we can remove it. // We were the last reference to this entity, so we can remove it.
let mut entity_map = RwLockUpgradableReadGuard::upgrade(entity_map); let mut entity_map = RwLockUpgradableReadGuard::upgrade(entity_map);
@ -330,8 +330,8 @@ impl Drop for AnyEntity {
} }
impl<T> From<Entity<T>> for AnyEntity { impl<T> From<Entity<T>> for AnyEntity {
fn from(model: Entity<T>) -> Self { fn from(entity: Entity<T>) -> Self {
model.any_entity entity.any_entity
} }
} }
@ -351,7 +351,7 @@ impl Eq for AnyEntity {}
impl std::fmt::Debug for AnyEntity { impl std::fmt::Debug for AnyEntity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AnyModel") f.debug_struct("AnyEntity")
.field("entity_id", &self.entity_id.as_u64()) .field("entity_id", &self.entity_id.as_u64())
.finish() .finish()
} }
@ -406,7 +406,7 @@ impl<T: 'static> Entity<T> {
}) })
} }
/// Convert this into a dynamically typed model. /// Convert this into a dynamically typed entity.
pub fn into_any(self) -> AnyEntity { pub fn into_any(self) -> AnyEntity {
self.any_entity self.any_entity
} }
@ -416,7 +416,7 @@ impl<T: 'static> Entity<T> {
cx.entities.read(self) cx.entities.read(self)
} }
/// Read the entity referenced by this model with the given function. /// Read the entity referenced by this handle with the given function.
pub fn read_with<R, C: AppContext>( pub fn read_with<R, C: AppContext>(
&self, &self,
cx: &C, cx: &C,
@ -425,11 +425,11 @@ impl<T: 'static> Entity<T> {
cx.read_entity(self, f) cx.read_entity(self, f)
} }
/// Updates the entity referenced by this model with the given function. /// Updates the entity referenced by this handle with the given function.
/// ///
/// The update function receives a context appropriate for its environment. /// The update function receives a context appropriate for its environment.
/// When updating in an `AppContext`, it receives a `ModelContext`. /// When updating in an `App`, it receives a `Context`.
/// When updating in a `WindowContext`, it receives a `ViewContext`. /// When updating in a `Window`, it receives a `Window` and a `Context`.
pub fn update<C, R>( pub fn update<C, R>(
&self, &self,
cx: &mut C, cx: &mut C,
@ -441,7 +441,7 @@ impl<T: 'static> Entity<T> {
cx.update_entity(self, update) cx.update_entity(self, update)
} }
/// Updates the entity referenced by this model with the given function if /// Updates the entity referenced by this handle with the given function if
/// the referenced entity still exists, within a visual context that has a window. /// the referenced entity still exists, within a visual context that has a window.
/// Returns an error if the entity has been released. /// Returns an error if the entity has been released.
pub fn update_in<C, R>( pub fn update_in<C, R>(
@ -467,7 +467,7 @@ impl<T> Clone for Entity<T> {
impl<T> std::fmt::Debug for Entity<T> { impl<T> std::fmt::Debug for Entity<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Model") f.debug_struct("Entity")
.field("entity_id", &self.any_entity.entity_id) .field("entity_id", &self.any_entity.entity_id)
.field("entity_type", &type_name::<T>()) .field("entity_type", &type_name::<T>())
.finish() .finish()
@ -494,7 +494,7 @@ impl<T> PartialEq<WeakEntity<T>> for Entity<T> {
} }
} }
/// A type erased, weak reference to a model. /// A type erased, weak reference to a entity.
#[derive(Clone)] #[derive(Clone)]
pub struct AnyWeakEntity { pub struct AnyWeakEntity {
pub(crate) entity_id: EntityId, pub(crate) entity_id: EntityId,
@ -508,7 +508,7 @@ impl AnyWeakEntity {
self.entity_id self.entity_id
} }
/// Check if this weak handle can be upgraded, or if the model has already been dropped /// Check if this weak handle can be upgraded, or if the entity has already been dropped
pub fn is_upgradable(&self) -> bool { pub fn is_upgradable(&self) -> bool {
let ref_count = self let ref_count = self
.entity_ref_counts .entity_ref_counts
@ -518,7 +518,7 @@ impl AnyWeakEntity {
ref_count > 0 ref_count > 0
} }
/// Upgrade this weak model reference to a strong reference. /// Upgrade this weak entity reference to a strong reference.
pub fn upgrade(&self) -> Option<AnyEntity> { pub fn upgrade(&self) -> Option<AnyEntity> {
let ref_counts = &self.entity_ref_counts.upgrade()?; let ref_counts = &self.entity_ref_counts.upgrade()?;
let ref_counts = ref_counts.read(); let ref_counts = ref_counts.read();
@ -546,7 +546,7 @@ impl AnyWeakEntity {
}) })
} }
/// Assert that model referenced by this weak handle has been released. /// Assert that entity referenced by this weak handle has been released.
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
pub fn assert_released(&self) { pub fn assert_released(&self) {
self.entity_ref_counts self.entity_ref_counts
@ -579,8 +579,8 @@ impl std::fmt::Debug for AnyWeakEntity {
} }
impl<T> From<WeakEntity<T>> for AnyWeakEntity { impl<T> From<WeakEntity<T>> for AnyWeakEntity {
fn from(model: WeakEntity<T>) -> Self { fn from(entity: WeakEntity<T>) -> Self {
model.any_entity entity.any_entity
} }
} }
@ -598,7 +598,7 @@ impl PartialEq for AnyWeakEntity {
impl Eq for AnyWeakEntity {} impl Eq for AnyWeakEntity {}
/// A weak reference to a model of the given type. /// A weak reference to a entity of the given type.
#[derive(Deref, DerefMut)] #[derive(Deref, DerefMut)]
pub struct WeakEntity<T> { pub struct WeakEntity<T> {
#[deref] #[deref]
@ -629,13 +629,13 @@ impl<T> Clone for WeakEntity<T> {
} }
impl<T: 'static> WeakEntity<T> { impl<T: 'static> WeakEntity<T> {
/// Upgrade this weak model reference into a strong model reference /// Upgrade this weak entity reference into a strong entity reference
pub fn upgrade(&self) -> Option<Entity<T>> { pub fn upgrade(&self) -> Option<Entity<T>> {
// Delegate to the trait implementation to keep behavior in one place. // Delegate to the trait implementation to keep behavior in one place.
Entity::upgrade_from(self) Entity::upgrade_from(self)
} }
/// Updates the entity referenced by this model with the given function if /// Updates the entity referenced by this handle with the given function if
/// the referenced entity still exists. Returns an error if the entity has /// the referenced entity still exists. Returns an error if the entity has
/// been released. /// been released.
pub fn update<C, R>( pub fn update<C, R>(
@ -654,7 +654,7 @@ impl<T: 'static> WeakEntity<T> {
) )
} }
/// Updates the entity referenced by this model with the given function if /// Updates the entity referenced by this handle with the given function if
/// the referenced entity still exists, within a visual context that has a window. /// the referenced entity still exists, within a visual context that has a window.
/// Returns an error if the entity has been released. /// Returns an error if the entity has been released.
pub fn update_in<C, R>( pub fn update_in<C, R>(
@ -670,11 +670,11 @@ impl<T: 'static> WeakEntity<T> {
let this = self.upgrade().ok_or_else(|| anyhow!("entity released"))?; let this = self.upgrade().ok_or_else(|| anyhow!("entity released"))?;
crate::Flatten::flatten(window.update(cx, |_, window, cx| { crate::Flatten::flatten(window.update(cx, |_, window, cx| {
this.update(cx, |model, cx| update(model, window, cx)) this.update(cx, |entity, cx| update(entity, window, cx))
})) }))
} }
/// Reads the entity referenced by this model with the given function if /// Reads the entity referenced by this handle with the given function if
/// the referenced entity still exists. Returns an error if the entity has /// the referenced entity still exists. Returns an error if the entity has
/// been released. /// been released.
pub fn read_with<C, R>(&self, cx: &C, read: impl FnOnce(&T, &App) -> R) -> Result<R> pub fn read_with<C, R>(&self, cx: &C, read: impl FnOnce(&T, &App) -> R) -> Result<R>

View file

@ -34,10 +34,10 @@ impl AppContext for TestAppContext {
fn new<T: 'static>( fn new<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
let mut app = self.app.borrow_mut(); let mut app = self.app.borrow_mut();
app.new(build_model) app.new(build_entity)
} }
fn reserve_entity<T: 'static>(&mut self) -> Self::Result<crate::Reservation<T>> { fn reserve_entity<T: 'static>(&mut self) -> Self::Result<crate::Reservation<T>> {
@ -48,10 +48,10 @@ impl AppContext for TestAppContext {
fn insert_entity<T: 'static>( fn insert_entity<T: 'static>(
&mut self, &mut self,
reservation: crate::Reservation<T>, reservation: crate::Reservation<T>,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
let mut app = self.app.borrow_mut(); let mut app = self.app.borrow_mut();
app.insert_entity(reservation, build_model) app.insert_entity(reservation, build_entity)
} }
fn update_entity<T: 'static, R>( fn update_entity<T: 'static, R>(
@ -178,13 +178,13 @@ impl TestAppContext {
&self.foreground_executor &self.foreground_executor
} }
/// Gives you an `&mut AppContext` for the duration of the closure /// Gives you an `&mut App` for the duration of the closure
pub fn update<R>(&self, f: impl FnOnce(&mut App) -> R) -> R { pub fn update<R>(&self, f: impl FnOnce(&mut App) -> R) -> R {
let mut cx = self.app.borrow_mut(); let mut cx = self.app.borrow_mut();
cx.update(f) cx.update(f)
} }
/// Gives you an `&AppContext` for the duration of the closure /// Gives you an `&App` for the duration of the closure
pub fn read<R>(&self, f: impl FnOnce(&App) -> R) -> R { pub fn read<R>(&self, f: impl FnOnce(&App) -> R) -> R {
let cx = self.app.borrow(); let cx = self.app.borrow();
f(&cx) f(&cx)
@ -231,7 +231,7 @@ impl TestAppContext {
} }
/// Adds a new window, and returns its root view and a `VisualTestContext` which can be used /// Adds a new window, and returns its root view and a `VisualTestContext` which can be used
/// as a `WindowContext` for the rest of the test. Typically you would shadow this context with /// as a `Window` and `App` for the rest of the test. Typically you would shadow this context with
/// the returned one. `let (view, cx) = cx.add_window_view(...);` /// the returned one. `let (view, cx) = cx.add_window_view(...);`
pub fn add_window_view<F, V>( pub fn add_window_view<F, V>(
&mut self, &mut self,
@ -436,7 +436,7 @@ impl TestAppContext {
.clone() .clone()
} }
/// Returns a stream of notifications whenever the View or Model is updated. /// Returns a stream of notifications whenever the Entity is updated.
pub fn notifications<T: 'static>(&mut self, entity: &Entity<T>) -> impl Stream<Item = ()> { pub fn notifications<T: 'static>(&mut self, entity: &Entity<T>) -> impl Stream<Item = ()> {
let (tx, rx) = futures::channel::mpsc::unbounded(); let (tx, rx) = futures::channel::mpsc::unbounded();
self.update(|cx| { self.update(|cx| {
@ -453,7 +453,7 @@ impl TestAppContext {
rx rx
} }
/// Returns a stream of events emitted by the given Model. /// Returns a stream of events emitted by the given Entity.
pub fn events<Evt, T: 'static + EventEmitter<Evt>>( pub fn events<Evt, T: 'static + EventEmitter<Evt>>(
&mut self, &mut self,
entity: &Entity<T>, entity: &Entity<T>,
@ -464,7 +464,7 @@ impl TestAppContext {
let (tx, rx) = futures::channel::mpsc::unbounded(); let (tx, rx) = futures::channel::mpsc::unbounded();
entity entity
.update(self, |_, cx: &mut Context<T>| { .update(self, |_, cx: &mut Context<T>| {
cx.subscribe(entity, move |_model, _handle, event, _cx| { cx.subscribe(entity, move |_entity, _handle, event, _cx| {
let _ = tx.unbounded_send(event.clone()); let _ = tx.unbounded_send(event.clone());
}) })
}) })
@ -476,23 +476,23 @@ impl TestAppContext {
/// don't need to jump in at a specific time). /// don't need to jump in at a specific time).
pub async fn condition<T: 'static>( pub async fn condition<T: 'static>(
&mut self, &mut self,
model: &Entity<T>, entity: &Entity<T>,
mut predicate: impl FnMut(&mut T, &mut Context<T>) -> bool, mut predicate: impl FnMut(&mut T, &mut Context<T>) -> bool,
) { ) {
let timer = self.executor().timer(Duration::from_secs(3)); let timer = self.executor().timer(Duration::from_secs(3));
let mut notifications = self.notifications(model); let mut notifications = self.notifications(entity);
use futures::FutureExt as _; use futures::FutureExt as _;
use smol::future::FutureExt as _; use smol::future::FutureExt as _;
async { async {
loop { loop {
if model.update(self, &mut predicate) { if entity.update(self, &mut predicate) {
return Ok(()); return Ok(());
} }
if notifications.next().await.is_none() { if notifications.next().await.is_none() {
bail!("model dropped") bail!("entity dropped")
} }
} }
} }
@ -509,7 +509,7 @@ impl TestAppContext {
} }
impl<T: 'static> Entity<T> { impl<T: 'static> Entity<T> {
/// Block until the next event is emitted by the model, then return it. /// Block until the next event is emitted by the entity, then return it.
pub fn next_event<Event>(&self, cx: &mut TestAppContext) -> impl Future<Output = Event> pub fn next_event<Event>(&self, cx: &mut TestAppContext) -> impl Future<Output = Event>
where where
Event: Send + Clone + 'static, Event: Send + Clone + 'static,
@ -560,7 +560,7 @@ impl<V: 'static> Entity<V> {
.await .await
.expect("next notification timed out"); .expect("next notification timed out");
drop(subscription); drop(subscription);
notification.expect("model dropped while test was waiting for its next notification") notification.expect("entity dropped while test was waiting for its next notification")
} }
} }
} }
@ -639,8 +639,8 @@ use derive_more::{Deref, DerefMut};
use super::{Context, Entity}; use super::{Context, Entity};
#[derive(Deref, DerefMut, Clone)] #[derive(Deref, DerefMut, Clone)]
/// A VisualTestContext is the test-equivalent of a `WindowContext`. It allows you to /// A VisualTestContext is the test-equivalent of a `Window` and `App`. It allows you to
/// run window-specific test code. /// run window-specific test code. It can be dereferenced to a `TextAppContext`.
pub struct VisualTestContext { pub struct VisualTestContext {
#[deref] #[deref]
#[deref_mut] #[deref_mut]
@ -650,7 +650,7 @@ pub struct VisualTestContext {
} }
impl VisualTestContext { impl VisualTestContext {
/// Provides the `WindowContext` for the duration of the closure. /// Provides a `Window` and `App` for the duration of the closure.
pub fn update<R>(&mut self, f: impl FnOnce(&mut Window, &mut App) -> R) -> R { pub fn update<R>(&mut self, f: impl FnOnce(&mut Window, &mut App) -> R) -> R {
self.cx self.cx
.update_window(self.window, |_, window, cx| f(window, cx)) .update_window(self.window, |_, window, cx| f(window, cx))
@ -680,7 +680,7 @@ impl VisualTestContext {
self.cx.dispatch_action(self.window, action) self.cx.dispatch_action(self.window, action)
} }
/// Read the title off the window (set by `WindowContext#set_window_title`) /// Read the title off the window (set by `Window#set_window_title`)
pub fn window_title(&mut self) -> Option<String> { pub fn window_title(&mut self) -> Option<String> {
self.cx.test_window(self.window).0.lock().title.clone() self.cx.test_window(self.window).0.lock().title.clone()
} }
@ -865,9 +865,9 @@ impl AppContext for VisualTestContext {
fn new<T: 'static>( fn new<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
self.cx.new(build_model) self.cx.new(build_entity)
} }
fn reserve_entity<T: 'static>(&mut self) -> Self::Result<crate::Reservation<T>> { fn reserve_entity<T: 'static>(&mut self) -> Self::Result<crate::Reservation<T>> {
@ -877,9 +877,9 @@ impl AppContext for VisualTestContext {
fn insert_entity<T: 'static>( fn insert_entity<T: 'static>(
&mut self, &mut self,
reservation: crate::Reservation<T>, reservation: crate::Reservation<T>,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
self.cx.insert_entity(reservation, build_model) self.cx.insert_entity(reservation, build_entity)
} }
fn update_entity<T, R>( fn update_entity<T, R>(
@ -945,11 +945,11 @@ impl VisualContext for VisualTestContext {
fn new_window_entity<T: 'static>( fn new_window_entity<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut Window, &mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Window, &mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>> { ) -> Self::Result<Entity<T>> {
self.window self.window
.update(&mut self.cx, |_, window, cx| { .update(&mut self.cx, |_, window, cx| {
cx.new(|cx| build_model(window, cx)) cx.new(|cx| build_entity(window, cx))
}) })
.unwrap() .unwrap()
} }
@ -991,7 +991,7 @@ impl VisualContext for VisualTestContext {
impl AnyWindowHandle { impl AnyWindowHandle {
/// Creates the given view in this window. /// Creates the given view in this window.
pub fn build_model<V: Render + 'static>( pub fn build_entity<V: Render + 'static>(
&self, &self,
cx: &mut TestAppContext, cx: &mut TestAppContext,
build_view: impl FnOnce(&mut Window, &mut Context<V>) -> V, build_view: impl FnOnce(&mut Window, &mut Context<V>) -> V,

View file

@ -114,8 +114,8 @@ pub trait IntoElement: Sized {
impl<T: IntoElement> FluentBuilder for T {} impl<T: IntoElement> FluentBuilder for T {}
/// An object that can be drawn to the screen. This is the trait that distinguishes `Views` from /// An object that can be drawn to the screen. This is the trait that distinguishes "views" from
/// models. Views are drawn to the screen and care about the current window's state, models are not and do not. /// other entities. Views are `Entity`'s which `impl Render` and drawn to the screen.
pub trait Render: 'static + Sized { pub trait Render: 'static + Sized {
/// Render this view into an element tree. /// Render this view into an element tree.
fn render(&mut self, window: &mut Window, cx: &mut Context<'_, Self>) -> impl IntoElement; fn render(&mut self, window: &mut Window, cx: &mut Context<'_, Self>) -> impl IntoElement;

View file

@ -84,7 +84,7 @@ impl Interactivity {
/// Bind the given callback to the mouse down event for the given mouse button, during the bubble phase /// Bind the given callback to the mouse down event for the given mouse button, during the bubble phase
/// The imperative API equivalent of [`InteractiveElement::on_mouse_down`] /// The imperative API equivalent of [`InteractiveElement::on_mouse_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to the view state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to the view state from this callback.
pub fn on_mouse_down( pub fn on_mouse_down(
&mut self, &mut self,
button: MouseButton, button: MouseButton,
@ -104,7 +104,7 @@ impl Interactivity {
/// Bind the given callback to the mouse down event for any button, during the capture phase /// Bind the given callback to the mouse down event for any button, during the capture phase
/// The imperative API equivalent of [`InteractiveElement::capture_any_mouse_down`] /// The imperative API equivalent of [`InteractiveElement::capture_any_mouse_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn capture_any_mouse_down( pub fn capture_any_mouse_down(
&mut self, &mut self,
listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static,
@ -120,7 +120,7 @@ impl Interactivity {
/// Bind the given callback to the mouse down event for any button, during the bubble phase /// Bind the given callback to the mouse down event for any button, during the bubble phase
/// the imperative API equivalent to [`InteractiveElement::on_any_mouse_down`] /// the imperative API equivalent to [`InteractiveElement::on_any_mouse_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_any_mouse_down( pub fn on_any_mouse_down(
&mut self, &mut self,
listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static,
@ -136,7 +136,7 @@ impl Interactivity {
/// Bind the given callback to the mouse up event for the given button, during the bubble phase /// Bind the given callback to the mouse up event for the given button, during the bubble phase
/// the imperative API equivalent to [`InteractiveElement::on_mouse_up`] /// the imperative API equivalent to [`InteractiveElement::on_mouse_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_mouse_up( pub fn on_mouse_up(
&mut self, &mut self,
button: MouseButton, button: MouseButton,
@ -156,7 +156,7 @@ impl Interactivity {
/// Bind the given callback to the mouse up event for any button, during the capture phase /// Bind the given callback to the mouse up event for any button, during the capture phase
/// the imperative API equivalent to [`InteractiveElement::capture_any_mouse_up`] /// the imperative API equivalent to [`InteractiveElement::capture_any_mouse_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn capture_any_mouse_up( pub fn capture_any_mouse_up(
&mut self, &mut self,
listener: impl Fn(&MouseUpEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseUpEvent, &mut Window, &mut App) + 'static,
@ -172,7 +172,7 @@ impl Interactivity {
/// Bind the given callback to the mouse up event for any button, during the bubble phase /// Bind the given callback to the mouse up event for any button, during the bubble phase
/// the imperative API equivalent to [`Interactivity::on_any_mouse_up`] /// the imperative API equivalent to [`Interactivity::on_any_mouse_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_any_mouse_up( pub fn on_any_mouse_up(
&mut self, &mut self,
listener: impl Fn(&MouseUpEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseUpEvent, &mut Window, &mut App) + 'static,
@ -189,7 +189,7 @@ impl Interactivity {
/// when the mouse is outside of the bounds of this element. /// when the mouse is outside of the bounds of this element.
/// The imperative API equivalent to [`InteractiveElement::on_mouse_down_out`] /// The imperative API equivalent to [`InteractiveElement::on_mouse_down_out`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_mouse_down_out( pub fn on_mouse_down_out(
&mut self, &mut self,
listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static,
@ -206,7 +206,7 @@ impl Interactivity {
/// when the mouse is outside of the bounds of this element. /// when the mouse is outside of the bounds of this element.
/// The imperative API equivalent to [`InteractiveElement::on_mouse_up_out`] /// The imperative API equivalent to [`InteractiveElement::on_mouse_up_out`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_mouse_up_out( pub fn on_mouse_up_out(
&mut self, &mut self,
button: MouseButton, button: MouseButton,
@ -226,7 +226,7 @@ impl Interactivity {
/// Bind the given callback to the mouse move event, during the bubble phase /// Bind the given callback to the mouse move event, during the bubble phase
/// The imperative API equivalent to [`InteractiveElement::on_mouse_move`] /// The imperative API equivalent to [`InteractiveElement::on_mouse_move`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_mouse_move( pub fn on_mouse_move(
&mut self, &mut self,
listener: impl Fn(&MouseMoveEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseMoveEvent, &mut Window, &mut App) + 'static,
@ -245,7 +245,7 @@ impl Interactivity {
/// UIs that don't conform to a drag and drop style interaction, like resizing. /// UIs that don't conform to a drag and drop style interaction, like resizing.
/// The imperative API equivalent to [`InteractiveElement::on_drag_move`] /// The imperative API equivalent to [`InteractiveElement::on_drag_move`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_drag_move<T>( pub fn on_drag_move<T>(
&mut self, &mut self,
listener: impl Fn(&DragMoveEvent<T>, &mut Window, &mut App) + 'static, listener: impl Fn(&DragMoveEvent<T>, &mut Window, &mut App) + 'static,
@ -276,7 +276,7 @@ impl Interactivity {
/// Bind the given callback to scroll wheel events during the bubble phase /// Bind the given callback to scroll wheel events during the bubble phase
/// The imperative API equivalent to [`InteractiveElement::on_scroll_wheel`] /// The imperative API equivalent to [`InteractiveElement::on_scroll_wheel`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_scroll_wheel( pub fn on_scroll_wheel(
&mut self, &mut self,
listener: impl Fn(&ScrollWheelEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&ScrollWheelEvent, &mut Window, &mut App) + 'static,
@ -292,7 +292,7 @@ impl Interactivity {
/// Bind the given callback to an action dispatch during the capture phase /// Bind the given callback to an action dispatch during the capture phase
/// The imperative API equivalent to [`InteractiveElement::capture_action`] /// The imperative API equivalent to [`InteractiveElement::capture_action`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn capture_action<A: Action>( pub fn capture_action<A: Action>(
&mut self, &mut self,
listener: impl Fn(&A, &mut Window, &mut App) + 'static, listener: impl Fn(&A, &mut Window, &mut App) + 'static,
@ -313,7 +313,7 @@ impl Interactivity {
/// Bind the given callback to an action dispatch during the bubble phase /// Bind the given callback to an action dispatch during the bubble phase
/// The imperative API equivalent to [`InteractiveElement::on_action`] /// The imperative API equivalent to [`InteractiveElement::on_action`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_action<A: Action>(&mut self, listener: impl Fn(&A, &mut Window, &mut App) + 'static) { pub fn on_action<A: Action>(&mut self, listener: impl Fn(&A, &mut Window, &mut App) + 'static) {
self.action_listeners.push(( self.action_listeners.push((
TypeId::of::<A>(), TypeId::of::<A>(),
@ -331,7 +331,7 @@ impl Interactivity {
/// action bindings to their users. /// action bindings to their users.
/// The imperative API equivalent to [`InteractiveElement::on_boxed_action`] /// The imperative API equivalent to [`InteractiveElement::on_boxed_action`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_boxed_action( pub fn on_boxed_action(
&mut self, &mut self,
action: &dyn Action, action: &dyn Action,
@ -351,7 +351,7 @@ impl Interactivity {
/// Bind the given callback to key down events during the bubble phase /// Bind the given callback to key down events during the bubble phase
/// The imperative API equivalent to [`InteractiveElement::on_key_down`] /// The imperative API equivalent to [`InteractiveElement::on_key_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_key_down( pub fn on_key_down(
&mut self, &mut self,
listener: impl Fn(&KeyDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&KeyDownEvent, &mut Window, &mut App) + 'static,
@ -367,7 +367,7 @@ impl Interactivity {
/// Bind the given callback to key down events during the capture phase /// Bind the given callback to key down events during the capture phase
/// The imperative API equivalent to [`InteractiveElement::capture_key_down`] /// The imperative API equivalent to [`InteractiveElement::capture_key_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn capture_key_down( pub fn capture_key_down(
&mut self, &mut self,
listener: impl Fn(&KeyDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&KeyDownEvent, &mut Window, &mut App) + 'static,
@ -383,7 +383,7 @@ impl Interactivity {
/// Bind the given callback to key up events during the bubble phase /// Bind the given callback to key up events during the bubble phase
/// The imperative API equivalent to [`InteractiveElement::on_key_up`] /// The imperative API equivalent to [`InteractiveElement::on_key_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_key_up(&mut self, listener: impl Fn(&KeyUpEvent, &mut Window, &mut App) + 'static) { pub fn on_key_up(&mut self, listener: impl Fn(&KeyUpEvent, &mut Window, &mut App) + 'static) {
self.key_up_listeners self.key_up_listeners
.push(Box::new(move |event, phase, window, cx| { .push(Box::new(move |event, phase, window, cx| {
@ -396,7 +396,7 @@ impl Interactivity {
/// Bind the given callback to key up events during the capture phase /// Bind the given callback to key up events during the capture phase
/// The imperative API equivalent to [`InteractiveElement::on_key_up`] /// The imperative API equivalent to [`InteractiveElement::on_key_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn capture_key_up( pub fn capture_key_up(
&mut self, &mut self,
listener: impl Fn(&KeyUpEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&KeyUpEvent, &mut Window, &mut App) + 'static,
@ -412,7 +412,7 @@ impl Interactivity {
/// Bind the given callback to modifiers changing events. /// Bind the given callback to modifiers changing events.
/// The imperative API equivalent to [`InteractiveElement::on_modifiers_changed`] /// The imperative API equivalent to [`InteractiveElement::on_modifiers_changed`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_modifiers_changed( pub fn on_modifiers_changed(
&mut self, &mut self,
listener: impl Fn(&ModifiersChangedEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&ModifiersChangedEvent, &mut Window, &mut App) + 'static,
@ -426,7 +426,7 @@ impl Interactivity {
/// Bind the given callback to drop events of the given type, whether or not the drag started on this element /// Bind the given callback to drop events of the given type, whether or not the drag started on this element
/// The imperative API equivalent to [`InteractiveElement::on_drop`] /// The imperative API equivalent to [`InteractiveElement::on_drop`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_drop<T: 'static>(&mut self, listener: impl Fn(&T, &mut Window, &mut App) + 'static) { pub fn on_drop<T: 'static>(&mut self, listener: impl Fn(&T, &mut Window, &mut App) + 'static) {
self.drop_listeners.push(( self.drop_listeners.push((
TypeId::of::<T>(), TypeId::of::<T>(),
@ -448,7 +448,7 @@ impl Interactivity {
/// Bind the given callback to click events of this element /// Bind the given callback to click events of this element
/// The imperative API equivalent to [`StatefulInteractiveElement::on_click`] /// The imperative API equivalent to [`StatefulInteractiveElement::on_click`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_click(&mut self, listener: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) pub fn on_click(&mut self, listener: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static)
where where
Self: Sized, Self: Sized,
@ -464,7 +464,7 @@ impl Interactivity {
/// the [`Self::on_drag_move`] API /// the [`Self::on_drag_move`] API
/// The imperative API equivalent to [`StatefulInteractiveElement::on_drag`] /// The imperative API equivalent to [`StatefulInteractiveElement::on_drag`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_drag<T, W>( pub fn on_drag<T, W>(
&mut self, &mut self,
value: T, value: T,
@ -490,7 +490,7 @@ impl Interactivity {
/// passed to the callback is true when the hover starts and false when it ends. /// passed to the callback is true when the hover starts and false when it ends.
/// The imperative API equivalent to [`StatefulInteractiveElement::on_drag`] /// The imperative API equivalent to [`StatefulInteractiveElement::on_drag`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
pub fn on_hover(&mut self, listener: impl Fn(&bool, &mut Window, &mut App) + 'static) pub fn on_hover(&mut self, listener: impl Fn(&bool, &mut Window, &mut App) + 'static)
where where
Self: Sized, Self: Sized,
@ -611,7 +611,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to the mouse down event for the given mouse button, /// Bind the given callback to the mouse down event for the given mouse button,
/// the fluent API equivalent to [`Interactivity::on_mouse_down`] /// the fluent API equivalent to [`Interactivity::on_mouse_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to the view state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to the view state from this callback.
fn on_mouse_down( fn on_mouse_down(
mut self, mut self,
button: MouseButton, button: MouseButton,
@ -642,7 +642,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to the mouse down event for any button, during the capture phase /// Bind the given callback to the mouse down event for any button, during the capture phase
/// the fluent API equivalent to [`Interactivity::capture_any_mouse_down`] /// the fluent API equivalent to [`Interactivity::capture_any_mouse_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn capture_any_mouse_down( fn capture_any_mouse_down(
mut self, mut self,
listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static,
@ -654,7 +654,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to the mouse down event for any button, during the capture phase /// Bind the given callback to the mouse down event for any button, during the capture phase
/// the fluent API equivalent to [`Interactivity::on_any_mouse_down`] /// the fluent API equivalent to [`Interactivity::on_any_mouse_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_any_mouse_down( fn on_any_mouse_down(
mut self, mut self,
listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static,
@ -666,7 +666,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to the mouse up event for the given button, during the bubble phase /// Bind the given callback to the mouse up event for the given button, during the bubble phase
/// the fluent API equivalent to [`Interactivity::on_mouse_up`] /// the fluent API equivalent to [`Interactivity::on_mouse_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_mouse_up( fn on_mouse_up(
mut self, mut self,
button: MouseButton, button: MouseButton,
@ -679,7 +679,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to the mouse up event for any button, during the capture phase /// Bind the given callback to the mouse up event for any button, during the capture phase
/// the fluent API equivalent to [`Interactivity::capture_any_mouse_up`] /// the fluent API equivalent to [`Interactivity::capture_any_mouse_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn capture_any_mouse_up( fn capture_any_mouse_up(
mut self, mut self,
listener: impl Fn(&MouseUpEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseUpEvent, &mut Window, &mut App) + 'static,
@ -692,7 +692,7 @@ pub trait InteractiveElement: Sized {
/// when the mouse is outside of the bounds of this element. /// when the mouse is outside of the bounds of this element.
/// The fluent API equivalent to [`Interactivity::on_mouse_down_out`] /// The fluent API equivalent to [`Interactivity::on_mouse_down_out`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_mouse_down_out( fn on_mouse_down_out(
mut self, mut self,
listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseDownEvent, &mut Window, &mut App) + 'static,
@ -705,7 +705,7 @@ pub trait InteractiveElement: Sized {
/// when the mouse is outside of the bounds of this element. /// when the mouse is outside of the bounds of this element.
/// The fluent API equivalent to [`Interactivity::on_mouse_up_out`] /// The fluent API equivalent to [`Interactivity::on_mouse_up_out`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_mouse_up_out( fn on_mouse_up_out(
mut self, mut self,
button: MouseButton, button: MouseButton,
@ -718,7 +718,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to the mouse move event, during the bubble phase /// Bind the given callback to the mouse move event, during the bubble phase
/// The fluent API equivalent to [`Interactivity::on_mouse_move`] /// The fluent API equivalent to [`Interactivity::on_mouse_move`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_mouse_move( fn on_mouse_move(
mut self, mut self,
listener: impl Fn(&MouseMoveEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&MouseMoveEvent, &mut Window, &mut App) + 'static,
@ -733,7 +733,7 @@ pub trait InteractiveElement: Sized {
/// UIs that don't conform to a drag and drop style interaction, like resizing. /// UIs that don't conform to a drag and drop style interaction, like resizing.
/// The fluent API equivalent to [`Interactivity::on_drag_move`] /// The fluent API equivalent to [`Interactivity::on_drag_move`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_drag_move<T: 'static>( fn on_drag_move<T: 'static>(
mut self, mut self,
listener: impl Fn(&DragMoveEvent<T>, &mut Window, &mut App) + 'static, listener: impl Fn(&DragMoveEvent<T>, &mut Window, &mut App) + 'static,
@ -745,7 +745,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to scroll wheel events during the bubble phase /// Bind the given callback to scroll wheel events during the bubble phase
/// The fluent API equivalent to [`Interactivity::on_scroll_wheel`] /// The fluent API equivalent to [`Interactivity::on_scroll_wheel`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_scroll_wheel( fn on_scroll_wheel(
mut self, mut self,
listener: impl Fn(&ScrollWheelEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&ScrollWheelEvent, &mut Window, &mut App) + 'static,
@ -757,7 +757,7 @@ pub trait InteractiveElement: Sized {
/// Capture the given action, before normal action dispatch can fire /// Capture the given action, before normal action dispatch can fire
/// The fluent API equivalent to [`Interactivity::on_scroll_wheel`] /// The fluent API equivalent to [`Interactivity::on_scroll_wheel`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn capture_action<A: Action>( fn capture_action<A: Action>(
mut self, mut self,
listener: impl Fn(&A, &mut Window, &mut App) + 'static, listener: impl Fn(&A, &mut Window, &mut App) + 'static,
@ -769,7 +769,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to an action dispatch during the bubble phase /// Bind the given callback to an action dispatch during the bubble phase
/// The fluent API equivalent to [`Interactivity::on_action`] /// The fluent API equivalent to [`Interactivity::on_action`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_action<A: Action>( fn on_action<A: Action>(
mut self, mut self,
listener: impl Fn(&A, &mut Window, &mut App) + 'static, listener: impl Fn(&A, &mut Window, &mut App) + 'static,
@ -783,7 +783,7 @@ pub trait InteractiveElement: Sized {
/// action bindings to their users. /// action bindings to their users.
/// The fluent API equivalent to [`Interactivity::on_boxed_action`] /// The fluent API equivalent to [`Interactivity::on_boxed_action`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_boxed_action( fn on_boxed_action(
mut self, mut self,
action: &dyn Action, action: &dyn Action,
@ -796,7 +796,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to key down events during the bubble phase /// Bind the given callback to key down events during the bubble phase
/// The fluent API equivalent to [`Interactivity::on_key_down`] /// The fluent API equivalent to [`Interactivity::on_key_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_key_down( fn on_key_down(
mut self, mut self,
listener: impl Fn(&KeyDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&KeyDownEvent, &mut Window, &mut App) + 'static,
@ -808,7 +808,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to key down events during the capture phase /// Bind the given callback to key down events during the capture phase
/// The fluent API equivalent to [`Interactivity::capture_key_down`] /// The fluent API equivalent to [`Interactivity::capture_key_down`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn capture_key_down( fn capture_key_down(
mut self, mut self,
listener: impl Fn(&KeyDownEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&KeyDownEvent, &mut Window, &mut App) + 'static,
@ -820,7 +820,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to key up events during the bubble phase /// Bind the given callback to key up events during the bubble phase
/// The fluent API equivalent to [`Interactivity::on_key_up`] /// The fluent API equivalent to [`Interactivity::on_key_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_key_up( fn on_key_up(
mut self, mut self,
listener: impl Fn(&KeyUpEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&KeyUpEvent, &mut Window, &mut App) + 'static,
@ -832,7 +832,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to key up events during the capture phase /// Bind the given callback to key up events during the capture phase
/// The fluent API equivalent to [`Interactivity::capture_key_up`] /// The fluent API equivalent to [`Interactivity::capture_key_up`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn capture_key_up( fn capture_key_up(
mut self, mut self,
listener: impl Fn(&KeyUpEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&KeyUpEvent, &mut Window, &mut App) + 'static,
@ -844,7 +844,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to modifiers changing events. /// Bind the given callback to modifiers changing events.
/// The fluent API equivalent to [`Interactivity::on_modifiers_changed`] /// The fluent API equivalent to [`Interactivity::on_modifiers_changed`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_modifiers_changed( fn on_modifiers_changed(
mut self, mut self,
listener: impl Fn(&ModifiersChangedEvent, &mut Window, &mut App) + 'static, listener: impl Fn(&ModifiersChangedEvent, &mut Window, &mut App) + 'static,
@ -891,7 +891,7 @@ pub trait InteractiveElement: Sized {
/// Bind the given callback to drop events of the given type, whether or not the drag started on this element /// Bind the given callback to drop events of the given type, whether or not the drag started on this element
/// The fluent API equivalent to [`Interactivity::on_drop`] /// The fluent API equivalent to [`Interactivity::on_drop`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_drop<T: 'static>( fn on_drop<T: 'static>(
mut self, mut self,
listener: impl Fn(&T, &mut Window, &mut App) + 'static, listener: impl Fn(&T, &mut Window, &mut App) + 'static,
@ -992,7 +992,7 @@ pub trait StatefulInteractiveElement: InteractiveElement {
/// Bind the given callback to click events of this element /// Bind the given callback to click events of this element
/// The fluent API equivalent to [`Interactivity::on_click`] /// The fluent API equivalent to [`Interactivity::on_click`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_click(mut self, listener: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) -> Self fn on_click(mut self, listener: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) -> Self
where where
Self: Sized, Self: Sized,
@ -1007,7 +1007,7 @@ pub trait StatefulInteractiveElement: InteractiveElement {
/// The callback also has access to the offset of triggering click from the origin of parent element. /// The callback also has access to the offset of triggering click from the origin of parent element.
/// The fluent API equivalent to [`Interactivity::on_drag`] /// The fluent API equivalent to [`Interactivity::on_drag`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_drag<T, W>( fn on_drag<T, W>(
mut self, mut self,
value: T, value: T,
@ -1026,7 +1026,7 @@ pub trait StatefulInteractiveElement: InteractiveElement {
/// passed to the callback is true when the hover starts and false when it ends. /// passed to the callback is true when the hover starts and false when it ends.
/// The fluent API equivalent to [`Interactivity::on_hover`] /// The fluent API equivalent to [`Interactivity::on_hover`]
/// ///
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback. /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
fn on_hover(mut self, listener: impl Fn(&bool, &mut Window, &mut App) + 'static) -> Self fn on_hover(mut self, listener: impl Fn(&bool, &mut Window, &mut App) + 'static) -> Self
where where
Self: Sized, Self: Sized,

View file

@ -2846,7 +2846,7 @@ impl From<ScaledPixels> for u32 {
} }
} }
/// Represents a length in rems, a unit based on the font-size of the window, which can be assigned with [`WindowContext::set_rem_size`][set_rem_size]. /// Represents a length in rems, a unit based on the font-size of the window, which can be assigned with [`Window::set_rem_size`][set_rem_size].
/// ///
/// Rems are used for defining lengths that are scalable and consistent across different UI elements. /// Rems are used for defining lengths that are scalable and consistent across different UI elements.
/// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers), /// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers),
@ -2855,7 +2855,7 @@ impl From<ScaledPixels> for u32 {
/// ///
/// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`. /// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`.
/// ///
/// [set_rem_size]: crate::WindowContext::set_rem_size /// [set_rem_size]: crate::Window::set_rem_size
#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)] #[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
pub struct Rems(pub f32); pub struct Rems(pub f32);

View file

@ -12,24 +12,24 @@
//! gpui = { git = "https://github.com/zed-industries/zed" } //! gpui = { git = "https://github.com/zed-industries/zed" }
//! ``` //! ```
//! //!
//! Everything in GPUI starts with an [`App`]. You can create one with [`App::new`], and //! Everything in GPUI starts with an [`Application`]. You can create one with [`Application::new`], and
//! kick off your application by passing a callback to [`App::run`]. Inside this callback, //! kick off your application by passing a callback to [`Application::run`]. Inside this callback,
//! you can create a new window with [`AppContext::open_window`], and register your first root //! you can create a new window with [`App::open_window`], and register your first root
//! view. See [gpui.rs](https://www.gpui.rs/) for a complete example. //! view. See [gpui.rs](https://www.gpui.rs/) for a complete example.
//! //!
//! ## The Big Picture //! ## The Big Picture
//! //!
//! GPUI offers three different [registers](https://en.wikipedia.org/wiki/Register_(sociolinguistics)) depending on your needs: //! GPUI offers three different [registers](https://en.wikipedia.org/wiki/Register_(sociolinguistics)) depending on your needs:
//! //!
//! - State management and communication with Models. Whenever you need to store application state //! - State management and communication with [`Entity`]'s. Whenever you need to store application state
//! that communicates between different parts of your application, you'll want to use GPUI's //! that communicates between different parts of your application, you'll want to use GPUI's
//! models. Models are owned by GPUI and are only accessible through an owned smart pointer //! entities. Entities are owned by GPUI and are only accessible through an owned smart pointer
//! similar to an [`Rc`]. See the [`app::model_context`] module for more information. //! similar to an [`std::rc::Rc`]. See the [`app::context`] module for more information.
//! //!
//! - High level, declarative UI with Views. All UI in GPUI starts with a View. A view is simply //! - High level, declarative UI with views. All UI in GPUI starts with a view. A view is simply
//! a model that can be rendered, via the [`Render`] trait. At the start of each frame, GPUI //! a [`Entity`] that can be rendered, by implementing the [`Render`] trait. At the start of each frame, GPUI
//! will call this render method on the root view of a given window. Views build a tree of //! will call this render method on the root view of a given window. Views build a tree of
//! `elements`, lay them out and style them with a tailwind-style API, and then give them to //! [`Element`]s, lay them out and style them with a tailwind-style API, and then give them to
//! GPUI to turn into pixels. See the [`elements::Div`] element for an all purpose swiss-army //! GPUI to turn into pixels. See the [`elements::Div`] element for an all purpose swiss-army
//! knife for UI. //! knife for UI.
//! //!
@ -49,7 +49,7 @@
//! //!
//! - Actions are user-defined structs that are used for converting keystrokes into logical operations in your UI. //! - Actions are user-defined structs that are used for converting keystrokes into logical operations in your UI.
//! Use this for implementing keyboard shortcuts, such as cmd-q. See the [`action`] module for more information. //! Use this for implementing keyboard shortcuts, such as cmd-q. See the [`action`] module for more information.
//! - Platform services, such as `quit the app` or `open a URL` are available as methods on the [`app::AppContext`]. //! - Platform services, such as `quit the app` or `open a URL` are available as methods on the [`app::App`].
//! - An async executor that is integrated with the platform's event loop. See the [`executor`] module for more information., //! - An async executor that is integrated with the platform's event loop. See the [`executor`] module for more information.,
//! - The [gpui::test] macro provides a convenient way to write tests for your GPUI applications. Tests also have their //! - The [gpui::test] macro provides a convenient way to write tests for your GPUI applications. Tests also have their
//! own kind of context, a [`TestAppContext`] which provides ways of simulating common platform input. See [`app::test_context`] //! own kind of context, a [`TestAppContext`] which provides ways of simulating common platform input. See [`app::test_context`]
@ -165,26 +165,26 @@ pub trait AppContext {
/// can't hold a direct reference to the application context. /// can't hold a direct reference to the application context.
type Result<T>; type Result<T>;
/// Create a new model in the app context. /// Create a new entity in the app context.
fn new<T: 'static>( fn new<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>>; ) -> Self::Result<Entity<T>>;
/// Reserve a slot for a model to be inserted later. /// Reserve a slot for a entity to be inserted later.
/// The returned [Reservation] allows you to obtain the [EntityId] for the future model. /// The returned [Reservation] allows you to obtain the [EntityId] for the future entity.
fn reserve_entity<T: 'static>(&mut self) -> Self::Result<Reservation<T>>; fn reserve_entity<T: 'static>(&mut self) -> Self::Result<Reservation<T>>;
/// Insert a new model in the app context based on a [Reservation] previously obtained from [`reserve_entity`]. /// Insert a new entity in the app context based on a [Reservation] previously obtained from [`reserve_entity`].
/// ///
/// [`reserve_entity`]: Self::reserve_entity /// [`reserve_entity`]: Self::reserve_entity
fn insert_entity<T: 'static>( fn insert_entity<T: 'static>(
&mut self, &mut self,
reservation: Reservation<T>, reservation: Reservation<T>,
build_model: impl FnOnce(&mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>>; ) -> Self::Result<Entity<T>>;
/// Update a model in the app context. /// Update a entity in the app context.
fn update_entity<T, R>( fn update_entity<T, R>(
&mut self, &mut self,
handle: &Entity<T>, handle: &Entity<T>,
@ -193,7 +193,7 @@ pub trait AppContext {
where where
T: 'static; T: 'static;
/// Read a model from the app context. /// Read a entity from the app context.
fn read_entity<T, R>( fn read_entity<T, R>(
&self, &self,
handle: &Entity<T>, handle: &Entity<T>,
@ -227,12 +227,12 @@ pub trait AppContext {
G: Global; G: Global;
} }
/// Returned by [Context::reserve_entity] to later be passed to [Context::insert_model]. /// Returned by [Context::reserve_entity] to later be passed to [Context::insert_entity].
/// Allows you to obtain the [EntityId] for a model before it is created. /// Allows you to obtain the [EntityId] for a entity before it is created.
pub struct Reservation<T>(pub(crate) Slot<T>); pub struct Reservation<T>(pub(crate) Slot<T>);
impl<T: 'static> Reservation<T> { impl<T: 'static> Reservation<T> {
/// Returns the [EntityId] that will be associated with the model once it is inserted. /// Returns the [EntityId] that will be associated with the entity once it is inserted.
pub fn entity_id(&self) -> EntityId { pub fn entity_id(&self) -> EntityId {
self.0.entity_id() self.0.entity_id()
} }
@ -247,14 +247,14 @@ pub trait VisualContext: AppContext {
/// Update a view with the given callback /// Update a view with the given callback
fn update_window_entity<T: 'static, R>( fn update_window_entity<T: 'static, R>(
&mut self, &mut self,
model: &Entity<T>, entity: &Entity<T>,
update: impl FnOnce(&mut T, &mut Window, &mut Context<T>) -> R, update: impl FnOnce(&mut T, &mut Window, &mut Context<T>) -> R,
) -> Self::Result<R>; ) -> Self::Result<R>;
/// Update a view with the given callback /// Update a view with the given callback
fn new_window_entity<T: 'static>( fn new_window_entity<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut Window, &mut Context<'_, T>) -> T, build_entity: impl FnOnce(&mut Window, &mut Context<'_, T>) -> T,
) -> Self::Result<Entity<T>>; ) -> Self::Result<Entity<T>>;
/// Replace the root view of a window with a new view. /// Replace the root view of a window with a new view.
@ -265,8 +265,8 @@ pub trait VisualContext: AppContext {
where where
V: 'static + Render; V: 'static + Render;
/// Focus a model in the window, if it implements the [`Focusable`] trait. /// Focus a entity in the window, if it implements the [`Focusable`] trait.
fn focus<V>(&mut self, model: &Entity<V>) -> Self::Result<()> fn focus<V>(&mut self, entity: &Entity<V>) -> Self::Result<()>
where where
V: Focusable; V: Focusable;
} }

View file

@ -4,7 +4,7 @@ use std::ops::Range;
/// Implement this trait to allow views to handle textual input when implementing an editor, field, etc. /// Implement this trait to allow views to handle textual input when implementing an editor, field, etc.
/// ///
/// Once your view implements this trait, you can use it to construct an [`ElementInputHandler<V>`]. /// Once your view implements this trait, you can use it to construct an [`ElementInputHandler<V>`].
/// This input handler can then be assigned during paint by calling [`WindowContext::handle_input`]. /// This input handler can then be assigned during paint by calling [`Window::handle_input`].
/// ///
/// See [`InputHandler`] for details on how to implement each method. /// See [`InputHandler`] for details on how to implement each method.
pub trait EntityInputHandler: 'static + Sized { pub trait EntityInputHandler: 'static + Sized {
@ -64,7 +64,7 @@ pub trait EntityInputHandler: 'static + Sized {
) -> Option<Bounds<Pixels>>; ) -> Option<Bounds<Pixels>>;
} }
/// The canonical implementation of [`PlatformInputHandler`]. Call [`WindowContext::handle_input`] /// The canonical implementation of [`PlatformInputHandler`]. Call [`Window::handle_input`]
/// with an instance during your element's paint. /// with an instance during your element's paint.
pub struct ElementInputHandler<V> { pub struct ElementInputHandler<V> {
view: Entity<V>, view: Entity<V>,
@ -72,8 +72,7 @@ pub struct ElementInputHandler<V> {
} }
impl<V: 'static> ElementInputHandler<V> { impl<V: 'static> ElementInputHandler<V> {
/// Used in [`Element::paint`][element_paint] with the element's bounds and a view context for its /// Used in [`Element::paint`][element_paint] with the element's bounds, a `Window`, and a `App` context.
/// containing view.
/// ///
/// [element_paint]: crate::Element::paint /// [element_paint]: crate::Element::paint
pub fn new(element_bounds: Bounds<Pixels>, view: Entity<V>) -> Self { pub fn new(element_bounds: Bounds<Pixels>, view: Entity<V>) -> Self {

View file

@ -949,7 +949,7 @@ impl PlatformWindow for MacWindow {
unsafe { self.0.lock().native_window.isKeyWindow() == YES } unsafe { self.0.lock().native_window.isKeyWindow() == YES }
} }
// is_hovered is unused on macOS. See WindowContext::is_window_hovered. // is_hovered is unused on macOS. See Window::is_window_hovered.
fn is_hovered(&self) -> bool { fn is_hovered(&self) -> bool {
false false
} }

View file

@ -163,7 +163,7 @@ impl Subscription {
} }
/// Detaches the subscription from this handle. The callback will /// Detaches the subscription from this handle. The callback will
/// continue to be invoked until the views or models it has been /// continue to be invoked until the entities it has been
/// subscribed to are dropped /// subscribed to are dropped
pub fn detach(mut self) { pub fn detach(mut self) {
self.unsubscribe.take(); self.unsubscribe.take();

View file

@ -101,7 +101,7 @@ impl<T: 'static> futures::Stream for Observation<T> {
} }
} }
/// observe returns a stream of the change events from the given `View` or `Model` /// observe returns a stream of the change events from the given `Entity`
pub fn observe<T: 'static>(entity: &Entity<T>, cx: &mut TestAppContext) -> Observation<()> { pub fn observe<T: 'static>(entity: &Entity<T>, cx: &mut TestAppContext) -> Observation<()> {
let (tx, rx) = smol::channel::unbounded(); let (tx, rx) = smol::channel::unbounded();
let _subscription = cx.update(|cx| { let _subscription = cx.update(|cx| {

View file

@ -68,10 +68,10 @@ impl<V: Render> Element for Entity<V> {
} }
} }
/// A dynamically-typed handle to a view, which can be downcast to a [View] for a specific type. /// A dynamically-typed handle to a view, which can be downcast to a [Entity] for a specific type.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct AnyView { pub struct AnyView {
model: AnyEntity, entity: AnyEntity,
render: fn(&AnyView, &mut Window, &mut App) -> AnyElement, render: fn(&AnyView, &mut Window, &mut App) -> AnyElement,
cached_style: Option<StyleRefinement>, cached_style: Option<StyleRefinement>,
} }
@ -79,7 +79,7 @@ pub struct AnyView {
impl<V: Render> From<Entity<V>> for AnyView { impl<V: Render> From<Entity<V>> for AnyView {
fn from(value: Entity<V>) -> Self { fn from(value: Entity<V>) -> Self {
AnyView { AnyView {
model: value.into_any(), entity: value.into_any(),
render: any_view::render::<V>, render: any_view::render::<V>,
cached_style: None, cached_style: None,
} }
@ -88,8 +88,8 @@ impl<V: Render> From<Entity<V>> for AnyView {
impl AnyView { impl AnyView {
/// Indicate that this view should be cached when using it as an element. /// Indicate that this view should be cached when using it as an element.
/// When using this method, the view's previous layout and paint will be recycled from the previous frame if [ViewContext::notify] has not been called since it was rendered. /// When using this method, the view's previous layout and paint will be recycled from the previous frame if [Context::notify] has not been called since it was rendered.
/// The one exception is when [WindowContext::refresh] is called, in which case caching is ignored. /// The one exception is when [Window::refresh] is called, in which case caching is ignored.
pub fn cached(mut self, style: StyleRefinement) -> Self { pub fn cached(mut self, style: StyleRefinement) -> Self {
self.cached_style = Some(style); self.cached_style = Some(style);
self self
@ -98,18 +98,18 @@ impl AnyView {
/// Convert this to a weak handle. /// Convert this to a weak handle.
pub fn downgrade(&self) -> AnyWeakView { pub fn downgrade(&self) -> AnyWeakView {
AnyWeakView { AnyWeakView {
model: self.model.downgrade(), entity: self.entity.downgrade(),
render: self.render, render: self.render,
} }
} }
/// Convert this to a [View] of a specific type. /// Convert this to a [Entity] of a specific type.
/// If this handle does not contain a view of the specified type, returns itself in an `Err` variant. /// If this handle does not contain a view of the specified type, returns itself in an `Err` variant.
pub fn downcast<T: 'static>(self) -> Result<Entity<T>, Self> { pub fn downcast<T: 'static>(self) -> Result<Entity<T>, Self> {
match self.model.downcast() { match self.entity.downcast() {
Ok(model) => Ok(model), Ok(entity) => Ok(entity),
Err(model) => Err(Self { Err(entity) => Err(Self {
model, entity,
render: self.render, render: self.render,
cached_style: self.cached_style, cached_style: self.cached_style,
}), }),
@ -118,18 +118,18 @@ impl AnyView {
/// Gets the [TypeId] of the underlying view. /// Gets the [TypeId] of the underlying view.
pub fn entity_type(&self) -> TypeId { pub fn entity_type(&self) -> TypeId {
self.model.entity_type self.entity.entity_type
} }
/// Gets the entity id of this handle. /// Gets the entity id of this handle.
pub fn entity_id(&self) -> EntityId { pub fn entity_id(&self) -> EntityId {
self.model.entity_id() self.entity.entity_id()
} }
} }
impl PartialEq for AnyView { impl PartialEq for AnyView {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.model == other.model self.entity == other.entity
} }
} }
@ -283,16 +283,16 @@ impl IntoElement for AnyView {
/// A weak, dynamically-typed view handle that does not prevent the view from being released. /// A weak, dynamically-typed view handle that does not prevent the view from being released.
pub struct AnyWeakView { pub struct AnyWeakView {
model: AnyWeakEntity, entity: AnyWeakEntity,
render: fn(&AnyView, &mut Window, &mut App) -> AnyElement, render: fn(&AnyView, &mut Window, &mut App) -> AnyElement,
} }
impl AnyWeakView { impl AnyWeakView {
/// Convert to a strongly-typed handle if the referenced view has not yet been released. /// Convert to a strongly-typed handle if the referenced view has not yet been released.
pub fn upgrade(&self) -> Option<AnyView> { pub fn upgrade(&self) -> Option<AnyView> {
let model = self.model.upgrade()?; let entity = self.entity.upgrade()?;
Some(AnyView { Some(AnyView {
model, entity,
render: self.render, render: self.render,
cached_style: None, cached_style: None,
}) })
@ -302,7 +302,7 @@ impl AnyWeakView {
impl<V: 'static + Render> From<WeakEntity<V>> for AnyWeakView { impl<V: 'static + Render> From<WeakEntity<V>> for AnyWeakView {
fn from(view: WeakEntity<V>) -> Self { fn from(view: WeakEntity<V>) -> Self {
AnyWeakView { AnyWeakView {
model: view.into(), entity: view.into(),
render: any_view::render::<V>, render: any_view::render::<V>,
} }
} }
@ -310,14 +310,14 @@ impl<V: 'static + Render> From<WeakEntity<V>> for AnyWeakView {
impl PartialEq for AnyWeakView { impl PartialEq for AnyWeakView {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.model == other.model self.entity == other.entity
} }
} }
impl std::fmt::Debug for AnyWeakView { impl std::fmt::Debug for AnyWeakView {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AnyWeakView") f.debug_struct("AnyWeakView")
.field("entity_id", &self.model.entity_id) .field("entity_id", &self.entity.entity_id)
.finish_non_exhaustive() .finish_non_exhaustive()
} }
} }

View file

@ -189,7 +189,7 @@ impl WindowFocusEvent {
} }
} }
/// This is provided when subscribing for `ViewContext::on_focus_out` events. /// This is provided when subscribing for `Context::on_focus_out` events.
pub struct FocusOutEvent { pub struct FocusOutEvent {
/// A weak focus handle representing what was blurred. /// A weak focus handle representing what was blurred.
pub blurred: WeakFocusHandle, pub blurred: WeakFocusHandle,
@ -423,7 +423,7 @@ impl HitboxId {
} }
/// A rectangular region that potentially blocks hitboxes inserted prior. /// A rectangular region that potentially blocks hitboxes inserted prior.
/// See [WindowContext::insert_hitbox] for more details. /// See [Window::insert_hitbox] for more details.
#[derive(Clone, Debug, Deref)] #[derive(Clone, Debug, Deref)]
pub struct Hitbox { pub struct Hitbox {
/// A unique identifier for the hitbox. /// A unique identifier for the hitbox.
@ -1193,9 +1193,9 @@ impl Window {
}); });
} }
/// Subscribe to events emitted by a model or view. /// Subscribe to events emitted by a entity.
/// The entity to which you're subscribing must implement the [`EventEmitter`] trait. /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
/// The callback will be invoked a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a window context for the current window. /// The callback will be invoked a handle to the emitting entity, the event, and a window context for the current window.
pub fn observe<T: 'static>( pub fn observe<T: 'static>(
&mut self, &mut self,
observed: &Entity<T>, observed: &Entity<T>,
@ -1222,9 +1222,9 @@ impl Window {
) )
} }
/// Subscribe to events emitted by a model or view. /// Subscribe to events emitted by a entity.
/// The entity to which you're subscribing must implement the [`EventEmitter`] trait. /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
/// The callback will be invoked a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a window context for the current window. /// The callback will be invoked a handle to the emitting entity, the event, and a window context for the current window.
pub fn subscribe<Emitter, Evt>( pub fn subscribe<Emitter, Evt>(
&mut self, &mut self,
entity: &Entity<Emitter>, entity: &Entity<Emitter>,
@ -1259,7 +1259,7 @@ impl Window {
) )
} }
/// Register a callback to be invoked when the given Model or View is released. /// Register a callback to be invoked when the given `Entity` is released.
pub fn observe_release<T>( pub fn observe_release<T>(
&self, &self,
entity: &Entity<T>, entity: &Entity<T>,
@ -1914,7 +1914,7 @@ impl Window {
} }
/// Push a text style onto the stack, and call a function with that style active. /// Push a text style onto the stack, and call a function with that style active.
/// Use [`AppContext::text_style`] to get the current, combined text style. This method /// Use [`Window::text_style`] to get the current, combined text style. This method
/// should only be called as part of element drawing. /// should only be called as part of element drawing.
pub fn with_text_style<F, R>(&mut self, style: Option<TextStyleRefinement>, f: F) -> R pub fn with_text_style<F, R>(&mut self, style: Option<TextStyleRefinement>, f: F) -> R
where where
@ -4071,7 +4071,7 @@ impl From<(&'static str, u32)> for ElementId {
} }
/// A rectangle to be rendered in the window at the given position and size. /// A rectangle to be rendered in the window at the given position and size.
/// Passed as an argument [`WindowContext::paint_quad`]. /// Passed as an argument [`Window::paint_quad`].
#[derive(Clone)] #[derive(Clone)]
pub struct PaintQuad { pub struct PaintQuad {
/// The bounds of the quad within the window. /// The bounds of the quad within the window.

View file

@ -68,7 +68,7 @@ pub struct RenderablePromptHandle {
pub(crate) view: Box<dyn PromptViewHandle>, pub(crate) view: Box<dyn PromptViewHandle>,
} }
/// Use this function in conjunction with [AppContext::set_prompt_renderer] to force /// Use this function in conjunction with [App::set_prompt_builder] to force
/// GPUI to always use the fallback prompt renderer. /// GPUI to always use the fallback prompt renderer.
pub fn fallback_prompt_renderer( pub fn fallback_prompt_renderer(
level: PromptLevel, level: PromptLevel,

View file

@ -25,9 +25,9 @@ pub fn derive_app_context(input: TokenStream) -> TokenStream {
fn new<T: 'static>( fn new<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut gpui::Context<'_, T>) -> T, build_entity: impl FnOnce(&mut gpui::Context<'_, T>) -> T,
) -> Self::Result<gpui::Entity<T>> { ) -> Self::Result<gpui::Entity<T>> {
self.#app_variable.new(build_model) self.#app_variable.new(build_entity)
} }
fn reserve_entity<T: 'static>(&mut self) -> Self::Result<gpui::Reservation<T>> { fn reserve_entity<T: 'static>(&mut self) -> Self::Result<gpui::Reservation<T>> {
@ -37,9 +37,9 @@ pub fn derive_app_context(input: TokenStream) -> TokenStream {
fn insert_entity<T: 'static>( fn insert_entity<T: 'static>(
&mut self, &mut self,
reservation: gpui::Reservation<T>, reservation: gpui::Reservation<T>,
build_model: impl FnOnce(&mut gpui::Context<'_, T>) -> T, build_entity: impl FnOnce(&mut gpui::Context<'_, T>) -> T,
) -> Self::Result<gpui::Entity<T>> { ) -> Self::Result<gpui::Entity<T>> {
self.#app_variable.insert_entity(reservation, build_model) self.#app_variable.insert_entity(reservation, build_entity)
} }
fn update_entity<T, R>( fn update_entity<T, R>(

View file

@ -34,17 +34,17 @@ pub fn derive_visual_context(input: TokenStream) -> TokenStream {
fn update_window_entity<T: 'static, R>( fn update_window_entity<T: 'static, R>(
&mut self, &mut self,
model: &gpui::Entity<T>, entity: &gpui::Entity<T>,
update: impl FnOnce(&mut T, &mut gpui::Window, &mut gpui::Context<T>) -> R, update: impl FnOnce(&mut T, &mut gpui::Window, &mut gpui::Context<T>) -> R,
) -> Self::Result<R> { ) -> Self::Result<R> {
gpui::AppContext::update_entity(self.#app_variable, model, |entity, cx| update(entity, self.#window_variable, cx)) gpui::AppContext::update_entity(self.#app_variable, entity, |entity, cx| update(entity, self.#window_variable, cx))
} }
fn new_window_entity<T: 'static>( fn new_window_entity<T: 'static>(
&mut self, &mut self,
build_model: impl FnOnce(&mut gpui::Window, &mut gpui::Context<'_, T>) -> T, build_entity: impl FnOnce(&mut gpui::Window, &mut gpui::Context<'_, T>) -> T,
) -> Self::Result<gpui::Entity<T>> { ) -> Self::Result<gpui::Entity<T>> {
gpui::AppContext::new(self.#app_variable, |cx| build_model(self.#window_variable, cx)) gpui::AppContext::new(self.#app_variable, |cx| build_entity(self.#window_variable, cx))
} }
fn replace_root_view<V>( fn replace_root_view<V>(
@ -57,11 +57,11 @@ pub fn derive_visual_context(input: TokenStream) -> TokenStream {
self.#window_variable.replace_root(self.#app_variable, build_view) self.#window_variable.replace_root(self.#app_variable, build_view)
} }
fn focus<V>(&mut self, model: &gpui::Entity<V>) -> Self::Result<()> fn focus<V>(&mut self, entity: &gpui::Entity<V>) -> Self::Result<()>
where where
V: gpui::Focusable, V: gpui::Focusable,
{ {
let focus_handle = gpui::Focusable::focus_handle(model, self.#app_variable); let focus_handle = gpui::Focusable::focus_handle(entity, self.#app_variable);
self.#window_variable.focus(&focus_handle) self.#window_variable.focus(&focus_handle)
} }
} }

View file

@ -1845,11 +1845,11 @@ mod tests {
let buffer = cx.new(|cx| Buffer::local(buffer_text, cx)); let buffer = cx.new(|cx| Buffer::local(buffer_text, cx));
let window = cx.add_window(|_, _| gpui::Empty); let window = cx.add_window(|_, _| gpui::Empty);
let editor = window.build_model(cx, |window, cx| { let editor = window.build_entity(cx, |window, cx| {
Editor::for_buffer(buffer.clone(), None, window, cx) Editor::for_buffer(buffer.clone(), None, window, cx)
}); });
let search_bar = window.build_model(cx, |window, cx| { let search_bar = window.build_entity(cx, |window, cx| {
let mut search_bar = BufferSearchBar::new(window, cx); let mut search_bar = BufferSearchBar::new(window, cx);
search_bar.set_active_pane_item(Some(&editor), window, cx); search_bar.set_active_pane_item(Some(&editor), window, cx);
search_bar.show(window, cx); search_bar.show(window, cx);

View file

@ -2337,7 +2337,7 @@ pub mod tests {
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx)); let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx));
let workspace = window; let workspace = window;
let search_bar = window.build_model(cx, |_, _| ProjectSearchBar::new()); let search_bar = window.build_entity(cx, |_, _| ProjectSearchBar::new());
let active_item = cx.read(|cx| { let active_item = cx.read(|cx| {
workspace workspace
@ -2577,7 +2577,7 @@ pub mod tests {
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx)); let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx));
let workspace = window; let workspace = window;
let search_bar = window.build_model(cx, |_, _| ProjectSearchBar::new()); let search_bar = window.build_entity(cx, |_, _| ProjectSearchBar::new());
let active_item = cx.read(|cx| { let active_item = cx.read(|cx| {
workspace workspace
@ -2879,7 +2879,7 @@ pub mod tests {
}); });
let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx)); let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx));
let workspace = window.root(cx).unwrap(); let workspace = window.root(cx).unwrap();
let search_bar = window.build_model(cx, |_, _| ProjectSearchBar::new()); let search_bar = window.build_entity(cx, |_, _| ProjectSearchBar::new());
let active_item = cx.read(|cx| { let active_item = cx.read(|cx| {
workspace workspace
@ -2997,7 +2997,7 @@ pub mod tests {
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx)); let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx));
let workspace = window.root(cx).unwrap(); let workspace = window.root(cx).unwrap();
let search_bar = window.build_model(cx, |_, _| ProjectSearchBar::new()); let search_bar = window.build_entity(cx, |_, _| ProjectSearchBar::new());
window window
.update(cx, { .update(cx, {
@ -3333,8 +3333,8 @@ pub mod tests {
.update(cx, |this, _, _| this.panes().to_owned()) .update(cx, |this, _, _| this.panes().to_owned())
.unwrap(); .unwrap();
let search_bar_1 = window.build_model(cx, |_, _| ProjectSearchBar::new()); let search_bar_1 = window.build_entity(cx, |_, _| ProjectSearchBar::new());
let search_bar_2 = window.build_model(cx, |_, _| ProjectSearchBar::new()); let search_bar_2 = window.build_entity(cx, |_, _| ProjectSearchBar::new());
assert_eq!(panes.len(), 1); assert_eq!(panes.len(), 1);
let first_pane = panes.first().cloned().unwrap(); let first_pane = panes.first().cloned().unwrap();
@ -3587,7 +3587,7 @@ pub mod tests {
.focus_handle(cx) .focus_handle(cx)
.contains_focused(window, cx)) .contains_focused(window, cx))
.unwrap()); .unwrap());
let search_bar = window.build_model(cx, |_, _| ProjectSearchBar::new()); let search_bar = window.build_entity(cx, |_, _| ProjectSearchBar::new());
window window
.update(cx, { .update(cx, {
let search_bar = search_bar.clone(); let search_bar = search_bar.clone();

View file

@ -15,7 +15,7 @@ use workspace::ui::StyledExt;
pub fn init(cx: &mut App) { pub fn init(cx: &mut App) {
cx.set_prompt_builder(fallback_prompt_renderer) cx.set_prompt_builder(fallback_prompt_renderer)
} }
/// Use this function in conjunction with [AppContext::set_prompt_renderer] to force /// Use this function in conjunction with [App::set_prompt_builder] to force
/// GPUI to always use the fallback prompt renderer. /// GPUI to always use the fallback prompt renderer.
pub fn fallback_prompt_renderer( pub fn fallback_prompt_renderer(
level: PromptLevel, level: PromptLevel,