mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
WIP
This commit is contained in:
parent
3de8fe0f87
commit
e115baa60c
@ -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<Self>) -> Content {
|
||||
fn content_to_render(&mut self, cx: &mut ViewContext<Self>) -> 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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let Content {
|
||||
icon,
|
||||
message,
|
||||
|
@ -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<Self>) -> gpui::ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
let theme = &theme.update_notification;
|
||||
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let active_item = match &self.active_item {
|
||||
Some(active_item) => active_item,
|
||||
None => return Empty::new().boxed(),
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> 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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> ElementBox {
|
||||
let titlebar = &theme.workspace.titlebar;
|
||||
|
||||
@ -390,7 +390,7 @@ impl CollabTitlebarItem {
|
||||
&self,
|
||||
theme: &Theme,
|
||||
room: &ModelHandle<Room>,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> ElementBox {
|
||||
let icon;
|
||||
let tooltip;
|
||||
@ -436,7 +436,7 @@ impl CollabTitlebarItem {
|
||||
&self,
|
||||
workspace: &ViewHandle<Workspace>,
|
||||
theme: &Theme,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<ElementBox> {
|
||||
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<Self>) -> ElementBox {
|
||||
fn render_user_menu_button(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> 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<Self>) -> ElementBox {
|
||||
fn render_sign_in_button(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let titlebar = &theme.workspace.titlebar;
|
||||
MouseEventHandler::<SignIn>::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<Self>,
|
||||
cx: &'a ViewContext<Self>,
|
||||
) -> Option<ElementBox> {
|
||||
self.contacts_popover.as_ref().map(|popover| {
|
||||
Overlay::new(ChildView::new(popover, cx).boxed())
|
||||
@ -573,7 +573,7 @@ impl CollabTitlebarItem {
|
||||
workspace: &ViewHandle<Workspace>,
|
||||
theme: &Theme,
|
||||
room: &ModelHandle<Room>,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Vec<ElementBox> {
|
||||
let mut participants = room
|
||||
.read(cx)
|
||||
@ -615,7 +615,7 @@ impl CollabTitlebarItem {
|
||||
theme: &Theme,
|
||||
user: &Arc<User>,
|
||||
peer_id: PeerId,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> 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<ParticipantLocation>,
|
||||
workspace: &ViewHandle<Workspace>,
|
||||
theme: &Theme,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> 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<Workspace>,
|
||||
location: Option<ParticipantLocation>,
|
||||
mut style: AvatarStyle,
|
||||
cx: &RenderContext<Self>,
|
||||
cx: &ViewContext<Self>,
|
||||
) -> 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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<ElementBox> {
|
||||
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(
|
||||
|
@ -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<Self>,
|
||||
}
|
||||
|
||||
impl Entity for CollaboratorListPopover {
|
||||
@ -33,7 +30,7 @@ impl View for CollaboratorListPopover {
|
||||
"CollaboratorListPopover"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
MouseEventHandler::<Self>::new(0, cx, |_, _| {
|
||||
@ -120,7 +117,7 @@ fn render_collaborator_list_entry<UA: Action + Clone, IA: Action + Clone>(
|
||||
icon: Svg,
|
||||
icon_action: IA,
|
||||
icon_tooltip: String,
|
||||
cx: &mut RenderContext<CollaboratorListPopover>,
|
||||
cx: &mut ViewContext<CollaboratorListPopover>,
|
||||
) -> ElementBox {
|
||||
enum Username {}
|
||||
enum UsernameTooltip {}
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
ChildView::new(&self.picker, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> 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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> 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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> ElementBox {
|
||||
enum Header {}
|
||||
enum LeaveCallContactList {}
|
||||
@ -1077,7 +1077,7 @@ impl ContactList {
|
||||
project: &ModelHandle<Project>,
|
||||
theme: &theme::ContactList,
|
||||
is_selected: bool,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> 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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> ElementBox {
|
||||
enum Decline {}
|
||||
enum Accept {}
|
||||
@ -1331,7 +1331,7 @@ impl View for ContactList {
|
||||
cx
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
enum AddContact {}
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
match self.kind {
|
||||
ContactEventKind::Requested => render_user_notification(
|
||||
self.user.clone(),
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
let child = match &self.child {
|
||||
Child::ContactList(child) => ChildView::new(child, cx),
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render_caller(&self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = &cx.global::<Settings>().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<Self>) -> ElementBox {
|
||||
fn render_buttons(&self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
enum Accept {}
|
||||
enum Decline {}
|
||||
|
||||
@ -222,7 +222,7 @@ impl View for IncomingCallNotification {
|
||||
"IncomingCallNotification"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::ElementBox {
|
||||
let background = cx
|
||||
.global::<Settings>()
|
||||
.theme
|
||||
|
@ -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<V: View, A: Action + Clone>(
|
||||
body: Option<&'static str>,
|
||||
dismiss_action: A,
|
||||
buttons: Vec<(&'static str, Box<dyn Action>)>,
|
||||
cx: &mut RenderContext<V>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
let theme = &theme.contact_notification;
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render_owner(&self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = &cx.global::<Settings>().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<Self>) -> ElementBox {
|
||||
fn render_buttons(&self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
enum Open {}
|
||||
enum Dismiss {}
|
||||
|
||||
@ -227,7 +227,7 @@ impl View for ProjectSharedNotification {
|
||||
"ProjectSharedNotification"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::ElementBox {
|
||||
let background = cx
|
||||
.global::<Settings>()
|
||||
.theme
|
||||
|
@ -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(),
|
||||
|
@ -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<Workspace>) {
|
||||
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<Self>) -> gpui::ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::ElementBox {
|
||||
ChildView::new(&self.picker, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<dyn Fn(&mut AppContext) -> 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<dyn Fn(&mut AppContext) -> ElementBox<ContextMenu>>;
|
||||
|
||||
type ContextMenuItemBuilder =
|
||||
Box<dyn Fn(&mut MouseState, &theme::ContextMenuItem) -> ElementBox>;
|
||||
Box<dyn Fn(&mut MouseState, &theme::ContextMenuItem) -> ElementBox<ContextMenu>>;
|
||||
|
||||
pub enum ContextMenuItemLabel {
|
||||
String(Cow<'static, str>),
|
||||
@ -142,7 +142,7 @@ impl View for ContextMenu {
|
||||
cx
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
|
||||
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<Self>) -> impl Element {
|
||||
fn render_menu_for_measurement(&self, cx: &mut ViewContext<Self>) -> impl Element<ContextMenu> {
|
||||
let window_id = cx.window_id();
|
||||
let style = cx.global::<Settings>().theme.context_menu.clone();
|
||||
Flex::row()
|
||||
@ -415,14 +415,14 @@ impl ContextMenu {
|
||||
.with_style(style.container)
|
||||
}
|
||||
|
||||
fn render_menu(&self, cx: &mut RenderContext<Self>) -> impl Element {
|
||||
fn render_menu(&self, cx: &mut ViewContext<Self>) -> impl Element<ContextMenu> {
|
||||
enum Menu {}
|
||||
enum MenuItem {}
|
||||
|
||||
let style = cx.global::<Settings>().theme.context_menu.clone();
|
||||
|
||||
let window_id = cx.window_id();
|
||||
MouseEventHandler::<Menu>::new(0, cx, |_, cx| {
|
||||
MouseEventHandler::<Menu, ContextMenu>::new(0, cx, |_, cx| {
|
||||
Flex::column()
|
||||
.with_children(self.items.iter().enumerate().map(|(ix, item)| {
|
||||
match item {
|
||||
@ -436,7 +436,7 @@ impl ContextMenu {
|
||||
}
|
||||
};
|
||||
|
||||
MouseEventHandler::<MenuItem>::new(ix, cx, |state, _| {
|
||||
MouseEventHandler::<MenuItem, ContextMenu>::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))
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ impl CopilotCodeVerification {
|
||||
fn render_device_code(
|
||||
data: &PromptUserDeviceFlow,
|
||||
style: &theme::Copilot,
|
||||
cx: &mut gpui::RenderContext<Self>,
|
||||
cx: &mut gpui::ViewContext<Self>,
|
||||
) -> 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<Self>,
|
||||
cx: &mut gpui::ViewContext<Self>,
|
||||
) -> ElementBox {
|
||||
Flex::column()
|
||||
.with_children([
|
||||
@ -205,7 +205,7 @@ impl CopilotCodeVerification {
|
||||
}
|
||||
fn render_enabled_modal(
|
||||
style: &theme::Copilot,
|
||||
cx: &mut gpui::RenderContext<Self>,
|
||||
cx: &mut gpui::ViewContext<Self>,
|
||||
) -> 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<Self>,
|
||||
cx: &mut gpui::ViewContext<Self>,
|
||||
) -> 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::<Settings>().theme.clone();
|
||||
|
||||
modal("Connect Copilot to Zed", &style.copilot.modal, cx, |cx| {
|
||||
|
@ -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::<Settings>();
|
||||
|
||||
if !settings.enable_copilot_integration {
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
if self.path_states.is_empty() {
|
||||
let theme = &cx.global::<Settings>().theme.project_diagnostics;
|
||||
Label::new("No problems in workspace", theme.empty_message.clone())
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
enum Summary {}
|
||||
enum Message {}
|
||||
|
||||
|
@ -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<V: View> {
|
||||
region_offset: Vector2F,
|
||||
region: RectF,
|
||||
payload: Rc<dyn Any + 'static>,
|
||||
render: Rc<dyn Fn(Rc<dyn Any>, &mut RenderContext<V>) -> ElementBox>,
|
||||
render: Rc<dyn Fn(Rc<dyn Any>, &mut ViewContext<V>) -> ElementBox<V>>,
|
||||
},
|
||||
Canceled,
|
||||
}
|
||||
@ -111,7 +111,7 @@ impl<V: View> DragAndDrop<V> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn drag_started(event: MouseDown, cx: &mut EventContext) {
|
||||
pub fn drag_started(event: MouseDown, cx: &mut ViewContext<V>) {
|
||||
cx.update_global(|this: &mut Self, _| {
|
||||
this.currently_dragged = Some(State::Down {
|
||||
region_offset: event.position - event.region.origin(),
|
||||
@ -123,8 +123,8 @@ impl<V: View> DragAndDrop<V> {
|
||||
pub fn dragging<T: Any>(
|
||||
event: MouseDrag,
|
||||
payload: Rc<T>,
|
||||
cx: &mut EventContext,
|
||||
render: Rc<impl 'static + Fn(&T, &mut RenderContext<V>) -> ElementBox>,
|
||||
cx: &mut ViewContext<V>,
|
||||
render: Rc<impl 'static + Fn(&T, &mut ViewContext<V>) -> ElementBox<V>>,
|
||||
) {
|
||||
let window_id = cx.window_id();
|
||||
cx.update_global(|this: &mut Self, cx| {
|
||||
@ -178,7 +178,7 @@ impl<V: View> DragAndDrop<V> {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn render(cx: &mut RenderContext<V>) -> Option<ElementBox> {
|
||||
pub fn render(cx: &mut ViewContext<V>) -> Option<ElementBox<V>> {
|
||||
enum DraggedElementHandler {}
|
||||
cx.global::<Self>()
|
||||
.currently_dragged
|
||||
@ -202,20 +202,22 @@ impl<V: View> DragAndDrop<V> {
|
||||
let position = position - region_offset;
|
||||
Some(
|
||||
Overlay::new(
|
||||
MouseEventHandler::<DraggedElementHandler>::new(0, cx, |_, cx| {
|
||||
render(payload, cx)
|
||||
})
|
||||
MouseEventHandler::<DraggedElementHandler, V>::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::<Self, _, _>(|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::<Self, _, _>(|this, cx| {
|
||||
this.finish_dragging(cx)
|
||||
});
|
||||
@ -234,22 +236,22 @@ impl<V: View> DragAndDrop<V> {
|
||||
}
|
||||
|
||||
State::Canceled => Some(
|
||||
MouseEventHandler::<DraggedElementHandler>::new(0, cx, |_, _| {
|
||||
MouseEventHandler::<DraggedElementHandler, V>::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::<Self, _, _>(|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::<Self, _, _>(|this, _| {
|
||||
this.currently_dragged = None;
|
||||
});
|
||||
@ -294,32 +296,32 @@ impl<V: View> DragAndDrop<V> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Draggable {
|
||||
fn as_draggable<V: View, P: Any>(
|
||||
pub trait Draggable<V: View> {
|
||||
fn as_draggable<P: Any>(
|
||||
self,
|
||||
payload: P,
|
||||
render: impl 'static + Fn(&P, &mut RenderContext<V>) -> ElementBox,
|
||||
render: impl 'static + Fn(&P, &mut ViewContext<V>) -> ElementBox<V>,
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
impl<Tag> Draggable for MouseEventHandler<Tag> {
|
||||
fn as_draggable<V: View, P: Any>(
|
||||
impl<Tag, V: View> Draggable<V> for MouseEventHandler<Tag, V> {
|
||||
fn as_draggable<P: Any>(
|
||||
self,
|
||||
payload: P,
|
||||
render: impl 'static + Fn(&P, &mut RenderContext<V>) -> ElementBox,
|
||||
render: impl 'static + Fn(&P, &mut ViewContext<V>) -> ElementBox<V>,
|
||||
) -> 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::<V>::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::<V>::dragging(e, payload, cx, render)
|
||||
|
@ -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
|
||||
|
@ -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<Editor>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> (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<Editor>) -> ElementBox {
|
||||
fn render(&self, style: EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox {
|
||||
enum CompletionTag {}
|
||||
|
||||
let completions = self.completions.clone();
|
||||
@ -950,7 +950,7 @@ impl CodeActionsMenu {
|
||||
&self,
|
||||
mut cursor_position: DisplayPoint,
|
||||
style: EditorStyle,
|
||||
cx: &mut RenderContext<Editor>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> (DisplayPoint, ElementBox) {
|
||||
enum ActionTag {}
|
||||
|
||||
@ -2928,7 +2928,7 @@ impl Editor {
|
||||
&self,
|
||||
style: &EditorStyle,
|
||||
active: bool,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<ElementBox> {
|
||||
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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Vec<Option<ElementBox>> {
|
||||
enum FoldIndicators {}
|
||||
|
||||
@ -3027,7 +3027,7 @@ impl Editor {
|
||||
&self,
|
||||
cursor_position: DisplayPoint,
|
||||
style: EditorStyle,
|
||||
cx: &mut RenderContext<Editor>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> 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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> 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<Editor>| {
|
||||
if let Some(editor) = handle.upgrade(cx) {
|
||||
editor.update(cx, |editor, cx| {
|
||||
hide_hover(editor, &HideHover, cx);
|
||||
|
@ -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::<EditorElementMouseHandlers>(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::<GutterHandlers>(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<Editor>,
|
||||
) -> 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<Editor>,
|
||||
) -> 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<Editor>,
|
||||
) {
|
||||
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::<FoldMarkers>(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));
|
||||
scene.push_layer(Some(bounds));
|
||||
|
||||
scene.paint_layer(Some(bounds), |scene| {
|
||||
for cursor in cursors {
|
||||
cursor.paint(content_origin, cx);
|
||||
cursor.paint(scene, content_origin, cx);
|
||||
}
|
||||
cx.scene.pop_layer();
|
||||
});
|
||||
|
||||
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<Editor>,
|
||||
) {
|
||||
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::<ScrollbarMouseHandlers>(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<DisplayPoint>,
|
||||
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<Self>,
|
||||
) {
|
||||
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<BlockLayout>) {
|
||||
let editor = if let Some(editor) = self.view.upgrade(cx) {
|
||||
editor
|
||||
} else {
|
||||
return Default::default();
|
||||
};
|
||||
|
||||
let tooltip_style = cx.global::<Settings>().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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<u32>,
|
||||
cx: &mut RenderContext<Editor>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> Option<(DisplayPoint, Vec<ElementBox>)> {
|
||||
// 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<Editor>) -> ElementBox {
|
||||
pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox {
|
||||
MouseEventHandler::<InfoPopover>::new(0, cx, |_, cx| {
|
||||
let mut flex = Flex::new(Axis::Vertical).scrollable::<HoverBlock, _>(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<Editor>) -> ElementBox {
|
||||
pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox {
|
||||
enum PrimaryDiagnostic {}
|
||||
|
||||
let mut text_style = style.hover_popover.prose.clone();
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
if let Some(position) = self.position {
|
||||
let theme = &cx.global::<Settings>().theme.workspace.status_bar;
|
||||
let mut text = format!("{},{}", position.row + 1, position.column + 1);
|
||||
|
@ -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::<Settings>().theme.clone();
|
||||
Stack::new()
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
ChildView::new(&self.editor, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
Flex::row()
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
enum SubmitFeedbackButton {}
|
||||
MouseEventHandler::<SubmitFeedbackButton>::new(0, cx, |state, _| {
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
ChildView::new(&self.picker, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = &cx.global::<Settings>().theme.picker;
|
||||
|
||||
let label = format!(
|
||||
|
@ -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<Self>) -> gpui::ElementBox {
|
||||
fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> ElementBox<TextView> {
|
||||
TextElement.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl gpui::Element for TextElement {
|
||||
impl<V: View> Element<V> 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<V>,
|
||||
) -> (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<V>,
|
||||
) -> 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<V>,
|
||||
) -> Option<RectF> {
|
||||
None
|
||||
}
|
||||
@ -121,7 +125,8 @@ impl gpui::Element for TextElement {
|
||||
_: RectF,
|
||||
_: &Self::LayoutState,
|
||||
_: &Self::PaintState,
|
||||
_: &DebugContext,
|
||||
_: &V,
|
||||
_: &ViewContext<V>,
|
||||
) -> gpui::json::Value {
|
||||
todo!()
|
||||
}
|
||||
|
@ -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<Self>;
|
||||
fn render(&mut self, cx: &mut ViewContext<'_, '_, '_, Self>) -> ElementBox<Self>;
|
||||
fn focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
|
||||
fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
|
||||
fn key_down(&mut self, _: &KeyDownEvent, _: &mut ViewContext<Self>) -> 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<dyn FnMut(&dyn Any, &mut AppContext) -> 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<usize> {
|
||||
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,7 +863,8 @@ impl AppContext {
|
||||
self.active_labeled_tasks.values().cloned()
|
||||
}
|
||||
|
||||
// pub fn render_view(&mut self, params: RenderParams) -> Result<ElementBox<Self>> {
|
||||
pub fn render_view(&mut self, params: RenderParams) -> Result<Box<dyn RenderedView>> {
|
||||
todo!()
|
||||
// let window_id = params.window_id;
|
||||
// let view_id = params.view_id;
|
||||
// let mut view = self
|
||||
@ -868,14 +874,15 @@ impl AppContext {
|
||||
// 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<usize, ElementBox> {
|
||||
pub fn render_views(
|
||||
&mut self,
|
||||
window_id: usize,
|
||||
titlebar_height: f32,
|
||||
appearance: Appearance,
|
||||
) -> HashMap<usize, Box<dyn RenderedView>> {
|
||||
todo!()
|
||||
// self.start_frame();
|
||||
// #[allow(clippy::needless_collect)]
|
||||
// let view_ids = self
|
||||
@ -908,7 +915,7 @@ impl AppContext {
|
||||
// )
|
||||
// })
|
||||
// .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<T, F>(
|
||||
pub fn add_window<V, F>(
|
||||
&mut self,
|
||||
window_options: WindowOptions,
|
||||
build_root_view: F,
|
||||
) -> (usize, ViewHandle<T>)
|
||||
) -> (usize, ViewHandle<V>)
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> T,
|
||||
V: View,
|
||||
F: FnOnce(&mut ViewContext<V>) -> 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::<V>().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<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
|
||||
pub fn add_status_bar_item<V, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<V>)
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> T,
|
||||
V: View,
|
||||
F: FnOnce(&mut ViewContext<V>) -> 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::<V>().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<T, F>(&mut self, window_id: usize, build_root_view: F) -> ViewHandle<T>
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> 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<V, F>(
|
||||
&mut self,
|
||||
window_id: usize,
|
||||
root_view: AnyViewHandle,
|
||||
mut platform_window: Box<dyn platform::Window>,
|
||||
) -> Window {
|
||||
build_root_view: F,
|
||||
) -> Window
|
||||
where
|
||||
V: View,
|
||||
F: FnOnce(&mut ViewContext<V>) -> 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<T, F>(&mut self, parent_handle: &AnyViewHandle, build_view: F) -> ViewHandle<T>
|
||||
pub fn add_view<S, F>(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle<S>
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> T,
|
||||
S: View,
|
||||
F: FnOnce(&mut ViewContext<S>) -> S,
|
||||
{
|
||||
self.build_and_insert_view(
|
||||
parent_handle.window_id,
|
||||
ParentId::View(parent_handle.view_id),
|
||||
|cx| Some(build_view(cx)),
|
||||
)
|
||||
self.update_window(parent.window_id, |cx| {
|
||||
cx.build_and_insert_view(ParentId::View(parent.view_id), |cx| Some(build_view(cx)))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn add_option_view<T, F>(
|
||||
&mut self,
|
||||
parent_handle: impl Into<AnyViewHandle>,
|
||||
build_view: F,
|
||||
) -> Option<ViewHandle<T>>
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> Option<T>,
|
||||
{
|
||||
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<T, F>(
|
||||
&mut self,
|
||||
window_id: usize,
|
||||
parent_id: ParentId,
|
||||
build_view: F,
|
||||
) -> Option<ViewHandle<T>>
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> Option<T>,
|
||||
{
|
||||
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
|
||||
})
|
||||
.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::<Vec<_>>() {
|
||||
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)) {
|
||||
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)) = this
|
||||
if let Some((name, mut handlers)) = cx
|
||||
.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 {
|
||||
cx.halt_action_dispatch = true;
|
||||
handler(view, action, cx, view_id);
|
||||
if cx.halt_action_dispatch {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.actions_mut(capture_phase)
|
||||
cx.actions_mut(capture_phase)
|
||||
.get_mut(&type_id)
|
||||
.unwrap()
|
||||
.insert(name, handlers);
|
||||
}
|
||||
|
||||
this.views.insert((window_id, view_id), view);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
!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(
|
||||
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,
|
||||
);
|
||||
this.views.insert((handle.window_id, handle.view_id), view);
|
||||
result
|
||||
)
|
||||
})
|
||||
.unwrap() // TODO: Are these unwraps safe?
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -2877,68 +2814,42 @@ pub trait AnyView {
|
||||
cx: &mut AppContext,
|
||||
) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
|
||||
fn ui_name(&self) -> &'static str;
|
||||
fn render<'a, 'b>(
|
||||
&mut self,
|
||||
params: RenderParams,
|
||||
cx: &'b mut WindowContext<'a, 'b>,
|
||||
) -> Box<dyn RenderedView>;
|
||||
fn render(&mut self, params: RenderParams, cx: &mut WindowContext) -> Box<dyn RenderedView>;
|
||||
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<usize>,
|
||||
cx: &'b mut WindowContext<'a, 'b>,
|
||||
) -> Option<String>;
|
||||
fn selected_text_range<'a, 'b>(
|
||||
&self,
|
||||
cx: &'b mut WindowContext<'a, 'b>,
|
||||
) -> Option<Range<usize>>;
|
||||
fn marked_text_range<'a, 'b>(&self, cx: &'b mut WindowContext<'a, 'b>) -> Option<Range<usize>>;
|
||||
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<usize>, cx: &WindowContext) -> Option<String>;
|
||||
fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
|
||||
fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
|
||||
fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize);
|
||||
fn replace_text_in_range(
|
||||
&mut self,
|
||||
range: Option<Range<usize>>,
|
||||
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<Range<usize>>,
|
||||
new_text: &str,
|
||||
new_selected_range: Option<Range<usize>>,
|
||||
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<dyn RenderedView> {
|
||||
View::render(self, &mut ViewContext::new(params, cx))
|
||||
fn render(&mut self, params: RenderParams, cx: &mut WindowContext) -> Box<dyn RenderedView> {
|
||||
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<usize>,
|
||||
cx: &mut WindowContext<'a, 'b>,
|
||||
) -> Option<String> {
|
||||
fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String> {
|
||||
View::text_for_range(self, range, cx)
|
||||
}
|
||||
|
||||
fn selected_text_range<'a, 'b>(&self, cx: &mut WindowContext<'a, 'b>) -> Option<Range<usize>> {
|
||||
fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
|
||||
View::selected_text_range(self, cx)
|
||||
}
|
||||
|
||||
fn marked_text_range<'a, 'b>(&self, cx: &mut WindowContext<'a, 'b>) -> Option<Range<usize>> {
|
||||
fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
|
||||
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<Range<usize>>,
|
||||
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<Range<usize>>,
|
||||
new_text: &str,
|
||||
new_selected_range: Option<Range<usize>>,
|
||||
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<M> 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<T>,
|
||||
}
|
||||
|
||||
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<T: View> 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<AnyViewHandle>) -> 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<F>(&mut self, mut callback: F)
|
||||
@ -3466,23 +3360,13 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
|
||||
where
|
||||
S: Entity,
|
||||
F: FnOnce(&mut ModelContext<S>) -> S,
|
||||
{
|
||||
self.window_context.add_model(build_model)
|
||||
}
|
||||
|
||||
pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
|
||||
where
|
||||
S: View,
|
||||
F: FnOnce(&mut ViewContext<S>) -> 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<S>) -> Option<S>,
|
||||
{
|
||||
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<W, F>(&mut self, build_root_view: F) -> ViewHandle<W>
|
||||
where
|
||||
W: View,
|
||||
F: FnOnce(&mut ViewContext<W>) -> 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<E, H, F>(&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<V>),
|
||||
{
|
||||
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<V>),
|
||||
{
|
||||
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<V>),
|
||||
{
|
||||
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<dyn Action>) {
|
||||
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<V>)) {
|
||||
@ -3813,14 +3686,12 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
|
||||
pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
|
||||
let region_id = MouseRegionId::new::<Tag>(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<V> UpgradeModelHandle for ViewContext<'_, '_, V> {
|
||||
impl<V> UpgradeModelHandle for ViewContext<'_, '_, '_, V> {
|
||||
fn upgrade_model_handle<T: Entity>(
|
||||
&self,
|
||||
handle: &WeakModelHandle<T>,
|
||||
@ -3867,7 +3738,7 @@ impl<V> UpgradeModelHandle for ViewContext<'_, '_, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> UpgradeViewHandle for ViewContext<'_, '_, V> {
|
||||
impl<V> UpgradeViewHandle for ViewContext<'_, '_, '_, V> {
|
||||
fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
|
||||
self.window_context.upgrade_view_handle(handle)
|
||||
}
|
||||
@ -3877,7 +3748,13 @@ impl<V> UpgradeViewHandle for ViewContext<'_, '_, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> UpdateModel for ViewContext<'_, '_, V> {
|
||||
impl<V: View> ReadModel for ViewContext<'_, '_, '_, V> {
|
||||
fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
|
||||
self.window_context.read_model(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> UpdateModel for ViewContext<'_, '_, '_, V> {
|
||||
fn update_model<T: Entity, O>(
|
||||
&mut self,
|
||||
handle: &ModelHandle<T>,
|
||||
@ -3887,13 +3764,13 @@ impl<V: View> UpdateModel for ViewContext<'_, '_, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> ReadView for ViewContext<'_, '_, V> {
|
||||
impl<V: View> ReadView for ViewContext<'_, '_, '_, V> {
|
||||
fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
|
||||
self.window_context.read_view(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> UpdateView for ViewContext<'_, '_, V> {
|
||||
impl<V: View> UpdateView for ViewContext<'_, '_, '_, V> {
|
||||
fn update_view<T, S>(
|
||||
&mut self,
|
||||
handle: &ViewHandle<T>,
|
||||
@ -3906,6 +3783,33 @@ impl<V: View> 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<T: 'static> ElementStateHandle<T> {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
|
||||
pub fn update<C, D, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
|
||||
where
|
||||
C: DerefMut<Target = AppContext>,
|
||||
C: DerefMut<Target = D>,
|
||||
D: DerefMut<Target = AppContext>,
|
||||
{
|
||||
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<Self>) -> ElementBox<Self> {
|
||||
enum Handler {}
|
||||
let mouse_down_count = self.mouse_down_count.clone();
|
||||
MouseEventHandler::<Handler>::new(0, cx, |_, _| Empty::new().boxed())
|
||||
.on_down(MouseButton::Left, move |_, _| {
|
||||
MouseEventHandler::<Handler, _>::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();
|
||||
});
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<A: 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<AnyViewHandle> {
|
||||
self.cx.borrow().root_view(window_id)
|
||||
Some(
|
||||
self.cx
|
||||
.borrow()
|
||||
.windows
|
||||
.get(&window_id)?
|
||||
.root_view()
|
||||
.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
|
||||
@ -172,20 +178,21 @@ impl TestAppContext {
|
||||
F: FnOnce(&mut V, &mut ViewContext<V>) -> 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 {
|
||||
|
@ -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<AnyViewHandle>,
|
||||
pub(crate) focused_view_id: Option<usize>,
|
||||
pub(crate) is_active: bool,
|
||||
pub(crate) is_fullscreen: bool,
|
||||
@ -43,27 +41,29 @@ pub struct Window {
|
||||
cursor_regions: Vec<CursorRegion>,
|
||||
mouse_regions: Vec<(MouseRegion, usize)>,
|
||||
last_mouse_moved_event: Option<Event>,
|
||||
hovered_region_ids: HashSet<MouseRegionId>,
|
||||
clicked_region_ids: HashSet<MouseRegionId>,
|
||||
clicked_button: Option<MouseButton>,
|
||||
pub(crate) hovered_region_ids: HashSet<MouseRegionId>,
|
||||
pub(crate) clicked_region_ids: HashSet<MouseRegionId>,
|
||||
pub(crate) clicked_button: Option<MouseButton>,
|
||||
mouse_position: Vector2F,
|
||||
text_layout_cache: TextLayoutCache,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(
|
||||
pub fn new<V, F>(
|
||||
window_id: usize,
|
||||
root_view: AnyViewHandle,
|
||||
platform_window: Box<dyn platform::Window>,
|
||||
cx: &mut AppContext,
|
||||
) -> Self {
|
||||
let focused_view_id = Some(root_view.id());
|
||||
build_view: F,
|
||||
) -> Self
|
||||
where
|
||||
F: FnOnce(&mut ViewContext<V>) -> 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<F, T>(&mut self, view_id: usize, f: F) -> Option<T>
|
||||
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<F, T>(&mut self, view_id: usize, f: F) -> Option<T>
|
||||
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::<Vec<_>>()
|
||||
@ -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<usize> {
|
||||
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<usize> {
|
||||
self.window.platform_window.prompt(level, msg, answers)
|
||||
}
|
||||
|
||||
fn add_view<T, F>(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle<T>
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> 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<T, F>(
|
||||
&mut self,
|
||||
parent_handle: impl Into<AnyViewHandle>,
|
||||
build_view: F,
|
||||
) -> Option<ViewHandle<T>>
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> Option<T>,
|
||||
{
|
||||
let parent_handle = parent_handle.into();
|
||||
self.build_and_insert_view(ParentId::View(parent_handle.view_id), build_view)
|
||||
}
|
||||
|
||||
pub fn replace_root_view<V, F>(&mut self, build_root_view: F) -> ViewHandle<V>
|
||||
where
|
||||
V: View,
|
||||
F: FnOnce(&mut ViewContext<V>) -> 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<T, F>(
|
||||
&mut self,
|
||||
parent_id: ParentId,
|
||||
build_view: F,
|
||||
) -> Option<ViewHandle<T>>
|
||||
where
|
||||
T: View,
|
||||
F: FnOnce(&mut ViewContext<T>) -> Option<T>,
|
||||
{
|
||||
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<usize>,
|
||||
cx: &WindowContext,
|
||||
view_id: usize,
|
||||
) -> Option<RectF>;
|
||||
fn debug(&self, cx: &WindowContext, view_id: usize) -> serde_json::Value;
|
||||
fn name(&self) -> Option<&str>;
|
||||
}
|
||||
|
||||
impl<V: View> RenderedView for ElementBox<V> {
|
||||
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))
|
||||
cx.update_any_view(view_id, |view, cx| {
|
||||
let view = view.as_any_mut().downcast_mut::<V>().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::<V>().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<usize>,
|
||||
cx: &WindowContext,
|
||||
view_id: usize,
|
||||
) -> Option<RectF> {
|
||||
let view = cx
|
||||
.views
|
||||
.get(&(cx.window_id, view_id))
|
||||
.unwrap()
|
||||
.as_any()
|
||||
.downcast_ref::<V>()
|
||||
.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::<V>()
|
||||
.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<V: View> Element<V> 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<V>,
|
||||
) -> (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<V>,
|
||||
) {
|
||||
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<usize>,
|
||||
// _: RectF,
|
||||
// _: RectF,
|
||||
// view_is_valid: &Self::LayoutState,
|
||||
// _: &Self::PaintState,
|
||||
// cx: &MeasurementContext,
|
||||
// ) -> Option<RectF> {
|
||||
// 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<usize>,
|
||||
_: RectF,
|
||||
_: RectF,
|
||||
_: &Self::LayoutState,
|
||||
_: &Self::PaintState,
|
||||
_: &V,
|
||||
cx: &ViewContext<V>,
|
||||
) -> Option<RectF> {
|
||||
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<V>,
|
||||
) -> 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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<RefCell<AppContext>>,
|
||||
@ -12,7 +12,7 @@ pub struct WindowInputHandler {
|
||||
impl WindowInputHandler {
|
||||
fn read_focused_view<T, F>(&self, f: F) -> Option<T>
|
||||
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);
|
||||
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<T, F>(&mut self, f: F) -> Option<T>
|
||||
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<Range<usize>>, 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<Range<usize>>,
|
||||
) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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<V: View> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
view: &mut V,
|
||||
constraint: SizeConstraint,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Vector2F;
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
view: &mut V,
|
||||
scene: &mut SceneBuilder,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
);
|
||||
|
||||
fn rect_for_text_range(
|
||||
&self,
|
||||
view: &V,
|
||||
range_utf16: Range<usize>,
|
||||
view: &V,
|
||||
cx: &ViewContext<V>,
|
||||
) -> Option<RectF>;
|
||||
|
||||
@ -118,7 +118,8 @@ pub trait Element<V: View> {
|
||||
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<V: View> {
|
||||
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<V: View> {
|
||||
where
|
||||
Self: 'static + Sized,
|
||||
{
|
||||
Tooltip::new::<Tag>(id, text, action, style, self.boxed(), cx)
|
||||
Tooltip::new::<Tag, V>(id, text, action, style, self.boxed(), cx)
|
||||
}
|
||||
|
||||
fn with_resize_handle<Tag: 'static>(
|
||||
@ -207,7 +209,7 @@ pub trait Element<V: View> {
|
||||
where
|
||||
Self: 'static + Sized,
|
||||
{
|
||||
Resizable::new::<Tag>(
|
||||
Resizable::new::<Tag, V>(
|
||||
self.boxed(),
|
||||
element_id,
|
||||
side,
|
||||
@ -242,8 +244,8 @@ pub enum Lifecycle<V: View, E: Element<V>> {
|
||||
impl<V: View, E: Element<V>> AnyElement<V> for Lifecycle<V, E> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
view: &mut V,
|
||||
constraint: SizeConstraint,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Vector2F {
|
||||
let result;
|
||||
@ -252,7 +254,7 @@ impl<V: View, E: Element<V>> AnyElement<V> for Lifecycle<V, E> {
|
||||
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<V: View, E: Element<V>> AnyElement<V> for Lifecycle<V, E> {
|
||||
fn paint(
|
||||
&mut self,
|
||||
scene: &mut SceneBuilder,
|
||||
view: &mut V,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
*self = match mem::take(self) {
|
||||
@ -321,9 +323,9 @@ impl<V: View, E: Element<V>> AnyElement<V> for Lifecycle<V, E> {
|
||||
|
||||
fn rect_for_text_range(
|
||||
&self,
|
||||
view: &V,
|
||||
range_utf16: Range<usize>,
|
||||
cx: &mut ViewContext<V>,
|
||||
view: &V,
|
||||
cx: &ViewContext<V>,
|
||||
) -> Option<RectF> {
|
||||
if let Lifecycle::PostPaint {
|
||||
element,
|
||||
@ -404,41 +406,40 @@ impl<V: View, E: Element<V>> Default for Lifecycle<V, E> {
|
||||
}
|
||||
|
||||
pub struct ElementBox<V: View> {
|
||||
element: Box<RefCell<dyn AnyElement<V>>>,
|
||||
element: Box<dyn AnyElement<V>>,
|
||||
view_type: PhantomData<V>,
|
||||
name: Option<Cow<'static, str>>,
|
||||
}
|
||||
|
||||
impl<V: View> ElementBox<V> {
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
self.0.name.as_deref()
|
||||
self.name.as_deref()
|
||||
}
|
||||
|
||||
pub fn metadata<T: 'static>(&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::<T>())
|
||||
}
|
||||
|
||||
pub fn layout(
|
||||
&self,
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> 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<V>,
|
||||
) {
|
||||
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<V: View> ElementBox<V> {
|
||||
view: &V,
|
||||
cx: &ViewContext<V>,
|
||||
) -> Option<RectF> {
|
||||
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<V>) -> 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<V: View> ElementBox<V> {
|
||||
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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,13 +46,13 @@ impl<V: View> Element<V> for Align<V> {
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view: &mut V,
|
||||
mut constraint: SizeConstraint,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (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<V: View> Element<V> for Align<V> {
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
view: &mut V,
|
||||
scene: &mut SceneBuilder,
|
||||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
let my_center = bounds.size() / 2.;
|
||||
@ -78,33 +78,33 @@ impl<V: View> Element<V> for Align<V> {
|
||||
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<usize>,
|
||||
_: RectF,
|
||||
_: RectF,
|
||||
_: &Self::LayoutState,
|
||||
_: &Self::PaintState,
|
||||
view: &V,
|
||||
cx: &ViewContext<V>,
|
||||
) -> Option<RectF> {
|
||||
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<V>,
|
||||
) -> json::Value {
|
||||
json!({
|
||||
|
@ -25,7 +25,7 @@ where
|
||||
|
||||
impl<V: View, F> Element<V> for Canvas<V, F>
|
||||
where
|
||||
F: FnMut(RectF, RectF, &mut ViewContext<V>),
|
||||
F: FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext<V>),
|
||||
{
|
||||
type LayoutState = ();
|
||||
type PaintState = ();
|
||||
@ -58,7 +58,7 @@ where
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
self.0(bounds, visible_bounds, cx)
|
||||
self.0(scene, bounds, visible_bounds, view, cx)
|
||||
}
|
||||
|
||||
fn rect_for_text_range(
|
||||
|
@ -37,10 +37,10 @@ impl<V: View> Element<V> for Clipped<V> {
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
cx.scene.push_layer(Some(bounds));
|
||||
scene.paint_layer(Some(bounds), |scene| {
|
||||
self.child
|
||||
.paint(scene, bounds.origin(), visible_bounds, view, cx);
|
||||
cx.scene.pop_layer();
|
||||
.paint(scene, bounds.origin(), visible_bounds, view, cx)
|
||||
})
|
||||
}
|
||||
|
||||
fn rect_for_text_range(
|
||||
|
@ -157,7 +157,7 @@ impl<V: View> Element<V> for ConstrainedBox<V> {
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> 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);
|
||||
})
|
||||
|
@ -221,7 +221,7 @@ impl<V: View> Element<V> for Container<V> {
|
||||
);
|
||||
|
||||
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<V: View> Element<V> for Container<V> {
|
||||
|
||||
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<V: View> Element<V> for Container<V> {
|
||||
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<V: View> Element<V> for Container<V> {
|
||||
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<V: View> Element<V> for Container<V> {
|
||||
.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ impl<V: View> Element<V> for Empty {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
_: &V,
|
||||
_: &mut V,
|
||||
_: &mut ViewContext<V>,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
let x = if constraint.max.x().is_finite() && !self.collapsed {
|
||||
@ -56,6 +56,7 @@ impl<V: View> Element<V> for Empty {
|
||||
_: RectF,
|
||||
_: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
_: &mut V,
|
||||
_: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ impl<V: View> Element<V> for Expanded<V> {
|
||||
&mut self,
|
||||
mut constraint: SizeConstraint,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<Self>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
if self.full_width {
|
||||
constraint.min.set_x(constraint.max.x());
|
||||
|
@ -73,7 +73,7 @@ impl<V: View> Flex<V> {
|
||||
remaining_space: &mut f32,
|
||||
remaining_flex: &mut f32,
|
||||
cross_axis_max: &mut f32,
|
||||
view: &V,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
let cross_axis = self.axis.invert();
|
||||
@ -124,7 +124,7 @@ impl<V: View> Element<V> for Flex<V> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
view: &V,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
let mut total_flex = None;
|
||||
@ -253,7 +253,7 @@ impl<V: View> Element<V> for Flex<V> {
|
||||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
remaining_space: &mut Self::LayoutState,
|
||||
view: &V,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
|
||||
@ -261,16 +261,16 @@ impl<V: View> Element<V> for Flex<V> {
|
||||
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::<Self>(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<V: View> Element<V> for Flex<V> {
|
||||
}
|
||||
}
|
||||
})
|
||||
.on_move(|_, _| { /* Capture move events */ }),
|
||||
.on_move(|_, _: &mut V, _| { /* Capture move events */ }),
|
||||
)
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ impl<V: View> Element<V> for Flex<V> {
|
||||
}
|
||||
|
||||
if overflowing {
|
||||
cx.scene.pop_layer();
|
||||
scene.pop_layer();
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,7 +372,7 @@ impl<V: View> Element<V> for Flex<V> {
|
||||
) -> Option<RectF> {
|
||||
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<V: View> Element<V> for FlexItem<V> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
view: &V,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
let size = self.child.layout(constraint, view, cx);
|
||||
@ -444,7 +444,7 @@ impl<V: View> Element<V> for FlexItem<V> {
|
||||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
view: &V,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
self.child
|
||||
@ -474,7 +474,6 @@ impl<V: View> Element<V> for FlexItem<V> {
|
||||
_: &Self::LayoutState,
|
||||
_: &Self::PaintState,
|
||||
view: &V,
|
||||
|
||||
cx: &ViewContext<V>,
|
||||
) -> Value {
|
||||
json!({
|
||||
|
@ -35,7 +35,7 @@ impl<V: View> Element<V> for Hook<V> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
view: &V,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
let size = self.child.layout(constraint, view, cx);
|
||||
|
@ -62,7 +62,7 @@ impl<V: View> Element<V> for Image {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
view: &V,
|
||||
_: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
let data = match &self.source {
|
||||
@ -94,8 +94,8 @@ impl<V: View> Element<V> for Image {
|
||||
bounds: RectF,
|
||||
_: RectF,
|
||||
layout: &mut Self::LayoutState,
|
||||
_: &V,
|
||||
cx: &mut ViewContext<V>,
|
||||
_: &mut V,
|
||||
_: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
if let Some(data) = layout {
|
||||
scene.push_image(scene::Image {
|
||||
|
@ -41,12 +41,11 @@ impl<V: View> Element<V> for KeystrokeLabel {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
view: &V,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (Vector2F, ElementBox<V>) {
|
||||
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<V: View> Element<V> for KeystrokeLabel {
|
||||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
element: &mut ElementBox<V>,
|
||||
view: &V,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
element.paint(scene, bounds.origin(), visible_bounds, view, cx);
|
||||
|
@ -134,13 +134,15 @@ impl<V: View> Element<V> for Label {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
view: &V,
|
||||
_: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (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<V: View> Element<V> for Label {
|
||||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
line: &mut Self::LayoutState,
|
||||
_: &V,
|
||||
cx: &mut ViewContext<Self>,
|
||||
_: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
line.paint(
|
||||
scene,
|
||||
|
@ -13,7 +13,6 @@ pub struct List<V: View> {
|
||||
state: ListState<V>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ListState<V: View>(Rc<RefCell<StateInner<V>>>);
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
@ -42,7 +41,7 @@ pub struct ListOffset {
|
||||
|
||||
enum ListItem<V: View> {
|
||||
Unrendered,
|
||||
Rendered(Rc<ElementBox<V>>),
|
||||
Rendered(Rc<RefCell<ElementBox<V>>>),
|
||||
Removed(f32),
|
||||
}
|
||||
|
||||
@ -145,7 +144,7 @@ impl<V: View> Element<V> for List<V> {
|
||||
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<V: View> Element<V> for List<V> {
|
||||
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<V: View> Element<V> for List<V> {
|
||||
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<V: View> Element<V> for List<V> {
|
||||
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<V: View> Element<V> for List<V> {
|
||||
);
|
||||
|
||||
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<V: View> Element<V> for List<V> {
|
||||
}
|
||||
|
||||
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<V: View> Element<V> for List<V> {
|
||||
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::<Vec<_>>();
|
||||
let visible_range = scroll_top.item_ix..(scroll_top.item_ix + visible_elements.len());
|
||||
json!({
|
||||
@ -345,8 +351,7 @@ impl<V: View> ListState<V> {
|
||||
element_count: usize,
|
||||
orientation: Orientation,
|
||||
overdraw: f32,
|
||||
cx: &mut ViewContext<V>,
|
||||
mut render_item: F,
|
||||
render_item: F,
|
||||
) -> Self
|
||||
where
|
||||
V: View,
|
||||
@ -354,14 +359,9 @@ impl<V: View> ListState<V> {
|
||||
{
|
||||
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<V: View> ListState<V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> Clone for ListState<V> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> StateInner<V> {
|
||||
fn render_item(
|
||||
&mut self,
|
||||
@ -447,13 +453,13 @@ impl<V: View> StateInner<V> {
|
||||
constraint: SizeConstraint,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Option<Rc<ElementBox<V>>> {
|
||||
) -> Option<Rc<RefCell<ElementBox<V>>>> {
|
||||
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<V: View> StateInner<V> {
|
||||
&'a self,
|
||||
bounds: RectF,
|
||||
scroll_top: &ListOffset,
|
||||
) -> impl Iterator<Item = (Rc<ElementBox<V>>, Vector2F)> + 'a {
|
||||
) -> impl Iterator<Item = (Rc<RefCell<ElementBox<V>>>, Vector2F)> + 'a {
|
||||
let mut item_origin = bounds.origin() - vec2f(0., scroll_top.offset_in_item);
|
||||
let mut cursor = self.items.cursor::<Count>();
|
||||
cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
|
||||
@ -481,7 +487,7 @@ impl<V: View> StateInner<V> {
|
||||
|
||||
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<V: View> StateInner<V> {
|
||||
|
||||
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<V: View> ListItem<V> {
|
||||
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<V: View> sum_tree::Item for ListItem<V> {
|
||||
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) {
|
||||
|
@ -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<Tag: 'static, V: View> {
|
||||
/// 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<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
pub fn new<F>(region_id: usize, view: &mut V, cx: &mut ViewContext<V>, render_child: F) -> Self
|
||||
pub fn new<F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: FnOnce(&mut MouseState, &mut V, &mut ViewContext<V>) -> ElementBox<V>,
|
||||
F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> ElementBox<V>,
|
||||
{
|
||||
let mut mouse_state = cx.mouse_state::<Tag>(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<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
/// 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<F>(
|
||||
region_id: usize,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
render_child: F,
|
||||
) -> Self
|
||||
pub fn above<F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: FnOnce(&mut MouseState, &mut V, &mut ViewContext<V>) -> ElementBox<V>,
|
||||
F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> ElementBox<V>,
|
||||
{
|
||||
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<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn on_move(mut self, handler: impl Fn(MouseMove, &mut ViewContext<V>) + 'static) -> Self {
|
||||
pub fn on_move(
|
||||
mut self,
|
||||
handler: impl Fn(MouseMove, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_move(handler);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn on_move_out(
|
||||
mut self,
|
||||
handler: impl Fn(MouseMoveOut, &mut ViewContext<V>) + 'static,
|
||||
handler: impl Fn(MouseMoveOut, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_move_out(handler);
|
||||
self
|
||||
@ -98,7 +96,7 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
pub fn on_down(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(MouseDown, &mut ViewContext<V>) + 'static,
|
||||
handler: impl Fn(MouseDown, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_down(button, handler);
|
||||
self
|
||||
@ -107,7 +105,7 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
pub fn on_up(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(MouseUp, &mut ViewContext<V>) + 'static,
|
||||
handler: impl Fn(MouseUp, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_up(button, handler);
|
||||
self
|
||||
@ -116,7 +114,7 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
pub fn on_click(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(MouseClick, &mut ViewContext<V>) + 'static,
|
||||
handler: impl Fn(MouseClick, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_click(button, handler);
|
||||
self
|
||||
@ -125,7 +123,7 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
pub fn on_down_out(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(MouseDownOut, &mut ViewContext<V>) + 'static,
|
||||
handler: impl Fn(MouseDownOut, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_down_out(button, handler);
|
||||
self
|
||||
@ -134,7 +132,7 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
pub fn on_up_out(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(MouseUpOut, &mut ViewContext<V>) + 'static,
|
||||
handler: impl Fn(MouseUpOut, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_up_out(button, handler);
|
||||
self
|
||||
@ -143,20 +141,23 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
pub fn on_drag(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(MouseDrag, &mut ViewContext<V>) + 'static,
|
||||
handler: impl Fn(MouseDrag, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_drag(button, handler);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn on_hover(mut self, handler: impl Fn(MouseHover, &mut ViewContext<V>) + 'static) -> Self {
|
||||
pub fn on_hover(
|
||||
mut self,
|
||||
handler: impl Fn(MouseHover, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_hover(handler);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn on_scroll(
|
||||
mut self,
|
||||
handler: impl Fn(MouseScrollWheel, &mut ViewContext<V>) + 'static,
|
||||
handler: impl Fn(MouseScrollWheel, &mut V, &mut EventContext<V>) + 'static,
|
||||
) -> Self {
|
||||
self.handlers = self.handlers.on_scroll(handler);
|
||||
self
|
||||
@ -191,14 +192,14 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||
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::<Tag>(
|
||||
cx.current_view_id(),
|
||||
cx.view_id(),
|
||||
self.region_id,
|
||||
hit_bounds,
|
||||
self.handlers.clone(),
|
||||
@ -236,7 +237,7 @@ impl<Tag, V: View> Element<V> for MouseEventHandler<Tag, V> {
|
||||
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<Tag, V: View> Element<V> for MouseEventHandler<Tag, V> {
|
||||
_: &Self::LayoutState,
|
||||
_: &Self::PaintState,
|
||||
view: &V,
|
||||
cx: &ViewContext<Self>,
|
||||
cx: &ViewContext<V>,
|
||||
) -> Option<RectF> {
|
||||
self.child.rect_for_text_range(range_utf16, view, cx)
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ impl<V: View> Element<V> for Overlay<V> {
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (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<V: View> Element<V> for Overlay<V> {
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
scene: SceneBuilder,
|
||||
scene: &mut SceneBuilder,
|
||||
bounds: RectF,
|
||||
_: RectF,
|
||||
size: &mut Self::LayoutState,
|
||||
@ -163,9 +163,9 @@ impl<V: View> Element<V> for Overlay<V> {
|
||||
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<V: View> Element<V> for Overlay<V> {
|
||||
|
||||
// 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<V: View> Element<V> for Overlay<V> {
|
||||
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,14 +212,13 @@ impl<V: View> Element<V> for Overlay<V> {
|
||||
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::<OverlayHoverCapture>(
|
||||
cx.current_view_id(),
|
||||
cx.current_view_id(),
|
||||
scene.push_mouse_region(MouseRegion::new::<OverlayHoverCapture>(
|
||||
cx.view_id(),
|
||||
cx.view_id(),
|
||||
bounds,
|
||||
));
|
||||
}
|
||||
@ -227,7 +226,7 @@ impl<V: View> Element<V> for Overlay<V> {
|
||||
self.child.paint(
|
||||
scene,
|
||||
bounds.origin(),
|
||||
RectF::new(Vector2F::zero(), cx.window_size),
|
||||
RectF::new(Vector2F::zero(), cx.window_size()),
|
||||
view,
|
||||
cx,
|
||||
);
|
||||
|
@ -154,22 +154,18 @@ impl<V: View> Element<V> for Resizable<V> {
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> 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::<ResizeHandle>(
|
||||
cx.current_view_id(),
|
||||
self.side as usize,
|
||||
handle_region,
|
||||
)
|
||||
.on_down(MouseButton::Left, |_, _| {}) // This prevents the mouse down event from being propagated elsewhere
|
||||
scene.push_mouse_region(
|
||||
MouseRegion::new::<ResizeHandle>(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, cx| {
|
||||
move |e, _: &mut V, cx| {
|
||||
let prev_width = state.actual_dimension.get();
|
||||
state
|
||||
.custom_dimension
|
||||
@ -179,7 +175,7 @@ impl<V: View> Element<V> for Resizable<V> {
|
||||
}),
|
||||
);
|
||||
|
||||
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<V: View> Element<V> for Resizable<V> {
|
||||
},
|
||||
});
|
||||
|
||||
cx.scene.pop_stacking_context();
|
||||
scene.pop_stacking_context();
|
||||
|
||||
self.child
|
||||
.paint(scene, bounds.origin(), visible_bounds, view, cx);
|
||||
|
@ -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<V: View> {
|
||||
children: Vec<ElementBox<V>>,
|
||||
}
|
||||
|
||||
impl<V: View> Default for Stack<V> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
children: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> Stack<V> {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
@ -53,7 +60,7 @@ impl<V: View> Element<V> for Stack<V> {
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> 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);
|
||||
});
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ impl<V: View> Element<V> for Svg {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
view: &mut V,
|
||||
_: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
match cx.asset_cache.svg(&self.path) {
|
||||
|
@ -98,7 +98,7 @@ impl<V: View> Element<V> 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<V: View> Element<V> for Text {
|
||||
/// Perform text layout on a series of highlighted chunks of text.
|
||||
pub fn layout_highlighted_chunks<'a>(
|
||||
chunks: impl Iterator<Item = (&'a str, Option<HighlightStyle>)>,
|
||||
text_style: &'a TextStyle,
|
||||
text_layout_cache: &'a TextLayoutCache,
|
||||
font_cache: &'a Arc<FontCache>,
|
||||
text_style: &TextStyle,
|
||||
text_layout_cache: &TextLayoutCache,
|
||||
font_cache: &Arc<FontCache>,
|
||||
max_line_len: usize,
|
||||
max_line_count: usize,
|
||||
) -> Vec<Line> {
|
||||
@ -276,27 +276,23 @@ 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(), || {
|
||||
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)),
|
||||
&mut presenter.build_layout_context(Default::default(), false, cx),
|
||||
view,
|
||||
cx,
|
||||
);
|
||||
assert_eq!(state.shaped_lines.len(), 2);
|
||||
assert_eq!(state.wrap_boundaries.len(), 2);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
struct TestView;
|
||||
|
@ -55,7 +55,6 @@ impl<V: View> Tooltip<V> {
|
||||
action: Option<Box<dyn Action>>,
|
||||
style: TooltipStyle,
|
||||
child: ElementBox<V>,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self {
|
||||
struct ElementState<Tag>(Tag);
|
||||
@ -78,10 +77,10 @@ impl<V: View> Tooltip<V> {
|
||||
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,12 +92,11 @@ impl<V: View> Tooltip<V> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let child =
|
||||
MouseEventHandler::<MouseEventHandlerState<Tag>>::new(id, view, cx, |_, _| child)
|
||||
.on_hover(move |e, cx| {
|
||||
let child = MouseEventHandler::<MouseEventHandlerState<Tag>, _>::new(id, 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() {
|
||||
let view_id = cx.view_id();
|
||||
if e.started {
|
||||
if !state.visible.get() {
|
||||
state.position.set(position);
|
||||
@ -107,7 +105,7 @@ impl<V: View> Tooltip<V> {
|
||||
if debounce.is_none() {
|
||||
*debounce = Some(cx.spawn({
|
||||
let state = state.clone();
|
||||
|mut cx| async move {
|
||||
|_, mut cx| async move {
|
||||
cx.background().timer(DEBOUNCE_TIMEOUT).await;
|
||||
state.visible.set(true);
|
||||
cx.update(|cx| cx.notify_view(window_id, view_id));
|
||||
@ -120,7 +118,6 @@ impl<V: View> Tooltip<V> {
|
||||
state.debounce.take();
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
})
|
||||
.boxed();
|
||||
Self {
|
||||
@ -137,7 +134,7 @@ impl<V: View> Tooltip<V> {
|
||||
style: TooltipStyle,
|
||||
action: Option<Box<dyn Action>>,
|
||||
measure: bool,
|
||||
) -> impl Element {
|
||||
) -> impl Element<V> {
|
||||
Flex::row()
|
||||
.with_child({
|
||||
let text = Text::new(text, style.text)
|
||||
@ -181,7 +178,7 @@ impl<V: View> Element<V> for Tooltip<V> {
|
||||
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,
|
||||
);
|
||||
|
@ -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<V: View> {
|
||||
state: UniformListState,
|
||||
item_count: usize,
|
||||
#[allow(clippy::type_complexity)]
|
||||
append_items: Box<dyn Fn(Range<usize>, &mut Vec<ElementBox<V>>, &mut V, &mut ViewContext<V>)>,
|
||||
append_items: Box<dyn Fn(&mut V, Range<usize>, &mut Vec<ElementBox<V>>, &mut ViewContext<V>)>,
|
||||
padding_top: f32,
|
||||
padding_bottom: f32,
|
||||
get_width_from_item: Option<usize>,
|
||||
@ -63,19 +62,12 @@ impl<V: View> UniformList<V> {
|
||||
) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: 'static + Fn(&mut V, Range<usize>, &mut Vec<ElementBox<V>>, &mut V, &mut ViewContext<V>),
|
||||
F: 'static + Fn(&mut V, Range<usize>, &mut Vec<ElementBox<V>>, &mut ViewContext<V>),
|
||||
{
|
||||
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<V: View> Element<V> for UniformList<V> {
|
||||
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<V: View> Element<V> for UniformList<V> {
|
||||
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<V: View> Element<V> for UniformList<V> {
|
||||
|
||||
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<V: View> Element<V> for UniformList<V> {
|
||||
) -> 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>(self.view_id, 0, visible_bounds).on_scroll({
|
||||
let scroll_max = layout.scroll_max;
|
||||
let state = self.state.clone();
|
||||
move |MouseScrollWheel {
|
||||
platform_event:
|
||||
ScrollWheelEvent {
|
||||
move |event, _, cx| {
|
||||
let ScrollWheelEvent {
|
||||
position, delta, ..
|
||||
},
|
||||
..
|
||||
},
|
||||
cx| {
|
||||
} = event.platform_event;
|
||||
if !Self::scroll(
|
||||
state.clone(),
|
||||
position,
|
||||
@ -328,7 +317,7 @@ impl<V: View> Element<V> for UniformList<V> {
|
||||
item_origin += vec2f(0.0, layout.item_height);
|
||||
}
|
||||
|
||||
cx.scene.pop_layer();
|
||||
scene.pop_layer();
|
||||
}
|
||||
|
||||
fn rect_for_text_range(
|
||||
|
@ -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;
|
||||
|
@ -236,6 +236,19 @@ impl SceneBuilder {
|
||||
self.scale_factor
|
||||
}
|
||||
|
||||
pub fn paint_stacking_context<F>(
|
||||
&mut self,
|
||||
clip_bounds: Option<RectF>,
|
||||
z_index: Option<usize>,
|
||||
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<RectF>, z_index: Option<usize>) {
|
||||
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<F>(&mut self, clip_bounds: Option<RectF>, 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<RectF>) {
|
||||
self.active_stacking_context().push_layer(clip_bounds);
|
||||
}
|
||||
|
@ -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<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseDown, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseDown, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_down(button, handler);
|
||||
self
|
||||
@ -72,7 +78,7 @@ impl MouseRegion {
|
||||
pub fn on_up<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseUp, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseUp, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_up(button, handler);
|
||||
self
|
||||
@ -81,7 +87,7 @@ impl MouseRegion {
|
||||
pub fn on_click<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseClick, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseClick, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_click(button, handler);
|
||||
self
|
||||
@ -90,7 +96,7 @@ impl MouseRegion {
|
||||
pub fn on_down_out<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseDownOut, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseDownOut, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_down_out(button, handler);
|
||||
self
|
||||
@ -99,7 +105,7 @@ impl MouseRegion {
|
||||
pub fn on_up_out<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseUpOut, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseUpOut, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_up_out(button, handler);
|
||||
self
|
||||
@ -108,7 +114,7 @@ impl MouseRegion {
|
||||
pub fn on_drag<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseDrag, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseDrag, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_drag(button, handler);
|
||||
self
|
||||
@ -117,7 +123,7 @@ impl MouseRegion {
|
||||
pub fn on_hover<V, F>(mut self, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(&mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseHover, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_hover(handler);
|
||||
self
|
||||
@ -126,7 +132,7 @@ impl MouseRegion {
|
||||
pub fn on_move<V, F>(mut self, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(&mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseMove, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_move(handler);
|
||||
self
|
||||
@ -135,7 +141,7 @@ impl MouseRegion {
|
||||
pub fn on_move_out<V, F>(mut self, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(&mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseMoveOut, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_move_out(handler);
|
||||
self
|
||||
@ -144,7 +150,7 @@ impl MouseRegion {
|
||||
pub fn on_scroll<V, F>(mut self, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(&mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseScrollWheel, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
self.handlers = self.handlers.on_scroll(handler);
|
||||
self
|
||||
@ -196,7 +202,39 @@ impl MouseRegionId {
|
||||
}
|
||||
}
|
||||
|
||||
pub type HandlerCallback = Rc<dyn Fn(MouseEvent, &mut WindowContext)>;
|
||||
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<V: View> DerefMut for EventContext<'_, '_, '_, '_, V> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.view_context
|
||||
}
|
||||
}
|
||||
|
||||
pub type HandlerCallback = Rc<dyn Fn(MouseEvent, &mut dyn Any, &mut WindowContext, usize) -> 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<V, F>(mut self, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseMove, &mut V, &mut ViewContext<Self>) + 'static,
|
||||
F: Fn(MouseMove, &mut V, &mut EventContext<V>) + '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<V, F>(mut self, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseMoveOut, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseMoveOut, &mut V, &mut EventContext<V>) + '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::<V>::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<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseDown, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseDown, &mut V, &mut EventContext<V>) + '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<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseUp, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseUp, &mut V, &mut EventContext<V>) + '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<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseClick, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseClick, &mut V, &mut EventContext<V>) + '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<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseDownOut, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseDownOut, &mut V, &mut EventContext<V>) + '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<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseUpOut, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseUpOut, &mut V, &mut EventContext<V>) + '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<V, F>(mut self, button: MouseButton, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseDrag, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseDrag, &mut V, &mut EventContext<V>) + '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<V, F>(mut self, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseHover, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseHover, &mut V, &mut EventContext<V>) + '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<V, F>(mut self, handler: F) -> Self
|
||||
where
|
||||
V: View,
|
||||
F: Fn(MouseScrollWheel, &mut V, &mut ViewContext<V>) + 'static,
|
||||
F: Fn(MouseScrollWheel, &mut V, &mut EventContext<V>) + '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 {:?}",
|
||||
|
@ -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,
|
||||
|
@ -106,11 +106,7 @@ impl View for Select {
|
||||
Default::default()
|
||||
};
|
||||
let mut result = Flex::column().with_child(
|
||||
MouseEventHandler::<Header>::new(
|
||||
self.handle.id(),
|
||||
self,
|
||||
cx,
|
||||
|mouse_state, this, cx| {
|
||||
MouseEventHandler::<Header, _>::new(self.handle.id(), cx, |mouse_state, cx| {
|
||||
Container::new((self.render_item)(
|
||||
self.selected_item_ix,
|
||||
ItemType::Header,
|
||||
@ -119,9 +115,8 @@ impl View for Select {
|
||||
))
|
||||
.with_style(style.header)
|
||||
.boxed()
|
||||
},
|
||||
)
|
||||
.on_click(MouseButton::Left, move |_, cx| {
|
||||
})
|
||||
.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::<Item>::new(
|
||||
MouseEventHandler::<Item, _>::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()
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> 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()
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
ChildView::new(&self.picker, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
ChildView::new(&self.picker, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<D: PickerDelegate> View for Picker<D> {
|
||||
"Picker"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::ElementBox {
|
||||
let theme = (self.theme.lock())(&cx.global::<settings::Settings>().theme);
|
||||
let query = self.query(cx);
|
||||
let delegate = self.delegate.clone();
|
||||
|
@ -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<usize>,
|
||||
cx: &mut RenderContext<ProjectPanel>,
|
||||
mut callback: impl FnMut(ProjectEntryId, EntryDetails, &mut RenderContext<ProjectPanel>),
|
||||
cx: &mut ViewContext<ProjectPanel>,
|
||||
mut callback: impl FnMut(ProjectEntryId, EntryDetails, &mut ViewContext<ProjectPanel>),
|
||||
) {
|
||||
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<V>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> ElementBox {
|
||||
let kind = details.kind;
|
||||
let show_editor = details.is_editing && !details.is_processing;
|
||||
@ -1154,7 +1154,7 @@ impl ProjectPanel {
|
||||
editor: &ViewHandle<Editor>,
|
||||
dragged_entry_destination: &mut Option<Arc<Path>>,
|
||||
theme: &theme::ProjectPanel,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> 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<Workspace>| {
|
||||
move |_, cx: &mut ViewContext<Workspace>| {
|
||||
let theme = cx.global::<Settings>().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::<Settings>().theme.project_panel;
|
||||
let mut container_style = theme.container;
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
ChildView::new(&self.picker, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
ChildView::new(&self.picker, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<ElementBox> {
|
||||
if !option_supported {
|
||||
return None;
|
||||
@ -364,7 +363,7 @@ impl BufferSearchBar {
|
||||
&self,
|
||||
icon: &'static str,
|
||||
direction: Direction,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> ElementBox {
|
||||
let action: Box<dyn Action>;
|
||||
let tooltip;
|
||||
@ -408,11 +407,7 @@ impl BufferSearchBar {
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn render_close_button(
|
||||
&self,
|
||||
theme: &theme::Search,
|
||||
cx: &mut RenderContext<Self>,
|
||||
) -> ElementBox {
|
||||
fn render_close_button(&self, theme: &theme::Search, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let action = Box::new(Dismiss);
|
||||
let tooltip = "Dismiss Buffer Search";
|
||||
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> 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<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> ElementBox {
|
||||
let action: Box<dyn Action>;
|
||||
let tooltip;
|
||||
@ -795,7 +794,7 @@ impl ProjectSearchBar {
|
||||
&self,
|
||||
icon: &'static str,
|
||||
option: SearchOption,
|
||||
cx: &mut RenderContext<Self>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> ElementBox {
|
||||
let tooltip_style = cx.global::<Settings>().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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
if let Some(search) = self.active_project_search.as_ref() {
|
||||
let search = search.read(cx);
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
@ -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::<TerminalView>())
|
||||
|
@ -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<ElementBox>,
|
||||
hyperlink_tooltip: Option<ElementBox<TerminalView>>,
|
||||
}
|
||||
|
||||
///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<TerminalView>,
|
||||
) {
|
||||
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<TerminalView>,
|
||||
) {
|
||||
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<TerminalView>,
|
||||
) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
|
||||
let settings = cx.global::<Settings>();
|
||||
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<TerminalView>,
|
||||
) -> 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<TerminalView>::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,
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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<T: 'static, V: View>(
|
||||
pub fn checkbox<Tag: 'static, V: View>(
|
||||
label: &'static str,
|
||||
style: &CheckboxStyle,
|
||||
checked: bool,
|
||||
cx: &mut RenderContext<V>,
|
||||
change: fn(checked: bool, cx: &mut EventContext) -> (),
|
||||
) -> MouseEventHandler<T> {
|
||||
cx: &mut ViewContext<V>,
|
||||
change: fn(checked: bool, cx: &mut EventContext<V>) -> (),
|
||||
) -> MouseEventHandler<Tag, V> {
|
||||
let label = Label::new(label, style.label.text.clone())
|
||||
.contained()
|
||||
.with_style(style.label.container)
|
||||
@ -42,14 +42,14 @@ pub fn checkbox<T: 'static, V: View>(
|
||||
checkbox_with_label(label, style, checked, cx, change)
|
||||
}
|
||||
|
||||
pub fn checkbox_with_label<T: 'static, V: View>(
|
||||
label: ElementBox,
|
||||
pub fn checkbox_with_label<Tag: 'static, V: View>(
|
||||
label: ElementBox<V>,
|
||||
style: &CheckboxStyle,
|
||||
checked: bool,
|
||||
cx: &mut RenderContext<V>,
|
||||
change: fn(checked: bool, cx: &mut EventContext) -> (),
|
||||
) -> MouseEventHandler<T> {
|
||||
MouseEventHandler::<T>::new(0, cx, |state, _| {
|
||||
cx: &mut ViewContext<V>,
|
||||
change: fn(checked: bool, cx: &mut EventContext<V>) -> (),
|
||||
) -> MouseEventHandler<Tag, V> {
|
||||
MouseEventHandler::new(0, cx, |state, _| {
|
||||
let indicator = if checked {
|
||||
svg(&style.icon)
|
||||
} else {
|
||||
@ -82,7 +82,7 @@ pub fn checkbox_with_label<T: 'static, V: View>(
|
||||
.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<V: View>(style: &SvgStyle) -> ConstrainedBox<V> {
|
||||
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<V: View>(style: &IconStyle) -> Container<V> {
|
||||
svg(&style.icon).contained().with_style(style.container)
|
||||
}
|
||||
|
||||
@ -130,8 +130,8 @@ pub fn keystroke_label<V: View>(
|
||||
label_style: &ContainedText,
|
||||
keystroke_style: &ContainedText,
|
||||
action: Box<dyn Action>,
|
||||
cx: &mut RenderContext<V>,
|
||||
) -> Container {
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Container<V> {
|
||||
// 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<V: View>(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn keystroke_label_for(
|
||||
pub fn keystroke_label_for<V: View>(
|
||||
window_id: usize,
|
||||
view_id: usize,
|
||||
label_text: &'static str,
|
||||
label_style: &ContainedText,
|
||||
keystroke_style: &ContainedText,
|
||||
action: Box<dyn Action>,
|
||||
) -> Container {
|
||||
) -> Container<V> {
|
||||
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<ContainedText>;
|
||||
|
||||
pub fn cta_button<L, A, V>(
|
||||
pub fn cta_button<Tag, L, A, V>(
|
||||
label: L,
|
||||
action: A,
|
||||
max_width: f32,
|
||||
style: &ButtonStyle,
|
||||
cx: &mut RenderContext<V>,
|
||||
) -> ElementBox
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> ElementBox<V>
|
||||
where
|
||||
Tag: 'static,
|
||||
L: Into<Cow<'static, str>>,
|
||||
A: 'static + Action + Clone,
|
||||
V: View,
|
||||
{
|
||||
cta_button_with_click(label, max_width, style, cx, move |_, cx| {
|
||||
cta_button_with_click::<Tag, _, _, _>(label, max_width, style, cx, move |_, _, cx| {
|
||||
cx.dispatch_action(action.clone())
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
pub fn cta_button_with_click<L, V, F>(
|
||||
pub fn cta_button_with_click<Tag, L, V, F>(
|
||||
label: L,
|
||||
max_width: f32,
|
||||
style: &ButtonStyle,
|
||||
cx: &mut RenderContext<V>,
|
||||
cx: &mut ViewContext<V>,
|
||||
f: F,
|
||||
) -> MouseEventHandler<F>
|
||||
) -> MouseEventHandler<Tag, V>
|
||||
where
|
||||
Tag: 'static,
|
||||
L: Into<Cow<'static, str>>,
|
||||
V: View,
|
||||
F: Fn(MouseClick, &mut EventContext) + 'static,
|
||||
F: Fn(MouseClick, &mut V, &mut EventContext<V>) + 'static,
|
||||
{
|
||||
MouseEventHandler::<F>::new(0, cx, |state, _| {
|
||||
MouseEventHandler::<Tag, V>::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<V, I, F>(
|
||||
pub fn modal<Tag, V, I, F>(
|
||||
title: I,
|
||||
style: &ModalStyle,
|
||||
cx: &mut RenderContext<V>,
|
||||
cx: &mut ViewContext<V>,
|
||||
build_modal: F,
|
||||
) -> ElementBox
|
||||
) -> ElementBox<V>
|
||||
where
|
||||
Tag: 'static,
|
||||
V: View,
|
||||
I: Into<Cow<'static, str>>,
|
||||
F: FnOnce(&mut gpui::RenderContext<V>) -> ElementBox,
|
||||
F: FnOnce(&mut gpui::ViewContext<V>) -> ElementBox<V>,
|
||||
{
|
||||
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::<V>::new(999999, cx, |state, _cx| {
|
||||
MouseEventHandler::<Tag, V>::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);
|
||||
})
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
ChildView::new(&self.picker, cx).boxed()
|
||||
}
|
||||
|
||||
|
@ -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<fn(&StyleSet) -> &Style>,
|
||||
cx: &mut RenderContext<'_, Self>,
|
||||
cx: &mut ViewContext<'_, Self>,
|
||||
) -> ElementBox {
|
||||
enum TestBenchButton {}
|
||||
MouseEventHandler::<TestBenchButton>::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::<Settings>();
|
||||
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::<Settings>().theme.clone().color_scheme;
|
||||
|
||||
Flex::row()
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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::<Settings>();
|
||||
let theme = settings.theme.clone();
|
||||
|
@ -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<Workspace>,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<ElementBox> {
|
||||
let style = &theme.workspace.dock;
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
|
@ -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::<Settings>().theme.clone();
|
||||
let theme = &theme.simple_message_notification;
|
||||
|
||||
|
@ -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<Self>) -> impl Element {
|
||||
fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
let pane = cx.handle();
|
||||
@ -1302,7 +1301,7 @@ impl Pane {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
let detail = detail.clone();
|
||||
move |dragged_item, cx: &mut RenderContext<Workspace>| {
|
||||
move |dragged_item, cx: &mut ViewContext<Workspace>| {
|
||||
let tab_style = &theme.workspace.tab_bar.dragged_tab;
|
||||
Self::render_tab(
|
||||
&dragged_item.item,
|
||||
@ -1384,7 +1383,7 @@ impl Pane {
|
||||
detail: Option<usize>,
|
||||
hovered: bool,
|
||||
tab_style: &theme::Tab,
|
||||
cx: &mut RenderContext<V>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> 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<Self>,
|
||||
) -> ElementBox {
|
||||
fn render_tab_bar_buttons(&mut self, theme: &Theme, cx: &mut ViewContext<Self>) -> 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<Self>) -> ElementBox {
|
||||
fn render_blank_pane(&mut self, theme: &Theme, _cx: &mut ViewContext<Self>) -> 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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let this = cx.handle();
|
||||
|
||||
enum MouseNavigationHandler {}
|
||||
@ -1705,7 +1700,7 @@ impl View for Pane {
|
||||
fn render_tab_bar_button<A: Action + Clone>(
|
||||
index: usize,
|
||||
icon: &'static str,
|
||||
cx: &mut RenderContext<Pane>,
|
||||
cx: &mut ViewContext<Pane>,
|
||||
action: A,
|
||||
context_menu: Option<ViewHandle<ContextMenu>>,
|
||||
) -> ElementBox {
|
||||
@ -1853,7 +1848,7 @@ impl PaneBackdrop {
|
||||
}
|
||||
}
|
||||
|
||||
impl Element for PaneBackdrop {
|
||||
impl Element<Pane> 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<Pane>,
|
||||
) -> (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<Pane>,
|
||||
) -> Self::PaintState {
|
||||
let background = cx.global::<Settings>().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::<Self>(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<V>,
|
||||
) -> Option<RectF> {
|
||||
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<V>,
|
||||
) -> 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),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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<Tag, F>(
|
||||
drop_index: usize,
|
||||
allow_same_pane: bool,
|
||||
split_margin: Option<f32>,
|
||||
cx: &mut RenderContext<Pane>,
|
||||
cx: &mut ViewContext<Pane>,
|
||||
render_child: F,
|
||||
) -> MouseEventHandler<Tag>
|
||||
where
|
||||
Tag: 'static,
|
||||
F: FnOnce(&mut MouseState, &mut RenderContext<Pane>) -> ElementBox,
|
||||
F: FnOnce(&mut MouseState, &mut ViewContext<Pane>) -> ElementBox,
|
||||
{
|
||||
MouseEventHandler::<Tag>::above(region_id, cx, |state, cx| {
|
||||
MouseEventHandler::<Tag>::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<f32>,
|
||||
cx: &mut EventContext,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
enum Action {
|
||||
Move(WeakViewHandle<Pane>, usize),
|
||||
@ -110,11 +110,11 @@ pub fn handle_dropped_item(
|
||||
}
|
||||
let drag_and_drop = cx.global::<DragAndDrop<Workspace>>();
|
||||
let action = if let Some((_, dragged_item)) =
|
||||
drag_and_drop.currently_dragged::<DraggedItem>(cx.window_id)
|
||||
drag_and_drop.currently_dragged::<DraggedItem>(cx.window_id())
|
||||
{
|
||||
Action::Move(dragged_item.pane.clone(), dragged_item.item.id())
|
||||
} else if let Some((_, project_entry)) =
|
||||
drag_and_drop.currently_dragged::<ProjectEntryId>(cx.window_id)
|
||||
drag_and_drop.currently_dragged::<ProjectEntryId>(cx.window_id())
|
||||
{
|
||||
Action::Open(*project_entry)
|
||||
} else {
|
||||
|
@ -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<ActiveCall>>,
|
||||
active_pane: &ViewHandle<Pane>,
|
||||
cx: &mut RenderContext<Workspace>,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> ElementBox {
|
||||
self.root.render(
|
||||
project,
|
||||
@ -131,7 +131,7 @@ impl Member {
|
||||
follower_states: &FollowerStatesByLeader,
|
||||
active_call: Option<&ModelHandle<ActiveCall>>,
|
||||
active_pane: &ViewHandle<Pane>,
|
||||
cx: &mut RenderContext<Workspace>,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> ElementBox {
|
||||
enum FollowIntoExternalProject {}
|
||||
|
||||
@ -366,7 +366,7 @@ impl PaneAxis {
|
||||
follower_state: &FollowerStatesByLeader,
|
||||
active_call: Option<&ModelHandle<ActiveCall>>,
|
||||
active_pane: &ViewHandle<Pane>,
|
||||
cx: &mut RenderContext<Workspace>,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> ElementBox {
|
||||
let last_member_ix = self.members.len() - 1;
|
||||
Flex::new(self.axis)
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> 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(),
|
||||
});
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
if let Some(active_item) = self.active_item() {
|
||||
enum ResizeHandleTag {}
|
||||
let style = &cx.global::<Settings>().theme.workspace.sidebar;
|
||||
@ -225,7 +225,7 @@ impl View for SidebarButtons {
|
||||
"SidebarToggleButton"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = &cx.global::<Settings>().theme;
|
||||
let tooltip_style = theme.tooltip.clone();
|
||||
let theme = &theme.workspace.status_bar.sidebar_buttons;
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = &cx.global::<Settings>().theme.workspace.status_bar;
|
||||
|
||||
StatusBarElement {
|
||||
@ -143,44 +143,49 @@ struct StatusBarElement {
|
||||
right: ElementBox,
|
||||
}
|
||||
|
||||
impl Element for StatusBarElement {
|
||||
impl<V: View> Element<V> for StatusBarElement {
|
||||
type LayoutState = ();
|
||||
type PaintState = ();
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
mut constraint: SizeConstraint,
|
||||
cx: &mut LayoutContext,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (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<V>,
|
||||
) -> 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(
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = &cx.global::<Settings>().theme.workspace.toolbar;
|
||||
|
||||
let mut primary_left_items = Vec::new();
|
||||
@ -168,7 +168,7 @@ fn nav_button<A: Action + Clone>(
|
||||
action: A,
|
||||
tooltip_action: A,
|
||||
action_name: &str,
|
||||
cx: &mut RenderContext<Toolbar>,
|
||||
cx: &mut ViewContext<Toolbar>,
|
||||
) -> ElementBox {
|
||||
MouseEventHandler::<A>::new(0, cx, |state, _| {
|
||||
let style = if enabled {
|
||||
|
@ -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<Self>) -> ElementBox {
|
||||
fn render_titlebar(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> 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<Workspace>) -> Option<ElementBox> {
|
||||
fn render_disconnected_overlay(&self, cx: &mut ViewContext<Workspace>) -> Option<ElementBox> {
|
||||
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<Self>) -> ElementBox {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
Stack::new()
|
||||
.with_child(
|
||||
|
Loading…
Reference in New Issue
Block a user