This commit is contained in:
Nathan Sobo 2023-04-12 10:07:17 -06:00
parent 83070a19c4
commit 868301bedb
26 changed files with 194 additions and 175 deletions

View file

@ -41,7 +41,7 @@ impl View for Breadcrumbs {
"Breadcrumbs" "Breadcrumbs"
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let active_item = match &self.active_item { let active_item = match &self.active_item {
Some(active_item) => active_item, Some(active_item) => active_item,
None => return Empty::new().boxed(), None => return Empty::new().boxed(),

View file

@ -7,7 +7,8 @@ use gpui::{
}, },
json::ToJson, json::ToJson,
serde_json::{self, json}, serde_json::{self, json},
Axis, DebugContext, Element, ElementBox, MeasurementContext, PaintContext, Axis, DebugContext, Element, ElementBox, MeasurementContext, PaintContext, SceneBuilder,
ViewContext,
}; };
pub(crate) struct FacePile { pub(crate) struct FacePile {
@ -24,14 +25,15 @@ impl FacePile {
} }
} }
impl Element for FacePile { impl<V: View> Element<V> for FacePile {
type LayoutState = (); type LayoutState = ();
type PaintState = (); type PaintState = ();
fn layout( fn layout(
&mut self, &mut self,
constraint: gpui::SizeConstraint, constraint: gpui::SizeConstraint,
cx: &mut gpui::LayoutContext, view: &mut Self,
cx: &mut ViewContext<Self>,
) -> (Vector2F, Self::LayoutState) { ) -> (Vector2F, Self::LayoutState) {
debug_assert!(constraint.max_along(Axis::Horizontal) == f32::INFINITY); debug_assert!(constraint.max_along(Axis::Horizontal) == f32::INFINITY);
@ -46,10 +48,12 @@ impl Element for FacePile {
fn paint( fn paint(
&mut self, &mut self,
scene: &mut SceneBuilder,
bounds: RectF, bounds: RectF,
visible_bounds: RectF, visible_bounds: RectF,
_layout: &mut Self::LayoutState, _layout: &mut Self::LayoutState,
cx: &mut PaintContext, view: &mut Self,
cx: &mut ViewContext<Self>,
) -> Self::PaintState { ) -> Self::PaintState {
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
@ -59,7 +63,7 @@ impl Element for FacePile {
for face in self.faces.iter_mut().rev() { for face in self.faces.iter_mut().rev() {
let size = face.size(); let size = face.size();
origin_x -= size.x(); origin_x -= size.x();
cx.paint_layer(None, |cx| { scene.paint_layer(None, |scene| {
face.paint(scene, vec2f(origin_x, origin_y), visible_bounds, view, cx); face.paint(scene, vec2f(origin_x, origin_y), visible_bounds, view, cx);
}); });
origin_x += self.overlap; origin_x += self.overlap;
@ -94,8 +98,8 @@ impl Element for FacePile {
} }
} }
impl Extend<ElementBox> for FacePile { impl Extend<ElementBox<Self>> for FacePile {
fn extend<T: IntoIterator<Item = ElementBox>>(&mut self, children: T) { fn extend<T: IntoIterator<Item = ElementBox<Self>>>(&mut self, children: T) {
self.faces.extend(children); self.faces.extend(children);
} }
} }

View file

@ -1176,9 +1176,7 @@ mod tests {
} }
fn editor_blocks(editor: &ViewHandle<Editor>, cx: &mut AppContext) -> Vec<(u32, String)> { fn editor_blocks(editor: &ViewHandle<Editor>, cx: &mut AppContext) -> Vec<(u32, String)> {
let mut presenter = cx.build_window(editor.id(), 0., Default::default()); editor.update(cx, |editor, cx| {
let mut cx = presenter.build_layout_context(Default::default(), false, cx);
cx.render(editor, |editor, cx| {
let snapshot = editor.snapshot(cx); let snapshot = editor.snapshot(cx);
snapshot snapshot
.blocks_in_range(0..snapshot.max_point().row()) .blocks_in_range(0..snapshot.max_point().row())

View file

@ -32,7 +32,7 @@ impl View for DeployFeedbackButton {
let theme = cx.global::<Settings>().theme.clone(); let theme = cx.global::<Settings>().theme.clone();
Stack::new() Stack::new()
.with_child( .with_child(
MouseEventHandler::<Self>::new(0, cx, |state, _| { MouseEventHandler::<Self, Self>::new(0, cx, |state, _| {
let style = &theme let style = &theme
.workspace .workspace
.status_bar .status_bar
@ -53,12 +53,12 @@ impl View for DeployFeedbackButton {
.boxed() .boxed()
}) })
.with_cursor_style(CursorStyle::PointingHand) .with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, move |_, cx| { .on_click(MouseButton::Left, move |_, _, cx| {
if !active { if !active {
cx.dispatch_action(GiveFeedback) cx.dispatch_action(GiveFeedback)
} }
}) })
.with_tooltip::<Self, _>( .with_tooltip::<Self>(
0, 0,
"Send Feedback".into(), "Send Feedback".into(),
Some(Box::new(GiveFeedback)), Some(Box::new(GiveFeedback)),

View file

@ -43,7 +43,7 @@ impl View for FeedbackInfoText {
.boxed(), .boxed(),
) )
.with_child( .with_child(
MouseEventHandler::<OpenZedCommunityRepo>::new(0, cx, |state, _| { MouseEventHandler::<OpenZedCommunityRepo, Self>::new(0, cx, |state, _| {
let contained_text = if state.hovered() { let contained_text = if state.hovered() {
&theme.feedback.link_text_hover &theme.feedback.link_text_hover
} else { } else {
@ -58,7 +58,7 @@ impl View for FeedbackInfoText {
.boxed() .boxed()
}) })
.with_cursor_style(CursorStyle::PointingHand) .with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, cx| { .on_click(MouseButton::Left, |_, _, cx| {
cx.dispatch_action(OpenZedCommunityRepo) cx.dispatch_action(OpenZedCommunityRepo)
}) })
.boxed(), .boxed(),

View file

@ -32,7 +32,7 @@ impl View for SubmitFeedbackButton {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> { fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let theme = cx.global::<Settings>().theme.clone(); let theme = cx.global::<Settings>().theme.clone();
enum SubmitFeedbackButton {} enum SubmitFeedbackButton {}
MouseEventHandler::<SubmitFeedbackButton>::new(0, cx, |state, _| { MouseEventHandler::<SubmitFeedbackButton, Self>::new(0, cx, |state, _| {
let style = theme.feedback.submit_button.style_for(state, false); let style = theme.feedback.submit_button.style_for(state, false);
Label::new("Submit as Markdown", style.text.clone()) Label::new("Submit as Markdown", style.text.clone())
.contained() .contained()
@ -40,13 +40,13 @@ impl View for SubmitFeedbackButton {
.boxed() .boxed()
}) })
.with_cursor_style(CursorStyle::PointingHand) .with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, cx| { .on_click(MouseButton::Left, |_, _, cx| {
cx.dispatch_action(SubmitFeedback) cx.dispatch_action(SubmitFeedback)
}) })
.aligned() .aligned()
.contained() .contained()
.with_margin_left(theme.feedback.button_margin) .with_margin_left(theme.feedback.button_margin)
.with_tooltip::<Self, _>( .with_tooltip::<Self>(
0, 0,
"cmd-s".into(), "cmd-s".into(),
Some(Box::new(SubmitFeedback)), Some(Box::new(SubmitFeedback)),

View file

@ -3823,6 +3823,94 @@ impl<V: View> UpdateView for ViewContext<'_, '_, '_, V> {
} }
} }
pub struct EventContext<'a, 'b, 'c, 'd, V: View> {
view_context: &'d mut ViewContext<'a, 'b, 'c, V>,
pub(crate) handled: bool,
}
impl<'a, 'b, 'c, 'd, V: View> EventContext<'a, 'b, 'c, 'd, V> {
pub(crate) 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
}
}
impl<V: View> UpdateModel for EventContext<'_, '_, '_, '_, V> {
fn update_model<T: Entity, O>(
&mut self,
handle: &ModelHandle<T>,
update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
) -> O {
self.view_context.update_model(handle, update)
}
}
impl<V: View> ReadView for EventContext<'_, '_, '_, '_, V> {
fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
self.view_context.read_view(handle)
}
}
impl<V: View> UpdateView for EventContext<'_, '_, '_, '_, V> {
fn update_view<T, S>(
&mut self,
handle: &ViewHandle<T>,
update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
) -> S
where
T: View,
{
self.view_context.update_view(handle, update)
}
}
impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, '_, V> {
fn upgrade_model_handle<T: Entity>(
&self,
handle: &WeakModelHandle<T>,
) -> Option<ModelHandle<T>> {
self.view_context.upgrade_model_handle(handle)
}
fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
self.view_context.model_handle_is_upgradable(handle)
}
fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
self.view_context.upgrade_any_model_handle(handle)
}
}
impl<V: View> UpgradeViewHandle for EventContext<'_, '_, '_, '_, V> {
fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
self.view_context.upgrade_view_handle(handle)
}
fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
self.view_context.upgrade_any_view_handle(handle)
}
}
pub(crate) enum Reference<'a, T> { pub(crate) enum Reference<'a, T> {
Immutable(&'a T), Immutable(&'a T),
Mutable(&'a mut T), Mutable(&'a mut T),

View file

@ -7,10 +7,11 @@ use crate::{
platform::CursorStyle, platform::CursorStyle,
platform::MouseButton, platform::MouseButton,
scene::{ scene::{
CursorRegion, EventContext, HandlerSet, MouseClick, MouseDown, MouseDownOut, MouseDrag, CursorRegion, HandlerSet, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseHover,
MouseHover, MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut,
}, },
Element, ElementBox, MouseRegion, MouseState, SceneBuilder, SizeConstraint, View, ViewContext, Element, ElementBox, EventContext, MouseRegion, MouseState, SceneBuilder, SizeConstraint, View,
ViewContext,
}; };
use serde_json::json; use serde_json::json;
use std::{marker::PhantomData, ops::Range}; use std::{marker::PhantomData, ops::Range};

View file

@ -15,9 +15,7 @@ pub use clipboard::ClipboardItem;
pub mod fonts; pub mod fonts;
pub mod geometry; pub mod geometry;
pub mod scene; pub mod scene;
pub use scene::{ pub use scene::{Border, CursorRegion, MouseRegion, MouseRegionId, Quad, Scene, SceneBuilder};
Border, CursorRegion, EventContext, MouseRegion, MouseRegionId, Quad, Scene, SceneBuilder,
};
pub mod text_layout; pub mod text_layout;
pub use text_layout::TextLayoutCache; pub use text_layout::TextLayoutCache;
mod util; mod util;

View file

@ -1,22 +1,14 @@
use crate::{platform::MouseButton, window::WindowContext, EventContext, View, ViewContext};
use collections::HashMap;
use pathfinder_geometry::rect::RectF;
use smallvec::SmallVec;
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
fmt::Debug, fmt::Debug,
mem::Discriminant, mem::Discriminant,
ops::{Deref, DerefMut},
rc::Rc, rc::Rc,
}; };
use collections::HashMap;
use pathfinder_geometry::rect::RectF;
use smallvec::SmallVec;
use crate::{
platform::MouseButton, window::WindowContext, AnyModelHandle, AnyViewHandle,
AnyWeakModelHandle, AnyWeakViewHandle, Entity, ModelHandle, ReadView, UpgradeModelHandle,
UpgradeViewHandle, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle,
};
use super::{ use super::{
mouse_event::{ mouse_event::{
MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, MouseMove, MouseUp, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, MouseMove, MouseUp,
@ -206,71 +198,6 @@ impl MouseRegionId {
} }
} }
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
}
}
impl<V: View> ReadView for EventContext<'_, '_, '_, '_, V> {
fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
self.view_context.read_view(handle)
}
}
impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, '_, V> {
fn upgrade_model_handle<T: Entity>(
&self,
handle: &WeakModelHandle<T>,
) -> Option<ModelHandle<T>> {
self.view_context.upgrade_model_handle(handle)
}
fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
self.view_context.model_handle_is_upgradable(handle)
}
fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
self.view_context.upgrade_any_model_handle(handle)
}
}
impl<V: View> UpgradeViewHandle for EventContext<'_, '_, '_, '_, V> {
fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
self.view_context.upgrade_view_handle(handle)
}
fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
self.view_context.upgrade_any_view_handle(handle)
}
}
pub type HandlerCallback = Rc<dyn Fn(MouseEvent, &mut dyn Any, &mut WindowContext, usize) -> bool>; pub type HandlerCallback = Rc<dyn Fn(MouseEvent, &mut dyn Any, &mut WindowContext, usize) -> bool>;
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]

View file

@ -1,8 +1,8 @@
use serde::Deserialize; use serde::Deserialize;
use crate::{ use crate::{
actions, elements::*, impl_actions, platform::MouseButton, AppContext, Entity, View, actions, elements::*, impl_actions, platform::MouseButton, AppContext, Entity, EventContext,
ViewContext, WeakViewHandle, View, ViewContext, WeakViewHandle,
}; };
pub struct Select { pub struct Select {
@ -116,9 +116,10 @@ impl View for Select {
.with_style(style.header) .with_style(style.header)
.boxed() .boxed()
}) })
.on_click(MouseButton::Left, move |_, _, cx| { .on_click(
cx.dispatch_action(ToggleSelect) MouseButton::Left,
}) move |_, _, cx: &mut EventContext<Self>| cx.dispatch_action(ToggleSelect),
)
.boxed(), .boxed(),
); );
if self.is_open { if self.is_open {
@ -150,9 +151,12 @@ impl View for Select {
) )
}, },
) )
.on_click(MouseButton::Left, move |_, _, cx| { .on_click(
cx.dispatch_action(SelectItem(ix)) MouseButton::Left,
}) move |_, _, cx: &mut EventContext<Self>| {
cx.dispatch_action(SelectItem(ix))
},
)
.boxed() .boxed()
})) }))
}, },

View file

@ -50,7 +50,7 @@ impl View for ActiveBufferLanguage {
"ActiveBufferLanguage" "ActiveBufferLanguage"
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
if let Some(active_language) = self.active_language.as_ref() { if let Some(active_language) = self.active_language.as_ref() {
let active_language_text = if let Some(active_language_text) = active_language { let active_language_text = if let Some(active_language_text) = active_language {
active_language_text.to_string() active_language_text.to_string()
@ -58,7 +58,7 @@ impl View for ActiveBufferLanguage {
"Unknown".to_string() "Unknown".to_string()
}; };
MouseEventHandler::<Self>::new(0, cx, |state, cx| { MouseEventHandler::<Self, Self>::new(0, cx, |state, cx| {
let theme = &cx.global::<Settings>().theme.workspace.status_bar; let theme = &cx.global::<Settings>().theme.workspace.status_bar;
let style = theme.active_language.style_for(state, false); let style = theme.active_language.style_for(state, false);
Label::new(active_language_text, style.text.clone()) Label::new(active_language_text, style.text.clone())
@ -67,7 +67,9 @@ impl View for ActiveBufferLanguage {
.boxed() .boxed()
}) })
.with_cursor_style(CursorStyle::PointingHand) .with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, cx| cx.dispatch_action(crate::Toggle)) .on_click(MouseButton::Left, |_, _, cx| {
cx.dispatch_action(crate::Toggle)
})
.boxed() .boxed()
} else { } else {
Empty::new().boxed() Empty::new().boxed()

View file

@ -120,7 +120,7 @@ impl View for LanguageSelector {
"LanguageSelector" "LanguageSelector"
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
ChildView::new(&self.picker, cx).boxed() ChildView::new(&self.picker, cx).boxed()
} }
@ -210,7 +210,7 @@ impl PickerDelegate for LanguageSelector {
mouse_state: &mut MouseState, mouse_state: &mut MouseState,
selected: bool, selected: bool,
cx: &AppContext, cx: &AppContext,
) -> ElementBox { ) -> ElementBox<Picker<Self>> {
let settings = cx.global::<Settings>(); let settings = cx.global::<Settings>();
let theme = &settings.theme; let theme = &settings.theme;
let mat = &self.matches[ix]; let mat = &self.matches[ix];

View file

@ -48,7 +48,7 @@ impl View for OutlineView {
"OutlineView" "OutlineView"
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
ChildView::new(&self.picker, cx).boxed() ChildView::new(&self.picker, cx).boxed()
} }
@ -238,7 +238,7 @@ impl PickerDelegate for OutlineView {
mouse_state: &mut MouseState, mouse_state: &mut MouseState,
selected: bool, selected: bool,
cx: &AppContext, cx: &AppContext,
) -> ElementBox { ) -> ElementBox<Picker<Self>> {
let settings = cx.global::<Settings>(); let settings = cx.global::<Settings>();
let string_match = &self.matches[ix]; let string_match = &self.matches[ix];
let style = settings.theme.picker.item.style_for(mouse_state, selected); let style = settings.theme.picker.item.style_for(mouse_state, selected);

View file

@ -1251,7 +1251,7 @@ impl ProjectPanel {
.as_draggable(entry_id, { .as_draggable(entry_id, {
let row_container_style = theme.dragged_entry.container; let row_container_style = theme.dragged_entry.container;
move |_, _, cx: &mut ViewContext<Workspace>| { move |_, cx: &mut ViewContext<ProjectPanel>| {
let theme = cx.global::<Settings>().theme.clone(); let theme = cx.global::<Settings>().theme.clone();
Self::render_entry_visual_element( Self::render_entry_visual_element(
&details, &details,

View file

@ -48,7 +48,7 @@ impl View for ProjectSymbolsView {
"ProjectSymbolsView" "ProjectSymbolsView"
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
ChildView::new(&self.picker, cx).boxed() ChildView::new(&self.picker, cx).boxed()
} }
@ -238,7 +238,7 @@ impl PickerDelegate for ProjectSymbolsView {
mouse_state: &mut MouseState, mouse_state: &mut MouseState,
selected: bool, selected: bool,
cx: &AppContext, cx: &AppContext,
) -> ElementBox { ) -> ElementBox<Picker<Self>> {
let string_match = &self.matches[ix]; let string_match = &self.matches[ix];
let settings = cx.global::<Settings>(); let settings = cx.global::<Settings>();
let style = &settings.theme.picker.item; let style = &settings.theme.picker.item;

View file

@ -3,7 +3,7 @@ use std::path::Path;
use fuzzy::StringMatch; use fuzzy::StringMatch;
use gpui::{ use gpui::{
elements::{Label, LabelStyle}, elements::{Label, LabelStyle},
Element, ElementBox, Element, ElementBox, View,
}; };
use workspace::WorkspaceLocation; use workspace::WorkspaceLocation;
@ -42,7 +42,7 @@ impl HighlightedText {
} }
} }
pub fn render(self, style: impl Into<LabelStyle>) -> ElementBox { pub fn render<V: View>(self, style: impl Into<LabelStyle>) -> ElementBox<V> {
Label::new(self.text, style) Label::new(self.text, style)
.with_highlights(self.highlight_positions) .with_highlights(self.highlight_positions)
.boxed() .boxed()

View file

@ -101,7 +101,7 @@ impl View for RecentProjectsView {
"RecentProjectsView" "RecentProjectsView"
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
ChildView::new(&self.picker, cx).boxed() ChildView::new(&self.picker, cx).boxed()
} }
@ -183,7 +183,7 @@ impl PickerDelegate for RecentProjectsView {
mouse_state: &mut gpui::MouseState, mouse_state: &mut gpui::MouseState,
selected: bool, selected: bool,
cx: &gpui::AppContext, cx: &gpui::AppContext,
) -> ElementBox { ) -> ElementBox<Picker<Self>> {
let settings = cx.global::<Settings>(); let settings = cx.global::<Settings>();
let string_match = &self.matches[ix]; let string_match = &self.matches[ix];
let style = settings.theme.picker.item.style_for(mouse_state, selected); let style = settings.theme.picker.item.style_for(mouse_state, selected);

View file

@ -410,7 +410,7 @@ impl TerminalElement {
), ),
) )
// Update drag selections // Update drag selections
.on_drag(MouseButton::Left, move |event, _, cx| { .on_drag(MouseButton::Left, move |event, _: &mut TerminalView, cx| {
if cx.is_parent_view_focused() { if cx.is_parent_view_focused() {
if let Some(conn_handle) = connection.upgrade(cx) { if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, cx| { conn_handle.update(cx, |terminal, cx| {
@ -432,7 +432,7 @@ impl TerminalElement {
), ),
) )
// Context menu // Context menu
.on_click(MouseButton::Right, move |e, _, cx| { .on_click(MouseButton::Right, move |e, _: &mut TerminalView, cx| {
let mouse_mode = if let Some(conn_handle) = connection.upgrade(cx) { let mouse_mode = if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, _cx| terminal.mouse_mode(e.shift)) conn_handle.update(cx, |terminal, _cx| terminal.mouse_mode(e.shift))
} else { } else {
@ -445,7 +445,7 @@ impl TerminalElement {
}); });
} }
}) })
.on_move(move |event, _, cx| { .on_move(move |event, _: &mut TerminalView, cx| {
if cx.is_parent_view_focused() { if cx.is_parent_view_focused() {
if let Some(conn_handle) = connection.upgrade(cx) { if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, cx| { conn_handle.update(cx, |terminal, cx| {
@ -455,7 +455,7 @@ impl TerminalElement {
} }
} }
}) })
.on_scroll(move |event, _, cx| { .on_scroll(move |event, _: &mut TerminalView, cx| {
if let Some(conn_handle) = connection.upgrade(cx) { if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, cx| { conn_handle.update(cx, |terminal, cx| {
terminal.scroll_wheel(event, origin); terminal.scroll_wheel(event, origin);
@ -598,27 +598,25 @@ impl Element<TerminalView> for TerminalElement {
}); });
let view_handle = self.view.clone(); let view_handle = self.view.clone();
let hyperlink_tooltip = last_hovered_hyperlink.and_then(|(uri, _, id)| { let hyperlink_tooltip = last_hovered_hyperlink.map(|(uri, _, id)| {
// last_mouse.and_then(|_last_mouse| { let mut tooltip = Overlay::new(
view_handle.upgrade(cx).map(|handle| { Empty::new()
let mut tooltip = cx.render(&handle, |_, cx| { .contained()
Overlay::new( .constrained()
Empty::new() .with_width(dimensions.width())
.contained() .with_height(dimensions.height())
.constrained() .with_tooltip::<TerminalElement>(id, uri, None, tooltip_style, cx)
.with_width(dimensions.width()) .boxed(),
.with_height(dimensions.height()) )
.with_tooltip::<TerminalElement, _>(id, uri, None, tooltip_style, cx) .with_position_mode(gpui::elements::OverlayPositionMode::Local)
.boxed(), .boxed();
)
.with_position_mode(gpui::elements::OverlayPositionMode::Local)
.boxed()
});
tooltip.layout(SizeConstraint::new(Vector2F::zero(), cx.window_size), cx); tooltip.layout(
tooltip SizeConstraint::new(Vector2F::zero(), cx.window_size()),
}) view,
// }) cx,
);
tooltip
}); });
let TerminalContent { let TerminalContent {
@ -647,7 +645,7 @@ impl Element<TerminalView> for TerminalElement {
cells, cells,
&text_style, &text_style,
&terminal_theme, &terminal_theme,
cx.text_layout_cache, cx.text_layout_cache(),
cx.font_cache(), cx.font_cache(),
last_hovered_hyperlink last_hovered_hyperlink
.as_ref() .as_ref()
@ -669,7 +667,7 @@ impl Element<TerminalView> for TerminalElement {
terminal_theme.foreground terminal_theme.foreground
}; };
cx.text_layout_cache.layout_str( cx.text_layout_cache().layout_str(
&str_trxt, &str_trxt,
text_style.font_size, text_style.font_size,
&[( &[(
@ -744,11 +742,11 @@ impl Element<TerminalView> for TerminalElement {
// Elements are ephemeral, only at paint time do we know what could be clicked by a mouse // Elements are ephemeral, only at paint time do we know what could be clicked by a mouse
self.attach_mouse_handlers( self.attach_mouse_handlers(
scene,
origin, origin,
self.view.id(), self.view.id(),
visible_bounds, visible_bounds,
layout.mode, layout.mode,
view,
cx, cx,
); );

View file

@ -396,7 +396,7 @@ impl View for TerminalView {
Stack::new() Stack::new()
.with_child( .with_child(
TerminalElement::new( TerminalElement::new(
cx.handle(), cx.handle().downgrade(),
terminal_handle, terminal_handle,
focused, focused,
self.should_show_cursor(focused, cx), self.should_show_cursor(focused, cx),

View file

@ -175,7 +175,7 @@ pub fn keystroke_label_for<V: View>(
pub type ButtonStyle = Interactive<ContainedText>; pub type ButtonStyle = Interactive<ContainedText>;
pub fn cta_button<Tag, L, A, V>( pub fn cta_button<L, A, V>(
label: L, label: L,
action: A, action: A,
max_width: f32, max_width: f32,
@ -183,12 +183,11 @@ pub fn cta_button<Tag, L, A, V>(
cx: &mut ViewContext<V>, cx: &mut ViewContext<V>,
) -> ElementBox<V> ) -> ElementBox<V>
where where
Tag: 'static,
L: Into<Cow<'static, str>>, L: Into<Cow<'static, str>>,
A: 'static + Action + Clone, A: 'static + Action + Clone,
V: View, V: View,
{ {
cta_button_with_click::<Tag, _, _, _>(label, max_width, style, cx, move |_, _, cx| { cta_button_with_click::<A, _, _, _>(label, max_width, style, cx, move |_, _, cx| {
cx.dispatch_action(action.clone()) cx.dispatch_action(action.clone())
}) })
.boxed() .boxed()

View file

@ -251,7 +251,7 @@ fn paste(_: &mut Workspace, _: &Paste, cx: &mut ViewContext<Workspace>) {
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.transact(cx, |editor, cx| { editor.transact(cx, |editor, cx| {
editor.set_clip_at_line_ends(false, cx); editor.set_clip_at_line_ends(false, cx);
if let Some(item) = cx.as_mut().read_from_clipboard() { if let Some(item) = cx.read_from_clipboard() {
let mut clipboard_text = Cow::Borrowed(item.text()); let mut clipboard_text = Cow::Borrowed(item.text());
if let Some(mut clipboard_selections) = if let Some(mut clipboard_selections) =
item.metadata::<Vec<ClipboardSelection>>() item.metadata::<Vec<ClipboardSelection>>()

View file

@ -209,7 +209,7 @@ pub fn paste(_: &mut Workspace, _: &VisualPaste, cx: &mut ViewContext<Workspace>
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.transact(cx, |editor, cx| { editor.transact(cx, |editor, cx| {
if let Some(item) = cx.as_mut().read_from_clipboard() { if let Some(item) = cx.read_from_clipboard() {
copy_selections_content(editor, editor.selections.line_mode, cx); copy_selections_content(editor, editor.selections.line_mode, cx);
let mut clipboard_text = Cow::Borrowed(item.text()); let mut clipboard_text = Cow::Borrowed(item.text());
if let Some(mut clipboard_selections) = if let Some(mut clipboard_selections) =

View file

@ -161,7 +161,7 @@ impl PickerDelegate for BaseKeymapSelector {
mouse_state: &mut gpui::MouseState, mouse_state: &mut gpui::MouseState,
selected: bool, selected: bool,
cx: &gpui::AppContext, cx: &gpui::AppContext,
) -> gpui::ElementBox { ) -> gpui::ElementBox<Picker<Self>> {
let theme = &cx.global::<Settings>().theme; let theme = &cx.global::<Settings>().theme;
let keymap_match = &self.matches[ix]; let keymap_match = &self.matches[ix];
let style = theme.picker.item.style_for(mouse_state, selected); let style = theme.picker.item.style_for(mouse_state, selected);

View file

@ -10,7 +10,7 @@ use gpui::{
use settings::{settings_file::SettingsFile, Settings}; use settings::{settings_file::SettingsFile, Settings};
use workspace::{ use workspace::{
item::Item, open_new, sidebar::SidebarSide, AppState, PaneBackdrop, Welcome, Workspace, item::Item, open_new, sidebar::SidebarSide, AppState, Pane, PaneBackdrop, Welcome, Workspace,
WorkspaceId, WorkspaceId,
}; };
@ -55,7 +55,7 @@ impl View for WelcomePage {
"WelcomePage" "WelcomePage"
} }
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox<Self> {
let self_handle = cx.handle(); let self_handle = cx.handle();
let settings = cx.global::<Settings>(); let settings = cx.global::<Settings>();
let theme = settings.theme.clone(); let theme = settings.theme.clone();
@ -203,7 +203,7 @@ impl Item for WelcomePage {
_detail: Option<usize>, _detail: Option<usize>,
style: &theme::Tab, style: &theme::Tab,
_cx: &gpui::AppContext, _cx: &gpui::AppContext,
) -> gpui::ElementBox { ) -> ElementBox<Pane> {
Flex::row() Flex::row()
.with_child( .with_child(
Label::new("Welcome to Zed!", style.label.clone()) Label::new("Welcome to Zed!", style.label.clone())

View file

@ -1851,13 +1851,13 @@ impl NavHistory {
} }
} }
pub struct PaneBackdrop { pub struct PaneBackdrop<V: View> {
child_view: usize, child_view: usize,
child: ElementBox<Pane>, child: ElementBox<V>,
} }
impl PaneBackdrop { impl<V: View> PaneBackdrop<V> {
pub fn new(pane_item_view: usize, child: ElementBox<Pane>) -> Self { pub fn new(pane_item_view: usize, child: ElementBox<V>) -> Self {
PaneBackdrop { PaneBackdrop {
child, child,
child_view: pane_item_view, child_view: pane_item_view,
@ -1865,7 +1865,7 @@ impl PaneBackdrop {
} }
} }
impl Element<Pane> for PaneBackdrop { impl<V: View> Element<V> for PaneBackdrop<V> {
type LayoutState = (); type LayoutState = ();
type PaintState = (); type PaintState = ();
@ -1873,8 +1873,8 @@ impl Element<Pane> for PaneBackdrop {
fn layout( fn layout(
&mut self, &mut self,
constraint: gpui::SizeConstraint, constraint: gpui::SizeConstraint,
view: &mut Pane, view: &mut V,
cx: &mut ViewContext<Pane>, cx: &mut ViewContext<V>,
) -> (Vector2F, Self::LayoutState) { ) -> (Vector2F, Self::LayoutState) {
let size = self.child.layout(constraint, view, cx); let size = self.child.layout(constraint, view, cx);
(size, ()) (size, ())
@ -1886,8 +1886,8 @@ impl Element<Pane> for PaneBackdrop {
bounds: RectF, bounds: RectF,
visible_bounds: RectF, visible_bounds: RectF,
_: &mut Self::LayoutState, _: &mut Self::LayoutState,
view: &mut Pane, view: &mut V,
cx: &mut ViewContext<Pane>, cx: &mut ViewContext<V>,
) -> Self::PaintState { ) -> Self::PaintState {
let background = cx.global::<Settings>().theme.editor.background; let background = cx.global::<Settings>().theme.editor.background;
@ -1903,7 +1903,7 @@ impl Element<Pane> for PaneBackdrop {
scene.push_mouse_region( scene.push_mouse_region(
MouseRegion::new::<Self>(child_view_id, 0, visible_bounds).on_down( MouseRegion::new::<Self>(child_view_id, 0, visible_bounds).on_down(
gpui::platform::MouseButton::Left, gpui::platform::MouseButton::Left,
move |_, _: &mut Pane, cx| { move |_, _: &mut V, cx| {
let window_id = cx.window_id(); let window_id = cx.window_id();
cx.app_context().focus(window_id, Some(child_view_id)) cx.app_context().focus(window_id, Some(child_view_id))
}, },
@ -1923,8 +1923,8 @@ impl Element<Pane> for PaneBackdrop {
_visible_bounds: RectF, _visible_bounds: RectF,
_layout: &Self::LayoutState, _layout: &Self::LayoutState,
_paint: &Self::PaintState, _paint: &Self::PaintState,
view: &Pane, view: &V,
cx: &gpui::ViewContext<Pane>, cx: &gpui::ViewContext<V>,
) -> Option<RectF> { ) -> Option<RectF> {
self.child.rect_for_text_range(range_utf16, view, cx) self.child.rect_for_text_range(range_utf16, view, cx)
} }
@ -1934,8 +1934,8 @@ impl Element<Pane> for PaneBackdrop {
_bounds: RectF, _bounds: RectF,
_layout: &Self::LayoutState, _layout: &Self::LayoutState,
_paint: &Self::PaintState, _paint: &Self::PaintState,
view: &Pane, view: &V,
cx: &gpui::ViewContext<Pane>, cx: &gpui::ViewContext<V>,
) -> serde_json::Value { ) -> serde_json::Value {
gpui::json::json!({ gpui::json::json!({
"type": "Pane Back Drop", "type": "Pane Back Drop",