diff --git a/crates/activity_indicator/src/activity_indicator.rs b/crates/activity_indicator/src/activity_indicator.rs index 2fd8774398..99b0b9dc8b 100644 --- a/crates/activity_indicator/src/activity_indicator.rs +++ b/crates/activity_indicator/src/activity_indicator.rs @@ -5,7 +5,7 @@ use gpui::{ actions, elements::*, platform::{CursorStyle, MouseButton}, - Action, AppContext, Entity, ModelHandle, RenderContext, View, ViewContext, ViewHandle, + Action, AppContext, Entity, ModelHandle, View, ViewContext, ViewHandle, }; use language::{LanguageRegistry, LanguageServerBinaryStatus}; use project::{LanguageServerProgress, Project}; @@ -172,7 +172,7 @@ impl ActivityIndicator { .flatten() } - fn content_to_render(&mut self, cx: &mut RenderContext) -> Content { + fn content_to_render(&mut self, cx: &mut ViewContext) -> Content { // Show any language server has pending activity. let mut pending_work = self.pending_language_server_work(cx); if let Some(PendingWork { @@ -314,7 +314,7 @@ impl View for ActivityIndicator { "ActivityIndicator" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let Content { icon, message, diff --git a/crates/auto_update/src/update_notification.rs b/crates/auto_update/src/update_notification.rs index 414dcdf5a1..c3a8f9ed69 100644 --- a/crates/auto_update/src/update_notification.rs +++ b/crates/auto_update/src/update_notification.rs @@ -26,7 +26,7 @@ impl View for UpdateNotification { "UpdateNotification" } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext) -> gpui::ElementBox { let theme = cx.global::().theme.clone(); let theme = &theme.update_notification; diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index 6c8cbc5516..ecb5d8adaf 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -1,6 +1,6 @@ use gpui::{ - elements::*, platform::MouseButton, AppContext, Entity, RenderContext, Subscription, View, - ViewContext, ViewHandle, + elements::*, platform::MouseButton, AppContext, Entity, Subscription, View, ViewContext, + ViewHandle, }; use itertools::Itertools; use search::ProjectSearchView; @@ -41,7 +41,7 @@ impl View for Breadcrumbs { "Breadcrumbs" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let active_item = match &self.active_item { Some(active_item) => active_item, None => return Empty::new().boxed(), diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index 60272b66bb..537c77a7e4 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -16,8 +16,8 @@ use gpui::{ impl_internal_actions, json::{self, ToJson}, platform::{CursorStyle, MouseButton}, - AppContext, Entity, ImageData, ModelHandle, RenderContext, Subscription, View, ViewContext, - ViewHandle, WeakViewHandle, + AppContext, Entity, ImageData, ModelHandle, Subscription, View, ViewContext, ViewHandle, + WeakViewHandle, }; use settings::Settings; use std::{ops::Range, sync::Arc}; @@ -68,7 +68,7 @@ impl View for CollabTitlebarItem { "CollabTitlebarItem" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let workspace = if let Some(workspace) = self.workspace.upgrade(cx) { workspace } else { @@ -325,7 +325,7 @@ impl CollabTitlebarItem { fn render_toggle_contacts_button( &self, theme: &Theme, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let titlebar = &theme.workspace.titlebar; @@ -390,7 +390,7 @@ impl CollabTitlebarItem { &self, theme: &Theme, room: &ModelHandle, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let icon; let tooltip; @@ -436,7 +436,7 @@ impl CollabTitlebarItem { &self, workspace: &ViewHandle, theme: &Theme, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Option { let project = workspace.read(cx).project(); if project.read(cx).is_remote() { @@ -491,7 +491,7 @@ impl CollabTitlebarItem { ) } - fn render_user_menu_button(&self, theme: &Theme, cx: &mut RenderContext) -> ElementBox { + fn render_user_menu_button(&self, theme: &Theme, cx: &mut ViewContext) -> ElementBox { let titlebar = &theme.workspace.titlebar; Stack::new() @@ -535,7 +535,7 @@ impl CollabTitlebarItem { .boxed() } - fn render_sign_in_button(&self, theme: &Theme, cx: &mut RenderContext) -> ElementBox { + fn render_sign_in_button(&self, theme: &Theme, cx: &mut ViewContext) -> ElementBox { let titlebar = &theme.workspace.titlebar; MouseEventHandler::::new(0, cx, |state, _| { let style = titlebar.sign_in_prompt.style_for(state, false); @@ -554,7 +554,7 @@ impl CollabTitlebarItem { fn render_contacts_popover_host<'a>( &'a self, _theme: &'a theme::Titlebar, - cx: &'a RenderContext, + cx: &'a ViewContext, ) -> Option { self.contacts_popover.as_ref().map(|popover| { Overlay::new(ChildView::new(popover, cx).boxed()) @@ -573,7 +573,7 @@ impl CollabTitlebarItem { workspace: &ViewHandle, theme: &Theme, room: &ModelHandle, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Vec { let mut participants = room .read(cx) @@ -615,7 +615,7 @@ impl CollabTitlebarItem { theme: &Theme, user: &Arc, peer_id: PeerId, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let replica_id = workspace.read(cx).project().read(cx).replica_id(); Container::new(self.render_face_pile( @@ -639,7 +639,7 @@ impl CollabTitlebarItem { location: Option, workspace: &ViewHandle, theme: &Theme, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let project_id = workspace.read(cx).project().read(cx).remote_id(); let room = ActiveCall::global(cx).read(cx).room(); @@ -804,7 +804,7 @@ impl CollabTitlebarItem { workspace: &ViewHandle, location: Option, mut style: AvatarStyle, - cx: &RenderContext, + cx: &ViewContext, ) -> AvatarStyle { if let Some(location) = location { if let ParticipantLocation::SharedProject { project_id } = location { @@ -840,7 +840,7 @@ impl CollabTitlebarItem { fn render_connection_status( &self, status: &client::Status, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Option { enum ConnectionStatusButton {} @@ -927,7 +927,7 @@ impl Element for AvatarRibbon { path.line_to(bounds.upper_right() - vec2f(bounds.height(), 0.)); path.curve_to(bounds.lower_right(), bounds.upper_right()); path.line_to(bounds.lower_left()); - cx.scene.push_path(path.build(self.color, None)); + scene.push_path(path.build(self.color, None)); } fn rect_for_text_range( diff --git a/crates/collab_ui/src/collaborator_list_popover.rs b/crates/collab_ui/src/collaborator_list_popover.rs index c409b541c9..bfdcf69eeb 100644 --- a/crates/collab_ui/src/collaborator_list_popover.rs +++ b/crates/collab_ui/src/collaborator_list_popover.rs @@ -1,10 +1,7 @@ use call::ActiveCall; use client::UserStore; use gpui::Action; -use gpui::{ - actions, elements::*, platform::MouseButton, Entity, ModelHandle, RenderContext, View, - ViewContext, -}; +use gpui::{actions, elements::*, platform::MouseButton, Entity, ModelHandle, View, ViewContext}; use settings::Settings; use crate::collab_titlebar_item::ToggleCollaboratorList; @@ -21,7 +18,7 @@ enum Collaborator { actions!(collaborator_list_popover, [NoOp]); pub(crate) struct CollaboratorListPopover { - list_state: ListState, + list_state: ListState, } impl Entity for CollaboratorListPopover { @@ -33,7 +30,7 @@ impl View for CollaboratorListPopover { "CollaboratorListPopover" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = cx.global::().theme.clone(); MouseEventHandler::::new(0, cx, |_, _| { @@ -120,7 +117,7 @@ fn render_collaborator_list_entry( icon: Svg, icon_action: IA, icon_tooltip: String, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { enum Username {} enum UsernameTooltip {} diff --git a/crates/collab_ui/src/contact_finder.rs b/crates/collab_ui/src/contact_finder.rs index d34a344cd6..5d0f315400 100644 --- a/crates/collab_ui/src/contact_finder.rs +++ b/crates/collab_ui/src/contact_finder.rs @@ -1,7 +1,7 @@ use client::{ContactRequestStatus, User, UserStore}; use gpui::{ - elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, RenderContext, Task, - View, ViewContext, ViewHandle, + elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, Task, View, + ViewContext, ViewHandle, }; use picker::{Picker, PickerDelegate}; use settings::Settings; @@ -32,7 +32,7 @@ impl View for ContactFinder { "ContactFinder" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/collab_ui/src/contact_list.rs b/crates/collab_ui/src/contact_list.rs index adbc4d7ec8..891db3d2ac 100644 --- a/crates/collab_ui/src/contact_list.rs +++ b/crates/collab_ui/src/contact_list.rs @@ -11,7 +11,7 @@ use gpui::{ impl_actions, impl_internal_actions, keymap_matcher::KeymapContext, platform::{CursorStyle, MouseButton, PromptLevel}, - AppContext, Entity, ModelHandle, RenderContext, Subscription, View, ViewContext, ViewHandle, + AppContext, Entity, ModelHandle, Subscription, View, ViewContext, ViewHandle, }; use menu::{Confirm, SelectNext, SelectPrev}; use project::Project; @@ -799,7 +799,7 @@ impl ContactList { is_last: bool, is_selected: bool, theme: &theme::ContactList, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let font_cache = cx.font_cache(); let host_avatar_height = theme @@ -834,7 +834,7 @@ impl ContactList { let start_y = bounds.min_y(); let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.); - cx.scene.push_quad(gpui::Quad { + scene.push_quad(gpui::Quad { bounds: RectF::from_points( vec2f(start_x, start_y), vec2f( @@ -846,7 +846,7 @@ impl ContactList { border: gpui::Border::default(), corner_radius: 0., }); - cx.scene.push_quad(gpui::Quad { + scene.push_quad(gpui::Quad { bounds: RectF::from_points( vec2f(start_x, end_y), vec2f(end_x, end_y + tree_branch.width), @@ -898,7 +898,7 @@ impl ContactList { is_last: bool, is_selected: bool, theme: &theme::ContactList, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let font_cache = cx.font_cache(); let host_avatar_height = theme @@ -932,7 +932,7 @@ impl ContactList { let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.); - cx.scene.push_quad(gpui::Quad { + scene.push_quad(gpui::Quad { bounds: RectF::from_points( vec2f(start_x, start_y), vec2f( @@ -944,7 +944,7 @@ impl ContactList { border: gpui::Border::default(), corner_radius: 0., }); - cx.scene.push_quad(gpui::Quad { + scene.push_quad(gpui::Quad { bounds: RectF::from_points( vec2f(start_x, end_y), vec2f(end_x, end_y + tree_branch.width), @@ -999,7 +999,7 @@ impl ContactList { theme: &theme::ContactList, is_selected: bool, is_collapsed: bool, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { enum Header {} enum LeaveCallContactList {} @@ -1077,7 +1077,7 @@ impl ContactList { project: &ModelHandle, theme: &theme::ContactList, is_selected: bool, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let online = contact.online; let busy = contact.busy || calling; @@ -1194,7 +1194,7 @@ impl ContactList { theme: &theme::ContactList, is_incoming: bool, is_selected: bool, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { enum Decline {} enum Accept {} @@ -1331,7 +1331,7 @@ impl View for ContactList { cx } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { enum AddContact {} let theme = cx.global::().theme.clone(); diff --git a/crates/collab_ui/src/contact_notification.rs b/crates/collab_ui/src/contact_notification.rs index 5badae695b..c504a5771b 100644 --- a/crates/collab_ui/src/contact_notification.rs +++ b/crates/collab_ui/src/contact_notification.rs @@ -3,8 +3,7 @@ use std::sync::Arc; use crate::notifications::render_user_notification; use client::{ContactEventKind, User, UserStore}; use gpui::{ - elements::*, impl_internal_actions, AppContext, Entity, ModelHandle, RenderContext, View, - ViewContext, + elements::*, impl_internal_actions, AppContext, Entity, ModelHandle, View, ViewContext, }; use workspace::notifications::Notification; @@ -43,7 +42,7 @@ impl View for ContactNotification { "ContactNotification" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { match self.kind { ContactEventKind::Requested => render_user_notification( self.user.clone(), diff --git a/crates/collab_ui/src/contacts_popover.rs b/crates/collab_ui/src/contacts_popover.rs index 52925738b7..ee900c285c 100644 --- a/crates/collab_ui/src/contacts_popover.rs +++ b/crates/collab_ui/src/contacts_popover.rs @@ -1,8 +1,8 @@ use crate::{contact_finder::ContactFinder, contact_list::ContactList, ToggleContactsMenu}; use client::UserStore; use gpui::{ - actions, elements::*, platform::MouseButton, AppContext, Entity, ModelHandle, RenderContext, - View, ViewContext, ViewHandle, + actions, elements::*, platform::MouseButton, AppContext, Entity, ModelHandle, View, + ViewContext, ViewHandle, }; use project::Project; use settings::Settings; @@ -91,7 +91,7 @@ impl View for ContactsPopover { "ContactsPopover" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = cx.global::().theme.clone(); let child = match &self.child { Child::ContactList(child) => ChildView::new(child, cx), diff --git a/crates/collab_ui/src/face_pile.rs b/crates/collab_ui/src/face_pile.rs index 3b95443fee..9269a32fdb 100644 --- a/crates/collab_ui/src/face_pile.rs +++ b/crates/collab_ui/src/face_pile.rs @@ -37,7 +37,7 @@ impl Element for FacePile { let mut width = 0.; for face in &mut self.faces { - width += face.layout(constraint, cx).x(); + width += face.layout(constraint, view, cx).x(); } width -= self.overlap * self.faces.len().saturating_sub(1) as f32; @@ -60,7 +60,7 @@ impl Element for FacePile { let size = face.size(); origin_x -= size.x(); cx.paint_layer(None, |cx| { - face.paint(vec2f(origin_x, origin_y), visible_bounds, cx); + face.paint(scene, vec2f(origin_x, origin_y), visible_bounds, view, cx); }); origin_x += self.overlap; } diff --git a/crates/collab_ui/src/incoming_call_notification.rs b/crates/collab_ui/src/incoming_call_notification.rs index 58c42f919f..ed60959413 100644 --- a/crates/collab_ui/src/incoming_call_notification.rs +++ b/crates/collab_ui/src/incoming_call_notification.rs @@ -6,7 +6,7 @@ use gpui::{ geometry::{rect::RectF, vector::vec2f}, impl_internal_actions, platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions}, - AppContext, Entity, RenderContext, View, ViewContext, + AppContext, Entity, View, ViewContext, }; use settings::Settings; use util::ResultExt; @@ -99,7 +99,7 @@ impl IncomingCallNotification { } } - fn render_caller(&self, cx: &mut RenderContext) -> ElementBox { + fn render_caller(&self, cx: &mut ViewContext) -> ElementBox { let theme = &cx.global::().theme.incoming_call_notification; let default_project = proto::ParticipantProject::default(); let initial_project = self @@ -165,7 +165,7 @@ impl IncomingCallNotification { .boxed() } - fn render_buttons(&self, cx: &mut RenderContext) -> ElementBox { + fn render_buttons(&self, cx: &mut ViewContext) -> ElementBox { enum Accept {} enum Decline {} @@ -222,7 +222,7 @@ impl View for IncomingCallNotification { "IncomingCallNotification" } - fn render(&mut self, cx: &mut RenderContext) -> gpui::ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> gpui::ElementBox { let background = cx .global::() .theme diff --git a/crates/collab_ui/src/notifications.rs b/crates/collab_ui/src/notifications.rs index 0353557681..952c6777a3 100644 --- a/crates/collab_ui/src/notifications.rs +++ b/crates/collab_ui/src/notifications.rs @@ -2,7 +2,7 @@ use client::User; use gpui::{ elements::*, platform::{CursorStyle, MouseButton}, - Action, Element, ElementBox, RenderContext, View, + Action, Element, ElementBox, View, ViewContext, }; use settings::Settings; use std::sync::Arc; @@ -16,7 +16,7 @@ pub fn render_user_notification( body: Option<&'static str>, dismiss_action: A, buttons: Vec<(&'static str, Box)>, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let theme = cx.global::().theme.clone(); let theme = &theme.contact_notification; diff --git a/crates/collab_ui/src/project_shared_notification.rs b/crates/collab_ui/src/project_shared_notification.rs index 7cf666c7ca..9c22ed734e 100644 --- a/crates/collab_ui/src/project_shared_notification.rs +++ b/crates/collab_ui/src/project_shared_notification.rs @@ -6,7 +6,7 @@ use gpui::{ elements::*, geometry::{rect::RectF, vector::vec2f}, platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions}, - AppContext, Entity, RenderContext, View, ViewContext, + AppContext, Entity, View, ViewContext, }; use settings::Settings; use std::sync::Arc; @@ -104,7 +104,7 @@ impl ProjectSharedNotification { cx.remove_window(window_id); } - fn render_owner(&self, cx: &mut RenderContext) -> ElementBox { + fn render_owner(&self, cx: &mut ViewContext) -> ElementBox { let theme = &cx.global::().theme.project_shared_notification; Flex::row() .with_children(self.owner.avatar.clone().map(|avatar| { @@ -164,7 +164,7 @@ impl ProjectSharedNotification { .boxed() } - fn render_buttons(&self, cx: &mut RenderContext) -> ElementBox { + fn render_buttons(&self, cx: &mut ViewContext) -> ElementBox { enum Open {} enum Dismiss {} @@ -227,7 +227,7 @@ impl View for ProjectSharedNotification { "ProjectSharedNotification" } - fn render(&mut self, cx: &mut RenderContext) -> gpui::ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> gpui::ElementBox { let background = cx .global::() .theme diff --git a/crates/collab_ui/src/sharing_status_indicator.rs b/crates/collab_ui/src/sharing_status_indicator.rs index aa5c50f449..340c048bf9 100644 --- a/crates/collab_ui/src/sharing_status_indicator.rs +++ b/crates/collab_ui/src/sharing_status_indicator.rs @@ -3,7 +3,7 @@ use gpui::{ color::Color, elements::{MouseEventHandler, Svg}, platform::{Appearance, MouseButton}, - AppContext, Element, ElementBox, Entity, RenderContext, View, + AppContext, Element, ElementBox, Entity, View, ViewContext, }; use settings::Settings; @@ -40,7 +40,7 @@ impl View for SharingStatusIndicator { "SharingStatusIndicator" } - fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> ElementBox { let color = match cx.appearance { Appearance::Light | Appearance::VibrantLight => Color::black(), Appearance::Dark | Appearance::VibrantDark => Color::white(), diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index bc49f4f101..d7e2178302 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -4,8 +4,7 @@ use gpui::{ actions, elements::{ChildView, Flex, Label, ParentElement}, keymap_matcher::Keystroke, - Action, AnyViewHandle, AppContext, Element, Entity, MouseState, RenderContext, View, - ViewContext, ViewHandle, + Action, AnyViewHandle, AppContext, Element, Entity, MouseState, View, ViewContext, ViewHandle, }; use picker::{Picker, PickerDelegate}; use settings::Settings; @@ -80,9 +79,7 @@ impl CommandPalette { fn toggle(_: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { let workspace = cx.handle(); let window_id = cx.window_id(); - let focused_view_id = cx - .focused_view_id(window_id) - .unwrap_or_else(|| workspace.id()); + let focused_view_id = cx.focused_view_id().unwrap_or_else(|| workspace.id()); cx.as_mut().defer(move |cx| { let this = cx.add_view(&workspace, |cx| Self::new(focused_view_id, cx)); @@ -128,7 +125,7 @@ impl View for CommandPalette { "CommandPalette" } - fn render(&mut self, cx: &mut RenderContext) -> gpui::ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> gpui::ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index 25d9b0ec10..47cb253a4e 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -4,15 +4,13 @@ use gpui::{ impl_internal_actions, keymap_matcher::KeymapContext, platform::{CursorStyle, MouseButton}, - Action, AnyViewHandle, AppContext, Axis, Entity, MouseState, RenderContext, SizeConstraint, - Subscription, View, ViewContext, + Action, AnyViewHandle, AppContext, Axis, Entity, MouseState, SizeConstraint, Subscription, + View, ViewContext, }; use menu::*; use settings::Settings; use std::{any::TypeId, borrow::Cow, time::Duration}; -pub type StaticItem = Box ElementBox>; - #[derive(Copy, Clone, PartialEq)] struct Clicked; @@ -28,8 +26,10 @@ pub fn init(cx: &mut AppContext) { cx.add_action(ContextMenu::cancel); } +pub type StaticItem = Box ElementBox>; + type ContextMenuItemBuilder = - Box ElementBox>; + Box ElementBox>; pub enum ContextMenuItemLabel { String(Cow<'static, str>), @@ -142,7 +142,7 @@ impl View for ContextMenu { cx } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { if !self.visible { return Empty::new().boxed(); } @@ -152,10 +152,10 @@ impl View for ContextMenu { let expanded_menu = self .render_menu(cx) .constrained() - .dynamically(move |constraint, cx| { + .dynamically(move |constraint, view, cx| { SizeConstraint::strict_along( Axis::Horizontal, - collapsed_menu.layout(constraint, cx).x(), + collapsed_menu.layout(constraint, view, cx).x(), ) }) .boxed(); @@ -315,7 +315,7 @@ impl ContextMenu { self.visible = true; self.show_count += 1; if !cx.is_self_focused() { - self.previously_focused_view_id = cx.focused_view_id(cx.window_id()); + self.previously_focused_view_id = cx.focused_view_id(); } cx.focus_self(); } else { @@ -328,7 +328,7 @@ impl ContextMenu { self.position_mode = mode; } - fn render_menu_for_measurement(&self, cx: &mut RenderContext) -> impl Element { + fn render_menu_for_measurement(&self, cx: &mut ViewContext) -> impl Element { let window_id = cx.window_id(); let style = cx.global::().theme.context_menu.clone(); Flex::row() @@ -415,14 +415,14 @@ impl ContextMenu { .with_style(style.container) } - fn render_menu(&self, cx: &mut RenderContext) -> impl Element { + fn render_menu(&self, cx: &mut ViewContext) -> impl Element { enum Menu {} enum MenuItem {} let style = cx.global::().theme.context_menu.clone(); let window_id = cx.window_id(); - MouseEventHandler::::new(0, cx, |_, cx| { + MouseEventHandler::::new(0, cx, |_, cx| { Flex::column() .with_children(self.items.iter().enumerate().map(|(ix, item)| { match item { @@ -436,7 +436,7 @@ impl ContextMenu { } }; - MouseEventHandler::::new(ix, cx, |state, _| { + MouseEventHandler::::new(ix, cx, |state, _| { let style = style.item.style_for(state, Some(ix) == self.selected_index); @@ -467,14 +467,14 @@ impl ContextMenu { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_up(MouseButton::Left, |_, _| {}) // Capture these events - .on_down(MouseButton::Left, |_, _| {}) // Capture these events - .on_click(MouseButton::Left, move |_, cx| { + .on_up(MouseButton::Left, |_, _, _| {}) // Capture these events + .on_down(MouseButton::Left, |_, _, _| {}) // Capture these events + .on_click(MouseButton::Left, move |_, _, cx| { cx.dispatch_action(Clicked); let window_id = cx.window_id(); cx.dispatch_any_action_at(window_id, view_id, action.boxed_clone()); }) - .on_drag(MouseButton::Left, |_, _| {}) + .on_drag(MouseButton::Left, |_, _, _| {}) .boxed() } @@ -492,7 +492,7 @@ impl ContextMenu { .with_style(style.container) .boxed() }) - .on_down_out(MouseButton::Left, |_, cx| cx.dispatch_action(Cancel)) - .on_down_out(MouseButton::Right, |_, cx| cx.dispatch_action(Cancel)) + .on_down_out(MouseButton::Left, |_, _, cx| cx.dispatch_action(Cancel)) + .on_down_out(MouseButton::Right, |_, _, cx| cx.dispatch_action(Cancel)) } } diff --git a/crates/copilot/src/sign_in.rs b/crates/copilot/src/sign_in.rs index a65be325ce..74f9828598 100644 --- a/crates/copilot/src/sign_in.rs +++ b/crates/copilot/src/sign_in.rs @@ -96,7 +96,7 @@ impl CopilotCodeVerification { fn render_device_code( data: &PromptUserDeviceFlow, style: &theme::Copilot, - cx: &mut gpui::RenderContext, + cx: &mut gpui::ViewContext, ) -> ElementBox { let copied = cx .read_from_clipboard() @@ -145,7 +145,7 @@ impl CopilotCodeVerification { fn render_prompting_modal( data: &PromptUserDeviceFlow, style: &theme::Copilot, - cx: &mut gpui::RenderContext, + cx: &mut gpui::ViewContext, ) -> ElementBox { Flex::column() .with_children([ @@ -205,7 +205,7 @@ impl CopilotCodeVerification { } fn render_enabled_modal( style: &theme::Copilot, - cx: &mut gpui::RenderContext, + cx: &mut gpui::ViewContext, ) -> ElementBox { let enabled_style = &style.auth.authorized; Flex::column() @@ -254,7 +254,7 @@ impl CopilotCodeVerification { } fn render_unauthorized_modal( style: &theme::Copilot, - cx: &mut gpui::RenderContext, + cx: &mut gpui::ViewContext, ) -> ElementBox { let unauthorized_style = &style.auth.not_authorized; @@ -333,7 +333,7 @@ impl View for CopilotCodeVerification { cx.notify() } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> gpui::ElementBox { let style = cx.global::().theme.clone(); modal("Connect Copilot to Zed", &style.copilot.modal, cx, |cx| { diff --git a/crates/copilot_button/src/copilot_button.rs b/crates/copilot_button/src/copilot_button.rs index 8721829241..e9e83d4f0c 100644 --- a/crates/copilot_button/src/copilot_button.rs +++ b/crates/copilot_button/src/copilot_button.rs @@ -6,8 +6,8 @@ use gpui::{ elements::*, impl_internal_actions, platform::{CursorStyle, MouseButton}, - AppContext, Element, ElementBox, Entity, MouseState, RenderContext, Subscription, View, - ViewContext, ViewHandle, + AppContext, Element, ElementBox, Entity, MouseState, Subscription, View, ViewContext, + ViewHandle, }; use settings::{settings_file::SettingsFile, Settings}; use workspace::{ @@ -91,7 +91,7 @@ impl View for CopilotButton { "CopilotButton" } - fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> ElementBox { let settings = cx.global::(); if !settings.enable_copilot_integration { diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 72337c4696..a341ea4449 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -11,8 +11,7 @@ use editor::{ }; use gpui::{ actions, elements::*, fonts::TextStyle, impl_internal_actions, serde_json, AnyViewHandle, - AppContext, Entity, ModelHandle, RenderContext, Task, View, ViewContext, ViewHandle, - WeakViewHandle, + AppContext, Entity, ModelHandle, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use language::{ Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection, @@ -87,7 +86,7 @@ impl View for ProjectDiagnosticsEditor { "ProjectDiagnosticsEditor" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { if self.path_states.is_empty() { let theme = &cx.global::().theme.project_diagnostics; Label::new("No problems in workspace", theme.empty_message.clone()) diff --git a/crates/diagnostics/src/items.rs b/crates/diagnostics/src/items.rs index 6ebae6e204..5c8f91e32f 100644 --- a/crates/diagnostics/src/items.rs +++ b/crates/diagnostics/src/items.rs @@ -3,8 +3,8 @@ use editor::{Editor, GoToDiagnostic}; use gpui::{ elements::*, platform::{CursorStyle, MouseButton}, - serde_json, AppContext, Entity, ModelHandle, RenderContext, Subscription, View, ViewContext, - ViewHandle, WeakViewHandle, + serde_json, AppContext, Entity, ModelHandle, Subscription, View, ViewContext, ViewHandle, + WeakViewHandle, }; use language::Diagnostic; use project::Project; @@ -84,7 +84,7 @@ impl View for DiagnosticIndicator { "DiagnosticIndicator" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { enum Summary {} enum Message {} diff --git a/crates/drag_and_drop/src/drag_and_drop.rs b/crates/drag_and_drop/src/drag_and_drop.rs index d54e7a86ac..2fd068c408 100644 --- a/crates/drag_and_drop/src/drag_and_drop.rs +++ b/crates/drag_and_drop/src/drag_and_drop.rs @@ -6,7 +6,7 @@ use gpui::{ geometry::{rect::RectF, vector::Vector2F}, platform::{CursorStyle, MouseButton}, scene::{MouseDown, MouseDrag}, - AppContext, Element, ElementBox, EventContext, RenderContext, View, WeakViewHandle, + AppContext, Element, ElementBox, View, ViewContext, WeakViewHandle, }; const DEAD_ZONE: f32 = 4.; @@ -26,7 +26,7 @@ enum State { region_offset: Vector2F, region: RectF, payload: Rc, - render: Rc, &mut RenderContext) -> ElementBox>, + render: Rc, &mut ViewContext) -> ElementBox>, }, Canceled, } @@ -111,7 +111,7 @@ impl DragAndDrop { }) } - pub fn drag_started(event: MouseDown, cx: &mut EventContext) { + pub fn drag_started(event: MouseDown, cx: &mut ViewContext) { cx.update_global(|this: &mut Self, _| { this.currently_dragged = Some(State::Down { region_offset: event.position - event.region.origin(), @@ -123,8 +123,8 @@ impl DragAndDrop { pub fn dragging( event: MouseDrag, payload: Rc, - cx: &mut EventContext, - render: Rc) -> ElementBox>, + cx: &mut ViewContext, + render: Rc) -> ElementBox>, ) { let window_id = cx.window_id(); cx.update_global(|this: &mut Self, cx| { @@ -178,7 +178,7 @@ impl DragAndDrop { }); } - pub fn render(cx: &mut RenderContext) -> Option { + pub fn render(cx: &mut ViewContext) -> Option> { enum DraggedElementHandler {} cx.global::() .currently_dragged @@ -202,20 +202,22 @@ impl DragAndDrop { let position = position - region_offset; Some( Overlay::new( - MouseEventHandler::::new(0, cx, |_, cx| { - render(payload, cx) - }) + MouseEventHandler::::new( + 0, + cx, + |_, cx| render(payload, cx), + ) .with_cursor_style(CursorStyle::Arrow) - .on_up(MouseButton::Left, |_, cx| { - cx.defer(|cx| { + .on_up(MouseButton::Left, |_, _, cx| { + cx.defer(|_, cx| { cx.update_global::(|this, cx| { this.finish_dragging(cx) }); }); cx.propagate_event(); }) - .on_up_out(MouseButton::Left, |_, cx| { - cx.defer(|cx| { + .on_up_out(MouseButton::Left, |_, _, cx| { + cx.defer(|_, cx| { cx.update_global::(|this, cx| { this.finish_dragging(cx) }); @@ -234,22 +236,22 @@ impl DragAndDrop { } State::Canceled => Some( - MouseEventHandler::::new(0, cx, |_, _| { + MouseEventHandler::::new(0, cx, |_, _| { Empty::new() .constrained() .with_width(0.) .with_height(0.) .boxed() }) - .on_up(MouseButton::Left, |_, cx| { - cx.defer(|cx| { + .on_up(MouseButton::Left, |_, _, cx| { + cx.defer(|_, cx| { cx.update_global::(|this, _| { this.currently_dragged = None; }); }); }) - .on_up_out(MouseButton::Left, |_, cx| { - cx.defer(|cx| { + .on_up_out(MouseButton::Left, |_, _, cx| { + cx.defer(|_, cx| { cx.update_global::(|this, _| { this.currently_dragged = None; }); @@ -294,32 +296,32 @@ impl DragAndDrop { } } -pub trait Draggable { - fn as_draggable( +pub trait Draggable { + fn as_draggable( self, payload: P, - render: impl 'static + Fn(&P, &mut RenderContext) -> ElementBox, + render: impl 'static + Fn(&P, &mut ViewContext) -> ElementBox, ) -> Self where Self: Sized; } -impl Draggable for MouseEventHandler { - fn as_draggable( +impl Draggable for MouseEventHandler { + fn as_draggable( self, payload: P, - render: impl 'static + Fn(&P, &mut RenderContext) -> ElementBox, + render: impl 'static + Fn(&P, &mut ViewContext) -> ElementBox, ) -> Self where Self: Sized, { let payload = Rc::new(payload); let render = Rc::new(render); - self.on_down(MouseButton::Left, move |e, cx| { + self.on_down(MouseButton::Left, move |e, _, cx| { cx.propagate_event(); DragAndDrop::::drag_started(e, cx); }) - .on_drag(MouseButton::Left, move |e, cx| { + .on_drag(MouseButton::Left, move |e, _, cx| { let payload = payload.clone(); let render = render.clone(); DragAndDrop::::dragging(e, payload, cx, render) diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index cabc3ce3f9..a88c96863b 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::{Anchor, ExcerptId, ExcerptRange, ToPoint as _}; use collections::{Bound, HashMap, HashSet}; -use gpui::{fonts::HighlightStyle, RenderContext, ElementBox}; +use gpui::{fonts::HighlightStyle, ElementBox, ViewContext}; use language::{BufferSnapshot, Chunk, Patch, Point}; use parking_lot::Mutex; use std::{ @@ -81,7 +81,7 @@ pub enum BlockStyle { } pub struct BlockContext<'a, 'b> { - pub cx: &'b mut RenderContext<'a, crate::Editor>, + pub cx: &'b mut ViewContext<'a, crate::Editor>, pub anchor_x: f32, pub scroll_x: f32, pub gutter_width: f32, @@ -933,7 +933,7 @@ impl BlockDisposition { } impl<'a, 'b> Deref for BlockContext<'a, 'b> { - type Target = RenderContext<'a, crate::Editor>; + type Target = ViewContext<'a, crate::Editor>; fn deref(&self) -> &Self::Target { self.cx diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index dd5bb7b053..fba189b709 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -42,7 +42,7 @@ use gpui::{ platform::{CursorStyle, MouseButton}, serde_json::{self, json}, AnyViewHandle, AppContext, AsyncAppContext, ClipboardItem, Element, ElementBox, Entity, - ModelHandle, RenderContext, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, + ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; use hover_popover::{hide_hover, HideHover, HoverState}; @@ -721,7 +721,7 @@ impl ContextMenu { &self, cursor_position: DisplayPoint, style: EditorStyle, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> (DisplayPoint, ElementBox) { match self { ContextMenu::Completions(menu) => (cursor_position, menu.render(style, cx)), @@ -774,7 +774,7 @@ impl CompletionsMenu { !self.matches.is_empty() } - fn render(&self, style: EditorStyle, cx: &mut RenderContext) -> ElementBox { + fn render(&self, style: EditorStyle, cx: &mut ViewContext) -> ElementBox { enum CompletionTag {} let completions = self.completions.clone(); @@ -950,7 +950,7 @@ impl CodeActionsMenu { &self, mut cursor_position: DisplayPoint, style: EditorStyle, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> (DisplayPoint, ElementBox) { enum ActionTag {} @@ -2928,7 +2928,7 @@ impl Editor { &self, style: &EditorStyle, active: bool, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Option { if self.available_code_actions.is_some() { enum CodeActions {} @@ -2959,7 +2959,7 @@ impl Editor { gutter_hovered: bool, line_height: f32, gutter_margin: f32, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Vec> { enum FoldIndicators {} @@ -3027,7 +3027,7 @@ impl Editor { &self, cursor_position: DisplayPoint, style: EditorStyle, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Option<(DisplayPoint, ElementBox)> { self.context_menu .as_ref() @@ -6795,7 +6795,7 @@ impl Entity for Editor { } impl View for Editor { - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let style = self.style(cx); let font_changed = self.display_map.update(cx, |map, cx| { map.set_fold_ellipses_color(style.folds.ellipses.text_color); @@ -6804,7 +6804,7 @@ impl View for Editor { if font_changed { let handle = self.handle.clone(); - cx.defer(move |cx| { + cx.defer(move |cx: &mut ViewContext| { if let Some(editor) = handle.upgrade(cx) { editor.update(cx, |editor, cx| { hide_hover(editor, &HideHover, cx); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 96d84f59af..59fe561e48 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -31,8 +31,8 @@ use gpui::{ json::{self, ToJson}, platform::{CursorStyle, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent}, text_layout::{self, Line, RunStyle, TextLayoutCache}, - AppContext, Axis, Border, CursorRegion, Element, ElementBox, EventContext, LayoutContext, - MouseRegion, PaintContext, Quad, SceneBuilder, SizeConstraint, ViewContext, WeakViewHandle, + AppContext, Axis, Border, CursorRegion, Element, ElementBox, MouseRegion, Quad, SceneBuilder, + SizeConstraint, ViewContext, WeakViewHandle, }; use itertools::Itertools; use json::json; @@ -124,7 +124,7 @@ impl EditorElement { cx: &mut PaintContext, ) { enum EditorElementMouseHandlers {} - cx.scene.push_mouse_region( + scene.push_mouse_region( MouseRegion::new::(view.id(), view.id(), visible_bounds) .on_down(MouseButton::Left, { let position_map = position_map.clone(); @@ -216,7 +216,7 @@ impl EditorElement { ); enum GutterHandlers {} - cx.scene.push_mouse_region( + scene.push_mouse_region( MouseRegion::new::(view.id(), view.id() + 1, gutter_bounds).on_hover( |hover, cx| { cx.dispatch_action(GutterHover { @@ -409,7 +409,7 @@ impl EditorElement { }: MouseMovedEvent, position_map: &PositionMap, text_bounds: RectF, - cx: &mut EventContext, + cx: &mut ViewContext, ) -> bool { // This will be handled more correctly once https://github.com/zed-industries/zed/issues/1218 is completed // Don't trigger hover popover if mouse is hovering over context menu @@ -432,7 +432,7 @@ impl EditorElement { precise: bool, position_map: &PositionMap, bounds: RectF, - cx: &mut EventContext, + cx: &mut ViewContext, ) -> bool { if !bounds.contains_point(position) { return false; @@ -465,21 +465,22 @@ impl EditorElement { fn paint_background( &self, + scene: &mut SceneBuilder, gutter_bounds: RectF, text_bounds: RectF, layout: &LayoutState, - cx: &mut PaintContext, + cx: &mut ViewContext, ) { let bounds = gutter_bounds.union_rect(text_bounds); let scroll_top = layout.position_map.snapshot.scroll_position().y() * layout.position_map.line_height; - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: gutter_bounds, background: Some(self.style.gutter_background), border: Border::new(0., Color::transparent_black()), corner_radius: 0., }); - cx.scene.push_quad(Quad { + c.push_quad(Quad { bounds: text_bounds, background: Some(self.style.background), border: Border::new(0., Color::transparent_black()), @@ -507,7 +508,7 @@ impl EditorElement { bounds.width(), layout.position_map.line_height * (end_row - start_row + 1) as f32, ); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: RectF::new(origin, size), background: Some(self.style.active_line_background), border: Border::default(), @@ -527,7 +528,7 @@ impl EditorElement { bounds.width(), layout.position_map.line_height * highlighted_rows.len() as f32, ); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: RectF::new(origin, size), background: Some(self.style.highlighted_line_background), border: Border::default(), @@ -539,9 +540,11 @@ impl EditorElement { fn paint_gutter( &mut self, + scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut LayoutState, + editor: &mut Editor, cx: &mut PaintContext, ) { let line_height = layout.position_map.line_height; @@ -569,7 +572,7 @@ impl EditorElement { ix as f32 * line_height - (scroll_top % line_height), ); - line.paint(line_origin, visible_bounds, line_height, cx); + line.paint(scene, line_origin, visible_bounds, line_height, cx); } } @@ -586,7 +589,7 @@ impl EditorElement { let indicator_origin = bounds.origin() + position + centering_offset; - indicator.paint(indicator_origin, visible_bounds, cx); + indicator.paint(scene, indicator_origin, visible_bounds, editor, cx); } } @@ -595,7 +598,13 @@ impl EditorElement { let mut y = *row as f32 * line_height - scroll_top; x += ((layout.gutter_padding + layout.gutter_margin) - indicator.size().x()) / 2.; y += (line_height - indicator.size().y()) / 2.; - indicator.paint(bounds.origin() + vec2f(x, y), visible_bounds, cx); + indicator.paint( + scene, + bounds.origin() + vec2f(x, y), + visible_bounds, + editor, + cx, + ); } } @@ -618,7 +627,7 @@ impl EditorElement { let highlight_size = vec2f(width * 2., end_y - start_y); let highlight_bounds = RectF::new(highlight_origin, highlight_size); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: highlight_bounds, background: Some(diff_style.modified), border: Border::new(0., Color::transparent_black()), @@ -651,7 +660,7 @@ impl EditorElement { let highlight_size = vec2f(width * 2., end_y - start_y); let highlight_bounds = RectF::new(highlight_origin, highlight_size); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: highlight_bounds, background: Some(diff_style.deleted), border: Border::new(0., Color::transparent_black()), @@ -673,7 +682,7 @@ impl EditorElement { let highlight_size = vec2f(width * 2., end_y - start_y); let highlight_bounds = RectF::new(highlight_origin, highlight_size); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: highlight_bounds, background: Some(color), border: Border::new(0., Color::transparent_black()), @@ -684,9 +693,11 @@ impl EditorElement { fn paint_text( &mut self, + scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut LayoutState, + editor: &mut Editor, cx: &mut PaintContext, ) { let view = self.view(cx.app); @@ -700,9 +711,9 @@ impl EditorElement { let content_origin = bounds.origin() + vec2f(layout.gutter_margin, 0.); let line_end_overshoot = 0.15 * layout.position_map.line_height; - cx.scene.push_layer(Some(bounds)); + scene.push_layer(Some(bounds)); - cx.scene.push_cursor_region(CursorRegion { + scene.push_cursor_region(CursorRegion { bounds, style: if !view.link_go_to_definition_state.definitions.is_empty() { CursorStyle::PointingHand @@ -715,6 +726,7 @@ impl EditorElement { self.style.folds.ellipses.corner_radius_factor * layout.position_map.line_height; for (id, range, color) in layout.fold_ranges.iter() { self.paint_highlighted_range( + scene, range.clone(), *color, fold_corner_radius, @@ -736,7 +748,7 @@ impl EditorElement { line_end_overshoot, &layout.position_map, ) { - cx.scene.push_cursor_region(CursorRegion { + scene.push_cursor_region(CursorRegion { bounds: bound, style: CursorStyle::PointingHand, }); @@ -747,7 +759,7 @@ impl EditorElement { .to_point(&layout.position_map.snapshot.display_snapshot) .row; - cx.scene.push_mouse_region( + scene.push_mouse_region( MouseRegion::new::(self.view.id(), *id as usize, bound) .on_click(MouseButton::Left, move |_, cx| { cx.dispatch_action(UnfoldAt { buffer_row }) @@ -760,6 +772,7 @@ impl EditorElement { for (range, color) in &layout.highlighted_ranges { self.paint_highlighted_range( + scene, range.clone(), *color, 0., @@ -781,6 +794,7 @@ impl EditorElement { for selection in selections { self.paint_highlighted_range( + scene, selection.range.clone(), selection_style.selection, corner_radius, @@ -858,6 +872,7 @@ impl EditorElement { for (ix, line) in layout.position_map.line_layouts.iter().enumerate() { let row = start_row + ix as u32; line.paint( + scene, content_origin + vec2f( -scroll_left, @@ -870,14 +885,16 @@ impl EditorElement { } } - cx.scene.push_layer(Some(bounds)); - for cursor in cursors { - cursor.paint(content_origin, cx); - } - cx.scene.pop_layer(); + scene.push_layer(Some(bounds)); + + scene.paint_layer(Some(bounds), |scene| { + for cursor in cursors { + cursor.paint(scene, content_origin, cx); + } + }); if let Some((position, context_menu)) = layout.context_menu.as_mut() { - cx.scene.push_stacking_context(None, None); + scene.push_stacking_context(None, None); let cursor_row_layout = &layout.position_map.line_layouts[(position.row() - start_row) as usize]; let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left; @@ -897,16 +914,18 @@ impl EditorElement { } context_menu.paint( + scene, list_origin, RectF::from_points(Vector2F::zero(), vec2f(f32::MAX, f32::MAX)), // Let content bleed outside of editor + editor, cx, ); - cx.scene.pop_stacking_context(); + scene.pop_stacking_context(); } if let Some((position, hover_popovers)) = layout.hover_popovers.as_mut() { - cx.scene.push_stacking_context(None, None); + scene.push_stacking_context(None, None); // This is safe because we check on layout whether the required row is available let hovered_row_layout = @@ -937,8 +956,10 @@ impl EditorElement { } hover_popover.paint( + scene, popover_origin, RectF::from_points(Vector2F::zero(), vec2f(f32::MAX, f32::MAX)), // Let content bleed outside of editor + editor, cx, ); @@ -957,8 +978,10 @@ impl EditorElement { } hover_popover.paint( + scene, popover_origin, RectF::from_points(Vector2F::zero(), vec2f(f32::MAX, f32::MAX)), // Let content bleed outside of editor + editor, cx, ); @@ -966,13 +989,19 @@ impl EditorElement { } } - cx.scene.pop_stacking_context(); + scene.pop_stacking_context(); } - cx.scene.pop_layer(); + scene.pop_layer(); } - fn paint_scrollbar(&mut self, bounds: RectF, layout: &mut LayoutState, cx: &mut PaintContext) { + fn paint_scrollbar( + &mut self, + scene: &mut SceneBuilder, + bounds: RectF, + layout: &mut LayoutState, + cx: &mut ViewContext, + ) { enum ScrollbarMouseHandlers {} if layout.mode != EditorMode::Full { return; @@ -1008,13 +1037,13 @@ impl EditorElement { let thumb_bounds = RectF::from_points(vec2f(left, thumb_top), vec2f(right, thumb_bottom)); if layout.show_scrollbars { - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: track_bounds, border: style.track.border, background: style.track.background_color, ..Default::default() }); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: thumb_bounds, border: style.thumb.border, background: style.thumb.background_color, @@ -1022,11 +1051,11 @@ impl EditorElement { }); } - cx.scene.push_cursor_region(CursorRegion { + scene.push_cursor_region(CursorRegion { bounds: track_bounds, style: CursorStyle::Arrow, }); - cx.scene.push_mouse_region( + scene.push_mouse_region( MouseRegion::new::(view.id(), view.id(), track_bounds) .on_move({ let view = view.clone(); @@ -1088,6 +1117,7 @@ impl EditorElement { #[allow(clippy::too_many_arguments)] fn paint_highlighted_range( &self, + scene: &mut SceneBuilder, range: Range, color: Color, corner_radius: f32, @@ -1097,7 +1127,7 @@ impl EditorElement { scroll_top: f32, scroll_left: f32, bounds: RectF, - cx: &mut PaintContext, + cx: &mut ViewContext, ) { let start_row = layout.visible_display_row_range.start; let end_row = layout.visible_display_row_range.end; @@ -1141,15 +1171,17 @@ impl EditorElement { .collect(), }; - highlighted_range.paint(bounds, cx.scene); + highlighted_range.paint(bounds, scene); } } fn paint_blocks( &mut self, + scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut LayoutState, + editor: &mut Editor, cx: &mut PaintContext, ) { let scroll_position = layout.position_map.snapshot.scroll_position(); @@ -1165,7 +1197,9 @@ impl EditorElement { if !matches!(block.style, BlockStyle::Sticky) { origin += vec2f(-scroll_left, 0.); } - block.element.paint(origin, visible_bounds, cx); + block + .element + .paint(scene, origin, visible_bounds, editor, cx); } } @@ -1384,14 +1418,9 @@ impl EditorElement { style: &EditorStyle, line_layouts: &[text_layout::Line], include_root: bool, + editor: &mut Editor, cx: &mut LayoutContext, ) -> (f32, Vec) { - let editor = if let Some(editor) = self.view.upgrade(cx) { - editor - } else { - return Default::default(); - }; - let tooltip_style = cx.global::().theme.tooltip.clone(); let scroll_x = snapshot.scroll_anchor.offset.x(); let (fixed_blocks, non_fixed_blocks) = snapshot @@ -1542,6 +1571,7 @@ impl EditorElement { min: Vector2F::zero(), max: vec2f(width, block.height() as f32 * line_height), }, + editor, cx, ); element @@ -1847,6 +1877,7 @@ impl Element for EditorElement { &style, &line_layouts, include_root, + editor, cx, ); @@ -1924,6 +1955,7 @@ impl Element for EditorElement { (12. * line_height).min((size.y() - line_height) / 2.), ), }, + editor, cx, ); } @@ -1934,6 +1966,7 @@ impl Element for EditorElement { Axis::Vertical, line_height * style.code_actions.vertical_scale, ), + editor, cx, ); } @@ -2014,7 +2047,7 @@ impl Element for EditorElement { cx: &mut PaintContext, ) -> Self::PaintState { let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - cx.scene.push_layer(Some(visible_bounds)); + scene.push_layer(Some(visible_bounds)); let gutter_bounds = RectF::new(bounds.origin(), layout.gutter_size); let text_bounds = RectF::new( @@ -2033,20 +2066,20 @@ impl Element for EditorElement { cx, ); - self.paint_background(gutter_bounds, text_bounds, layout, cx); + self.paint_background(scene, gutter_bounds, text_bounds, layout, cx); if layout.gutter_size.x() > 0. { - self.paint_gutter(gutter_bounds, visible_bounds, layout, cx); + self.paint_gutter(scene, gutter_bounds, visible_bounds, layout, editor, cx); } - self.paint_text(text_bounds, visible_bounds, layout, cx); + self.paint_text(scene, text_bounds, visible_bounds, layout, editor, cx); - cx.scene.push_layer(Some(bounds)); + scene.push_layer(Some(bounds)); if !layout.blocks.is_empty() { - self.paint_blocks(bounds, visible_bounds, layout, cx); + self.paint_blocks(scene, bounds, visible_bounds, layout, editor, cx); } - self.paint_scrollbar(bounds, layout, cx); - cx.scene.pop_layer(); + self.paint_scrollbar(scene, bounds, layout, cx); + scene.pop_layer(); - cx.scene.pop_layer(); + scene.pop_layer(); } fn rect_for_text_range( @@ -2254,7 +2287,7 @@ impl Cursor { ) } - pub fn paint(&self, origin: Vector2F, cx: &mut PaintContext) { + pub fn paint(&self, scene: &mut SceneBuilder, origin: Vector2F, cx: &mut AppContext) { let bounds = match self.shape { CursorShape::Bar => RectF::new(self.origin + origin, vec2f(2.0, self.line_height)), CursorShape::Block | CursorShape::Hollow => RectF::new( @@ -2269,14 +2302,14 @@ impl Cursor { //Draw background or border quad if matches!(self.shape, CursorShape::Hollow) { - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds, background: None, border: Border::all(1., self.color), corner_radius: 0., }); } else { - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds, background: Some(self.color), border: Default::default(), @@ -2285,7 +2318,7 @@ impl Cursor { } if let Some(block_text) = &self.block_text { - block_text.paint(self.origin + origin, bounds, self.line_height, cx); + block_text.paint(scene, self.origin + origin, bounds, self.line_height, cx); } } diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index 76a7d41e10..23d1328fd4 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -4,7 +4,7 @@ use gpui::{ elements::{Flex, MouseEventHandler, Padding, Text}, impl_internal_actions, platform::{CursorStyle, MouseButton}, - AppContext, Axis, Element, ElementBox, ModelHandle, RenderContext, Task, ViewContext, + AppContext, Axis, Element, ElementBox, ModelHandle, Task, ViewContext, }; use language::{Bias, DiagnosticEntry, DiagnosticSeverity}; use project::{HoverBlock, Project}; @@ -282,7 +282,7 @@ impl HoverState { snapshot: &EditorSnapshot, style: &EditorStyle, visible_rows: Range, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Option<(DisplayPoint, Vec)> { // If there is a diagnostic, position the popovers based on that. // Otherwise use the start of the hover range @@ -323,7 +323,7 @@ pub struct InfoPopover { } impl InfoPopover { - pub fn render(&self, style: &EditorStyle, cx: &mut RenderContext) -> ElementBox { + pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext) -> ElementBox { MouseEventHandler::::new(0, cx, |_, cx| { let mut flex = Flex::new(Axis::Vertical).scrollable::(1, None, cx); flex.extend(self.contents.iter().map(|content| { @@ -378,7 +378,7 @@ pub struct DiagnosticPopover { } impl DiagnosticPopover { - pub fn render(&self, style: &EditorStyle, cx: &mut RenderContext) -> ElementBox { + pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext) -> ElementBox { enum PrimaryDiagnostic {} let mut text_style = style.hover_popover.prose.clone(); diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 0f2a98dfe9..83e1a4d7f6 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -7,8 +7,8 @@ use anyhow::{anyhow, Context, Result}; use collections::HashSet; use futures::future::try_join_all; use gpui::{ - elements::*, geometry::vector::vec2f, AppContext, Entity, ModelHandle, RenderContext, - Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, + elements::*, geometry::vector::vec2f, AppContext, Entity, ModelHandle, Subscription, Task, + View, ViewContext, ViewContext, ViewHandle, WeakViewHandle, }; use language::{ proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point, @@ -1078,7 +1078,7 @@ impl View for CursorPosition { "CursorPosition" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { if let Some(position) = self.position { let theme = &cx.global::().theme.workspace.status_bar; let mut text = format!("{},{}", position.row + 1, position.column + 1); diff --git a/crates/feedback/src/deploy_feedback_button.rs b/crates/feedback/src/deploy_feedback_button.rs index 395ac54a61..aa900597d7 100644 --- a/crates/feedback/src/deploy_feedback_button.rs +++ b/crates/feedback/src/deploy_feedback_button.rs @@ -1,7 +1,7 @@ use gpui::{ elements::*, platform::{CursorStyle, MouseButton}, - Entity, RenderContext, View, ViewContext, + Entity, View, ViewContext, }; use settings::Settings; use workspace::{item::ItemHandle, StatusItemView}; @@ -27,7 +27,7 @@ impl View for DeployFeedbackButton { "DeployFeedbackButton" } - fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> ElementBox { let active = self.active; let theme = cx.global::().theme.clone(); Stack::new() diff --git a/crates/feedback/src/feedback_editor.rs b/crates/feedback/src/feedback_editor.rs index 15334138db..bae006b8c6 100644 --- a/crates/feedback/src/feedback_editor.rs +++ b/crates/feedback/src/feedback_editor.rs @@ -12,8 +12,8 @@ use gpui::{ actions, elements::{ChildView, Flex, Label, ParentElement, Svg}, platform::PromptLevel, - serde_json, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle, RenderContext, - Task, View, ViewContext, ViewHandle, + serde_json, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle, Task, View, + ViewContext, ViewContext, ViewHandle, }; use isahc::Request; use language::Buffer; @@ -232,7 +232,7 @@ impl View for FeedbackEditor { "FeedbackEditor" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { ChildView::new(&self.editor, cx).boxed() } diff --git a/crates/feedback/src/feedback_info_text.rs b/crates/feedback/src/feedback_info_text.rs index afa9bd8fc1..fe1a4bc82c 100644 --- a/crates/feedback/src/feedback_info_text.rs +++ b/crates/feedback/src/feedback_info_text.rs @@ -1,7 +1,7 @@ use gpui::{ elements::{Flex, Label, MouseEventHandler, ParentElement, Text}, platform::{CursorStyle, MouseButton}, - Element, ElementBox, Entity, RenderContext, View, ViewContext, ViewHandle, + Element, ElementBox, Entity, View, ViewContext, ViewHandle, }; use settings::Settings; use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView}; @@ -29,7 +29,7 @@ impl View for FeedbackInfoText { "FeedbackInfoText" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = cx.global::().theme.clone(); Flex::row() diff --git a/crates/feedback/src/submit_feedback_button.rs b/crates/feedback/src/submit_feedback_button.rs index 23f5885cb6..720f032c4d 100644 --- a/crates/feedback/src/submit_feedback_button.rs +++ b/crates/feedback/src/submit_feedback_button.rs @@ -1,7 +1,7 @@ use gpui::{ elements::{Label, MouseEventHandler}, platform::{CursorStyle, MouseButton}, - Element, ElementBox, Entity, RenderContext, View, ViewContext, ViewHandle, + Element, ElementBox, Entity, View, ViewContext, ViewHandle, }; use settings::Settings; use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView}; @@ -29,7 +29,7 @@ impl View for SubmitFeedbackButton { "SubmitFeedbackButton" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = cx.global::().theme.clone(); enum SubmitFeedbackButton {} MouseEventHandler::::new(0, cx, |state, _| { diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 8e3490902e..0995578e7c 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -1,7 +1,7 @@ use fuzzy::PathMatch; use gpui::{ - actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, - RenderContext, Task, View, ViewContext, ViewHandle, + actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, Task, View, + ViewContext, ViewHandle, }; use picker::{Picker, PickerDelegate}; use project::{PathMatchCandidateSet, Project, ProjectPath, WorktreeId}; @@ -50,7 +50,7 @@ impl View for FileFinder { "FileFinder" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 981f222744..af90f6b0c9 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, DisplayPoint, Editor}; use gpui::{ actions, elements::*, geometry::vector::Vector2F, AnyViewHandle, AppContext, Axis, Entity, - RenderContext, View, ViewContext, ViewHandle, + View, ViewContext, ViewHandle, }; use menu::{Cancel, Confirm}; use settings::Settings; @@ -156,7 +156,7 @@ impl View for GoToLine { "GoToLine" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = &cx.global::().theme.picker; let label = format!( diff --git a/crates/gpui/examples/text.rs b/crates/gpui/examples/text.rs index e16ac440fd..fa14dc2b0a 100644 --- a/crates/gpui/examples/text.rs +++ b/crates/gpui/examples/text.rs @@ -2,7 +2,7 @@ use gpui::{ color::Color, fonts::{Properties, Weight}, text_layout::RunStyle, - DebugContext, Element as _, MeasurementContext, Quad, + Element, ElementBox, Quad, SceneBuilder, View, ViewContext, }; use log::LevelFilter; use pathfinder_geometry::rect::RectF; @@ -30,12 +30,12 @@ impl gpui::View for TextView { "View" } - fn render(&mut self, _: &mut gpui::RenderContext) -> gpui::ElementBox { + fn render(&mut self, _: &mut gpui::ViewContext) -> ElementBox { TextElement.boxed() } } -impl gpui::Element for TextElement { +impl Element for TextElement { type LayoutState = (); type PaintState = (); @@ -43,17 +43,20 @@ impl gpui::Element for TextElement { fn layout( &mut self, constraint: gpui::SizeConstraint, - _: &mut gpui::LayoutContext, + _: &mut V, + _: &mut ViewContext, ) -> (pathfinder_geometry::vector::Vector2F, Self::LayoutState) { (constraint.max, ()) } fn paint( &mut self, + scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, - cx: &mut gpui::PaintContext, + _: &mut V, + cx: &mut ViewContext, ) -> Self::PaintState { let font_size = 12.; let family = cx @@ -84,7 +87,7 @@ impl gpui::Element for TextElement { }; let text = "Hello world!"; - let line = cx.text_layout_cache.layout_str( + let line = cx.text_layout_cache().layout_str( text, font_size, &[ @@ -96,12 +99,12 @@ impl gpui::Element for TextElement { ], ); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds, background: Some(Color::white()), ..Default::default() }); - line.paint(bounds.origin(), visible_bounds, bounds.height(), cx); + line.paint(scene, bounds.origin(), visible_bounds, bounds.height(), cx); } fn rect_for_text_range( @@ -111,7 +114,8 @@ impl gpui::Element for TextElement { _: RectF, _: &Self::LayoutState, _: &Self::PaintState, - _: &MeasurementContext, + _: &V, + _: &ViewContext, ) -> Option { None } @@ -121,7 +125,8 @@ impl gpui::Element for TextElement { _: RectF, _: &Self::LayoutState, _: &Self::PaintState, - _: &DebugContext, + _: &V, + _: &ViewContext, ) -> gpui::json::Value { todo!() } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 70307063e1..f30ab75663 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -69,7 +69,7 @@ pub trait Entity: 'static { pub trait View: Entity + Sized { fn ui_name() -> &'static str; - fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> ElementBox; + fn render(&mut self, cx: &mut ViewContext<'_, '_, '_, Self>) -> ElementBox; fn focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext) {} fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext) {} fn key_down(&mut self, _: &KeyDownEvent, _: &mut ViewContext) -> bool { @@ -488,7 +488,7 @@ impl ReadViewWith for AsyncAppContext { } } -type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut AppContext, usize, usize); +type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut WindowContext, usize); type GlobalActionCallback = dyn FnMut(&dyn Action, &mut AppContext); type SubscriptionCallback = Box bool>; @@ -725,11 +725,10 @@ impl AppContext { let handler = Box::new( move |view: &mut dyn AnyView, action: &dyn Action, - cx: &mut AppContext, - window_id: usize, + cx: &mut WindowContext, view_id: usize| { let action = action.as_any().downcast_ref().unwrap(); - let mut cx = ViewContext::new(cx, view_id); + let mut cx = ViewContext::mutable(cx, view_id); handler( view.as_any_mut() .downcast_mut() @@ -842,6 +841,12 @@ impl AppContext { } } + fn focused_view_id(&self, window_id: usize) -> Option { + self.windows + .get(&window_id) + .and_then(|window| window.focused_view_id) + } + pub fn is_child_focused(&self, view: &AnyViewHandle) -> bool { if let Some(focused_view_id) = self.focused_view_id(view.window_id) { self.ancestors(view.window_id, focused_view_id) @@ -858,57 +863,59 @@ impl AppContext { self.active_labeled_tasks.values().cloned() } - // pub fn render_view(&mut self, params: RenderParams) -> Result> { - // let window_id = params.window_id; - // let view_id = params.view_id; - // let mut view = self - // .views - // .remove(&(window_id, view_id)) - // .ok_or_else(|| anyhow!("view not found"))?; - // let element = view.render(params, self); - // self.views.insert((window_id, view_id), view); - // Ok(element) - // } + pub fn render_view(&mut self, params: RenderParams) -> Result> { + todo!() + // let window_id = params.window_id; + // let view_id = params.view_id; + // let mut view = self + // .views + // .remove(&(window_id, view_id)) + // .ok_or_else(|| anyhow!("view not found"))?; + // let element = view.render(params, self); + // self.views.insert((window_id, view_id), view); + // Ok(element) + } - // pub fn render_views( - // &mut self, - // window_id: usize, - // titlebar_height: f32, - // appearance: Appearance, - // ) -> HashMap { - // self.start_frame(); - // #[allow(clippy::needless_collect)] - // let view_ids = self - // .views - // .keys() - // .filter_map(|(win_id, view_id)| { - // if *win_id == window_id { - // Some(*view_id) - // } else { - // None - // } - // }) - // .collect::>(); + pub fn render_views( + &mut self, + window_id: usize, + titlebar_height: f32, + appearance: Appearance, + ) -> HashMap> { + todo!() + // self.start_frame(); + // #[allow(clippy::needless_collect)] + // let view_ids = self + // .views + // .keys() + // .filter_map(|(win_id, view_id)| { + // if *win_id == window_id { + // Some(*view_id) + // } else { + // None + // } + // }) + // .collect::>(); - // view_ids - // .into_iter() - // .map(|view_id| { - // ( - // view_id, - // self.render_view(RenderParams { - // window_id, - // view_id, - // titlebar_height, - // hovered_region_ids: Default::default(), - // clicked_region_ids: None, - // refreshing: false, - // appearance, - // }) - // .unwrap(), - // ) - // }) - // .collect() - // } + // view_ids + // .into_iter() + // .map(|view_id| { + // ( + // view_id, + // self.render_view(RenderParams { + // window_id, + // view_id, + // titlebar_height, + // hovered_region_ids: Default::default(), + // clicked_region_ids: None, + // refreshing: false, + // appearance, + // }) + // .unwrap(), + // ) + // }) + // .collect() + } pub(crate) fn start_frame(&mut self) { self.frame_count += 1; @@ -932,6 +939,7 @@ impl AppContext { app_context, window: &mut window, window_id, + refreshing: false, }; let result = callback(&mut window_context); @@ -1510,25 +1518,22 @@ impl AppContext { }) } - pub fn add_window( + pub fn add_window( &mut self, window_options: WindowOptions, build_root_view: F, - ) -> (usize, ViewHandle) + ) -> (usize, ViewHandle) where - T: View, - F: FnOnce(&mut ViewContext) -> T, + V: View, + F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { let window_id = post_inc(&mut this.next_window_id); - let root_view = this - .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx))) - .unwrap(); let platform_window = this.platform .open_window(window_id, window_options, this.foreground.clone()); - let window = - this.build_window(window_id, root_view.clone().into_any(), platform_window); + let window = this.build_window(window_id, platform_window, build_root_view); + let root_view = window.root_view().clone().downcast::().unwrap(); this.windows.insert(window_id, window); root_view.update(this, |view, cx| view.focus_in(cx.handle().into_any(), cx)); @@ -1537,20 +1542,16 @@ impl AppContext { }) } - pub fn add_status_bar_item(&mut self, build_root_view: F) -> (usize, ViewHandle) + pub fn add_status_bar_item(&mut self, build_root_view: F) -> (usize, ViewHandle) where - T: View, - F: FnOnce(&mut ViewContext) -> T, + V: View, + F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { let window_id = post_inc(&mut this.next_window_id); - let root_view = this - .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx))) - .unwrap(); - let platform_window = this.platform.add_status_item(); - let window = - this.build_window(window_id, root_view.clone().into_any(), platform_window); + let window = this.build_window(window_id, platform_window, build_root_view); + let root_view = window.root_view().clone().downcast::().unwrap(); this.windows.insert(window_id, window); root_view.update(this, |view, cx| view.focus_in(cx.handle().into_any(), cx)); @@ -1563,33 +1564,21 @@ impl AppContext { self.remove_window(id); } - pub fn replace_root_view(&mut self, window_id: usize, build_root_view: F) -> ViewHandle - where - T: View, - F: FnOnce(&mut ViewContext) -> T, - { - self.update(|this| { - let root_view = this - .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx))) - .unwrap(); - let window = this.windows.get_mut(&window_id).unwrap(); - window.root_view = root_view.clone().into_any(); - window.focused_view_id = Some(root_view.id()); - root_view - }) - } - pub fn remove_window(&mut self, window_id: usize) { self.windows.remove(&window_id); self.flush_effects(); } - pub fn build_window( + pub fn build_window( &mut self, window_id: usize, - root_view: AnyViewHandle, mut platform_window: Box, - ) -> Window { + build_root_view: F, + ) -> Window + where + V: View, + F: FnOnce(&mut ViewContext) -> V, + { { let mut app = self.upgrade(); @@ -1653,73 +1642,22 @@ impl AppContext { window_id, })); - let mut window = Window::new(window_id, root_view, platform_window, self); + let mut window = Window::new(window_id, platform_window, self, build_root_view); let scene = WindowContext::new(self, &mut window, window_id).build_scene(); window.platform_window.present_scene(scene); window } - pub fn add_view(&mut self, parent_handle: &AnyViewHandle, build_view: F) -> ViewHandle + pub fn add_view(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle where - T: View, - F: FnOnce(&mut ViewContext) -> T, + S: View, + F: FnOnce(&mut ViewContext) -> S, { - self.build_and_insert_view( - parent_handle.window_id, - ParentId::View(parent_handle.view_id), - |cx| Some(build_view(cx)), - ) - .unwrap() - } - - pub fn add_option_view( - &mut self, - parent_handle: impl Into, - build_view: F, - ) -> Option> - where - T: View, - F: FnOnce(&mut ViewContext) -> Option, - { - let parent_handle = parent_handle.into(); - self.build_and_insert_view( - parent_handle.window_id, - ParentId::View(parent_handle.view_id), - build_view, - ) - } - - pub(crate) fn build_and_insert_view( - &mut self, - window_id: usize, - parent_id: ParentId, - build_view: F, - ) -> Option> - where - T: View, - F: FnOnce(&mut ViewContext) -> Option, - { - self.update(|this| { - let view_id = post_inc(&mut this.next_entity_id); - // Make sure we can tell child views about their parent - this.parents.insert((window_id, view_id), parent_id); - let mut cx = ViewContext::new(this, view_id); - let handle = if let Some(view) = build_view(&mut cx) { - this.views.insert((window_id, view_id), Box::new(view)); - if let Some(window) = this.windows.get_mut(&window_id) { - window - .invalidation - .get_or_insert_with(Default::default) - .updated - .insert(view_id); - } - Some(ViewHandle::new(window_id, view_id, &this.ref_counts)) - } else { - this.parents.remove(&(window_id, view_id)); - None - }; - handle + self.update_window(parent.window_id, |cx| { + cx.build_and_insert_view(ParentId::View(parent.view_id), |cx| Some(build_view(cx))) + .unwrap() }) + .unwrap() } fn remove_dropped_entities(&mut self) { @@ -1754,7 +1692,7 @@ impl AppContext { .removed .push(view_id); if window.focused_view_id == Some(view_id) { - Some(window.root_view.id()) + Some(window.root_view().id()) } else { None } @@ -2174,7 +2112,10 @@ impl AppContext { self.update(|cx| { cx.update_window(window_id, |cx| { - let focused_id = cx.window.focused_view_id?; + let Some(focused_id) = cx.window.focused_view_id else { + return; + }; + for view_id in cx.ancestors(window_id, focused_id).collect::>() { cx.update_any_view(focused_id, |view, cx| { if active { @@ -2254,29 +2195,28 @@ impl AppContext { if let Some(view_id) = view_id { this.halt_action_dispatch = false; this.visit_dispatch_path(window_id, view_id, |view_id, capture_phase, this| { - if let Some(mut view) = this.views.remove(&(window_id, view_id)) { - let type_id = view.as_any().type_id(); - - if let Some((name, mut handlers)) = this - .actions_mut(capture_phase) - .get_mut(&type_id) - .and_then(|h| h.remove_entry(&action.id())) - { - for handler in handlers.iter_mut().rev() { - this.halt_action_dispatch = true; - handler(view.as_mut(), action, this, window_id, view_id); - if this.halt_action_dispatch { - break; - } - } - this.actions_mut(capture_phase) + this.update_window(window_id, |cx| { + cx.update_any_view(view_id, |view, cx| { + let type_id = view.as_any().type_id(); + if let Some((name, mut handlers)) = cx + .actions_mut(capture_phase) .get_mut(&type_id) - .unwrap() - .insert(name, handlers); - } - - this.views.insert((window_id, view_id), view); - } + .and_then(|h| h.remove_entry(&action.id())) + { + for handler in handlers.iter_mut().rev() { + cx.halt_action_dispatch = true; + handler(view, action, cx, view_id); + if cx.halt_action_dispatch { + break; + } + } + cx.actions_mut(capture_phase) + .get_mut(&type_id) + .unwrap() + .insert(name, handlers); + } + }) + }); !this.halt_action_dispatch }); @@ -2523,22 +2463,19 @@ impl UpdateView for AppContext { where T: View, { - self.update(|this| { - let mut view = this - .views - .remove(&(handle.window_id, handle.view_id)) - .expect("circular view update"); - - let mut cx = ViewContext::new(this, handle.view_id); - let result = update( - view.as_any_mut() - .downcast_mut() - .expect("downcast is type safe"), - &mut cx, - ); - this.views.insert((handle.window_id, handle.view_id), view); - result + self.update_window(handle.window_id, |cx| { + cx.update_any_view(handle.view_id, |view, cx| { + let mut cx = ViewContext::mutable(cx, handle.view_id); + update( + view.as_any_mut() + .downcast_mut() + .expect("downcast is type safe"), + &mut cx, + ) + }) + .unwrap() // TODO: Are these unwraps safe? }) + .unwrap() } } @@ -2877,68 +2814,42 @@ pub trait AnyView { cx: &mut AppContext, ) -> Option>>>; fn ui_name(&self) -> &'static str; - fn render<'a, 'b>( - &mut self, - params: RenderParams, - cx: &'b mut WindowContext<'a, 'b>, - ) -> Box; + fn render(&mut self, params: RenderParams, cx: &mut WindowContext) -> Box; fn focus_in<'a, 'b>( &mut self, focused_id: usize, - cx: &'b mut WindowContext<'a, 'b>, + cx: &mut WindowContext<'a, 'b>, view_id: usize, ); - fn focus_out<'a, 'b>( - &mut self, - focused_id: usize, - cx: &'b mut WindowContext<'a, 'b>, - view_id: usize, - ); - fn key_down<'a, 'b>( - &mut self, - event: &KeyDownEvent, - cx: &'b mut WindowContext<'a, 'b>, - view_id: usize, - ) -> bool; - fn key_up<'a, 'b>( - &mut self, - event: &KeyUpEvent, - cx: &'b mut WindowContext<'a, 'b>, - view_id: usize, - ) -> bool; - fn modifiers_changed<'a, 'b>( + fn focus_out(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize); + fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool; + fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool; + fn modifiers_changed( &mut self, event: &ModifiersChangedEvent, - cx: &'b mut WindowContext<'a, 'b>, + cx: &mut WindowContext, view_id: usize, ) -> bool; - fn keymap_context<'a, 'b>(&self, cx: &'b mut WindowContext<'a, 'b>) -> KeymapContext; - fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a, 'b>) -> serde_json::Value; + fn keymap_context(&self, cx: &AppContext) -> KeymapContext; + fn debug_json(&self, cx: &WindowContext) -> serde_json::Value; - fn text_for_range<'a, 'b>( - &self, - range: Range, - cx: &'b mut WindowContext<'a, 'b>, - ) -> Option; - fn selected_text_range<'a, 'b>( - &self, - cx: &'b mut WindowContext<'a, 'b>, - ) -> Option>; - fn marked_text_range<'a, 'b>(&self, cx: &'b mut WindowContext<'a, 'b>) -> Option>; - fn unmark_text<'a, 'b>(&mut self, cx: &'b mut WindowContext<'a, 'b>, view_id: usize); - fn replace_text_in_range<'a, 'b>( + fn text_for_range(&self, range: Range, cx: &WindowContext) -> Option; + fn selected_text_range(&self, cx: &WindowContext) -> Option>; + fn marked_text_range(&self, cx: &WindowContext) -> Option>; + fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize); + fn replace_text_in_range( &mut self, range: Option>, text: &str, - cx: &'b mut WindowContext<'a, 'b>, + cx: &mut WindowContext, view_id: usize, ); - fn replace_and_mark_text_in_range<'a, 'b>( + fn replace_and_mark_text_in_range( &mut self, range: Option>, new_text: &str, new_selected_range: Option>, - cx: &'b mut WindowContext<'a, 'b>, + cx: &mut WindowContext, view_id: usize, ); fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle { @@ -2978,21 +2889,13 @@ where T::ui_name() } - fn render<'a, 'b>( - &mut self, - params: RenderParams, - cx: &mut WindowContext<'a, 'b>, - ) -> Box { - View::render(self, &mut ViewContext::new(params, cx)) + fn render(&mut self, params: RenderParams, cx: &mut WindowContext) -> Box { + todo!() + // Box::new(View::render(self, &mut ViewContext::new(params.view_id, cx))) } - fn focus_in<'a, 'b>( - &mut self, - cx: &mut WindowContext<'a, 'b>, - view_id: usize, - focused_id: usize, - ) { - let mut cx = ViewContext::new(cx, view_id); + fn focus_in(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize) { + let mut cx = ViewContext::mutable(cx, view_id); let focused_view_handle: AnyViewHandle = if view_id == focused_id { cx.handle().into_any() } else { @@ -3012,13 +2915,8 @@ where View::focus_in(self, focused_view_handle, &mut cx); } - fn focus_out<'a, 'b>( - &mut self, - cx: &mut WindowContext<'a, 'b>, - view_id: usize, - blurred_id: usize, - ) { - let mut cx = ViewContext::new(cx, view_id); + fn focus_out(&mut self, blurred_id: usize, cx: &mut WindowContext, view_id: usize) { + let mut cx = ViewContext::mutable(cx, view_id); let blurred_view_handle: AnyViewHandle = if view_id == blurred_id { cx.handle().into_any() } else { @@ -3038,85 +2936,71 @@ where View::focus_out(self, blurred_view_handle, &mut cx); } - fn key_down<'a, 'b>( - &mut self, - event: &KeyDownEvent, - cx: &mut WindowContext<'a, 'b>, - view_id: usize, - ) -> bool { - let mut cx = ViewContext::new(cx, view_id); + fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool { + let mut cx = ViewContext::mutable(cx, view_id); View::key_down(self, event, &mut cx) } - fn key_up<'a, 'b>( - &mut self, - event: &KeyUpEvent, - cx: &mut WindowContext<'a, 'b>, - view_id: usize, - ) -> bool { - let mut cx = ViewContext::new(cx, view_id); + fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool { + let mut cx = ViewContext::mutable(cx, view_id); View::key_up(self, event, &mut cx) } - fn modifiers_changed<'a, 'b>( + fn modifiers_changed( &mut self, event: &ModifiersChangedEvent, - cx: &mut WindowContext<'a, 'b>, + cx: &mut WindowContext, view_id: usize, ) -> bool { - let mut cx = ViewContext::new(cx, view_id); + let mut cx = ViewContext::mutable(cx, view_id); View::modifiers_changed(self, event, &mut cx) } - fn keymap_context<'a, 'b>(&self, cx: &mut WindowContext<'a, 'b>) -> KeymapContext { + fn keymap_context(&self, cx: &AppContext) -> KeymapContext { View::keymap_context(self, cx) } - fn debug_json<'a, 'b>(&self, cx: &mut WindowContext<'a, 'b>) -> serde_json::Value { + fn debug_json(&self, cx: &WindowContext) -> serde_json::Value { View::debug_json(self, cx) } - fn text_for_range<'a, 'b>( - &self, - range: Range, - cx: &mut WindowContext<'a, 'b>, - ) -> Option { + fn text_for_range(&self, range: Range, cx: &WindowContext) -> Option { View::text_for_range(self, range, cx) } - fn selected_text_range<'a, 'b>(&self, cx: &mut WindowContext<'a, 'b>) -> Option> { + fn selected_text_range(&self, cx: &WindowContext) -> Option> { View::selected_text_range(self, cx) } - fn marked_text_range<'a, 'b>(&self, cx: &mut WindowContext<'a, 'b>) -> Option> { + fn marked_text_range(&self, cx: &WindowContext) -> Option> { View::marked_text_range(self, cx) } - fn unmark_text<'a, 'b>(&mut self, cx: &mut WindowContext<'a, 'b>, view_id: usize) { - let mut cx = ViewContext::new(cx, view_id); + fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize) { + let mut cx = ViewContext::mutable(cx, view_id); View::unmark_text(self, &mut cx) } - fn replace_text_in_range<'a, 'b>( + fn replace_text_in_range( &mut self, range: Option>, text: &str, - cx: &mut WindowContext<'a, 'b>, + cx: &mut WindowContext, view_id: usize, ) { - let mut cx = ViewContext::new(cx, view_id); + let mut cx = ViewContext::mutable(cx, view_id); View::replace_text_in_range(self, range, text, &mut cx) } - fn replace_and_mark_text_in_range<'a, 'b>( + fn replace_and_mark_text_in_range( &mut self, range: Option>, new_text: &str, new_selected_range: Option>, - cx: &mut WindowContext<'a, 'b>, + cx: &mut WindowContext, view_id: usize, ) { - let mut cx = ViewContext::new(cx, view_id); + let mut cx = ViewContext::mutable(cx, view_id); View::replace_and_mark_text_in_range(self, range, new_text, new_selected_range, &mut cx) } } @@ -3339,13 +3223,13 @@ impl DerefMut for ModelContext<'_, M> { } } -pub struct ViewContext<'a, 'b, T: ?Sized> { - window_context: WindowContext<'a, 'b>, +pub struct ViewContext<'a, 'b, 'c, T: ?Sized> { + window_context: WindowContextRef<'a, 'b, 'c>, view_id: usize, view_type: PhantomData, } -impl<'a, 'b, T: View> Deref for ViewContext<'a, 'b, T> { +impl<'a, 'b, 'c, T: View> Deref for ViewContext<'a, 'b, 'c, T> { type Target = WindowContext<'a, 'b>; fn deref(&self) -> &Self::Target { @@ -3353,16 +3237,24 @@ impl<'a, 'b, T: View> Deref for ViewContext<'a, 'b, T> { } } -impl<'a, 'b, T: View> DerefMut for ViewContext<'a, 'b, T> { +impl DerefMut for ViewContext<'_, '_, '_, T> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.window_context } } -impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { - fn new(window_context: &'b mut WindowContext<'a, 'b>, view_id: usize) -> Self { +impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> { + pub(crate) fn mutable(window_context: &'c mut WindowContext<'a, 'b>, view_id: usize) -> Self { Self { - window_context, + window_context: WindowContextRef::Mutable(window_context), + view_id, + view_type: PhantomData, + } + } + + pub(crate) fn immutable(window_context: &'c WindowContext<'a, 'b>, view_id: usize) -> Self { + Self { + window_context: WindowContextRef::Immutable(window_context), view_id, view_type: PhantomData, } @@ -3425,12 +3317,13 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } pub fn focus_self(&mut self) { - self.window_context - .focus(self.window_id, Some(self.view_id)); + let window_id = self.window_id; + let view_id = self.view_id; + self.window_context.focus(window_id, Some(view_id)); } pub fn is_self_focused(&self) -> bool { - self.window.focused_view == Some(self.view_id) + self.window.focused_view_id == Some(self.view_id) } pub fn is_child(&self, view: impl Into) -> bool { @@ -3444,7 +3337,8 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } pub fn blur(&mut self) { - self.window_context.focus(self.window_id, None); + let window_id = self.window_id; + self.window_context.focus(window_id, None); } pub fn on_window_should_close(&mut self, mut callback: F) @@ -3466,23 +3360,13 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { }); } - pub fn add_model(&mut self, build_model: F) -> ModelHandle - where - S: Entity, - F: FnOnce(&mut ModelContext) -> S, - { - self.window_context.add_model(build_model) - } - pub fn add_view(&mut self, build_view: F) -> ViewHandle where S: View, F: FnOnce(&mut ViewContext) -> S, { self.window_context - .build_and_insert_view(self.window_id, ParentId::View(self.view_id), |cx| { - Some(build_view(cx)) - }) + .build_and_insert_view(ParentId::View(self.view_id), |cx| Some(build_view(cx))) .unwrap() } @@ -3491,11 +3375,8 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { S: View, F: FnOnce(&mut ViewContext) -> Option, { - self.window_context.build_and_insert_view( - self.window_id, - ParentId::View(self.view_id), - build_view, - ) + self.window_context + .build_and_insert_view(ParentId::View(self.view_id), build_view) } pub fn reparent(&mut self, view_handle: &AnyViewHandle) { @@ -3511,23 +3392,6 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { ); } - pub fn replace_root_view(&mut self, build_root_view: F) -> ViewHandle - where - W: View, - F: FnOnce(&mut ViewContext) -> W, - { - let window_id = self.window_id; - self.update(|this| { - let root_view = this - .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx))) - .unwrap(); - let window = this.windows.get_mut(&window_id).unwrap(); - window.root_view = root_view.clone().into_any(); - window.focused_view_id = Some(root_view.id()); - root_view - }) - } - pub fn subscribe(&mut self, handle: &H, mut callback: F) -> Subscription where E: Entity, @@ -3637,8 +3501,9 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { F: 'static + FnMut(&mut V, bool, &mut ViewContext), { let observer = self.weak_handle(); + let window_id = self.window_id; self.window_context - .observe_window_activation(self.window_id(), move |active, cx| { + .observe_window_activation(window_id, move |active, cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, active, cx); @@ -3655,8 +3520,9 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { F: 'static + FnMut(&mut V, bool, &mut ViewContext), { let observer = self.weak_handle(); + let window_id = self.window_id; self.window_context - .observe_fullscreen(self.window_id(), move |active, cx| { + .observe_fullscreen(window_id, move |active, cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, active, cx); @@ -3680,8 +3546,9 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { ) -> bool, { let observer = self.weak_handle(); + let window_id = self.window_id; self.window_context.observe_keystrokes( - self.window_id(), + window_id, move |keystroke, result, handled_by, cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { @@ -3700,8 +3567,9 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { F: 'static + FnMut(&mut V, WindowBounds, Uuid, &mut ViewContext), { let observer = self.weak_handle(); + let window_id = self.window_id; self.window_context - .observe_window_bounds(self.window_id(), move |bounds, display, cx| { + .observe_window_bounds(window_id, move |bounds, display, cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, bounds, display, cx); @@ -3740,18 +3608,23 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } pub fn notify(&mut self) { - self.window_context - .notify_view(self.window_id, self.view_id); + let window_id = self.window_id; + let view_id = self.view_id; + self.window_context.notify_view(window_id, view_id); } pub fn dispatch_action(&mut self, action: impl Action) { + let window_id = self.window_id; + let view_id = self.view_id; self.window_context - .dispatch_action_at(self.window_id, self.view_id, action) + .dispatch_action_at(window_id, view_id, action) } pub fn dispatch_any_action(&mut self, action: Box) { + let window_id = self.window_id; + let view_id = self.view_id; self.window_context - .dispatch_any_action_at(self.window_id, self.view_id, action) + .dispatch_any_action_at(window_id, view_id, action) } pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext)) { @@ -3813,14 +3686,12 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { pub fn mouse_state(&self, region_id: usize) -> MouseState { let region_id = MouseRegionId::new::(self.view_id, region_id); MouseState { - hovered: self.hovered_region_ids.contains(®ion_id), - clicked: self.clicked_region_ids.as_ref().and_then(|(ids, button)| { - if ids.contains(®ion_id) { - Some(*button) - } else { - None - } - }), + hovered: self.window.hovered_region_ids.contains(®ion_id), + clicked: self + .window + .clicked_region_ids + .get(®ion_id) + .and_then(|_| self.window.clicked_button), accessed_hovered: false, accessed_clicked: false, } @@ -3850,7 +3721,7 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } } -impl UpgradeModelHandle for ViewContext<'_, '_, V> { +impl UpgradeModelHandle for ViewContext<'_, '_, '_, V> { fn upgrade_model_handle( &self, handle: &WeakModelHandle, @@ -3867,7 +3738,7 @@ impl UpgradeModelHandle for ViewContext<'_, '_, V> { } } -impl UpgradeViewHandle for ViewContext<'_, '_, V> { +impl UpgradeViewHandle for ViewContext<'_, '_, '_, V> { fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { self.window_context.upgrade_view_handle(handle) } @@ -3877,7 +3748,13 @@ impl UpgradeViewHandle for ViewContext<'_, '_, V> { } } -impl UpdateModel for ViewContext<'_, '_, V> { +impl ReadModel for ViewContext<'_, '_, '_, V> { + fn read_model(&self, handle: &ModelHandle) -> &T { + self.window_context.read_model(handle) + } +} + +impl UpdateModel for ViewContext<'_, '_, '_, V> { fn update_model( &mut self, handle: &ModelHandle, @@ -3887,13 +3764,13 @@ impl UpdateModel for ViewContext<'_, '_, V> { } } -impl ReadView for ViewContext<'_, '_, V> { +impl ReadView for ViewContext<'_, '_, '_, V> { fn read_view(&self, handle: &ViewHandle) -> &T { self.window_context.read_view(handle) } } -impl UpdateView for ViewContext<'_, '_, V> { +impl UpdateView for ViewContext<'_, '_, '_, V> { fn update_view( &mut self, handle: &ViewHandle, @@ -3906,6 +3783,33 @@ impl UpdateView for ViewContext<'_, '_, V> { } } +enum WindowContextRef<'a, 'b, 'c> { + Immutable(&'c WindowContext<'a, 'b>), + Mutable(&'c mut WindowContext<'a, 'b>), +} + +impl<'a, 'b, 'c> Deref for WindowContextRef<'a, 'b, 'c> { + type Target = WindowContext<'a, 'b>; + + fn deref(&self) -> &Self::Target { + match self { + WindowContextRef::Immutable(window_context) => window_context, + WindowContextRef::Mutable(window_context) => window_context, + } + } +} + +impl<'a, 'b, 'c> DerefMut for WindowContextRef<'a, 'b, 'c> { + fn deref_mut(&mut self) -> &mut Self::Target { + match self { + WindowContextRef::Immutable(_) => { + panic!("cannot mutably deref an immutable WindowContext. this is a bug in GPUI."); + } + WindowContextRef::Mutable(window_context) => window_context, + } + } +} + pub struct RenderParams { pub window_id: usize, pub view_id: usize, @@ -4686,9 +4590,10 @@ impl ElementStateHandle { .unwrap() } - pub fn update(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R + pub fn update(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R where - C: DerefMut, + C: DerefMut, + D: DerefMut, { let mut element_state = cx.deref_mut().element_states.remove(&self.id).unwrap(); let result = f(element_state.downcast_mut().unwrap(), cx); @@ -5104,8 +5009,8 @@ mod tests { fn render(&mut self, cx: &mut ViewContext) -> ElementBox { enum Handler {} let mouse_down_count = self.mouse_down_count.clone(); - MouseEventHandler::::new(0, cx, |_, _| Empty::new().boxed()) - .on_down(MouseButton::Left, move |_, _| { + MouseEventHandler::::new(0, cx, |_, _| Empty::new().boxed()) + .on_down(MouseButton::Left, move |_, _, _| { mouse_down_count.fetch_add(1, SeqCst); }) .boxed() @@ -5504,8 +5409,8 @@ mod tests { }); view.update(cx, |_, c| { - c.observe(&model, |me, observed, c| { - me.events.push(observed.read(c).state.clone()) + c.observe(&model, |me, observed, cx| { + me.events.push(observed.read(cx).state.clone()) }) .detach(); }); diff --git a/crates/gpui/src/app/menu.rs b/crates/gpui/src/app/menu.rs index 24c8053906..c724f487b8 100644 --- a/crates/gpui/src/app/menu.rs +++ b/crates/gpui/src/app/menu.rs @@ -78,7 +78,11 @@ pub(crate) fn setup_menu_handlers(foreground_platform: &dyn ForegroundPlatform, move |action| { let mut cx = cx.borrow_mut(); if let Some(main_window_id) = cx.platform.main_window_id() { - if let Some(view_id) = cx.focused_view_id(main_window_id) { + if let Some(view_id) = cx + .windows + .get(&main_window_id) + .and_then(|w| w.focused_view_id) + { cx.handle_dispatch_action_from_effect(main_window_id, Some(view_id), action); return; } diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 7816b42ac9..a6624b0a54 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -1,6 +1,5 @@ use std::{ cell::RefCell, - marker::PhantomData, mem, path::PathBuf, rc::Rc, @@ -21,7 +20,7 @@ use crate::{ geometry::vector::Vector2F, keymap_matcher::Keystroke, platform, - platform::{Appearance, Event, InputHandler, KeyDownEvent, Platform}, + platform::{Event, InputHandler, KeyDownEvent, Platform}, Action, AnyViewHandle, AppContext, Entity, FontCache, Handle, ModelContext, ModelHandle, ReadModelWith, ReadViewWith, Task, UpdateModel, UpdateView, View, ViewContext, ViewHandle, WeakHandle, @@ -74,7 +73,7 @@ impl TestAppContext { pub fn dispatch_action(&self, window_id: usize, action: A) { let mut cx = self.cx.borrow_mut(); - if let Some(view_id) = cx.focused_view_id { + if let Some(view_id) = cx.windows.get(&window_id).and_then(|w| w.focused_view_id) { cx.handle_dispatch_action_from_effect(window_id, Some(view_id), &action); } } @@ -149,7 +148,14 @@ impl TestAppContext { } pub fn root_view(&self, window_id: usize) -> Option { - self.cx.borrow().root_view(window_id) + Some( + self.cx + .borrow() + .windows + .get(&window_id)? + .root_view() + .clone(), + ) } pub fn read T>(&self, callback: F) -> T { @@ -172,20 +178,21 @@ impl TestAppContext { F: FnOnce(&mut V, &mut ViewContext) -> T, V: View, { - handle.update(&mut *self.cx.borrow_mut(), |view, cx| { - let mut render_cx = ViewContext { - app: cx, - window_id: handle.window_id(), - view_id: handle.id(), - view_type: PhantomData, - titlebar_height: 0., - hovered_region_ids: Default::default(), - clicked_region_ids: None, - refreshing: false, - appearance: Appearance::Light, - }; - f(view, &mut render_cx) - }) + todo!() + // handle.update(&mut *self.cx.borrow_mut(), |view, cx| { + // let mut render_cx = ViewContext { + // app: cx, + // window_id: handle.window_id(), + // view_id: handle.id(), + // view_type: PhantomData, + // titlebar_height: 0., + // hovered_region_ids: Default::default(), + // clicked_region_ids: None, + // refreshing: false, + // appearance: Appearance::Light, + // }; + // f(view, &mut render_cx) + // }) } pub fn to_async(&self) -> AsyncAppContext { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index b7a9a0636a..36e0a6bfd2 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -1,6 +1,4 @@ use crate::{ - app::WindowInvalidation, - elements::Element, geometry::rect::RectF, json::{self, ToJson}, keymap_matcher::{Keystroke, MatchResult}, @@ -13,8 +11,9 @@ use crate::{ MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, Scene, }, text_layout::TextLayoutCache, - Action, AnyView, AnyViewHandle, AnyWeakViewHandle, AppContext, ElementBox, MouseRegion, - MouseRegionId, RenderParams, SceneBuilder, View, + util::post_inc, + AnyView, AnyViewHandle, AppContext, Element, ElementBox, MouseRegion, MouseRegionId, ParentId, + RenderParams, SceneBuilder, View, ViewContext, ViewHandle, WindowInvalidation, }; use anyhow::bail; use collections::{HashMap, HashSet}; @@ -30,8 +29,7 @@ use std::ops::{Deref, DerefMut, Range}; use uuid::Uuid; pub struct Window { - window_id: usize, - pub(crate) root_view: AnyViewHandle, + pub(crate) root_view: Option, pub(crate) focused_view_id: Option, pub(crate) is_active: bool, pub(crate) is_fullscreen: bool, @@ -43,27 +41,29 @@ pub struct Window { cursor_regions: Vec, mouse_regions: Vec<(MouseRegion, usize)>, last_mouse_moved_event: Option, - hovered_region_ids: HashSet, - clicked_region_ids: HashSet, - clicked_button: Option, + pub(crate) hovered_region_ids: HashSet, + pub(crate) clicked_region_ids: HashSet, + pub(crate) clicked_button: Option, mouse_position: Vector2F, text_layout_cache: TextLayoutCache, } impl Window { - pub fn new( + pub fn new( window_id: usize, - root_view: AnyViewHandle, platform_window: Box, cx: &mut AppContext, - ) -> Self { - let focused_view_id = Some(root_view.id()); + build_view: F, + ) -> Self + where + F: FnOnce(&mut ViewContext) -> V, + V: View, + { let titlebar_height = platform_window.titlebar_height(); let appearance = platform_window.appearance(); - Self { - window_id, - root_view, - focused_view_id, + let mut window = Self { + root_view: None, + focused_view_id: None, is_active: false, invalidation: None, is_fullscreen: false, @@ -79,15 +79,30 @@ impl Window { mouse_position: vec2f(0., 0.), titlebar_height, appearance, - } + }; + + let mut window_context = WindowContext::new(cx, &mut window, window_id); + let root_view = window_context + .build_and_insert_view(ParentId::Root, |cx| Some(build_view(cx))) + .unwrap(); + window.focused_view_id = Some(root_view.id()); + window.root_view = Some(root_view.into_any()); + window + } + + pub fn root_view(&self) -> &AnyViewHandle { + &self + .root_view + .as_ref() + .expect("root_view called during window construction") } } pub struct WindowContext<'a: 'b, 'b> { - app_context: &'a mut AppContext, + pub(crate) app_context: &'a mut AppContext, pub(crate) window: &'b mut Window, // TODO: make this private? pub(crate) window_id: usize, - pub refreshing: bool, + pub(crate) refreshing: bool, } impl Deref for WindowContext<'_, '_> { @@ -110,16 +125,30 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { app_context, window, window_id, + refreshing: false, } } - pub fn update_any_view(&mut self, view_id: usize, f: F) -> Option + pub fn window_id(&self) -> usize { + self.window_id + } + + pub fn window_size(&self) -> Vector2F { + self.window.platform_window.content_size() + } + + pub fn text_layout_cache(&self) -> &TextLayoutCache { + &self.window.text_layout_cache + } + + pub(crate) fn update_any_view(&mut self, view_id: usize, f: F) -> Option where F: FnOnce(&mut dyn AnyView, &mut Self) -> T, { - let view = self.views.remove(&(self.window_id, view_id))?; - let result = f(view.as_any_mut(), self); - self.views.insert((self.window_id, view_id), view); + let window_id = self.window_id; + let mut view = self.views.remove(&(window_id, view_id))?; + let result = f(view.as_mut(), self); + self.views.insert((window_id, view_id), view); Some(result) } @@ -453,8 +482,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { //3. Fire region events let hovered_region_ids = self.window.hovered_region_ids.clone(); for valid_region in valid_regions.into_iter() { - let mut event_cx = self.build_event_context(&mut notified_views); - + let mut handled = false; mouse_event.set_region(valid_region.bounds); if let MouseEvent::Hover(e) = &mut mouse_event { e.started = hovered_region_ids.contains(&valid_region.id()) @@ -473,25 +501,25 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { .handlers .contains(MouseEvent::down_disc(), Some(e.button)); if !has_down && (has_click || has_drag) { - event_cx.handled = true; + handled = true; } } // `event_consumed` should only be true if there are any handlers for this event. - let mut event_consumed = event_cx.handled; + let mut event_consumed = handled; if let Some(callbacks) = valid_region.handlers.get(&mouse_event.handler_key()) { for callback in callbacks { - event_cx.handled = true; - event_cx.with_current_view(valid_region.id().view_id(), { - let region_event = mouse_event.clone(); - |cx| callback(region_event, cx) + handled = true; + let view_id = valid_region.id().view_id(); + self.update_any_view(view_id, |view, cx| { + handled = callback(mouse_event.clone(), view.as_any_mut(), cx, view_id); }); - event_consumed |= event_cx.handled; - any_event_handled |= event_cx.handled; + event_consumed |= handled; + any_event_handled |= handled; } } - any_event_handled |= event_cx.handled; + any_event_handled |= handled; // For bubbling events, if the event was handled, don't continue dispatching. // This only makes sense for local events which return false from is_capturable. @@ -530,7 +558,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { } pub fn dispatch_key_up(&mut self, window_id: usize, event: &KeyUpEvent) -> bool { - if let Some(focused_view_id) = self.window.fo { + if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self .ancestors(window_id, focused_view_id) .collect::>() @@ -645,18 +673,17 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { let window_size = self.window.platform_window.content_size(); let scale_factor = self.window.platform_window.scale_factor(); - let root_view_id = self.window.root_view.id(); - let rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap(); - rendered_root.layout(root_view_id, SizeConstraint::strict(window_size), self); + let root_view_id = self.window.root_view().id(); + let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap(); + rendered_root.layout(SizeConstraint::strict(window_size), self, root_view_id); let mut scene_builder = SceneBuilder::new(scale_factor); - let paint_bounds = RectF::from_points(Vector2F::zero(), window_size); rendered_root.paint( - root_view_id, &mut scene_builder, - paint_bounds, - paint_bounds, + Vector2F::zero(), + RectF::from_points(Vector2F::zero(), window_size), self, + root_view_id, ); self.window.text_layout_cache.finish_frame(); @@ -719,14 +746,6 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { self.window.is_fullscreen } - pub fn root_view(&self, window_id: usize) -> &AnyViewHandle { - &self.window.root_view - } - - pub fn root_view_id(&self) -> usize { - self.window.root_view.id() - } - pub fn focused_view_id(&self) -> Option { self.window.focused_view_id } @@ -739,7 +758,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { self.window.platform_window.screen().display_uuid() } - fn show_character_palette(&self) { + pub fn show_character_palette(&self) { self.window.platform_window.show_character_palette(); } @@ -763,47 +782,162 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { ) -> oneshot::Receiver { self.window.platform_window.prompt(level, msg, answers) } + + fn add_view(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle + where + T: View, + F: FnOnce(&mut ViewContext) -> T, + { + if parent.window_id == self.window_id { + self.build_and_insert_view(ParentId::View(parent.view_id), |cx| Some(build_view(cx))) + .unwrap() + } else { + self.app_context.add_view(parent, build_view) + } + } + + fn add_option_view( + &mut self, + parent_handle: impl Into, + build_view: F, + ) -> Option> + where + T: View, + F: FnOnce(&mut ViewContext) -> Option, + { + let parent_handle = parent_handle.into(); + self.build_and_insert_view(ParentId::View(parent_handle.view_id), build_view) + } + + pub fn replace_root_view(&mut self, build_root_view: F) -> ViewHandle + where + V: View, + F: FnOnce(&mut ViewContext) -> V, + { + let root_view = self + .build_and_insert_view(ParentId::Root, |cx| Some(build_root_view(cx))) + .unwrap(); + self.window.root_view = Some(root_view.clone().into_any()); + self.window.focused_view_id = Some(root_view.id()); + root_view + } + + pub(crate) fn build_and_insert_view( + &mut self, + parent_id: ParentId, + build_view: F, + ) -> Option> + where + T: View, + F: FnOnce(&mut ViewContext) -> Option, + { + let window_id = self.window_id; + let view_id = post_inc(&mut self.next_entity_id); + // Make sure we can tell child views about their parentu + self.parents.insert((window_id, view_id), parent_id); + let mut cx = ViewContext::mutable(self, view_id); + let handle = if let Some(view) = build_view(&mut cx) { + self.views.insert((window_id, view_id), Box::new(view)); + self.window + .invalidation + .get_or_insert_with(Default::default) + .updated + .insert(view_id); + Some(ViewHandle::new(window_id, view_id, &self.ref_counts)) + } else { + self.parents.remove(&(window_id, view_id)); + None + }; + handle + } } pub trait RenderedView { fn layout( - &self, - view_id: usize, + &mut self, constraint: SizeConstraint, cx: &mut WindowContext, + view_id: usize, ) -> Vector2F; fn paint( - &self, - view_id: usize, + &mut self, scene: &mut SceneBuilder, - bounds: RectF, + origin: Vector2F, visible_bounds: RectF, cx: &mut WindowContext, + view_id: usize, ); + fn rect_for_text_range( + &self, + range_utf16: Range, + cx: &WindowContext, + view_id: usize, + ) -> Option; + fn debug(&self, cx: &WindowContext, view_id: usize) -> serde_json::Value; + fn name(&self) -> Option<&str>; } impl RenderedView for ElementBox { fn layout( - &self, - view_id: usize, + &mut self, constraint: SizeConstraint, cx: &mut WindowContext, + view_id: usize, ) -> Vector2F { - cx.update_view_for_id(view_id, |view, cx| self.layout(view, constraint, cx)) - .unwrap() + cx.update_any_view(view_id, |view, cx| { + let view = view.as_any_mut().downcast_mut::().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + ElementBox::layout(self, constraint, view, &mut cx) + }) + .unwrap() } fn paint( - &self, - view_id: usize, + &mut self, scene: &mut SceneBuilder, - bounds: RectF, + origin: Vector2F, visible_bounds: RectF, cx: &mut WindowContext, + view_id: usize, ) { - cx.update_view_for_id(view_id, |view, cx| { - self.paint(view, scene, bounds, visible_bounds, cx) - }) + cx.update_any_view(view_id, |view, cx| { + let view = view.as_any_mut().downcast_mut::().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + ElementBox::paint(self, scene, origin, visible_bounds, view, &mut cx) + }); + } + + fn rect_for_text_range( + &self, + range_utf16: Range, + cx: &WindowContext, + view_id: usize, + ) -> Option { + let view = cx + .views + .get(&(cx.window_id, view_id)) + .unwrap() + .as_any() + .downcast_ref::() + .unwrap(); + let cx = ViewContext::immutable(cx, view_id); + ElementBox::rect_for_text_range(self, range_utf16, view, &cx) + } + + fn debug(&self, cx: &WindowContext, view_id: usize) -> serde_json::Value { + let view = cx + .views + .get(&(cx.window_id, view_id)) + .unwrap() + .as_any() + .downcast_ref::() + .unwrap(); + let cx = ViewContext::immutable(cx, view_id); + ElementBox::debug(self, view, &cx) + } + + fn name(&self) -> Option<&str> { + ElementBox::name(self) } } @@ -950,7 +1084,7 @@ impl ToJson for SizeConstraint { } pub struct ChildView { - view: AnyWeakViewHandle, + view_id: usize, view_name: &'static str, } @@ -958,94 +1092,101 @@ impl ChildView { pub fn new(view: &AnyViewHandle, cx: &AppContext) -> Self { let view_name = cx.view_ui_name(view.window_id(), view.id()).unwrap(); Self { - view: view.downgrade(), + view_id: view.id(), view_name, } } } -// impl Element for ChildView { -// type LayoutState = bool; -// type PaintState = (); +impl Element for ChildView { + type LayoutState = (); + type PaintState = (); -// fn layout( -// &mut self, -// constraint: SizeConstraint, -// cx: &mut LayoutContext, -// ) -> (Vector2F, Self::LayoutState) { -// if cx.rendered_views.contains_key(&self.view.id()) { -// let size = cx.layout(self.view.id(), constraint); -// (size, true) -// } else { -// log::error!( -// "layout called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})", -// self.view.id(), -// self.view_name -// ); -// (Vector2F::zero(), false) -// } -// } + fn layout( + &mut self, + constraint: SizeConstraint, + _: &mut V, + cx: &mut ViewContext, + ) -> (Vector2F, Self::LayoutState) { + if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) { + let size = rendered_view.layout(constraint, cx, self.view_id); + cx.window.rendered_views.insert(self.view_id, rendered_view); + (size, ()) + } else { + log::error!( + "layout called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})", + self.view_id, + self.view_name + ); + (Vector2F::zero(), ()) + } + } -// fn paint( -// &mut self, -// bounds: RectF, -// visible_bounds: RectF, -// view_is_valid: &mut Self::LayoutState, -// cx: &mut PaintContext, -// ) { -// if *view_is_valid { -// cx.paint(self.view.id(), bounds.origin(), visible_bounds); -// } else { -// log::error!( -// "paint called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})", -// self.view.id(), -// self.view_name -// ); -// } -// } + fn paint( + &mut self, + scene: &mut SceneBuilder, + bounds: RectF, + visible_bounds: RectF, + _: &mut Self::LayoutState, + _: &mut V, + cx: &mut ViewContext, + ) { + if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) { + rendered_view.paint(scene, bounds.origin(), visible_bounds, cx, self.view_id); + cx.window.rendered_views.insert(self.view_id, rendered_view); + } else { + log::error!( + "paint called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})", + self.view_id, + self.view_name + ); + } + } -// fn rect_for_text_range( -// &self, -// range_utf16: Range, -// _: RectF, -// _: RectF, -// view_is_valid: &Self::LayoutState, -// _: &Self::PaintState, -// cx: &MeasurementContext, -// ) -> Option { -// if *view_is_valid { -// cx.rect_for_text_range(self.view.id(), range_utf16) -// } else { -// log::error!( -// "rect_for_text_range called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})", -// self.view.id(), -// self.view_name -// ); -// None -// } -// } + fn rect_for_text_range( + &self, + range_utf16: Range, + _: RectF, + _: RectF, + _: &Self::LayoutState, + _: &Self::PaintState, + _: &V, + cx: &ViewContext, + ) -> Option { + if let Some(rendered_view) = cx.window.rendered_views.get(&self.view_id) { + rendered_view.rect_for_text_range(range_utf16, &cx.window_context, self.view_id) + } else { + log::error!( + "rect_for_text_range called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})", + self.view_id, + self.view_name + ); + None + } + } -// fn debug( -// &self, -// bounds: RectF, -// _: &Self::LayoutState, -// _: &Self::PaintState, -// cx: &DebugContext, -// ) -> serde_json::Value { -// json!({ -// "type": "ChildView", -// "view_id": self.view.id(), -// "bounds": bounds.to_json(), -// "view": if let Some(view) = self.view.upgrade(cx.app) { -// view.debug_json(cx.app) -// } else { -// json!(null) -// }, -// "child": if let Some(view) = cx.rendered_views.get(&self.view.id()) { -// view.debug(cx) -// } else { -// json!(null) -// } -// }) -// } -// } + fn debug( + &self, + bounds: RectF, + _: &Self::LayoutState, + _: &Self::PaintState, + _: &V, + cx: &ViewContext, + ) -> serde_json::Value { + json!({ + "type": "ChildView", + "view_id": self.view_id, + "bounds": bounds.to_json(), + "view": if let Some(view) = cx.views.get(&(cx.window_id, self.view_id)) { + view.debug_json(cx) + } else { + json!(null) + }, + "child": if let Some(element) = cx.window.rendered_views.get(&self.view_id) { + element.debug(&cx.window_context, self.view_id) + } else { + json!(null) + } + }) + } +} diff --git a/crates/gpui/src/app/window_input_handler.rs b/crates/gpui/src/app/window_input_handler.rs index db92dd0b47..938dbe1a03 100644 --- a/crates/gpui/src/app/window_input_handler.rs +++ b/crates/gpui/src/app/window_input_handler.rs @@ -2,7 +2,7 @@ use std::{cell::RefCell, ops::Range, rc::Rc}; use pathfinder_geometry::rect::RectF; -use crate::{platform::InputHandler, AnyView, AppContext}; +use crate::{platform::InputHandler, window::WindowContext, AnyView, AppContext}; pub struct WindowInputHandler { pub app: Rc>, @@ -12,7 +12,7 @@ pub struct WindowInputHandler { impl WindowInputHandler { fn read_focused_view(&self, f: F) -> Option where - F: FnOnce(&dyn AnyView, &AppContext) -> T, + F: FnOnce(&dyn AnyView, &WindowContext) -> T, { // Input-related application hooks are sometimes called by the OS during // a call to a window-manipulation API, like prompting the user for file @@ -20,26 +20,26 @@ impl WindowInputHandler { // InputHandler methods need to fail gracefully. // // See https://github.com/zed-industries/community/issues/444 - let app = self.app.try_borrow().ok()?; - - let view_id = app.focused_view_id(self.window_id)?; - let view = app.views.get(&(self.window_id, view_id))?; - let result = f(view.as_ref(), &app); - Some(result) + let mut app = self.app.try_borrow_mut().ok()?; + app.update_window(self.window_id, |cx| { + let view_id = cx.window.focused_view_id?; + let view = cx.views.get(&(self.window_id, view_id))?; + let result = f(view.as_ref(), &cx); + Some(result) + }) + .flatten() } fn update_focused_view(&mut self, f: F) -> Option where - F: FnOnce(usize, usize, &mut dyn AnyView, &mut AppContext) -> T, + F: FnOnce(&mut dyn AnyView, &mut WindowContext, usize) -> T, { let mut app = self.app.try_borrow_mut().ok()?; - app.update(|app| { - let view_id = app.focused_view_id(self.window_id)?; - let mut view = app.views.remove(&(self.window_id, view_id))?; - let result = f(self.window_id, view_id, view.as_mut(), &mut *app); - app.views.insert((self.window_id, view_id), view); - Some(result) + app.update_window(self.window_id, |cx| { + let view_id = cx.window.focused_view_id?; + cx.update_any_view(view_id, |view, cx| f(view, cx, view_id)) }) + .flatten() } } @@ -55,8 +55,8 @@ impl InputHandler for WindowInputHandler { } fn replace_text_in_range(&mut self, range: Option>, text: &str) { - self.update_focused_view(|window_id, view_id, view, cx| { - view.replace_text_in_range(range, text, cx, window_id, view_id); + self.update_focused_view(|view, cx, view_id| { + view.replace_text_in_range(range, text, cx, view_id); }); } @@ -66,8 +66,8 @@ impl InputHandler for WindowInputHandler { } fn unmark_text(&mut self) { - self.update_focused_view(|window_id, view_id, view, cx| { - view.unmark_text(cx, window_id, view_id); + self.update_focused_view(|view, cx, view_id| { + view.unmark_text(cx, view_id); }); } @@ -77,15 +77,8 @@ impl InputHandler for WindowInputHandler { new_text: &str, new_selected_range: Option>, ) { - self.update_focused_view(|window_id, view_id, view, cx| { - view.replace_and_mark_text_in_range( - range, - new_text, - new_selected_range, - cx, - window_id, - view_id, - ); + self.update_focused_view(|view, cx, view_id| { + view.replace_and_mark_text_in_range(range, new_text, new_selected_range, cx, view_id); }); } diff --git a/crates/gpui/src/elements.rs b/crates/gpui/src/elements.rs index d23134acaf..f1a5c8dffd 100644 --- a/crates/gpui/src/elements.rs +++ b/crates/gpui/src/elements.rs @@ -35,29 +35,29 @@ use crate::{ }; use core::panic; use json::ToJson; -use std::{any::Any, borrow::Cow, cell::RefCell, marker::PhantomData, mem, ops::Range}; +use std::{any::Any, borrow::Cow, marker::PhantomData, mem, ops::Range}; trait AnyElement { fn layout( &mut self, - view: &mut V, constraint: SizeConstraint, + view: &mut V, cx: &mut ViewContext, ) -> Vector2F; fn paint( &mut self, - view: &mut V, scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, + view: &mut V, cx: &mut ViewContext, ); fn rect_for_text_range( &self, - view: &V, range_utf16: Range, + view: &V, cx: &ViewContext, ) -> Option; @@ -118,7 +118,8 @@ pub trait Element { Self: 'static + Sized, { ElementBox { - element: RefCell::new(Lifecycle::Init { element: self }), + element: Box::new(Lifecycle::Init { element: self }), + view_type: PhantomData, name: None, } } @@ -128,7 +129,8 @@ pub trait Element { Self: 'static + Sized, { ElementBox { - element: RefCell::new(Lifecycle::Init { element: self }), + element: Box::new(Lifecycle::Init { element: self }), + view_type: PhantomData, name: Some(name.into()), } } @@ -193,7 +195,7 @@ pub trait Element { where Self: 'static + Sized, { - Tooltip::new::(id, text, action, style, self.boxed(), cx) + Tooltip::new::(id, text, action, style, self.boxed(), cx) } fn with_resize_handle( @@ -207,7 +209,7 @@ pub trait Element { where Self: 'static + Sized, { - Resizable::new::( + Resizable::new::( self.boxed(), element_id, side, @@ -242,8 +244,8 @@ pub enum Lifecycle> { impl> AnyElement for Lifecycle { fn layout( &mut self, - view: &mut V, constraint: SizeConstraint, + view: &mut V, cx: &mut ViewContext, ) -> Vector2F { let result; @@ -252,7 +254,7 @@ impl> AnyElement for Lifecycle { Lifecycle::Init { mut element } | Lifecycle::PostLayout { mut element, .. } | Lifecycle::PostPaint { mut element, .. } => { - let (size, layout) = element.layout(view, constraint, cx); + let (size, layout) = element.layout(constraint, view, cx); debug_assert!(size.x().is_finite()); debug_assert!(size.y().is_finite()); @@ -271,9 +273,9 @@ impl> AnyElement for Lifecycle { fn paint( &mut self, scene: &mut SceneBuilder, - view: &mut V, origin: Vector2F, visible_bounds: RectF, + view: &mut V, cx: &mut ViewContext, ) { *self = match mem::take(self) { @@ -321,9 +323,9 @@ impl> AnyElement for Lifecycle { fn rect_for_text_range( &self, - view: &V, range_utf16: Range, - cx: &mut ViewContext, + view: &V, + cx: &ViewContext, ) -> Option { if let Lifecycle::PostPaint { element, @@ -404,41 +406,40 @@ impl> Default for Lifecycle { } pub struct ElementBox { - element: Box>>, + element: Box>, view_type: PhantomData, name: Option>, } impl ElementBox { pub fn name(&self) -> Option<&str> { - self.0.name.as_deref() + self.name.as_deref() } pub fn metadata(&self) -> Option<&T> { - // let element = unsafe { &*self.0.element.as_ptr() }; - // element.metadata().and_then(|m| m.downcast_ref()) + self.element + .metadata() + .and_then(|data| data.downcast_ref::()) } pub fn layout( - &self, + &mut self, constraint: SizeConstraint, view: &mut V, cx: &mut ViewContext, ) -> Vector2F { - self.element.borrow_mut().layout(view, constraint, cx) + self.element.layout(constraint, view, cx) } pub fn paint( - &self, + &mut self, scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, view: &mut V, cx: &mut ViewContext, ) { - self.element - .borrow_mut() - .paint(view, scene, origin, visible_bounds, cx); + self.element.paint(scene, origin, visible_bounds, view, cx); } pub fn rect_for_text_range( @@ -447,17 +448,15 @@ impl ElementBox { view: &V, cx: &ViewContext, ) -> Option { - self.element - .borrow() - .rect_for_text_range(view, range_utf16, cx) + self.element.rect_for_text_range(range_utf16, view, cx) } pub fn size(&self) -> Vector2F { - self.element.borrow().size() + self.element.size() } pub fn debug(&self, view: &V, cx: &ViewContext) -> json::Value { - let mut value = self.element.borrow().debug(view, cx); + let mut value = self.element.debug(view, cx); if let Some(name) = &self.name { if let json::Value::Object(map) = &mut value { @@ -476,8 +475,7 @@ impl ElementBox { T: 'static, F: FnOnce(Option<&T>) -> R, { - let element = self.element.borrow(); - f(element.metadata().and_then(|m| m.downcast_ref())) + f(self.element.metadata().and_then(|m| m.downcast_ref())) } } diff --git a/crates/gpui/src/elements/align.rs b/crates/gpui/src/elements/align.rs index 8915dc2b4f..9745f0224f 100644 --- a/crates/gpui/src/elements/align.rs +++ b/crates/gpui/src/elements/align.rs @@ -46,13 +46,13 @@ impl Element for Align { fn layout( &mut self, - view: &mut V, mut constraint: SizeConstraint, + view: &mut V, cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let mut size = constraint.max; constraint.min = Vector2F::zero(); - let child_size = self.child.layout(view, constraint, cx); + let child_size = self.child.layout(constraint, view, cx); if size.x().is_infinite() { size.set_x(child_size.x()); } @@ -64,11 +64,11 @@ impl Element for Align { fn paint( &mut self, - view: &mut V, scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, + view: &mut V, cx: &mut ViewContext, ) -> Self::PaintState { let my_center = bounds.size() / 2.; @@ -78,33 +78,33 @@ impl Element for Align { let child_target = child_center + child_center * self.alignment; self.child.paint( - view, scene, bounds.origin() - (child_target - my_target), visible_bounds, + view, cx, ); } fn rect_for_text_range( &self, - view: &V, range_utf16: std::ops::Range, _: RectF, _: RectF, _: &Self::LayoutState, _: &Self::PaintState, + view: &V, cx: &ViewContext, ) -> Option { - self.child.rect_for_text_range(view, range_utf16, cx) + self.child.rect_for_text_range(range_utf16, view, cx) } fn debug( &self, - view: &V, bounds: pathfinder_geometry::rect::RectF, _: &Self::LayoutState, _: &Self::PaintState, + view: &V, cx: &ViewContext, ) -> json::Value { json!({ diff --git a/crates/gpui/src/elements/canvas.rs b/crates/gpui/src/elements/canvas.rs index fb842f92f7..24f180ea97 100644 --- a/crates/gpui/src/elements/canvas.rs +++ b/crates/gpui/src/elements/canvas.rs @@ -25,7 +25,7 @@ where impl Element for Canvas where - F: FnMut(RectF, RectF, &mut ViewContext), + F: FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext), { type LayoutState = (); type PaintState = (); @@ -58,7 +58,7 @@ where view: &mut V, cx: &mut ViewContext, ) -> Self::PaintState { - self.0(bounds, visible_bounds, cx) + self.0(scene, bounds, visible_bounds, view, cx) } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/clipped.rs b/crates/gpui/src/elements/clipped.rs index 96c4f46f22..2a2d69a8ca 100644 --- a/crates/gpui/src/elements/clipped.rs +++ b/crates/gpui/src/elements/clipped.rs @@ -37,10 +37,10 @@ impl Element for Clipped { view: &mut V, cx: &mut ViewContext, ) -> Self::PaintState { - cx.scene.push_layer(Some(bounds)); - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx); - cx.scene.pop_layer(); + scene.paint_layer(Some(bounds), |scene| { + self.child + .paint(scene, bounds.origin(), visible_bounds, view, cx) + }) } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/constrained_box.rs b/crates/gpui/src/elements/constrained_box.rs index 64d78e87a9..4fddd3c534 100644 --- a/crates/gpui/src/elements/constrained_box.rs +++ b/crates/gpui/src/elements/constrained_box.rs @@ -157,7 +157,7 @@ impl Element for ConstrainedBox { view: &mut V, cx: &mut ViewContext, ) -> Self::PaintState { - cx.paint_layer(Some(visible_bounds), |cx| { + scene.paint_layer(Some(visible_bounds), |scene| { self.child .paint(scene, bounds.origin(), visible_bounds, view, cx); }) diff --git a/crates/gpui/src/elements/container.rs b/crates/gpui/src/elements/container.rs index 5631c01bc0..42183af6b5 100644 --- a/crates/gpui/src/elements/container.rs +++ b/crates/gpui/src/elements/container.rs @@ -221,7 +221,7 @@ impl Element for Container { ); if let Some(shadow) = self.style.shadow.as_ref() { - cx.scene.push_shadow(scene::Shadow { + scene.push_shadow(scene::Shadow { bounds: quad_bounds + shadow.offset, corner_radius: self.style.corner_radius, sigma: shadow.blur, @@ -231,7 +231,7 @@ impl Element for Container { if let Some(hit_bounds) = quad_bounds.intersection(visible_bounds) { if let Some(style) = self.style.cursor { - cx.scene.push_cursor_region(CursorRegion { + scene.push_cursor_region(CursorRegion { bounds: hit_bounds, style, }); @@ -242,7 +242,7 @@ impl Element for Container { quad_bounds.origin() + vec2f(self.style.padding.left, self.style.padding.top); if self.style.border.overlay { - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: quad_bounds, background: self.style.background_color, border: Default::default(), @@ -252,16 +252,16 @@ impl Element for Container { self.child .paint(scene, child_origin, visible_bounds, view, cx); - cx.scene.push_layer(None); - cx.scene.push_quad(Quad { + scene.push_layer(None); + scene.push_quad(Quad { bounds: quad_bounds, background: self.style.overlay_color, border: self.style.border, corner_radius: self.style.corner_radius, }); - cx.scene.pop_layer(); + scene.pop_layer(); } else { - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: quad_bounds, background: self.style.background_color, border: self.style.border, @@ -277,14 +277,14 @@ impl Element for Container { .paint(scene, child_origin, visible_bounds, view, cx); if self.style.overlay_color.is_some() { - cx.scene.push_layer(None); - cx.scene.push_quad(Quad { + scene.push_layer(None); + scene.push_quad(Quad { bounds: quad_bounds, background: self.style.overlay_color, border: Default::default(), corner_radius: 0., }); - cx.scene.pop_layer(); + scene.pop_layer(); } } } diff --git a/crates/gpui/src/elements/empty.rs b/crates/gpui/src/elements/empty.rs index 98289128b5..d1a3cbafdb 100644 --- a/crates/gpui/src/elements/empty.rs +++ b/crates/gpui/src/elements/empty.rs @@ -33,7 +33,7 @@ impl Element for Empty { fn layout( &mut self, constraint: SizeConstraint, - _: &V, + _: &mut V, _: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let x = if constraint.max.x().is_finite() && !self.collapsed { @@ -56,6 +56,7 @@ impl Element for Empty { _: RectF, _: RectF, _: &mut Self::LayoutState, + _: &mut V, _: &mut ViewContext, ) -> Self::PaintState { } diff --git a/crates/gpui/src/elements/expanded.rs b/crates/gpui/src/elements/expanded.rs index 186ad0300e..60cf5a9bb9 100644 --- a/crates/gpui/src/elements/expanded.rs +++ b/crates/gpui/src/elements/expanded.rs @@ -42,7 +42,7 @@ impl Element for Expanded { &mut self, mut constraint: SizeConstraint, view: &mut V, - cx: &mut ViewContext, + cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { if self.full_width { constraint.min.set_x(constraint.max.x()); diff --git a/crates/gpui/src/elements/flex.rs b/crates/gpui/src/elements/flex.rs index 31e3f25308..1327ac054d 100644 --- a/crates/gpui/src/elements/flex.rs +++ b/crates/gpui/src/elements/flex.rs @@ -73,7 +73,7 @@ impl Flex { remaining_space: &mut f32, remaining_flex: &mut f32, cross_axis_max: &mut f32, - view: &V, + view: &mut V, cx: &mut ViewContext, ) { let cross_axis = self.axis.invert(); @@ -124,7 +124,7 @@ impl Element for Flex { fn layout( &mut self, constraint: SizeConstraint, - view: &V, + view: &mut V, cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let mut total_flex = None; @@ -253,7 +253,7 @@ impl Element for Flex { bounds: RectF, visible_bounds: RectF, remaining_space: &mut Self::LayoutState, - view: &V, + view: &mut V, cx: &mut ViewContext, ) -> Self::PaintState { let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); @@ -261,16 +261,16 @@ impl Element for Flex { let mut remaining_space = *remaining_space; let overflowing = remaining_space < 0.; if overflowing { - cx.scene.push_layer(Some(visible_bounds)); + scene.push_layer(Some(visible_bounds)); } if let Some(scroll_state) = &self.scroll_state { - cx.scene.push_mouse_region( + scene.push_mouse_region( crate::MouseRegion::new::(scroll_state.1, 0, bounds) .on_scroll({ let scroll_state = scroll_state.0.read(cx).clone(); let axis = self.axis; - move |e, cx| { + move |e, _: &mut V, cx| { if remaining_space < 0. { let scroll_delta = e.delta.raw(); @@ -298,7 +298,7 @@ impl Element for Flex { } } }) - .on_move(|_, _| { /* Capture move events */ }), + .on_move(|_, _: &mut V, _| { /* Capture move events */ }), ) } @@ -356,7 +356,7 @@ impl Element for Flex { } if overflowing { - cx.scene.pop_layer(); + scene.pop_layer(); } } @@ -372,7 +372,7 @@ impl Element for Flex { ) -> Option { self.children .iter() - .find_map(|child| child.rect_for_text_range(view, range_utf16.clone(), cx)) + .find_map(|child| child.rect_for_text_range(range_utf16.clone(), view, cx)) } fn debug( @@ -431,7 +431,7 @@ impl Element for FlexItem { fn layout( &mut self, constraint: SizeConstraint, - view: &V, + view: &mut V, cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let size = self.child.layout(constraint, view, cx); @@ -444,7 +444,7 @@ impl Element for FlexItem { bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, - view: &V, + view: &mut V, cx: &mut ViewContext, ) -> Self::PaintState { self.child @@ -474,7 +474,6 @@ impl Element for FlexItem { _: &Self::LayoutState, _: &Self::PaintState, view: &V, - cx: &ViewContext, ) -> Value { json!({ diff --git a/crates/gpui/src/elements/hook.rs b/crates/gpui/src/elements/hook.rs index eec7b3aad3..0a310e6f74 100644 --- a/crates/gpui/src/elements/hook.rs +++ b/crates/gpui/src/elements/hook.rs @@ -35,7 +35,7 @@ impl Element for Hook { fn layout( &mut self, constraint: SizeConstraint, - view: &V, + view: &mut V, cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let size = self.child.layout(constraint, view, cx); diff --git a/crates/gpui/src/elements/image.rs b/crates/gpui/src/elements/image.rs index 479801a50c..162446c1f0 100644 --- a/crates/gpui/src/elements/image.rs +++ b/crates/gpui/src/elements/image.rs @@ -62,7 +62,7 @@ impl Element for Image { fn layout( &mut self, constraint: SizeConstraint, - view: &V, + _: &mut V, cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let data = match &self.source { @@ -94,8 +94,8 @@ impl Element for Image { bounds: RectF, _: RectF, layout: &mut Self::LayoutState, - _: &V, - cx: &mut ViewContext, + _: &mut V, + _: &mut ViewContext, ) -> Self::PaintState { if let Some(data) = layout { scene.push_image(scene::Image { diff --git a/crates/gpui/src/elements/keystroke_label.rs b/crates/gpui/src/elements/keystroke_label.rs index 5727a9f011..3d20930a5d 100644 --- a/crates/gpui/src/elements/keystroke_label.rs +++ b/crates/gpui/src/elements/keystroke_label.rs @@ -41,12 +41,11 @@ impl Element for KeystrokeLabel { fn layout( &mut self, constraint: SizeConstraint, - view: &V, + view: &mut V, cx: &mut ViewContext, ) -> (Vector2F, ElementBox) { let mut element = if let Some(keystrokes) = - cx.app - .keystrokes_for_action(self.window_id, self.view_id, self.action.as_ref()) + cx.keystrokes_for_action(self.window_id, self.view_id, self.action.as_ref()) { Flex::row() .with_children(keystrokes.iter().map(|keystroke| { @@ -70,7 +69,7 @@ impl Element for KeystrokeLabel { bounds: RectF, visible_bounds: RectF, element: &mut ElementBox, - view: &V, + view: &mut V, cx: &mut ViewContext, ) { element.paint(scene, bounds.origin(), visible_bounds, view, cx); diff --git a/crates/gpui/src/elements/label.rs b/crates/gpui/src/elements/label.rs index 2f68967a2f..2669f4d5f2 100644 --- a/crates/gpui/src/elements/label.rs +++ b/crates/gpui/src/elements/label.rs @@ -134,13 +134,15 @@ impl Element for Label { fn layout( &mut self, constraint: SizeConstraint, - view: &V, + _: &mut V, cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let runs = self.compute_runs(); - let line = - cx.text_layout_cache - .layout_str(&self.text, self.style.text.font_size, runs.as_slice()); + let line = cx.text_layout_cache().layout_str( + &self.text, + self.style.text.font_size, + runs.as_slice(), + ); let size = vec2f( line.width() @@ -159,8 +161,8 @@ impl Element for Label { bounds: RectF, visible_bounds: RectF, line: &mut Self::LayoutState, - _: &V, - cx: &mut ViewContext, + _: &mut V, + cx: &mut ViewContext, ) -> Self::PaintState { line.paint( scene, diff --git a/crates/gpui/src/elements/list.rs b/crates/gpui/src/elements/list.rs index ef9a202f1a..0cce90d022 100644 --- a/crates/gpui/src/elements/list.rs +++ b/crates/gpui/src/elements/list.rs @@ -13,7 +13,6 @@ pub struct List { state: ListState, } -#[derive(Clone)] pub struct ListState(Rc>>); #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -42,7 +41,7 @@ pub struct ListOffset { enum ListItem { Unrendered, - Rendered(Rc>), + Rendered(Rc>>), Removed(f32), } @@ -145,7 +144,7 @@ impl Element for List { view, cx, ) { - rendered_height += element.size().y(); + rendered_height += element.borrow().size().y(); rendered_items.push_back(ListItem::Rendered(element)); } } @@ -162,7 +161,7 @@ impl Element for List { if let Some(element) = state.render_item(cursor.start().0, None, item_constraint, view, cx) { - rendered_height += element.size().y(); + rendered_height += element.borrow().size().y(); rendered_items.push_front(ListItem::Rendered(element)); } } else { @@ -198,7 +197,7 @@ impl Element for List { if let Some(element) = state.render_item(cursor.start().0, Some(item), item_constraint, view, cx) { - leading_overdraw += element.size().y(); + leading_overdraw += element.borrow().size().y(); rendered_items.push_front(ListItem::Rendered(element)); } } else { @@ -264,12 +263,13 @@ impl Element for List { let state = self.state.clone(); let height = bounds.height(); let scroll_top = scroll_top.clone(); - move |e, cx| { + move |e, view, cx| { state.0.borrow_mut().scroll( &scroll_top, height, *e.platform_event.delta.raw(), e.platform_event.delta.precise(), + view, cx, ) } @@ -277,8 +277,10 @@ impl Element for List { ); let state = &mut *self.state.0.borrow_mut(); - for (mut element, origin) in state.visible_elements(bounds, scroll_top) { - element.paint(scene, origin, visible_bounds, view, cx); + for (element, origin) in state.visible_elements(bounds, scroll_top) { + element + .borrow_mut() + .paint(scene, origin, visible_bounds, view, cx); } scene.pop_layer(); @@ -304,11 +306,15 @@ impl Element for List { } if let ListItem::Rendered(element) = item { - if let Some(rect) = element.rect_for_text_range(range_utf16.clone(), view, cx) { + if let Some(rect) = + element + .borrow() + .rect_for_text_range(range_utf16.clone(), view, cx) + { return Some(rect); } - item_origin.set_y(item_origin.y() + element.size().y()); + item_origin.set_y(item_origin.y() + element.borrow().size().y()); cursor.next(&()); } else { unreachable!(); @@ -329,7 +335,7 @@ impl Element for List { let state = self.state.0.borrow_mut(); let visible_elements = state .visible_elements(bounds, scroll_top) - .map(|e| e.0.debug(view, cx)) + .map(|e| e.0.borrow().debug(view, cx)) .collect::>(); let visible_range = scroll_top.item_ix..(scroll_top.item_ix + visible_elements.len()); json!({ @@ -345,8 +351,7 @@ impl ListState { element_count: usize, orientation: Orientation, overdraw: f32, - cx: &mut ViewContext, - mut render_item: F, + render_item: F, ) -> Self where V: View, @@ -354,14 +359,9 @@ impl ListState { { let mut items = SumTree::new(); items.extend((0..element_count).map(|_| ListItem::Unrendered), &()); - let handle = cx.weak_handle(); Self(Rc::new(RefCell::new(StateInner { last_layout_width: None, - render_item: Box::new(move |ix, view, cx| { - render_item(view, ix, cx) - // let handle = handle.upgrade(cx)?; - // Some(cx.render(&handle, |view, cx| render_item(view, ix, cx))) - }), + render_item: Box::new(render_item), rendered_range: 0..0, items, logical_scroll_top: None, @@ -439,6 +439,12 @@ impl ListState { } } +impl Clone for ListState { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + impl StateInner { fn render_item( &mut self, @@ -447,13 +453,13 @@ impl StateInner { constraint: SizeConstraint, view: &mut V, cx: &mut ViewContext, - ) -> Option>> { + ) -> Option>>> { if let Some(ListItem::Rendered(element)) = existing_element { Some(element.clone()) } else { let mut element = (self.render_item)(view, ix, cx); element.layout(constraint, view, cx); - Some(element.into()) + Some(Rc::new(RefCell::new(element))) } } @@ -469,7 +475,7 @@ impl StateInner { &'a self, bounds: RectF, scroll_top: &ListOffset, - ) -> impl Iterator>, Vector2F)> + 'a { + ) -> impl Iterator>>, Vector2F)> + 'a { let mut item_origin = bounds.origin() - vec2f(0., scroll_top.offset_in_item); let mut cursor = self.items.cursor::(); cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &()); @@ -481,7 +487,7 @@ impl StateInner { if let ListItem::Rendered(element) = item { let result = (element.clone(), item_origin); - item_origin.set_y(item_origin.y() + element.size().y()); + item_origin.set_y(item_origin.y() + element.borrow().size().y()); cursor.next(&()); return Some(result); } @@ -526,7 +532,7 @@ impl StateInner { if self.scroll_handler.is_some() { let visible_range = self.visible_range(height, scroll_top); - self.scroll_handler.as_mut().unwrap()(visible_range, cx); + self.scroll_handler.as_mut().unwrap()(visible_range, view, cx); } cx.notify(); @@ -557,7 +563,7 @@ impl ListItem { fn remove(&self) -> Self { match self { ListItem::Unrendered => ListItem::Unrendered, - ListItem::Rendered(element) => ListItem::Removed(element.size().y()), + ListItem::Rendered(element) => ListItem::Removed(element.borrow().size().y()), ListItem::Removed(height) => ListItem::Removed(*height), } } @@ -578,7 +584,7 @@ impl sum_tree::Item for ListItem { count: 1, rendered_count: 1, unrendered_count: 0, - height: element.size().y(), + height: element.borrow().size().y(), }, ListItem::Removed(height) => ListItemSummary { count: 1, @@ -642,7 +648,6 @@ mod tests { use super::*; use crate::{elements::Empty, geometry::vector::vec2f, Entity}; use rand::prelude::*; - use std::env; #[crate::test(self)] fn test_layout(cx: &mut crate::AppContext) { diff --git a/crates/gpui/src/elements/mouse_event_handler.rs b/crates/gpui/src/elements/mouse_event_handler.rs index 93515bbc43..c2c53b8b15 100644 --- a/crates/gpui/src/elements/mouse_event_handler.rs +++ b/crates/gpui/src/elements/mouse_event_handler.rs @@ -7,8 +7,8 @@ use crate::{ platform::CursorStyle, platform::MouseButton, scene::{ - CursorRegion, HandlerSet, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseHover, - MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, + CursorRegion, EventContext, HandlerSet, MouseClick, MouseDown, MouseDownOut, MouseDrag, + MouseHover, MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, }, Element, ElementBox, MouseRegion, MouseState, SceneBuilder, SizeConstraint, View, ViewContext, }; @@ -31,13 +31,13 @@ pub struct MouseEventHandler { /// Element which provides a render_child callback with a MouseState and paints a mouse /// region under (or above) it for easy mouse event handling. impl MouseEventHandler { - pub fn new(region_id: usize, view: &mut V, cx: &mut ViewContext, render_child: F) -> Self + pub fn new(region_id: usize, cx: &mut ViewContext, render_child: F) -> Self where V: View, - F: FnOnce(&mut MouseState, &mut V, &mut ViewContext) -> ElementBox, + F: FnOnce(&mut MouseState, &mut ViewContext) -> ElementBox, { let mut mouse_state = cx.mouse_state::(region_id); - let child = render_child(&mut mouse_state, view, cx); + let child = render_child(&mut mouse_state, cx); let notify_on_hover = mouse_state.accessed_hovered(); let notify_on_click = mouse_state.accessed_clicked(); Self { @@ -57,17 +57,12 @@ impl MouseEventHandler { /// Modifies the MouseEventHandler to render the MouseRegion above the child element. Useful /// for drag and drop handling and similar events which should be captured before the child /// gets the opportunity - pub fn above( - region_id: usize, - view: &mut V, - cx: &mut ViewContext, - render_child: F, - ) -> Self + pub fn above(region_id: usize, cx: &mut ViewContext, render_child: F) -> Self where V: View, - F: FnOnce(&mut MouseState, &mut V, &mut ViewContext) -> ElementBox, + F: FnOnce(&mut MouseState, &mut ViewContext) -> ElementBox, { - let mut handler = Self::new(region_id, view, cx, render_child); + let mut handler = Self::new(region_id, cx, render_child); handler.above = true; handler } @@ -82,14 +77,17 @@ impl MouseEventHandler { self } - pub fn on_move(mut self, handler: impl Fn(MouseMove, &mut ViewContext) + 'static) -> Self { + pub fn on_move( + mut self, + handler: impl Fn(MouseMove, &mut V, &mut EventContext) + 'static, + ) -> Self { self.handlers = self.handlers.on_move(handler); self } pub fn on_move_out( mut self, - handler: impl Fn(MouseMoveOut, &mut ViewContext) + 'static, + handler: impl Fn(MouseMoveOut, &mut V, &mut EventContext) + 'static, ) -> Self { self.handlers = self.handlers.on_move_out(handler); self @@ -98,7 +96,7 @@ impl MouseEventHandler { pub fn on_down( mut self, button: MouseButton, - handler: impl Fn(MouseDown, &mut ViewContext) + 'static, + handler: impl Fn(MouseDown, &mut V, &mut EventContext) + 'static, ) -> Self { self.handlers = self.handlers.on_down(button, handler); self @@ -107,7 +105,7 @@ impl MouseEventHandler { pub fn on_up( mut self, button: MouseButton, - handler: impl Fn(MouseUp, &mut ViewContext) + 'static, + handler: impl Fn(MouseUp, &mut V, &mut EventContext) + 'static, ) -> Self { self.handlers = self.handlers.on_up(button, handler); self @@ -116,7 +114,7 @@ impl MouseEventHandler { pub fn on_click( mut self, button: MouseButton, - handler: impl Fn(MouseClick, &mut ViewContext) + 'static, + handler: impl Fn(MouseClick, &mut V, &mut EventContext) + 'static, ) -> Self { self.handlers = self.handlers.on_click(button, handler); self @@ -125,7 +123,7 @@ impl MouseEventHandler { pub fn on_down_out( mut self, button: MouseButton, - handler: impl Fn(MouseDownOut, &mut ViewContext) + 'static, + handler: impl Fn(MouseDownOut, &mut V, &mut EventContext) + 'static, ) -> Self { self.handlers = self.handlers.on_down_out(button, handler); self @@ -134,7 +132,7 @@ impl MouseEventHandler { pub fn on_up_out( mut self, button: MouseButton, - handler: impl Fn(MouseUpOut, &mut ViewContext) + 'static, + handler: impl Fn(MouseUpOut, &mut V, &mut EventContext) + 'static, ) -> Self { self.handlers = self.handlers.on_up_out(button, handler); self @@ -143,20 +141,23 @@ impl MouseEventHandler { pub fn on_drag( mut self, button: MouseButton, - handler: impl Fn(MouseDrag, &mut ViewContext) + 'static, + handler: impl Fn(MouseDrag, &mut V, &mut EventContext) + 'static, ) -> Self { self.handlers = self.handlers.on_drag(button, handler); self } - pub fn on_hover(mut self, handler: impl Fn(MouseHover, &mut ViewContext) + 'static) -> Self { + pub fn on_hover( + mut self, + handler: impl Fn(MouseHover, &mut V, &mut EventContext) + 'static, + ) -> Self { self.handlers = self.handlers.on_hover(handler); self } pub fn on_scroll( mut self, - handler: impl Fn(MouseScrollWheel, &mut ViewContext) + 'static, + handler: impl Fn(MouseScrollWheel, &mut V, &mut EventContext) + 'static, ) -> Self { self.handlers = self.handlers.on_scroll(handler); self @@ -191,14 +192,14 @@ impl MouseEventHandler { let hit_bounds = self.hit_bounds(visible_bounds); if let Some(style) = self.cursor_style { - cx.scene.push_cursor_region(CursorRegion { + scene.push_cursor_region(CursorRegion { bounds: hit_bounds, style, }); } - cx.scene.push_mouse_region( + scene.push_mouse_region( MouseRegion::from_handlers::( - cx.current_view_id(), + cx.view_id(), self.region_id, hit_bounds, self.handlers.clone(), @@ -236,7 +237,7 @@ impl Element for MouseEventHandler { self.child .paint(scene, bounds.origin(), visible_bounds, view, cx); - cx.paint_layer(None, |cx| { + scene.paint_layer(None, |scene| { self.paint_regions(scene, bounds, visible_bounds, cx); }); } else { @@ -254,7 +255,7 @@ impl Element for MouseEventHandler { _: &Self::LayoutState, _: &Self::PaintState, view: &V, - cx: &ViewContext, + cx: &ViewContext, ) -> Option { self.child.rect_for_text_range(range_utf16, view, cx) } diff --git a/crates/gpui/src/elements/overlay.rs b/crates/gpui/src/elements/overlay.rs index a95667934b..7d9acfc3c5 100644 --- a/crates/gpui/src/elements/overlay.rs +++ b/crates/gpui/src/elements/overlay.rs @@ -127,7 +127,7 @@ impl Element for Overlay { cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let constraint = if self.anchor_position.is_some() { - SizeConstraint::new(Vector2F::zero(), cx.window_size) + SizeConstraint::new(Vector2F::zero(), cx.window_size()) } else { constraint }; @@ -137,7 +137,7 @@ impl Element for Overlay { fn paint( &mut self, - scene: SceneBuilder, + scene: &mut SceneBuilder, bounds: RectF, _: RectF, size: &mut Self::LayoutState, @@ -163,9 +163,9 @@ impl Element for Overlay { OverlayFitMode::SnapToWindow => { // Snap the horizontal edges of the overlay to the horizontal edges of the window if // its horizontal bounds overflow - if bounds.max_x() > cx.window_size.x() { + if bounds.max_x() > cx.window_size().x() { let mut lower_right = bounds.lower_right(); - lower_right.set_x(cx.window_size.x()); + lower_right.set_x(cx.window_size().x()); bounds = RectF::from_points(lower_right - *size, lower_right); } else if bounds.min_x() < 0. { let mut upper_left = bounds.origin(); @@ -175,9 +175,9 @@ impl Element for Overlay { // Snap the vertical edges of the overlay to the vertical edges of the window if // its vertical bounds overflow. - if bounds.max_y() > cx.window_size.y() { + if bounds.max_y() > cx.window_size().y() { let mut lower_right = bounds.lower_right(); - lower_right.set_y(cx.window_size.y()); + lower_right.set_y(cx.window_size().y()); bounds = RectF::from_points(lower_right - *size, lower_right); } else if bounds.min_y() < 0. { let mut upper_left = bounds.origin(); @@ -188,11 +188,11 @@ impl Element for Overlay { OverlayFitMode::SwitchAnchor => { let mut anchor_corner = self.anchor_corner; - if bounds.max_x() > cx.window_size.x() { + if bounds.max_x() > cx.window_size().x() { anchor_corner = anchor_corner.switch_axis(Axis::Horizontal); } - if bounds.max_y() > cx.window_size.y() { + if bounds.max_y() > cx.window_size().y() { anchor_corner = anchor_corner.switch_axis(Axis::Vertical); } @@ -212,22 +212,21 @@ impl Element for Overlay { OverlayFitMode::None => {} } - cx.paint_stacking_context(None, self.z_index, |cx| { + scene.paint_stacking_context(None, self.z_index, |scene| { if self.hoverable { enum OverlayHoverCapture {} // Block hovers in lower stacking contexts - cx.scene - .push_mouse_region(MouseRegion::new::( - cx.current_view_id(), - cx.current_view_id(), - bounds, - )); + scene.push_mouse_region(MouseRegion::new::( + cx.view_id(), + cx.view_id(), + bounds, + )); } self.child.paint( scene, bounds.origin(), - RectF::new(Vector2F::zero(), cx.window_size), + RectF::new(Vector2F::zero(), cx.window_size()), view, cx, ); diff --git a/crates/gpui/src/elements/resizable.rs b/crates/gpui/src/elements/resizable.rs index 33f885bf9b..cdbcedeea1 100644 --- a/crates/gpui/src/elements/resizable.rs +++ b/crates/gpui/src/elements/resizable.rs @@ -154,32 +154,28 @@ impl Element for Resizable { view: &mut V, cx: &mut ViewContext, ) -> Self::PaintState { - cx.scene.push_stacking_context(None, None); + scene.push_stacking_context(None, None); let handle_region = self.side.of_rect(bounds, self.handle_size); enum ResizeHandle {} - cx.scene.push_mouse_region( - MouseRegion::new::( - cx.current_view_id(), - self.side as usize, - handle_region, - ) - .on_down(MouseButton::Left, |_, _| {}) // This prevents the mouse down event from being propagated elsewhere - .on_drag(MouseButton::Left, { - let state = self.state.clone(); - let side = self.side; - move |e, cx| { - let prev_width = state.actual_dimension.get(); - state - .custom_dimension - .set(0f32.max(prev_width + side.compute_delta(e)).round()); - cx.notify(); - } - }), + scene.push_mouse_region( + MouseRegion::new::(cx.view_id(), self.side as usize, handle_region) + .on_down(MouseButton::Left, |_, _: &mut V, _| {}) // This prevents the mouse down event from being propagated elsewhere + .on_drag(MouseButton::Left, { + let state = self.state.clone(); + let side = self.side; + move |e, _: &mut V, cx| { + let prev_width = state.actual_dimension.get(); + state + .custom_dimension + .set(0f32.max(prev_width + side.compute_delta(e)).round()); + cx.notify(); + } + }), ); - cx.scene.push_cursor_region(crate::CursorRegion { + scene.push_cursor_region(crate::CursorRegion { bounds: handle_region, style: match self.side.axis() { Axis::Horizontal => CursorStyle::ResizeLeftRight, @@ -187,7 +183,7 @@ impl Element for Resizable { }, }); - cx.scene.pop_stacking_context(); + scene.pop_stacking_context(); self.child .paint(scene, bounds.origin(), visible_bounds, view, cx); diff --git a/crates/gpui/src/elements/stack.rs b/crates/gpui/src/elements/stack.rs index 175c5182a7..2de7d1433b 100644 --- a/crates/gpui/src/elements/stack.rs +++ b/crates/gpui/src/elements/stack.rs @@ -8,11 +8,18 @@ use crate::{ /// Element which renders it's children in a stack on top of each other. /// The first child determines the size of the others. -#[derive(Default)] pub struct Stack { children: Vec>, } +impl Default for Stack { + fn default() -> Self { + Self { + children: Vec::new(), + } + } +} + impl Stack { pub fn new() -> Self { Self::default() @@ -53,7 +60,7 @@ impl Element for Stack { cx: &mut ViewContext, ) -> Self::PaintState { for child in &mut self.children { - cx.paint_layer(None, |cx| { + scene.paint_layer(None, |scene| { child.paint(scene, bounds.origin(), visible_bounds, view, cx); }); } diff --git a/crates/gpui/src/elements/svg.rs b/crates/gpui/src/elements/svg.rs index ace6af7ffa..0f75be82fd 100644 --- a/crates/gpui/src/elements/svg.rs +++ b/crates/gpui/src/elements/svg.rs @@ -37,7 +37,7 @@ impl Element for Svg { fn layout( &mut self, constraint: SizeConstraint, - view: &mut V, + _: &mut V, cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { match cx.asset_cache.svg(&self.path) { diff --git a/crates/gpui/src/elements/text.rs b/crates/gpui/src/elements/text.rs index 6a6a217aee..927bc3df02 100644 --- a/crates/gpui/src/elements/text.rs +++ b/crates/gpui/src/elements/text.rs @@ -98,7 +98,7 @@ impl Element for Text { let shaped_lines = layout_highlighted_chunks( chunks, &self.style, - cx.text_layout_cache, + cx.text_layout_cache(), &cx.font_cache, usize::MAX, self.text.matches('\n').count() + 1, @@ -213,9 +213,9 @@ impl Element for Text { /// Perform text layout on a series of highlighted chunks of text. pub fn layout_highlighted_chunks<'a>( chunks: impl Iterator)>, - text_style: &'a TextStyle, - text_layout_cache: &'a TextLayoutCache, - font_cache: &'a Arc, + text_style: &TextStyle, + text_layout_cache: &TextLayoutCache, + font_cache: &Arc, max_line_len: usize, max_line_count: usize, ) -> Vec { @@ -276,26 +276,22 @@ pub fn layout_highlighted_chunks<'a>( #[cfg(test)] mod tests { use super::*; - use crate::{ - elements::Empty, fonts, platform, AppContext, ElementBox, Entity, View, ViewContext, - }; + use crate::{elements::Empty, fonts, AppContext, ElementBox, Entity, View, ViewContext}; #[crate::test(self)] fn test_soft_wrapping_with_carriage_returns(cx: &mut AppContext) { let (window_id, root_view) = cx.add_window(Default::default(), |_| TestView); - let mut presenter = cx.build_window( - window_id, - root_view.into_any(), - Box::new(platform::test::Window::new(Vector2F::new(800., 600.))), - ); fonts::with_font_cache(cx.font_cache().clone(), || { - let mut text = Text::new("Hello\r\n", Default::default()).with_soft_wrap(true); - let (_, state) = text.layout( - SizeConstraint::new(Default::default(), vec2f(f32::INFINITY, f32::INFINITY)), - &mut presenter.build_layout_context(Default::default(), false, cx), - ); - assert_eq!(state.shaped_lines.len(), 2); - assert_eq!(state.wrap_boundaries.len(), 2); + root_view.update(cx, |view, cx| { + let mut text = Text::new("Hello\r\n", Default::default()).with_soft_wrap(true); + let (_, state) = text.layout( + SizeConstraint::new(Default::default(), vec2f(f32::INFINITY, f32::INFINITY)), + view, + cx, + ); + assert_eq!(state.shaped_lines.len(), 2); + assert_eq!(state.wrap_boundaries.len(), 2); + }); }); } diff --git a/crates/gpui/src/elements/tooltip.rs b/crates/gpui/src/elements/tooltip.rs index 39a2a61288..2dff3fd4f9 100644 --- a/crates/gpui/src/elements/tooltip.rs +++ b/crates/gpui/src/elements/tooltip.rs @@ -55,7 +55,6 @@ impl Tooltip { action: Option>, style: TooltipStyle, child: ElementBox, - view: &mut V, cx: &mut ViewContext, ) -> Self { struct ElementState(Tag); @@ -78,10 +77,10 @@ impl Tooltip { Overlay::new( Self::render_tooltip(cx.window_id, focused_view_id, text, style, action, false) .constrained() - .dynamically(move |constraint, cx| { + .dynamically(move |constraint, view, cx| { SizeConstraint::strict_along( Axis::Vertical, - collapsed_tooltip.layout(constraint, cx).y(), + collapsed_tooltip.layout(constraint, view, cx).y(), ) }) .boxed(), @@ -93,36 +92,34 @@ impl Tooltip { } else { None }; - let child = - MouseEventHandler::>::new(id, view, cx, |_, _| child) - .on_hover(move |e, cx| { - let position = e.position; - let window_id = cx.window_id(); - if let Some(view_id) = cx.view_id() { - if e.started { - if !state.visible.get() { - state.position.set(position); + let child = MouseEventHandler::, _>::new(id, cx, |_, _| child) + .on_hover(move |e, _, cx| { + let position = e.position; + let window_id = cx.window_id(); + let view_id = cx.view_id(); + if e.started { + if !state.visible.get() { + state.position.set(position); - let mut debounce = state.debounce.borrow_mut(); - if debounce.is_none() { - *debounce = Some(cx.spawn({ - let state = state.clone(); - |mut cx| async move { - cx.background().timer(DEBOUNCE_TIMEOUT).await; - state.visible.set(true); - cx.update(|cx| cx.notify_view(window_id, view_id)); - } - })); + let mut debounce = state.debounce.borrow_mut(); + if debounce.is_none() { + *debounce = Some(cx.spawn({ + let state = state.clone(); + |_, mut cx| async move { + cx.background().timer(DEBOUNCE_TIMEOUT).await; + state.visible.set(true); + cx.update(|cx| cx.notify_view(window_id, view_id)); } - } - } else { - state.visible.set(false); - state.debounce.take(); - cx.notify(); + })); } } - }) - .boxed(); + } else { + state.visible.set(false); + state.debounce.take(); + cx.notify(); + } + }) + .boxed(); Self { child, tooltip, @@ -137,7 +134,7 @@ impl Tooltip { style: TooltipStyle, action: Option>, measure: bool, - ) -> impl Element { + ) -> impl Element { Flex::row() .with_child({ let text = Text::new(text, style.text) @@ -181,7 +178,7 @@ impl Element for Tooltip { let size = self.child.layout(constraint, view, cx); if let Some(tooltip) = self.tooltip.as_mut() { tooltip.layout( - SizeConstraint::new(Vector2F::zero(), cx.window_size), + SizeConstraint::new(Vector2F::zero(), cx.window_size()), view, cx, ); diff --git a/crates/gpui/src/elements/uniform_list.rs b/crates/gpui/src/elements/uniform_list.rs index d6eb4f01d1..b0c2e08125 100644 --- a/crates/gpui/src/elements/uniform_list.rs +++ b/crates/gpui/src/elements/uniform_list.rs @@ -6,7 +6,6 @@ use crate::{ }, json::{self, json}, platform::ScrollWheelEvent, - scene::MouseScrollWheel, ElementBox, MouseRegion, SceneBuilder, View, ViewContext, }; use json::ToJson; @@ -47,7 +46,7 @@ pub struct UniformList { state: UniformListState, item_count: usize, #[allow(clippy::type_complexity)] - append_items: Box, &mut Vec>, &mut V, &mut ViewContext)>, + append_items: Box, &mut Vec>, &mut ViewContext)>, padding_top: f32, padding_bottom: f32, get_width_from_item: Option, @@ -63,19 +62,12 @@ impl UniformList { ) -> Self where V: View, - F: 'static + Fn(&mut V, Range, &mut Vec>, &mut V, &mut ViewContext), + F: 'static + Fn(&mut V, Range, &mut Vec>, &mut ViewContext), { - let handle = cx.handle(); Self { state, item_count, - append_items: Box::new(move |range, items, cx| { - if let Some(handle) = handle.upgrade(cx) { - cx.render(&handle, |view, cx| { - append_items(view, range, items, cx); - }); - } - }), + append_items: Box::new(append_items), padding_top: 0., padding_bottom: 0., get_width_from_item: None, @@ -194,18 +186,18 @@ impl Element for UniformList { let sample_item_ix; let sample_item; if let Some(sample_ix) = self.get_width_from_item { - (self.append_items)(sample_ix..sample_ix + 1, &mut items, cx); + (self.append_items)(view, sample_ix..sample_ix + 1, &mut items, cx); sample_item_ix = sample_ix; if let Some(mut item) = items.pop() { - item_size = item.layout(constraint, cx); + item_size = item.layout(constraint, view, cx); size.set_x(item_size.x()); sample_item = item; } else { return no_items; } } else { - (self.append_items)(0..1, &mut items, cx); + (self.append_items)(view, 0..1, &mut items, cx); sample_item_ix = 0; if let Some(mut item) = items.pop() { item_size = item.layout( @@ -213,6 +205,7 @@ impl Element for UniformList { vec2f(constraint.max.x(), 0.0), vec2f(constraint.max.x(), f32::INFINITY), ), + view, cx, ); item_size.set_x(size.x()); @@ -249,16 +242,16 @@ impl Element for UniformList { if (start..end).contains(&sample_item_ix) { if sample_item_ix > start { - (self.append_items)(start..sample_item_ix, &mut items, cx); + (self.append_items)(view, start..sample_item_ix, &mut items, cx); } items.push(sample_item); if sample_item_ix < end { - (self.append_items)(sample_item_ix + 1..end, &mut items, cx); + (self.append_items)(view, sample_item_ix + 1..end, &mut items, cx); } } else { - (self.append_items)(start..end, &mut items, cx); + (self.append_items)(view, start..end, &mut items, cx); } for item in &mut items { @@ -289,20 +282,16 @@ impl Element for UniformList { ) -> Self::PaintState { let visible_bounds = visible_bounds.intersection(bounds).unwrap_or_default(); - cx.scene.push_layer(Some(visible_bounds)); + scene.push_layer(Some(visible_bounds)); - cx.scene.push_mouse_region( + scene.push_mouse_region( MouseRegion::new::(self.view_id, 0, visible_bounds).on_scroll({ let scroll_max = layout.scroll_max; let state = self.state.clone(); - move |MouseScrollWheel { - platform_event: - ScrollWheelEvent { - position, delta, .. - }, - .. - }, - cx| { + move |event, _, cx| { + let ScrollWheelEvent { + position, delta, .. + } = event.platform_event; if !Self::scroll( state.clone(), position, @@ -328,7 +317,7 @@ impl Element for UniformList { item_origin += vec2f(0.0, layout.item_height); } - cx.scene.pop_layer(); + scene.pop_layer(); } fn rect_for_text_range( diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 90a4357c5e..235b9c4288 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -15,7 +15,9 @@ pub use clipboard::ClipboardItem; pub mod fonts; pub mod geometry; pub mod scene; -pub use scene::{Border, CursorRegion, MouseRegion, MouseRegionId, Quad, Scene, SceneBuilder}; +pub use scene::{ + Border, CursorRegion, EventContext, MouseRegion, MouseRegionId, Quad, Scene, SceneBuilder, +}; pub mod text_layout; pub use text_layout::TextLayoutCache; mod util; diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index 032087c95a..96edee1757 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -236,6 +236,19 @@ impl SceneBuilder { self.scale_factor } + pub fn paint_stacking_context( + &mut self, + clip_bounds: Option, + z_index: Option, + f: F, + ) where + F: FnOnce(&mut Self), + { + self.push_stacking_context(clip_bounds, z_index); + f(self); + self.pop_stacking_context(); + } + pub fn push_stacking_context(&mut self, clip_bounds: Option, z_index: Option) { let z_index = z_index.unwrap_or_else(|| self.active_stacking_context().z_index + 1); self.active_stacking_context_stack @@ -249,6 +262,15 @@ impl SceneBuilder { assert!(!self.active_stacking_context_stack.is_empty()); } + pub fn paint_layer(&mut self, clip_bounds: Option, f: F) + where + F: FnOnce(&mut Self), + { + self.push_layer(clip_bounds); + f(self); + self.pop_layer(); + } + pub fn push_layer(&mut self, clip_bounds: Option) { self.active_stacking_context().push_layer(clip_bounds); } diff --git a/crates/gpui/src/scene/mouse_region.rs b/crates/gpui/src/scene/mouse_region.rs index ac945af38a..b3c05c4280 100644 --- a/crates/gpui/src/scene/mouse_region.rs +++ b/crates/gpui/src/scene/mouse_region.rs @@ -1,4 +1,10 @@ -use std::{any::TypeId, fmt::Debug, mem::Discriminant, rc::Rc}; +use std::{ + any::{Any, TypeId}, + fmt::Debug, + mem::Discriminant, + ops::{Deref, DerefMut}, + rc::Rc, +}; use collections::HashMap; @@ -63,7 +69,7 @@ impl MouseRegion { pub fn on_down(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseDown, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseDown, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_down(button, handler); self @@ -72,7 +78,7 @@ impl MouseRegion { pub fn on_up(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseUp, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseUp, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_up(button, handler); self @@ -81,7 +87,7 @@ impl MouseRegion { pub fn on_click(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseClick, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseClick, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_click(button, handler); self @@ -90,7 +96,7 @@ impl MouseRegion { pub fn on_down_out(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseDownOut, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseDownOut, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_down_out(button, handler); self @@ -99,7 +105,7 @@ impl MouseRegion { pub fn on_up_out(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseUpOut, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseUpOut, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_up_out(button, handler); self @@ -108,7 +114,7 @@ impl MouseRegion { pub fn on_drag(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseDrag, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseDrag, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_drag(button, handler); self @@ -117,7 +123,7 @@ impl MouseRegion { pub fn on_hover(mut self, handler: F) -> Self where V: View, - F: Fn(&mut V, &mut ViewContext) + 'static, + F: Fn(MouseHover, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_hover(handler); self @@ -126,7 +132,7 @@ impl MouseRegion { pub fn on_move(mut self, handler: F) -> Self where V: View, - F: Fn(&mut V, &mut ViewContext) + 'static, + F: Fn(MouseMove, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_move(handler); self @@ -135,7 +141,7 @@ impl MouseRegion { pub fn on_move_out(mut self, handler: F) -> Self where V: View, - F: Fn(&mut V, &mut ViewContext) + 'static, + F: Fn(MouseMoveOut, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_move_out(handler); self @@ -144,7 +150,7 @@ impl MouseRegion { pub fn on_scroll(mut self, handler: F) -> Self where V: View, - F: Fn(&mut V, &mut ViewContext) + 'static, + F: Fn(MouseScrollWheel, &mut V, &mut EventContext) + 'static, { self.handlers = self.handlers.on_scroll(handler); self @@ -196,7 +202,39 @@ impl MouseRegionId { } } -pub type HandlerCallback = Rc; +pub struct EventContext<'a, 'b, 'c, 'd, V: View> { + view_context: &'d mut ViewContext<'a, 'b, 'c, V>, + handled: bool, +} + +impl<'a, 'b, 'c, 'd, V: View> EventContext<'a, 'b, 'c, 'd, V> { + fn new(view_context: &'d mut ViewContext<'a, 'b, 'c, V>) -> Self { + EventContext { + view_context, + handled: true, + } + } + + pub fn propagate_event(&mut self) { + self.handled = false; + } +} + +impl<'a, 'b, 'c, 'd, V: View> Deref for EventContext<'a, 'b, 'c, 'd, V> { + type Target = ViewContext<'a, 'b, 'c, V>; + + fn deref(&self) -> &Self::Target { + &self.view_context + } +} + +impl DerefMut for EventContext<'_, '_, '_, '_, V> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.view_context + } +} + +pub type HandlerCallback = Rc bool>; #[derive(Clone, PartialEq, Eq, Hash)] pub struct HandlerKey { @@ -221,41 +259,41 @@ impl HandlerSet { set.insert( HandlerKey::new(MouseEvent::move_disc(), None), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); set.insert( HandlerKey::new(MouseEvent::hover_disc(), None), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); for button in MouseButton::all() { set.insert( HandlerKey::new(MouseEvent::drag_disc(), Some(button)), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); set.insert( HandlerKey::new(MouseEvent::down_disc(), Some(button)), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); set.insert( HandlerKey::new(MouseEvent::up_disc(), Some(button)), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); set.insert( HandlerKey::new(MouseEvent::click_disc(), Some(button)), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); set.insert( HandlerKey::new(MouseEvent::down_out_disc(), Some(button)), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); set.insert( HandlerKey::new(MouseEvent::up_out_disc(), Some(button)), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); } set.insert( HandlerKey::new(MouseEvent::scroll_wheel_disc(), None), - SmallVec::from_buf([Rc::new(|_, _| {})]), + SmallVec::from_buf([Rc::new(|_, _, _, _| false)]), ); HandlerSet { set } @@ -296,12 +334,16 @@ impl HandlerSet { pub fn on_move(mut self, handler: F) -> Self where V: View, - F: Fn(MouseMove, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseMove, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::move_disc(), None, - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::Move(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Move, found {:?}", @@ -314,12 +356,16 @@ impl HandlerSet { pub fn on_move_out(mut self, handler: F) -> Self where V: View, - F: Fn(MouseMoveOut, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseMoveOut, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::move_out_disc(), None, - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::MoveOut(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::MoveOut, found {:?}", @@ -332,12 +378,16 @@ impl HandlerSet { pub fn on_down(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseDown, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseDown, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::down_disc(), Some(button), - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::Down(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Down, found {:?}", @@ -350,12 +400,16 @@ impl HandlerSet { pub fn on_up(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseUp, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseUp, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::up_disc(), Some(button), - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::Up(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Up, found {:?}", @@ -368,12 +422,16 @@ impl HandlerSet { pub fn on_click(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseClick, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseClick, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::click_disc(), Some(button), - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::Click(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Click, found {:?}", @@ -386,12 +444,16 @@ impl HandlerSet { pub fn on_down_out(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseDownOut, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseDownOut, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::down_out_disc(), Some(button), - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::DownOut(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::DownOut, found {:?}", @@ -404,12 +466,16 @@ impl HandlerSet { pub fn on_up_out(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseUpOut, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseUpOut, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::up_out_disc(), Some(button), - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::UpOut(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::UpOut, found {:?}", @@ -422,12 +488,16 @@ impl HandlerSet { pub fn on_drag(mut self, button: MouseButton, handler: F) -> Self where V: View, - F: Fn(MouseDrag, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseDrag, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::drag_disc(), Some(button), - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::Drag(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Drag, found {:?}", @@ -440,12 +510,16 @@ impl HandlerSet { pub fn on_hover(mut self, handler: F) -> Self where V: View, - F: Fn(MouseHover, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseHover, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::hover_disc(), None, - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::Hover(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Hover, found {:?}", @@ -458,12 +532,16 @@ impl HandlerSet { pub fn on_scroll(mut self, handler: F) -> Self where V: View, - F: Fn(MouseScrollWheel, &mut V, &mut ViewContext) + 'static, + F: Fn(MouseScrollWheel, &mut V, &mut EventContext) + 'static, { self.insert(MouseEvent::scroll_wheel_disc(), None, - Rc::new(move |region_event, cx| { + Rc::new(move |region_event, view, cx, view_id| { if let MouseEvent::ScrollWheel(e) = region_event { - handler(e, cx); + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled } else { panic!( "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::ScrollWheel, found {:?}", diff --git a/crates/gpui/src/text_layout.rs b/crates/gpui/src/text_layout.rs index 8f1b9190a8..e665859319 100644 --- a/crates/gpui/src/text_layout.rs +++ b/crates/gpui/src/text_layout.rs @@ -273,7 +273,7 @@ impl Line { pub fn paint( &self, - scene: &SceneBuilder, + scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, line_height: f32, @@ -334,7 +334,7 @@ impl Line { } if let Some((underline_origin, underline_style)) = finished_underline { - cx.scene.push_underline(scene::Underline { + scene.push_underline(scene::Underline { origin: underline_origin, width: glyph_origin.x() - underline_origin.x(), thickness: underline_style.thickness.into(), @@ -344,14 +344,14 @@ impl Line { } if glyph.is_emoji { - cx.scene.push_image_glyph(scene::ImageGlyph { + scene.push_image_glyph(scene::ImageGlyph { font_id: run.font_id, font_size: self.layout.font_size, id: glyph.id, origin: glyph_origin, }); } else { - cx.scene.push_glyph(scene::Glyph { + scene.push_glyph(scene::Glyph { font_id: run.font_id, font_size: self.layout.font_size, id: glyph.id, @@ -364,7 +364,7 @@ impl Line { if let Some((underline_start, underline_style)) = underline.take() { let line_end_x = origin.x() + self.layout.width; - cx.scene.push_underline(scene::Underline { + scene.push_underline(scene::Underline { origin: underline_start, width: line_end_x - underline_start.x(), color: underline_style.color.unwrap(), @@ -376,7 +376,7 @@ impl Line { pub fn paint_wrapped( &self, - scene: &SceneBuilder, + scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, line_height: f32, diff --git a/crates/gpui/src/views/select.rs b/crates/gpui/src/views/select.rs index 1bfaba4c3b..dba1b8023b 100644 --- a/crates/gpui/src/views/select.rs +++ b/crates/gpui/src/views/select.rs @@ -106,22 +106,17 @@ impl View for Select { Default::default() }; let mut result = Flex::column().with_child( - MouseEventHandler::
::new( - self.handle.id(), - self, - cx, - |mouse_state, this, cx| { - Container::new((self.render_item)( - self.selected_item_ix, - ItemType::Header, - mouse_state.hovered(), - cx, - )) - .with_style(style.header) - .boxed() - }, - ) - .on_click(MouseButton::Left, move |_, cx| { + MouseEventHandler::::new(self.handle.id(), cx, |mouse_state, cx| { + Container::new((self.render_item)( + self.selected_item_ix, + ItemType::Header, + mouse_state.hovered(), + cx, + )) + .with_style(style.header) + .boxed() + }) + .on_click(MouseButton::Left, move |_, _, cx| { cx.dispatch_action(ToggleSelect) }) .boxed(), @@ -139,11 +134,10 @@ impl View for Select { let selected_item_ix = this.selected_item_ix; range.end = range.end.min(this.item_count); items.extend(range.map(|ix| { - MouseEventHandler::::new( + MouseEventHandler::::new( ix, - self, cx, - |mouse_state, this, cx| { + |mouse_state, cx| { (this.render_item)( ix, if ix == selected_item_ix { @@ -156,7 +150,7 @@ impl View for Select { ) }, ) - .on_click(MouseButton::Left, move |_, cx| { + .on_click(MouseButton::Left, move |_, _, cx| { cx.dispatch_action(SelectItem(ix)) }) .boxed() diff --git a/crates/language_selector/src/active_buffer_language.rs b/crates/language_selector/src/active_buffer_language.rs index 1beccdca7a..87499664ae 100644 --- a/crates/language_selector/src/active_buffer_language.rs +++ b/crates/language_selector/src/active_buffer_language.rs @@ -2,7 +2,7 @@ use editor::Editor; use gpui::{ elements::*, platform::{CursorStyle, MouseButton}, - Entity, RenderContext, Subscription, View, ViewContext, ViewHandle, + Entity, Subscription, View, ViewContext, ViewHandle, }; use settings::Settings; use std::sync::Arc; @@ -50,7 +50,7 @@ impl View for ActiveBufferLanguage { "ActiveBufferLanguage" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { if let Some(active_language) = self.active_language.as_ref() { let active_language_text = if let Some(active_language_text) = active_language { active_language_text.to_string() diff --git a/crates/language_selector/src/language_selector.rs b/crates/language_selector/src/language_selector.rs index b281d621ba..3269fafed0 100644 --- a/crates/language_selector/src/language_selector.rs +++ b/crates/language_selector/src/language_selector.rs @@ -4,8 +4,8 @@ pub use active_buffer_language::ActiveBufferLanguage; use editor::Editor; use fuzzy::{match_strings, StringMatch, StringMatchCandidate}; use gpui::{ - actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, - RenderContext, View, ViewContext, ViewHandle, + actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, View, + ViewContext, ViewHandle, }; use language::{Buffer, LanguageRegistry}; use picker::{Picker, PickerDelegate}; @@ -120,7 +120,7 @@ impl View for LanguageSelector { "LanguageSelector" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 2259570fa0..c7167b0eb4 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -5,7 +5,7 @@ use editor::{ use fuzzy::StringMatch; use gpui::{ actions, elements::*, geometry::vector::Vector2F, AnyViewHandle, AppContext, Entity, - MouseState, RenderContext, Task, View, ViewContext, ViewHandle, + MouseState, Task, View, ViewContext, ViewHandle, }; use language::Outline; use ordered_float::OrderedFloat; @@ -48,7 +48,7 @@ impl View for OutlineView { "OutlineView" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/picker/src/picker.rs b/crates/picker/src/picker.rs index b17e61eddd..a5434359bc 100644 --- a/crates/picker/src/picker.rs +++ b/crates/picker/src/picker.rs @@ -4,8 +4,8 @@ use gpui::{ geometry::vector::{vec2f, Vector2F}, keymap_matcher::KeymapContext, platform::{CursorStyle, MouseButton}, - AnyViewHandle, AppContext, Axis, Entity, MouseState, RenderContext, Task, View, ViewContext, - ViewHandle, WeakViewHandle, + AnyViewHandle, AppContext, Axis, Entity, MouseState, Task, View, ViewContext, ViewHandle, + WeakViewHandle, }; use menu::{Cancel, Confirm, SelectFirst, SelectIndex, SelectLast, SelectNext, SelectPrev}; use parking_lot::Mutex; @@ -48,7 +48,7 @@ impl View for Picker { "Picker" } - fn render(&mut self, cx: &mut RenderContext) -> gpui::ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> gpui::ElementBox { let theme = (self.theme.lock())(&cx.global::().theme); let query = self.query(cx); let delegate = self.delegate.clone(); diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index ffe9ba065b..3128ec0d78 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -13,8 +13,8 @@ use gpui::{ impl_internal_actions, keymap_matcher::KeymapContext, platform::{CursorStyle, MouseButton, PromptLevel}, - AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, RenderContext, Task, View, - ViewContext, ViewHandle, + AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, Task, View, ViewContext, + ViewHandle, }; use menu::{Confirm, SelectNext, SelectPrev}; use project::{Entry, EntryKind, Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId}; @@ -1015,8 +1015,8 @@ impl ProjectPanel { fn for_each_visible_entry( &self, range: Range, - cx: &mut RenderContext, - mut callback: impl FnMut(ProjectEntryId, EntryDetails, &mut RenderContext), + cx: &mut ViewContext, + mut callback: impl FnMut(ProjectEntryId, EntryDetails, &mut ViewContext), ) { let mut ix = 0; for (worktree_id, visible_worktree_entries) in &self.visible_entries { @@ -1097,7 +1097,7 @@ impl ProjectPanel { padding: f32, row_container_style: ContainerStyle, style: &ProjectPanelEntry, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let kind = details.kind; let show_editor = details.is_editing && !details.is_processing; @@ -1154,7 +1154,7 @@ impl ProjectPanel { editor: &ViewHandle, dragged_entry_destination: &mut Option>, theme: &theme::ProjectPanel, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let this = cx.handle(); let kind = details.kind; @@ -1251,7 +1251,7 @@ impl ProjectPanel { .as_draggable(entry_id, { let row_container_style = theme.dragged_entry.container; - move |_, cx: &mut RenderContext| { + move |_, cx: &mut ViewContext| { let theme = cx.global::().theme.clone(); Self::render_entry_visual_element( &details, @@ -1273,7 +1273,7 @@ impl View for ProjectPanel { "ProjectPanel" } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> gpui::ElementBox { enum ProjectPanel {} let theme = &cx.global::().theme.project_panel; let mut container_style = theme.container; diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index a2e8012b89..3586ff7726 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -4,8 +4,8 @@ use editor::{ }; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ - actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, - RenderContext, Task, View, ViewContext, ViewHandle, + actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, Task, View, + ViewContext, ViewHandle, }; use ordered_float::OrderedFloat; use picker::{Picker, PickerDelegate}; @@ -48,7 +48,7 @@ impl View for ProjectSymbolsView { "ProjectSymbolsView" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index 58369f4aa5..ed45b778dd 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -4,8 +4,7 @@ use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ actions, elements::{ChildView, Flex, ParentElement}, - AnyViewHandle, AppContext, Element, ElementBox, Entity, RenderContext, Task, View, ViewContext, - ViewHandle, + AnyViewHandle, AppContext, Element, ElementBox, Entity, Task, View, ViewContext, ViewHandle, }; use highlighted_workspace_location::HighlightedWorkspaceLocation; use ordered_float::OrderedFloat; @@ -102,7 +101,7 @@ impl View for RecentProjectsView { "RecentProjectsView" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index c0445ca9c1..ffef25872e 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -9,8 +9,7 @@ use gpui::{ elements::*, impl_actions, platform::{CursorStyle, MouseButton}, - Action, AnyViewHandle, AppContext, Entity, RenderContext, Subscription, Task, View, - ViewContext, ViewHandle, + Action, AnyViewHandle, AppContext, Entity, Subscription, Task, View, ViewContext, ViewHandle, }; use project::search::SearchQuery; use serde::Deserialize; @@ -92,7 +91,7 @@ impl View for BufferSearchBar { } } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = cx.global::().theme.clone(); let editor_container = if self.query_contains_error { theme.search.invalid_editor @@ -324,7 +323,7 @@ impl BufferSearchBar { option_supported: bool, icon: &'static str, option: SearchOption, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Option { if !option_supported { return None; @@ -364,7 +363,7 @@ impl BufferSearchBar { &self, icon: &'static str, direction: Direction, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let action: Box; let tooltip; @@ -408,11 +407,7 @@ impl BufferSearchBar { .boxed() } - fn render_close_button( - &self, - theme: &theme::Search, - cx: &mut RenderContext, - ) -> ElementBox { + fn render_close_button(&self, theme: &theme::Search, cx: &mut ViewContext) -> ElementBox { let action = Box::new(Dismiss); let tooltip = "Dismiss Buffer Search"; let tooltip_style = cx.global::().theme.tooltip.clone(); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index a47b1ec76d..1c8cf74125 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -12,9 +12,8 @@ use gpui::{ actions, elements::*, platform::{CursorStyle, MouseButton}, - Action, AnyViewHandle, AppContext, Entity, ModelContext, ModelHandle, RenderContext, - Subscription, Task, View, ViewContext, ElementBox, ViewHandle, WeakModelHandle, - WeakViewHandle, + Action, AnyViewHandle, AppContext, ElementBox, Entity, ModelContext, ModelHandle, Subscription, + Task, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, }; use menu::Confirm; use project::{search::SearchQuery, Project}; @@ -178,7 +177,7 @@ impl View for ProjectSearchView { "ProjectSearchView" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let model = &self.model.read(cx); if model.match_ranges.is_empty() { enum Status {} @@ -747,7 +746,7 @@ impl ProjectSearchBar { &self, icon: &'static str, direction: Direction, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let action: Box; let tooltip; @@ -795,7 +794,7 @@ impl ProjectSearchBar { &self, icon: &'static str, option: SearchOption, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let tooltip_style = cx.global::().theme.tooltip.clone(); let is_active = self.is_option_enabled(option, cx); @@ -848,7 +847,7 @@ impl View for ProjectSearchBar { "ProjectSearchBar" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { if let Some(search) = self.active_project_search.as_ref() { let search = search.read(cx); let theme = cx.global::().theme.clone(); diff --git a/crates/terminal_view/src/terminal_button.rs b/crates/terminal_view/src/terminal_button.rs index 5964b90aa9..33738ff58f 100644 --- a/crates/terminal_view/src/terminal_button.rs +++ b/crates/terminal_view/src/terminal_button.rs @@ -3,8 +3,8 @@ use gpui::{ elements::*, impl_internal_actions, platform::{CursorStyle, MouseButton}, - AppContext, Element, ElementBox, Entity, RenderContext, View, ViewContext, ViewHandle, - WeakModelHandle, WeakViewHandle, + AppContext, Element, ElementBox, Entity, View, ViewContext, ViewHandle, WeakModelHandle, + WeakViewHandle, }; use settings::Settings; use std::any::TypeId; @@ -42,14 +42,14 @@ impl View for TerminalButton { "TerminalButton" } - fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> ElementBox { let workspace = self.workspace.upgrade(cx); let project = match workspace { Some(workspace) => workspace.read(cx).project().read(cx), None => return Empty::new().boxed(), }; - let focused_view = cx.focused_view_id(cx.window_id()); + let focused_view = cx.focused_view_id(); let active = focused_view .map(|view_id| { cx.view_type_id(cx.window_id(), view_id) == Some(TypeId::of::()) diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index 252ab128be..4864e13243 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -10,8 +10,8 @@ use gpui::{ platform::{CursorStyle, MouseButton}, serde_json::json, text_layout::{Line, RunStyle}, - Element, ElementBox, EventContext, FontCache, ModelContext, MouseRegion, PaintContext, Quad, - SizeConstraint, TextLayoutCache, WeakModelHandle, WeakViewHandle, + Element, ElementBox, EventContext, FontCache, ModelContext, MouseRegion, Quad, SceneBuilder, + SizeConstraint, TextLayoutCache, ViewContext, WeakModelHandle, WeakViewHandle, }; use itertools::Itertools; use language::CursorShape; @@ -45,7 +45,7 @@ pub struct LayoutState { size: TerminalSize, mode: TermMode, display_offset: usize, - hyperlink_tooltip: Option, + hyperlink_tooltip: Option>, } ///Helper struct for converting data between alacritty's cursor points, and displayed cursor points @@ -84,10 +84,12 @@ impl LayoutCell { fn paint( &self, + scene: &mut SceneBuilder, origin: Vector2F, layout: &LayoutState, visible_bounds: RectF, - cx: &mut PaintContext, + view: &mut TerminalView, + cx: &mut ViewContext, ) { let pos = { let point = self.point; @@ -98,7 +100,7 @@ impl LayoutCell { }; self.text - .paint(pos, visible_bounds, layout.size.line_height, cx); + .paint(pos, visible_bounds, layout.size.line_height, view, cx); } } @@ -139,7 +141,7 @@ impl LayoutRect { layout.size.line_height, ); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: RectF::new(position, size), background: Some(self.color), border: Default::default(), @@ -380,7 +382,7 @@ impl TerminalElement { view_id: usize, visible_bounds: RectF, mode: TermMode, - cx: &mut PaintContext, + cx: &mut ViewContext, ) { let connection = self.terminal; @@ -501,7 +503,7 @@ impl TerminalElement { ) } - cx.scene.push_mouse_region(region); + scene.push_mouse_region(region); } ///Configures a text style from the current settings. @@ -553,7 +555,8 @@ impl Element for TerminalElement { fn layout( &mut self, constraint: gpui::SizeConstraint, - cx: &mut gpui::LayoutContext, + view: &mut TerminalView, + cx: &mut ViewContext, ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) { let settings = cx.global::(); let font_cache = cx.font_cache(); @@ -717,23 +720,24 @@ impl Element for TerminalElement { fn paint( &mut self, - bounds: gpui::geometry::rect::RectF, - visible_bounds: gpui::geometry::rect::RectF, + scene: &mut SceneBuilder, + bounds: RectF, + visible_bounds: RectF, layout: &mut Self::LayoutState, - cx: &mut gpui::PaintContext, + cx: &mut ViewContext, ) -> Self::PaintState { let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); //Setup element stuff let clip_bounds = Some(visible_bounds); - cx.paint_layer(clip_bounds, |cx| { + scene.paint_layer(clip_bounds, |scene| { let origin = bounds.origin() + vec2f(layout.size.cell_width, 0.); // Elements are ephemeral, only at paint time do we know what could be clicked by a mouse self.attach_mouse_handlers(origin, self.view.id(), visible_bounds, layout.mode, cx); - cx.scene.push_cursor_region(gpui::CursorRegion { + scene.push_cursor_region(gpui::CursorRegion { bounds, style: if layout.hyperlink_tooltip.is_some() { CursorStyle::PointingHand @@ -742,9 +746,9 @@ impl Element for TerminalElement { }, }); - cx.paint_layer(clip_bounds, |cx| { + scene.paint_layer(clip_bounds, |scene| { //Start with a background color - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: RectF::new(bounds.origin(), bounds.size()), background: Some(layout.background_color), border: Default::default(), @@ -757,7 +761,7 @@ impl Element for TerminalElement { }); //Draw Highlighted Backgrounds - cx.paint_layer(clip_bounds, |cx| { + scene.paint_layer(clip_bounds, |scene| { for (relative_highlighted_range, color) in layout.relative_highlighted_ranges.iter() { if let Some((start_y, highlighted_range_lines)) = @@ -771,29 +775,29 @@ impl Element for TerminalElement { //Copied from editor. TODO: move to theme or something corner_radius: 0.15 * layout.size.line_height, }; - hr.paint(bounds, cx.scene); + hr.paint(bounds, scene); } } }); //Draw the text cells - cx.paint_layer(clip_bounds, |cx| { + scene.paint_layer(clip_bounds, |scene| { for cell in &layout.cells { - cell.paint(origin, layout, visible_bounds, cx); + cell.paint(scene, origin, layout, visible_bounds, view, cx); } }); //Draw cursor if self.cursor_visible { if let Some(cursor) = &layout.cursor { - cx.paint_layer(clip_bounds, |cx| { - cursor.paint(origin, cx); + scene.paint_layer(clip_bounds, |scene| { + cursor.paint(scene, origin, cx); }) } } if let Some(element) = &mut layout.hyperlink_tooltip { - element.paint(origin, visible_bounds, cx) + Element::paint(element, scene, origin, visible_bounds, view, cx) } }); } @@ -804,7 +808,7 @@ impl Element for TerminalElement { fn debug( &self, - _bounds: gpui::geometry::rect::RectF, + _bounds: RectF, _layout: &Self::LayoutState, _paint: &Self::PaintState, _cx: &gpui::DebugContext, diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 3af147b9ff..6f2ec00614 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -236,11 +236,7 @@ impl TerminalView { cx.notify(); } - pub fn should_show_cursor( - &self, - focused: bool, - cx: &mut gpui::RenderContext<'_, Self>, - ) -> bool { + pub fn should_show_cursor(&self, focused: bool, cx: &mut gpui::ViewContext<'_, Self>) -> bool { //Don't blink the cursor when not focused, blinking is disabled, or paused if !focused || !self.blinking_on @@ -388,12 +384,12 @@ impl View for TerminalView { "Terminal" } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> ElementBox { let terminal_handle = self.terminal.clone().downgrade(); let self_id = cx.view_id(); let focused = cx - .focused_view_id(cx.window_id()) + .focused_view_id() .filter(|view_id| *view_id == self_id) .is_some(); diff --git a/crates/theme/src/ui.rs b/crates/theme/src/ui.rs index 1013236dfa..093b990d7b 100644 --- a/crates/theme/src/ui.rs +++ b/crates/theme/src/ui.rs @@ -11,7 +11,7 @@ use gpui::{ platform, platform::MouseButton, scene::MouseClick, - Action, Element, ElementBox, EventContext, MouseState, RenderContext, View, + Action, Element, ElementBox, EventContext, MouseState, View, ViewContext, }; use serde::Deserialize; @@ -27,13 +27,13 @@ pub struct CheckboxStyle { pub hovered_and_checked: ContainerStyle, } -pub fn checkbox( +pub fn checkbox( label: &'static str, style: &CheckboxStyle, checked: bool, - cx: &mut RenderContext, - change: fn(checked: bool, cx: &mut EventContext) -> (), -) -> MouseEventHandler { + cx: &mut ViewContext, + change: fn(checked: bool, cx: &mut EventContext) -> (), +) -> MouseEventHandler { let label = Label::new(label, style.label.text.clone()) .contained() .with_style(style.label.container) @@ -42,14 +42,14 @@ pub fn checkbox( checkbox_with_label(label, style, checked, cx, change) } -pub fn checkbox_with_label( - label: ElementBox, +pub fn checkbox_with_label( + label: ElementBox, style: &CheckboxStyle, checked: bool, - cx: &mut RenderContext, - change: fn(checked: bool, cx: &mut EventContext) -> (), -) -> MouseEventHandler { - MouseEventHandler::::new(0, cx, |state, _| { + cx: &mut ViewContext, + change: fn(checked: bool, cx: &mut EventContext) -> (), +) -> MouseEventHandler { + MouseEventHandler::new(0, cx, |state, _| { let indicator = if checked { svg(&style.icon) } else { @@ -82,7 +82,7 @@ pub fn checkbox_with_label( .align_children_center() .boxed() }) - .on_click(platform::MouseButton::Left, move |_, cx| { + .on_click(platform::MouseButton::Left, move |_, _, cx| { change(!checked, cx) }) .with_cursor_style(platform::CursorStyle::PointingHand) @@ -107,7 +107,7 @@ impl Dimensions { } } -pub fn svg(style: &SvgStyle) -> ConstrainedBox { +pub fn svg(style: &SvgStyle) -> ConstrainedBox { Svg::new(style.asset.clone()) .with_color(style.color) .constrained() @@ -121,7 +121,7 @@ pub struct IconStyle { container: ContainerStyle, } -pub fn icon(style: &IconStyle) -> Container { +pub fn icon(style: &IconStyle) -> Container { svg(&style.icon).contained().with_style(style.container) } @@ -130,8 +130,8 @@ pub fn keystroke_label( label_style: &ContainedText, keystroke_style: &ContainedText, action: Box, - cx: &mut RenderContext, -) -> Container { + cx: &mut ViewContext, +) -> Container { // FIXME: Put the theme in it's own global so we can // query the keystroke style on our own keystroke_label_for( @@ -144,14 +144,14 @@ pub fn keystroke_label( ) } -pub fn keystroke_label_for( +pub fn keystroke_label_for( window_id: usize, view_id: usize, label_text: &'static str, label_style: &ContainedText, keystroke_style: &ContainedText, action: Box, -) -> Container { +) -> Container { Flex::row() .with_child( Label::new(label_text, label_style.text.clone()) @@ -175,37 +175,39 @@ pub fn keystroke_label_for( pub type ButtonStyle = Interactive; -pub fn cta_button( +pub fn cta_button( label: L, action: A, max_width: f32, style: &ButtonStyle, - cx: &mut RenderContext, -) -> ElementBox + cx: &mut ViewContext, +) -> ElementBox where + Tag: 'static, L: Into>, A: 'static + Action + Clone, V: View, { - cta_button_with_click(label, max_width, style, cx, move |_, cx| { + cta_button_with_click::(label, max_width, style, cx, move |_, _, cx| { cx.dispatch_action(action.clone()) }) .boxed() } -pub fn cta_button_with_click( +pub fn cta_button_with_click( label: L, max_width: f32, style: &ButtonStyle, - cx: &mut RenderContext, + cx: &mut ViewContext, f: F, -) -> MouseEventHandler +) -> MouseEventHandler where + Tag: 'static, L: Into>, V: View, - F: Fn(MouseClick, &mut EventContext) + 'static, + F: Fn(MouseClick, &mut V, &mut EventContext) + 'static, { - MouseEventHandler::::new(0, cx, |state, _| { + MouseEventHandler::::new(0, cx, |state, _| { let style = style.style_for(state, false); Label::new(label, style.text.to_owned()) .aligned() @@ -234,16 +236,17 @@ impl ModalStyle { } } -pub fn modal( +pub fn modal( title: I, style: &ModalStyle, - cx: &mut RenderContext, + cx: &mut ViewContext, build_modal: F, -) -> ElementBox +) -> ElementBox where + Tag: 'static, V: View, I: Into>, - F: FnOnce(&mut gpui::RenderContext) -> ElementBox, + F: FnOnce(&mut gpui::ViewContext) -> ElementBox, { const TITLEBAR_HEIGHT: f32 = 28.; // let active = cx.window_is_active(cx.window_id()); @@ -261,11 +264,11 @@ where ) .boxed(), // FIXME: Get a better tag type - MouseEventHandler::::new(999999, cx, |state, _cx| { + MouseEventHandler::::new(999999, cx, |state, _cx| { let style = style.close_icon.style_for(state, false); icon(style).boxed() }) - .on_click(platform::MouseButton::Left, move |_, cx| { + .on_click(platform::MouseButton::Left, move |_, _, cx| { let window_id = cx.window_id(); cx.remove_window(window_id); }) diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index f2bdc130bf..7ac5b27367 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -1,7 +1,7 @@ use fuzzy::{match_strings, StringMatch, StringMatchCandidate}; use gpui::{ - actions, elements::*, AnyViewHandle, AppContext, Element, ElementBox, Entity, MouseState, - RenderContext, View, ViewContext, ViewHandle, + actions, elements::*, AnyViewHandle, AppContext, Element, ElementBox, Entity, MouseState, View, + ViewContext, ViewHandle, }; use picker::{Picker, PickerDelegate}; use settings::{settings_file::SettingsFile, Settings}; @@ -255,7 +255,7 @@ impl View for ThemeSelector { "ThemeSelector" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/theme_testbench/src/theme_testbench.rs b/crates/theme_testbench/src/theme_testbench.rs index 9707b0a453..6d5f06d65e 100644 --- a/crates/theme_testbench/src/theme_testbench.rs +++ b/crates/theme_testbench/src/theme_testbench.rs @@ -2,12 +2,12 @@ use gpui::{ actions, color::Color, elements::{ - Canvas, Container, ContainerStyle, Flex, Label, Margin, MouseEventHandler, Padding, - ParentElement, ElementBox, + Canvas, Container, ContainerStyle, ElementBox, Flex, Label, Margin, MouseEventHandler, + Padding, ParentElement, }, fonts::TextStyle, - AppContext, Border, Element, Entity, ModelHandle, Quad, RenderContext, Task, View, ViewContext, - ViewHandle, WeakViewHandle, + AppContext, Border, Element, Entity, ModelHandle, Quad, Task, View, ViewContext, ViewHandle, + WeakViewHandle, }; use project::Project; use settings::Settings; @@ -39,7 +39,7 @@ impl ThemeTestbench { Flex::row() .with_children(ramp.iter().cloned().map(|color| { Canvas::new(move |bounds, _, cx| { - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds, background: Some(color), ..Default::default() @@ -67,7 +67,7 @@ impl ThemeTestbench { fn render_layer( layer_index: usize, layer: &Layer, - cx: &mut RenderContext<'_, Self>, + cx: &mut ViewContext<'_, Self>, ) -> Container { Flex::column() .with_child( @@ -123,7 +123,7 @@ impl ThemeTestbench { layer_index: usize, set_name: &'static str, style_set: &StyleSet, - cx: &mut RenderContext<'_, Self>, + cx: &mut ViewContext<'_, Self>, ) -> Flex { Flex::row() .with_child(Self::render_button( @@ -182,7 +182,7 @@ impl ThemeTestbench { text: &'static str, style_set: &StyleSet, style_override: Option &Style>, - cx: &mut RenderContext<'_, Self>, + cx: &mut ViewContext<'_, Self>, ) -> ElementBox { enum TestBenchButton {} MouseEventHandler::::new(layer_index + button_index, cx, |state, cx| { @@ -230,7 +230,7 @@ impl ThemeTestbench { .boxed() } - fn render_label(text: String, style: &Style, cx: &mut RenderContext<'_, Self>) -> Label { + fn render_label(text: String, style: &Style, cx: &mut ViewContext<'_, Self>) -> Label { let settings = cx.global::(); let font_cache = cx.font_cache(); let family_id = settings.buffer_font_family; @@ -262,7 +262,7 @@ impl View for ThemeTestbench { "ThemeTestbench" } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> gpui::ElementBox { let color_scheme = &cx.global::().theme.clone().color_scheme; Flex::row() diff --git a/crates/welcome/src/base_keymap_picker.rs b/crates/welcome/src/base_keymap_picker.rs index 8c08a63dc6..07cfe037a4 100644 --- a/crates/welcome/src/base_keymap_picker.rs +++ b/crates/welcome/src/base_keymap_picker.rs @@ -74,7 +74,7 @@ impl View for BaseKeymapSelector { "BaseKeymapSelector" } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> gpui::ElementBox { ChildView::new(&self.picker, cx).boxed() } diff --git a/crates/welcome/src/welcome.rs b/crates/welcome/src/welcome.rs index 28b0e43c57..50e85a4f3a 100644 --- a/crates/welcome/src/welcome.rs +++ b/crates/welcome/src/welcome.rs @@ -55,7 +55,7 @@ impl View for WelcomePage { "WelcomePage" } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> ElementBox { let self_handle = cx.handle(); let settings = cx.global::(); let theme = settings.theme.clone(); diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 06782cd48c..888c1d2021 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -9,8 +9,7 @@ use gpui::{ geometry::vector::Vector2F, impl_internal_actions, platform::{CursorStyle, MouseButton}, - AppContext, Border, Element, ElementBox, RenderContext, SizeConstraint, ViewContext, - ViewHandle, + AppContext, Border, Element, ElementBox, SizeConstraint, ViewContext, ViewHandle, }; use settings::{DockAnchor, Settings}; use theme::Theme; @@ -315,7 +314,7 @@ impl Dock { &self, theme: &Theme, anchor: DockAnchor, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> Option { let style = &theme.workspace.dock; diff --git a/crates/workspace/src/dock/toggle_dock_button.rs b/crates/workspace/src/dock/toggle_dock_button.rs index 5b46b0e21f..55cafbea01 100644 --- a/crates/workspace/src/dock/toggle_dock_button.rs +++ b/crates/workspace/src/dock/toggle_dock_button.rs @@ -34,7 +34,7 @@ impl View for ToggleDockButton { "Dock Toggle" } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> ElementBox { let workspace = self.workspace.upgrade(cx); if workspace.is_none() { diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index f9b3550003..76cf874de8 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -740,8 +740,8 @@ pub(crate) mod test { use super::{Item, ItemEvent}; use crate::{sidebar::SidebarItem, ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId}; use gpui::{ - elements::Empty, AppContext, Element, ElementBox, Entity, ModelHandle, RenderContext, Task, - View, ViewContext, ViewHandle, WeakViewHandle, + elements::Empty, AppContext, Element, ElementBox, Entity, ModelHandle, Task, View, + ViewContext, ViewHandle, WeakViewHandle, }; use project::{Project, ProjectEntryId, ProjectPath, WorktreeId}; use smallvec::SmallVec; @@ -899,7 +899,7 @@ pub(crate) mod test { "TestItem" } - fn render(&mut self, _: &mut RenderContext) -> ElementBox { + fn render(&mut self, _: &mut ViewContext) -> ElementBox { Empty::new().boxed() } } diff --git a/crates/workspace/src/notifications.rs b/crates/workspace/src/notifications.rs index 893f0ff0b4..8932c969f8 100644 --- a/crates/workspace/src/notifications.rs +++ b/crates/workspace/src/notifications.rs @@ -229,7 +229,7 @@ pub mod simple_message_notification { "MessageNotification" } - fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> gpui::ElementBox { let theme = cx.global::().theme.clone(); let theme = &theme.simple_message_notification; diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 4d2ff32ef3..6015beddf7 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -24,8 +24,7 @@ use gpui::{ keymap_matcher::KeymapContext, platform::{CursorStyle, MouseButton, NavigationDirection, PromptLevel}, Action, AnyViewHandle, AnyWeakViewHandle, AppContext, AsyncAppContext, Entity, EventContext, - ModelHandle, MouseRegion, Quad, RenderContext, Task, View, ViewContext, ViewHandle, - WeakViewHandle, + ModelHandle, MouseRegion, Quad, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use project::{Project, ProjectEntryId, ProjectPath}; use serde::Deserialize; @@ -1221,7 +1220,7 @@ impl Pane { }); } - fn render_tabs(&mut self, cx: &mut RenderContext) -> impl Element { + fn render_tabs(&mut self, cx: &mut ViewContext) -> impl Element { let theme = cx.global::().theme.clone(); let pane = cx.handle(); @@ -1302,7 +1301,7 @@ impl Pane { let theme = cx.global::().theme.clone(); let detail = detail.clone(); - move |dragged_item, cx: &mut RenderContext| { + move |dragged_item, cx: &mut ViewContext| { let tab_style = &theme.workspace.tab_bar.dragged_tab; Self::render_tab( &dragged_item.item, @@ -1384,7 +1383,7 @@ impl Pane { detail: Option, hovered: bool, tab_style: &theme::Tab, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let title = item.tab_content(detail, &tab_style, cx); let mut container = tab_style.container.clone(); @@ -1408,7 +1407,7 @@ impl Pane { Canvas::new(move |bounds, _, cx| { if let Some(color) = icon_color { let square = RectF::new(bounds.origin(), vec2f(diameter, diameter)); - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: square, background: Some(color), border: Default::default(), @@ -1476,11 +1475,7 @@ impl Pane { .boxed() } - fn render_tab_bar_buttons( - &mut self, - theme: &Theme, - cx: &mut RenderContext, - ) -> ElementBox { + fn render_tab_bar_buttons(&mut self, theme: &Theme, cx: &mut ViewContext) -> ElementBox { Flex::row() // New menu .with_child(render_tab_bar_button( @@ -1529,7 +1524,7 @@ impl Pane { .boxed() } - fn render_blank_pane(&mut self, theme: &Theme, _cx: &mut RenderContext) -> ElementBox { + fn render_blank_pane(&mut self, theme: &Theme, _cx: &mut ViewContext) -> ElementBox { let background = theme.workspace.background; Empty::new() .contained() @@ -1547,7 +1542,7 @@ impl View for Pane { "Pane" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let this = cx.handle(); enum MouseNavigationHandler {} @@ -1705,7 +1700,7 @@ impl View for Pane { fn render_tab_bar_button( index: usize, icon: &'static str, - cx: &mut RenderContext, + cx: &mut ViewContext, action: A, context_menu: Option>, ) -> ElementBox { @@ -1853,7 +1848,7 @@ impl PaneBackdrop { } } -impl Element for PaneBackdrop { +impl Element for PaneBackdrop { type LayoutState = (); type PaintState = (); @@ -1861,31 +1856,34 @@ impl Element for PaneBackdrop { fn layout( &mut self, constraint: gpui::SizeConstraint, - cx: &mut gpui::LayoutContext, + view: &mut Pane, + cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { - let size = self.child.layout(constraint, cx); + let size = self.child.layout(constraint, view, cx); (size, ()) } fn paint( &mut self, + scene: &mut gpui::SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, - cx: &mut gpui::PaintContext, + view: &mut Pane, + cx: &mut ViewContext, ) -> Self::PaintState { let background = cx.global::().theme.editor.background; let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - cx.scene.push_quad(gpui::Quad { + scene.push_quad(gpui::Quad { bounds: RectF::new(bounds.origin(), bounds.size()), background: Some(background), ..Default::default() }); let child_view_id = self.child_view; - cx.scene.push_mouse_region( + scene.push_mouse_region( MouseRegion::new::(child_view_id, 0, visible_bounds).on_down( gpui::platform::MouseButton::Left, move |_, cx| { @@ -1895,8 +1893,9 @@ impl Element for PaneBackdrop { ), ); - cx.paint_layer(Some(bounds), |cx| { - self.child.paint(bounds.origin(), visible_bounds, cx) + scene.paint_layer(Some(bounds), |scene| { + self.child + .paint(scene, bounds.origin(), visible_bounds, view, cx) }) } @@ -1907,9 +1906,10 @@ impl Element for PaneBackdrop { _visible_bounds: RectF, _layout: &Self::LayoutState, _paint: &Self::PaintState, - cx: &gpui::MeasurementContext, + view: &V, + cx: &gpui::ViewContext, ) -> Option { - self.child.rect_for_text_range(range_utf16, cx) + self.child.rect_for_text_range(range_utf16, view, cx) } fn debug( @@ -1917,12 +1917,13 @@ impl Element for PaneBackdrop { _bounds: RectF, _layout: &Self::LayoutState, _paint: &Self::PaintState, - cx: &gpui::DebugContext, + view: &V, + cx: &gpui::ViewContext, ) -> serde_json::Value { gpui::json::json!({ "type": "Pane Back Drop", "view": self.child_view, - "child": self.child.debug(cx), + "child": self.child.debug(view, cx), }) } } diff --git a/crates/workspace/src/pane/dragged_item_receiver.rs b/crates/workspace/src/pane/dragged_item_receiver.rs index 7026cc043f..86db110529 100644 --- a/crates/workspace/src/pane/dragged_item_receiver.rs +++ b/crates/workspace/src/pane/dragged_item_receiver.rs @@ -5,7 +5,7 @@ use gpui::{ geometry::{rect::RectF, vector::Vector2F}, platform::MouseButton, scene::MouseUp, - AppContext, Element, ElementBox, EventContext, MouseState, Quad, RenderContext, WeakViewHandle, + AppContext, Element, ElementBox, EventContext, MouseState, Quad, ViewContext, WeakViewHandle, }; use project::ProjectEntryId; use settings::Settings; @@ -22,14 +22,14 @@ pub fn dragged_item_receiver( drop_index: usize, allow_same_pane: bool, split_margin: Option, - cx: &mut RenderContext, + cx: &mut ViewContext, render_child: F, ) -> MouseEventHandler where Tag: 'static, - F: FnOnce(&mut MouseState, &mut RenderContext) -> ElementBox, + F: FnOnce(&mut MouseState, &mut ViewContext) -> ElementBox, { - MouseEventHandler::::above(region_id, cx, |state, cx| { + MouseEventHandler::::above(region_id, cx, |state, _, cx| { // Observing hovered will cause a render when the mouse enters regardless // of if mouse position was accessed before let drag_position = if state.hovered() { @@ -59,7 +59,7 @@ where .unwrap_or(bounds); cx.paint_stacking_context(None, None, |cx| { - cx.scene.push_quad(Quad { + scene.push_quad(Quad { bounds: overlay_region, background: Some(overlay_color(cx)), border: Default::default(), @@ -102,7 +102,7 @@ pub fn handle_dropped_item( index: usize, allow_same_pane: bool, split_margin: Option, - cx: &mut EventContext, + cx: &mut ViewContext, ) { enum Action { Move(WeakViewHandle, usize), @@ -110,11 +110,11 @@ pub fn handle_dropped_item( } let drag_and_drop = cx.global::>(); let action = if let Some((_, dragged_item)) = - drag_and_drop.currently_dragged::(cx.window_id) + drag_and_drop.currently_dragged::(cx.window_id()) { Action::Move(dragged_item.pane.clone(), dragged_item.item.id()) } else if let Some((_, project_entry)) = - drag_and_drop.currently_dragged::(cx.window_id) + drag_and_drop.currently_dragged::(cx.window_id()) { Action::Open(*project_entry) } else { diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 617c5b9a34..286d3cebbe 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -5,7 +5,7 @@ use gpui::{ elements::*, geometry::{rect::RectF, vector::Vector2F}, platform::{CursorStyle, MouseButton}, - Axis, Border, ModelHandle, RenderContext, ViewHandle, + Axis, Border, ModelHandle, ViewContext, ViewHandle, }; use project::Project; use serde::Deserialize; @@ -70,7 +70,7 @@ impl PaneGroup { follower_states: &FollowerStatesByLeader, active_call: Option<&ModelHandle>, active_pane: &ViewHandle, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { self.root.render( project, @@ -131,7 +131,7 @@ impl Member { follower_states: &FollowerStatesByLeader, active_call: Option<&ModelHandle>, active_pane: &ViewHandle, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { enum FollowIntoExternalProject {} @@ -366,7 +366,7 @@ impl PaneAxis { follower_state: &FollowerStatesByLeader, active_call: Option<&ModelHandle>, active_pane: &ViewHandle, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { let last_member_ix = self.members.len() - 1; Flex::new(self.axis) diff --git a/crates/workspace/src/shared_screen.rs b/crates/workspace/src/shared_screen.rs index 7f7bf3b25f..cad832a56d 100644 --- a/crates/workspace/src/shared_screen.rs +++ b/crates/workspace/src/shared_screen.rs @@ -9,7 +9,7 @@ use gpui::{ elements::*, geometry::{rect::RectF, vector::vec2f}, platform::MouseButton, - AppContext, Entity, RenderContext, Task, View, ViewContext, + AppContext, Entity, Task, View, ViewContext, }; use settings::Settings; use smallvec::SmallVec; @@ -64,7 +64,7 @@ impl View for SharedScreen { "SharedScreen" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { enum Focus {} let frame = self.frame.clone(); @@ -76,7 +76,7 @@ impl View for SharedScreen { vec2f(frame.width() as f32, frame.height() as f32), ); let origin = bounds.origin() + (bounds.size() / 2.) - size / 2.; - cx.scene.push_surface(gpui::platform::mac::Surface { + scene.push_surface(gpui::platform::mac::Surface { bounds: RectF::new(origin, size), image_buffer: frame.image(), }); diff --git a/crates/workspace/src/sidebar.rs b/crates/workspace/src/sidebar.rs index 8efee01c30..0a0d9339a3 100644 --- a/crates/workspace/src/sidebar.rs +++ b/crates/workspace/src/sidebar.rs @@ -1,7 +1,7 @@ use crate::StatusItemView; use gpui::{ elements::*, impl_actions, platform::CursorStyle, platform::MouseButton, AnyViewHandle, - AppContext, Entity, RenderContext, Subscription, View, ViewContext, ViewHandle, + AppContext, Entity, Subscription, View, ViewContext, ViewHandle, }; use serde::Deserialize; use settings::Settings; @@ -188,7 +188,7 @@ impl View for Sidebar { "Sidebar" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { if let Some(active_item) = self.active_item() { enum ResizeHandleTag {} let style = &cx.global::().theme.workspace.sidebar; @@ -225,7 +225,7 @@ impl View for SidebarButtons { "SidebarToggleButton" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = &cx.global::().theme; let tooltip_style = theme.tooltip.clone(); let theme = &theme.workspace.status_bar.sidebar_buttons; diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index 355c327dfd..3c35b986d7 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -9,7 +9,7 @@ use gpui::{ }, json::{json, ToJson}, AnyViewHandle, AppContext, DebugContext, ElementBox, Entity, LayoutContext, MeasurementContext, - PaintContext, RenderContext, SizeConstraint, Subscription, View, ViewContext, ViewHandle, + PaintContext, SceneBuilder, SizeConstraint, Subscription, View, ViewContext, ViewHandle, }; use settings::Settings; @@ -42,7 +42,7 @@ impl View for StatusBar { "StatusBar" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = &cx.global::().theme.workspace.status_bar; StatusBarElement { @@ -143,44 +143,49 @@ struct StatusBarElement { right: ElementBox, } -impl Element for StatusBarElement { +impl Element for StatusBarElement { type LayoutState = (); type PaintState = (); fn layout( &mut self, mut constraint: SizeConstraint, - cx: &mut LayoutContext, + view: &mut V, + cx: &mut ViewContext, ) -> (Vector2F, Self::LayoutState) { let max_width = constraint.max.x(); constraint.min = vec2f(0., constraint.min.y()); - let right_size = self.right.layout(constraint, cx); + let right_size = self.right.layout(constraint, view, cx); let constraint = SizeConstraint::new( vec2f(0., constraint.min.y()), vec2f(max_width - right_size.x(), constraint.max.y()), ); - self.left.layout(constraint, cx); + self.left.layout(constraint, view, cx); (vec2f(max_width, right_size.y()), ()) } fn paint( &mut self, + scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, - cx: &mut PaintContext, + view: &mut V, + cx: &mut ViewContext, ) -> Self::PaintState { let origin_y = bounds.upper_right().y(); let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); let left_origin = vec2f(bounds.lower_left().x(), origin_y); - self.left.paint(left_origin, visible_bounds, cx); + self.left + .paint(scene, left_origin, visible_bounds, view, cx); let right_origin = vec2f(bounds.upper_right().x() - self.right.size().x(), origin_y); - self.right.paint(right_origin, visible_bounds, cx); + self.right + .paint(scene, right_origin, visible_bounds, view, cx); } fn rect_for_text_range( diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs index 5df64bea1f..2ef45c0411 100644 --- a/crates/workspace/src/toolbar.rs +++ b/crates/workspace/src/toolbar.rs @@ -1,7 +1,7 @@ use crate::{ItemHandle, Pane}; use gpui::{ elements::*, platform::CursorStyle, platform::MouseButton, Action, AnyViewHandle, AppContext, - Entity, RenderContext, View, ViewContext, ElementBox, ViewHandle, WeakViewHandle, + ElementBox, Entity, View, ViewContext, ViewHandle, WeakViewHandle, }; use settings::Settings; @@ -59,7 +59,7 @@ impl View for Toolbar { "Toolbar" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = &cx.global::().theme.workspace.toolbar; let mut primary_left_items = Vec::new(); @@ -168,7 +168,7 @@ fn nav_button( action: A, tooltip_action: A, action_name: &str, - cx: &mut RenderContext, + cx: &mut ViewContext, ) -> ElementBox { MouseEventHandler::::new(0, cx, |state, _| { let style = if enabled { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 334578d67d..3253f9db6a 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -45,8 +45,7 @@ use gpui::{ WindowOptions, }, Action, AnyModelHandle, AnyViewHandle, AppContext, AsyncAppContext, Entity, ModelContext, - ModelHandle, RenderContext, SizeConstraint, Subscription, Task, View, ViewContext, ViewHandle, - WeakViewHandle, + ModelHandle, SizeConstraint, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem}; use language::LanguageRegistry; @@ -2054,10 +2053,10 @@ impl Workspace { self.leader_state.followers.contains(&peer_id) } - fn render_titlebar(&self, theme: &Theme, cx: &mut RenderContext) -> ElementBox { + fn render_titlebar(&self, theme: &Theme, cx: &mut ViewContext) -> ElementBox { // TODO: There should be a better system in place for this // (https://github.com/zed-industries/zed/issues/1290) - let is_fullscreen = cx.window_is_fullscreen(cx.window_id()); + let is_fullscreen = cx.window_is_fullscreen(); let container_theme = if is_fullscreen { let mut container_theme = theme.workspace.titlebar.container; container_theme.padding.left = container_theme.padding.right; @@ -2154,7 +2153,7 @@ impl Workspace { } } - fn render_disconnected_overlay(&self, cx: &mut RenderContext) -> Option { + fn render_disconnected_overlay(&self, cx: &mut ViewContext) -> Option { if self.project.read(cx).is_read_only() { enum DisconnectedOverlay {} Some( @@ -2810,7 +2809,7 @@ impl View for Workspace { "Workspace" } - fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut ViewContext) -> ElementBox { let theme = cx.global::().theme.clone(); Stack::new() .with_child(