mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-07 00:06:24 +03:00
WIP
This commit is contained in:
parent
e6cc132b19
commit
d9e4136b02
@ -802,6 +802,14 @@ impl AppContext {
|
||||
.is_some()
|
||||
}
|
||||
|
||||
pub fn window_is_active(&self, window_id: usize) -> bool {
|
||||
self.windows.get(&window_id).map_or(false, |w| w.is_active)
|
||||
}
|
||||
|
||||
pub fn root_view(&self, window_id: usize) -> Option<&AnyViewHandle> {
|
||||
self.windows.get(&window_id).map(|w| w.root_view())
|
||||
}
|
||||
|
||||
pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
|
||||
self.windows.keys().copied()
|
||||
}
|
||||
@ -1648,6 +1656,18 @@ impl AppContext {
|
||||
window
|
||||
}
|
||||
|
||||
pub fn replace_root_view<V, F>(
|
||||
&mut self,
|
||||
window_id: usize,
|
||||
build_root_view: F,
|
||||
) -> Option<ViewHandle<V>>
|
||||
where
|
||||
V: View,
|
||||
F: FnOnce(&mut ViewContext<V>) -> V,
|
||||
{
|
||||
self.update_window(window_id, |cx| cx.replace_root_view(build_root_view))
|
||||
}
|
||||
|
||||
pub fn add_view<S, F>(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle<S>
|
||||
where
|
||||
S: View,
|
||||
@ -3326,6 +3346,22 @@ impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
|
||||
self.window.focused_view_id == Some(self.view_id)
|
||||
}
|
||||
|
||||
pub fn is_parent_view_focused(&self) -> bool {
|
||||
if let Some(parent_view_id) = self.ancestors(self.window_id, self.view_id).next().clone() {
|
||||
self.focused_view_id() == Some(parent_view_id)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn focus_parent_view(&mut self) {
|
||||
let next = self.ancestors(self.window_id, self.view_id).next().clone();
|
||||
if let Some(parent_view_id) = next {
|
||||
let window_id = self.window_id;
|
||||
self.window_context.focus(window_id, Some(parent_view_id));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_child(&self, view: impl Into<AnyViewHandle>) -> bool {
|
||||
let view = view.into();
|
||||
if self.window_id != view.window_id {
|
||||
|
@ -12,8 +12,9 @@ use crate::{
|
||||
},
|
||||
text_layout::TextLayoutCache,
|
||||
util::post_inc,
|
||||
AnyView, AnyViewHandle, AppContext, Element, ElementBox, MouseRegion, MouseRegionId, ParentId,
|
||||
RenderParams, SceneBuilder, View, ViewContext, ViewHandle, WindowInvalidation,
|
||||
AnyView, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelContext, ModelHandle,
|
||||
MouseRegion, MouseRegionId, ParentId, ReadView, RenderParams, SceneBuilder, UpdateModel, View,
|
||||
ViewContext, ViewHandle, WindowInvalidation,
|
||||
};
|
||||
use anyhow::bail;
|
||||
use collections::{HashMap, HashSet};
|
||||
@ -119,6 +120,22 @@ impl DerefMut for WindowContext<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl UpdateModel for WindowContext<'_, '_> {
|
||||
fn update_model<M: Entity, R>(
|
||||
&mut self,
|
||||
handle: &ModelHandle<M>,
|
||||
update: &mut dyn FnMut(&mut M, &mut ModelContext<M>) -> R,
|
||||
) -> R {
|
||||
self.app_context.update_model(handle, update)
|
||||
}
|
||||
}
|
||||
|
||||
impl ReadView for WindowContext<'_, '_> {
|
||||
fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
|
||||
self.app_context.read_view(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
||||
pub fn new(app_context: &'a mut AppContext, window: &'b mut Window, window_id: usize) -> Self {
|
||||
Self {
|
||||
@ -133,6 +150,14 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
||||
self.window_id
|
||||
}
|
||||
|
||||
pub fn app_context(&mut self) -> &mut AppContext {
|
||||
self.app_context
|
||||
}
|
||||
|
||||
pub fn root_view(&self) -> &AnyViewHandle {
|
||||
self.window.root_view()
|
||||
}
|
||||
|
||||
pub fn window_size(&self) -> Vector2F {
|
||||
self.window.platform_window.content_size()
|
||||
}
|
||||
@ -701,23 +726,22 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
||||
}
|
||||
|
||||
pub fn rect_for_text_range(&self, range_utf16: Range<usize>) -> Option<RectF> {
|
||||
todo!()
|
||||
let root_view_id = self.window.root_view().id();
|
||||
self.window
|
||||
.rendered_views
|
||||
.get(&root_view_id)?
|
||||
.rect_for_text_range(range_utf16, self, root_view_id)
|
||||
}
|
||||
|
||||
pub fn debug_elements(&self) -> Option<json::Value> {
|
||||
todo!()
|
||||
// let view = self.root_view()?;
|
||||
// Some(json!({
|
||||
// "root_view": view.debug_json(self),
|
||||
// "root_element": self.window.rendered_views.get(&view.id())
|
||||
// .map(|root_element| {
|
||||
// root_element.debug(&DebugContext {
|
||||
// rendered_views: &self.window.rendered_views,
|
||||
// font_cache: &self.window.font_cache,
|
||||
// app: self,
|
||||
// })
|
||||
// })
|
||||
// }))
|
||||
let view = self.window.root_view();
|
||||
Some(json!({
|
||||
"root_view": view.debug_json(self),
|
||||
"root_element": self.window.rendered_views.get(&view.id())
|
||||
.map(|root_element| {
|
||||
root_element.debug(self, view.id())
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn set_window_title(&mut self, title: &str) {
|
||||
|
@ -11,7 +11,7 @@ use collections::HashMap;
|
||||
use pathfinder_geometry::rect::RectF;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{platform::MouseButton, window::WindowContext, View, ViewContext};
|
||||
use crate::{platform::MouseButton, window::WindowContext, ReadView, View, ViewContext};
|
||||
|
||||
use super::{
|
||||
mouse_event::{
|
||||
@ -234,6 +234,12 @@ impl<V: View> DerefMut for EventContext<'_, '_, '_, '_, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> ReadView for EventContext<'_, '_, '_, '_, V> {
|
||||
fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
|
||||
self.view_context.read_view(handle)
|
||||
}
|
||||
}
|
||||
|
||||
pub type HandlerCallback = Rc<dyn Fn(MouseEvent, &mut dyn Any, &mut WindowContext, usize) -> bool>;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -315,7 +315,7 @@ impl Dock {
|
||||
theme: &Theme,
|
||||
anchor: DockAnchor,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<ElementBox<Self>> {
|
||||
) -> Option<ElementBox<Workspace>> {
|
||||
let style = &theme.workspace.dock;
|
||||
|
||||
self.position
|
||||
@ -350,7 +350,7 @@ impl Dock {
|
||||
|
||||
let resizable = Container::new(ChildView::new(&self.pane, cx).boxed())
|
||||
.with_style(panel_style)
|
||||
.with_resize_handle::<DockResizeHandle, _>(
|
||||
.with_resize_handle::<DockResizeHandle>(
|
||||
resize_side as usize,
|
||||
resize_side,
|
||||
4.,
|
||||
@ -362,8 +362,8 @@ impl Dock {
|
||||
);
|
||||
|
||||
let size = resizable.current_size();
|
||||
let workspace = cx.handle();
|
||||
cx.defer(move |cx| {
|
||||
let workspace = cx.handle().downgrade();
|
||||
cx.defer(move |_, cx| {
|
||||
if let Some(workspace) = workspace.upgrade(cx) {
|
||||
workspace.update(cx, |workspace, _| {
|
||||
workspace.dock.panel_sizes.insert(anchor, size);
|
||||
@ -374,20 +374,20 @@ impl Dock {
|
||||
if anchor == DockAnchor::Right {
|
||||
resizable
|
||||
.constrained()
|
||||
.dynamically(|constraint, cx| {
|
||||
.dynamically(|constraint, _, cx| {
|
||||
SizeConstraint::new(
|
||||
Vector2F::new(20., constraint.min.y()),
|
||||
Vector2F::new(cx.window_size.x() * 0.8, constraint.max.y()),
|
||||
Vector2F::new(cx.window_size().x() * 0.8, constraint.max.y()),
|
||||
)
|
||||
})
|
||||
.boxed()
|
||||
} else {
|
||||
resizable
|
||||
.constrained()
|
||||
.dynamically(|constraint, cx| {
|
||||
.dynamically(|constraint, _, cx| {
|
||||
SizeConstraint::new(
|
||||
Vector2F::new(constraint.min.x(), 50.),
|
||||
Vector2F::new(constraint.max.x(), cx.window_size.y() * 0.8),
|
||||
Vector2F::new(constraint.max.x(), cx.window_size().y() * 0.8),
|
||||
)
|
||||
})
|
||||
.boxed()
|
||||
@ -399,21 +399,21 @@ impl Dock {
|
||||
Stack::new()
|
||||
.with_child(
|
||||
// Render wash under the dock which when clicked hides it
|
||||
MouseEventHandler::<ExpandedDockWash>::new(0, cx, |_, _| {
|
||||
MouseEventHandler::<ExpandedDockWash, _>::new(0, cx, |_, _| {
|
||||
Empty::new()
|
||||
.contained()
|
||||
.with_background_color(style.wash_color)
|
||||
.boxed()
|
||||
})
|
||||
.capture_all()
|
||||
.on_down(MouseButton::Left, |_, cx| {
|
||||
.on_down(MouseButton::Left, |_, _, cx| {
|
||||
cx.dispatch_action(HideDock);
|
||||
})
|
||||
.with_cursor_style(CursorStyle::Arrow)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
MouseEventHandler::<ExpandedDockPane>::new(0, cx, |_state, cx| {
|
||||
MouseEventHandler::<ExpandedDockPane, _>::new(0, cx, |_state, cx| {
|
||||
ChildView::new(&self.pane, cx).boxed()
|
||||
})
|
||||
// Make sure all events directly under the dock pane
|
||||
|
@ -43,11 +43,11 @@ impl View for ToggleDockButton {
|
||||
|
||||
let workspace = workspace.unwrap();
|
||||
let dock_position = workspace.read(cx).dock.position;
|
||||
let dock_pane = workspace.read(cx.app).dock_pane().clone();
|
||||
let dock_pane = workspace.read(cx).dock_pane().clone();
|
||||
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
let button = MouseEventHandler::<Self>::new(0, cx, {
|
||||
let button = MouseEventHandler::<Self, _>::new(0, cx, {
|
||||
let theme = theme.clone();
|
||||
move |state, _| {
|
||||
let style = theme
|
||||
@ -68,17 +68,17 @@ impl View for ToggleDockButton {
|
||||
}
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_up(MouseButton::Left, move |event, cx| {
|
||||
let drop_index = dock_pane.read(cx.app).items_len() + 1;
|
||||
.on_up(MouseButton::Left, move |event, _, cx| {
|
||||
let drop_index = dock_pane.read(cx).items_len() + 1;
|
||||
handle_dropped_item(event, &dock_pane.downgrade(), drop_index, false, None, cx);
|
||||
});
|
||||
|
||||
if dock_position.is_visible() {
|
||||
button
|
||||
.on_click(MouseButton::Left, |_, cx| {
|
||||
.on_click(MouseButton::Left, |_, _, cx| {
|
||||
cx.dispatch_action(HideDock);
|
||||
})
|
||||
.with_tooltip::<Self, _>(
|
||||
.with_tooltip::<Self>(
|
||||
0,
|
||||
"Hide Dock".into(),
|
||||
Some(Box::new(HideDock)),
|
||||
@ -87,10 +87,10 @@ impl View for ToggleDockButton {
|
||||
)
|
||||
} else {
|
||||
button
|
||||
.on_click(MouseButton::Left, |_, cx| {
|
||||
.on_click(MouseButton::Left, |_, _, cx| {
|
||||
cx.dispatch_action(FocusDock);
|
||||
})
|
||||
.with_tooltip::<Self, _>(
|
||||
.with_tooltip::<Self>(
|
||||
0,
|
||||
"Focus Dock".into(),
|
||||
Some(Box::new(FocusDock)),
|
||||
|
@ -52,7 +52,7 @@ pub trait Item: View {
|
||||
detail: Option<usize>,
|
||||
style: &theme::Tab,
|
||||
cx: &AppContext,
|
||||
) -> ElementBox<Self>;
|
||||
) -> ElementBox<Pane>;
|
||||
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {}
|
||||
fn is_singleton(&self, _cx: &AppContext) -> bool {
|
||||
false
|
||||
@ -134,7 +134,7 @@ pub trait Item: View {
|
||||
ToolbarItemLocation::Hidden
|
||||
}
|
||||
|
||||
fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option<Vec<ElementBox<Self>>> {
|
||||
fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
|
||||
None
|
||||
}
|
||||
|
||||
@ -591,7 +591,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
|
||||
self.read(cx).breadcrumb_location()
|
||||
}
|
||||
|
||||
fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<ElementBox<Self>>> {
|
||||
fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
|
||||
self.read(cx).breadcrumbs(theme, cx)
|
||||
}
|
||||
|
||||
@ -925,7 +925,7 @@ pub(crate) mod test {
|
||||
detail: Option<usize>,
|
||||
_: &theme::Tab,
|
||||
_: &AppContext,
|
||||
) -> ElementBox<Self> {
|
||||
) -> ElementBox<Pane> {
|
||||
self.tab_detail.set(detail);
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ pub mod simple_message_notification {
|
||||
|
||||
let has_click_action = click_action.is_some();
|
||||
|
||||
MouseEventHandler::<MessageNotificationTag>::new(0, cx, |state, cx| {
|
||||
MouseEventHandler::<MessageNotificationTag, _>::new(0, cx, |state, cx| {
|
||||
Flex::column()
|
||||
.with_child(
|
||||
Flex::row()
|
||||
@ -259,7 +259,7 @@ pub mod simple_message_notification {
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
MouseEventHandler::<Cancel>::new(0, cx, |state, _| {
|
||||
MouseEventHandler::<Cancel, _>::new(0, cx, |state, _| {
|
||||
let style = theme.dismiss_button.style_for(state, false);
|
||||
Svg::new("icons/x_mark_8.svg")
|
||||
.with_color(style.color)
|
||||
@ -274,7 +274,7 @@ pub mod simple_message_notification {
|
||||
.boxed()
|
||||
})
|
||||
.with_padding(Padding::uniform(5.))
|
||||
.on_click(MouseButton::Left, move |_, cx| {
|
||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
||||
cx.dispatch_action(CancelMessageNotification)
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
@ -312,9 +312,9 @@ pub mod simple_message_notification {
|
||||
.boxed()
|
||||
})
|
||||
// Since we're not using a proper overlay, we have to capture these extra events
|
||||
.on_down(MouseButton::Left, |_, _| {})
|
||||
.on_up(MouseButton::Left, |_, _| {})
|
||||
.on_click(MouseButton::Left, move |_, cx| {
|
||||
.on_down(MouseButton::Left, |_, _, _| {})
|
||||
.on_up(MouseButton::Left, |_, _, _| {})
|
||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
||||
if let Some(click_action) = click_action.as_ref() {
|
||||
cx.dispatch_any_action(click_action.boxed_clone());
|
||||
cx.dispatch_action(CancelMessageNotification)
|
||||
|
@ -1220,10 +1220,10 @@ impl Pane {
|
||||
});
|
||||
}
|
||||
|
||||
fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
|
||||
fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Element<Self> {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
let pane = cx.handle();
|
||||
let pane = cx.handle().downgrade();
|
||||
let autoscroll = if mem::take(&mut self.autoscroll) {
|
||||
Some(self.active_item_index)
|
||||
} else {
|
||||
@ -1233,7 +1233,7 @@ impl Pane {
|
||||
let pane_active = self.is_active;
|
||||
|
||||
enum Tabs {}
|
||||
let mut row = Flex::row().scrollable::<Tabs, _>(1, autoscroll, cx);
|
||||
let mut row = Flex::row().scrollable::<Tabs>(1, autoscroll, cx);
|
||||
for (ix, (item, detail)) in self
|
||||
.items
|
||||
.iter()
|
||||
@ -1260,8 +1260,8 @@ impl Pane {
|
||||
let hovered = mouse_state.hovered();
|
||||
|
||||
enum Tab {}
|
||||
MouseEventHandler::<Tab>::new(ix, cx, |_, cx| {
|
||||
Self::render_tab(
|
||||
MouseEventHandler::<Tab, Pane>::new(ix, cx, |_, cx| {
|
||||
Self::render_tab::<Pane>(
|
||||
&item,
|
||||
pane.clone(),
|
||||
ix == 0,
|
||||
@ -1271,12 +1271,12 @@ impl Pane {
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.on_down(MouseButton::Left, move |_, cx| {
|
||||
.on_down(MouseButton::Left, move |_, _, cx| {
|
||||
cx.dispatch_action(ActivateItem(ix));
|
||||
})
|
||||
.on_click(MouseButton::Middle, {
|
||||
let item = item.clone();
|
||||
move |_, cx: &mut EventContext| {
|
||||
move |_, _, cx: &mut EventContext<Self>| {
|
||||
cx.dispatch_action(CloseItem {
|
||||
item_id: item.id(),
|
||||
pane: pane.clone(),
|
||||
@ -1301,9 +1301,9 @@ impl Pane {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
|
||||
let detail = detail.clone();
|
||||
move |dragged_item, cx: &mut ViewContext<Workspace>| {
|
||||
move |dragged_item: &DraggedItem, cx: &mut ViewContext<Pane>| {
|
||||
let tab_style = &theme.workspace.tab_bar.dragged_tab;
|
||||
Self::render_tab(
|
||||
Self::render_tab::<Pane>(
|
||||
&dragged_item.item,
|
||||
dragged_item.pane.clone(),
|
||||
false,
|
||||
@ -1404,7 +1404,7 @@ impl Pane {
|
||||
};
|
||||
|
||||
ConstrainedBox::new(
|
||||
Canvas::new(move |scene, bounds, _, cx| {
|
||||
Canvas::new(move |scene, bounds, _, _, cx| {
|
||||
if let Some(color) = icon_color {
|
||||
let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
|
||||
scene.push_quad(Quad {
|
||||
@ -1441,18 +1441,22 @@ impl Pane {
|
||||
let item_id = item.id();
|
||||
enum TabCloseButton {}
|
||||
let icon = Svg::new("icons/x_mark_8.svg");
|
||||
MouseEventHandler::<TabCloseButton>::new(item_id, cx, |mouse_state, _| {
|
||||
if mouse_state.hovered() {
|
||||
icon.with_color(tab_style.icon_close_active).boxed()
|
||||
} else {
|
||||
icon.with_color(tab_style.icon_close).boxed()
|
||||
}
|
||||
})
|
||||
MouseEventHandler::<TabCloseButton, _>::new(
|
||||
item_id,
|
||||
cx,
|
||||
|mouse_state, _| {
|
||||
if mouse_state.hovered() {
|
||||
icon.with_color(tab_style.icon_close_active).boxed()
|
||||
} else {
|
||||
icon.with_color(tab_style.icon_close).boxed()
|
||||
}
|
||||
},
|
||||
)
|
||||
.with_padding(Padding::uniform(4.))
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, {
|
||||
let pane = pane.clone();
|
||||
move |_, cx| {
|
||||
move |_, _, cx| {
|
||||
cx.dispatch_action(CloseItem {
|
||||
item_id,
|
||||
pane: pane.clone(),
|
||||
@ -1551,13 +1555,13 @@ impl View for Pane {
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
|
||||
let this = cx.handle();
|
||||
let this = cx.handle().downgrade();
|
||||
|
||||
enum MouseNavigationHandler {}
|
||||
|
||||
Stack::new()
|
||||
.with_child(
|
||||
MouseEventHandler::<MouseNavigationHandler>::new(0, cx, |_, cx| {
|
||||
MouseEventHandler::<MouseNavigationHandler, _>::new(0, cx, |_, cx| {
|
||||
let active_item_index = self.active_item_index;
|
||||
|
||||
if let Some(active_item) = self.active_item() {
|
||||
@ -1569,13 +1573,17 @@ impl View for Pane {
|
||||
|
||||
enum TabBarEventHandler {}
|
||||
stack.add_child(
|
||||
MouseEventHandler::<TabBarEventHandler>::new(0, cx, |_, _| {
|
||||
Empty::new()
|
||||
.contained()
|
||||
.with_style(theme.workspace.tab_bar.container)
|
||||
.boxed()
|
||||
})
|
||||
.on_down(MouseButton::Left, move |_, cx| {
|
||||
MouseEventHandler::<TabBarEventHandler, _>::new(
|
||||
0,
|
||||
cx,
|
||||
|_, _| {
|
||||
Empty::new()
|
||||
.contained()
|
||||
.with_style(theme.workspace.tab_bar.container)
|
||||
.boxed()
|
||||
},
|
||||
)
|
||||
.on_down(MouseButton::Left, move |_, _, cx| {
|
||||
cx.dispatch_action(ActivateItem(active_item_index));
|
||||
})
|
||||
.boxed(),
|
||||
@ -1635,7 +1643,7 @@ impl View for Pane {
|
||||
dragged_item_receiver::<EmptyPane, _>(0, 0, false, None, cx, |_, cx| {
|
||||
self.render_blank_pane(&theme, cx)
|
||||
})
|
||||
.on_down(MouseButton::Left, |_, cx| {
|
||||
.on_down(MouseButton::Left, |_, _, cx| {
|
||||
cx.focus_parent_view();
|
||||
})
|
||||
.boxed()
|
||||
@ -1643,7 +1651,7 @@ impl View for Pane {
|
||||
})
|
||||
.on_down(MouseButton::Navigate(NavigationDirection::Back), {
|
||||
let this = this.clone();
|
||||
move |_, cx| {
|
||||
move |_, _, cx| {
|
||||
cx.dispatch_action(GoBack {
|
||||
pane: Some(this.clone()),
|
||||
});
|
||||
@ -1651,7 +1659,7 @@ impl View for Pane {
|
||||
})
|
||||
.on_down(MouseButton::Navigate(NavigationDirection::Forward), {
|
||||
let this = this.clone();
|
||||
move |_, cx| {
|
||||
move |_, _, cx| {
|
||||
cx.dispatch_action(GoForward {
|
||||
pane: Some(this.clone()),
|
||||
})
|
||||
@ -1716,7 +1724,7 @@ fn render_tab_bar_button<A: Action + Clone>(
|
||||
|
||||
Stack::new()
|
||||
.with_child(
|
||||
MouseEventHandler::<TabBarButton>::new(index, cx, |mouse_state, cx| {
|
||||
MouseEventHandler::<TabBarButton, _>::new(index, cx, |mouse_state, cx| {
|
||||
let theme = &cx.global::<Settings>().theme.workspace.tab_bar;
|
||||
let style = theme.pane_button.style_for(mouse_state, false);
|
||||
Svg::new(icon)
|
||||
@ -1730,7 +1738,7 @@ fn render_tab_bar_button<A: Action + Clone>(
|
||||
.boxed()
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, move |_, cx| {
|
||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
||||
cx.dispatch_action(action.clone());
|
||||
})
|
||||
.boxed(),
|
||||
@ -1895,9 +1903,9 @@ impl Element<Pane> for PaneBackdrop {
|
||||
scene.push_mouse_region(
|
||||
MouseRegion::new::<Self>(child_view_id, 0, visible_bounds).on_down(
|
||||
gpui::platform::MouseButton::Left,
|
||||
move |_, cx| {
|
||||
let window_id = cx.window_id;
|
||||
cx.focus(window_id, Some(child_view_id))
|
||||
move |_, _: &mut Pane, cx| {
|
||||
let window_id = cx.window_id();
|
||||
cx.app_context().focus(window_id, Some(child_view_id))
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -5,7 +5,8 @@ use gpui::{
|
||||
geometry::{rect::RectF, vector::Vector2F},
|
||||
platform::MouseButton,
|
||||
scene::MouseUp,
|
||||
AppContext, Element, ElementBox, MouseState, Quad, ViewContext, WeakViewHandle,
|
||||
AppContext, Element, ElementBox, EventContext, MouseState, Quad, View, ViewContext,
|
||||
WeakViewHandle,
|
||||
};
|
||||
use project::ProjectEntryId;
|
||||
use settings::Settings;
|
||||
@ -29,7 +30,7 @@ where
|
||||
Tag: 'static,
|
||||
F: FnOnce(&mut MouseState, &mut ViewContext<Pane>) -> ElementBox<Pane>,
|
||||
{
|
||||
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() {
|
||||
@ -48,7 +49,7 @@ where
|
||||
Stack::new()
|
||||
.with_child(render_child(state, cx))
|
||||
.with_children(drag_position.map(|drag_position| {
|
||||
Canvas::new(move |scene, bounds, _, cx| {
|
||||
Canvas::new(move |scene, bounds, _, _, cx| {
|
||||
if bounds.contains_point(drag_position) {
|
||||
let overlay_region = split_margin
|
||||
.and_then(|split_margin| {
|
||||
@ -58,7 +59,7 @@ where
|
||||
.map(|(dir, margin)| dir.along_edge(bounds, margin))
|
||||
.unwrap_or(bounds);
|
||||
|
||||
scene.paint_stacking_context(None, None, |cx| {
|
||||
scene.paint_stacking_context(None, None, |scene| {
|
||||
scene.push_quad(Quad {
|
||||
bounds: overlay_region,
|
||||
background: Some(overlay_color(cx)),
|
||||
@ -73,13 +74,13 @@ where
|
||||
.boxed()
|
||||
})
|
||||
.on_up(MouseButton::Left, {
|
||||
let pane = cx.handle();
|
||||
move |event, cx| {
|
||||
let pane = cx.handle().downgrade();
|
||||
move |event, _, cx| {
|
||||
handle_dropped_item(event, &pane, drop_index, allow_same_pane, split_margin, cx);
|
||||
cx.notify();
|
||||
}
|
||||
})
|
||||
.on_move(|_, cx| {
|
||||
.on_move(|_, _, cx| {
|
||||
let drag_and_drop = cx.global::<DragAndDrop<Workspace>>();
|
||||
|
||||
if drag_and_drop
|
||||
@ -96,13 +97,13 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub fn handle_dropped_item(
|
||||
pub fn handle_dropped_item<V: View>(
|
||||
event: MouseUp,
|
||||
pane: &WeakViewHandle<Pane>,
|
||||
index: usize,
|
||||
allow_same_pane: bool,
|
||||
split_margin: Option<f32>,
|
||||
cx: &mut ViewContext<Pane>,
|
||||
cx: &mut EventContext<V>,
|
||||
) {
|
||||
enum Action {
|
||||
Move(WeakViewHandle<Pane>, usize),
|
||||
|
@ -176,7 +176,7 @@ impl Member {
|
||||
let leader_user = leader.user.clone();
|
||||
let leader_user_id = leader.user.id;
|
||||
Some(
|
||||
MouseEventHandler::<FollowIntoExternalProject>::new(
|
||||
MouseEventHandler::<FollowIntoExternalProject, _>::new(
|
||||
pane.id(),
|
||||
cx,
|
||||
|_, _| {
|
||||
@ -199,7 +199,7 @@ impl Member {
|
||||
},
|
||||
)
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, move |_, cx| {
|
||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
||||
cx.dispatch_action(JoinProject {
|
||||
project_id: leader_project_id,
|
||||
follow_user_id: leader_user_id,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
item::{Item, ItemEvent},
|
||||
ItemNavHistory, WorkspaceId,
|
||||
ItemNavHistory, Pane, WorkspaceId,
|
||||
};
|
||||
use call::participant::{Frame, RemoteVideoTrack};
|
||||
use client::{proto::PeerId, User};
|
||||
@ -68,8 +68,8 @@ impl View for SharedScreen {
|
||||
enum Focus {}
|
||||
|
||||
let frame = self.frame.clone();
|
||||
MouseEventHandler::<Focus>::new(0, cx, |_, cx| {
|
||||
Canvas::new(move |scene, bounds, _, cx| {
|
||||
MouseEventHandler::<Focus, _>::new(0, cx, |_, cx| {
|
||||
Canvas::new(move |scene, bounds, _, _, cx| {
|
||||
if let Some(frame) = frame.clone() {
|
||||
let size = constrain_size_preserving_aspect_ratio(
|
||||
bounds.size(),
|
||||
@ -86,7 +86,7 @@ impl View for SharedScreen {
|
||||
.with_style(cx.global::<Settings>().theme.shared_screen)
|
||||
.boxed()
|
||||
})
|
||||
.on_down(MouseButton::Left, |_, cx| cx.focus_parent_view())
|
||||
.on_down(MouseButton::Left, |_, _, cx| cx.focus_parent_view())
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,7 @@ impl Item for SharedScreen {
|
||||
_: Option<usize>,
|
||||
style: &theme::Tab,
|
||||
_: &AppContext,
|
||||
) -> gpui::ElementBox<Self> {
|
||||
) -> gpui::ElementBox<Pane> {
|
||||
Flex::row()
|
||||
.with_child(
|
||||
Svg::new("icons/disable_screen_sharing_12.svg")
|
||||
|
@ -195,7 +195,7 @@ impl View for Sidebar {
|
||||
ChildView::new(active_item.as_any(), cx)
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
.with_resize_handle::<ResizeHandleTag, _>(
|
||||
.with_resize_handle::<ResizeHandleTag>(
|
||||
self.sidebar_side as usize,
|
||||
self.sidebar_side.to_resizable_side(),
|
||||
4.,
|
||||
@ -254,7 +254,7 @@ impl View for SidebarButtons {
|
||||
sidebar_side,
|
||||
item_index: ix,
|
||||
};
|
||||
MouseEventHandler::<Self>::new(ix, cx, |state, cx| {
|
||||
MouseEventHandler::<Self, _>::new(ix, cx, |state, cx| {
|
||||
let is_active = is_open && ix == active_ix;
|
||||
let style = item_style.style_for(state, is_active);
|
||||
Stack::new()
|
||||
@ -283,9 +283,9 @@ impl View for SidebarButtons {
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, {
|
||||
let action = action.clone();
|
||||
move |_, cx| cx.dispatch_action(action.clone())
|
||||
move |_, _, cx| cx.dispatch_action(action.clone())
|
||||
})
|
||||
.with_tooltip::<Self, _>(
|
||||
.with_tooltip::<Self>(
|
||||
ix,
|
||||
tooltip,
|
||||
Some(Box::new(action)),
|
||||
|
@ -170,7 +170,7 @@ fn nav_button<A: Action + Clone>(
|
||||
action_name: &str,
|
||||
cx: &mut ViewContext<Toolbar>,
|
||||
) -> ElementBox<Toolbar> {
|
||||
MouseEventHandler::<A>::new(0, cx, |state, _| {
|
||||
MouseEventHandler::<A, _>::new(0, cx, |state, _| {
|
||||
let style = if enabled {
|
||||
style.style_for(state, false)
|
||||
} else {
|
||||
@ -194,10 +194,10 @@ fn nav_button<A: Action + Clone>(
|
||||
} else {
|
||||
CursorStyle::default()
|
||||
})
|
||||
.on_click(MouseButton::Left, move |_, cx| {
|
||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
||||
cx.dispatch_action(action.clone())
|
||||
})
|
||||
.with_tooltip::<A, _>(
|
||||
.with_tooltip::<A>(
|
||||
0,
|
||||
action_name.to_string(),
|
||||
Some(Box::new(tooltip_action)),
|
||||
|
@ -928,11 +928,7 @@ impl Workspace {
|
||||
workspace
|
||||
};
|
||||
|
||||
let workspace = if let Some(window_id) = requesting_window_id {
|
||||
cx.update(|cx| {
|
||||
cx.replace_root_view(window_id, |cx| build_workspace(cx, serialized_workspace))
|
||||
})
|
||||
} else {
|
||||
let workspace = {
|
||||
let (bounds, display) = if let Some(bounds) = window_bounds_override {
|
||||
(Some(bounds), None)
|
||||
} else {
|
||||
@ -1133,7 +1129,14 @@ impl Workspace {
|
||||
let window_id = cx.window_id();
|
||||
let workspace_count = cx
|
||||
.window_ids()
|
||||
.filter_map(|window_id| cx.root_view(window_id)?.clone().downcast::<Workspace>())
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
.filter_map(|window_id| {
|
||||
cx.app_context()
|
||||
.root_view(window_id)?
|
||||
.clone()
|
||||
.downcast::<Workspace>()
|
||||
})
|
||||
.count();
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
@ -1142,23 +1145,22 @@ impl Workspace {
|
||||
&& workspace_count == 1
|
||||
&& active_call.read_with(&cx, |call, _| call.room().is_some())
|
||||
{
|
||||
let answer = cx
|
||||
.prompt(
|
||||
window_id,
|
||||
PromptLevel::Warning,
|
||||
"Do you want to leave the current call?",
|
||||
&["Close window and hang up", "Cancel"],
|
||||
)
|
||||
.next()
|
||||
.await;
|
||||
let answer = cx.prompt(
|
||||
window_id,
|
||||
PromptLevel::Warning,
|
||||
"Do you want to leave the current call?",
|
||||
&["Close window and hang up", "Cancel"],
|
||||
);
|
||||
|
||||
if answer == Some(1) {
|
||||
return anyhow::Ok(false);
|
||||
} else {
|
||||
active_call
|
||||
.update(&mut cx, |call, cx| call.hang_up(cx))
|
||||
.await
|
||||
.log_err();
|
||||
if let Some(mut answer) = answer {
|
||||
if answer.next().await == Some(1) {
|
||||
return anyhow::Ok(false);
|
||||
} else {
|
||||
active_call
|
||||
.update(&mut cx, |call, cx| call.hang_up(cx))
|
||||
.await
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1621,7 +1623,7 @@ impl Workspace {
|
||||
> {
|
||||
let project = self.project().clone();
|
||||
let project_item = project.update(cx, |project, cx| project.open_path(path, cx));
|
||||
cx.as_mut().spawn(|mut cx| async move {
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
let (project_entry_id, project_item) = project_item.await?;
|
||||
let build_item = cx.update(|cx| {
|
||||
cx.default_global::<ProjectItemBuilders>()
|
||||
@ -1802,15 +1804,14 @@ impl Workspace {
|
||||
}
|
||||
|
||||
let item = pane.read(cx).active_item()?;
|
||||
let maybe_pane_handle =
|
||||
if let Some(clone) = item.clone_on_split(self.database_id(), cx.as_mut()) {
|
||||
let new_pane = self.add_pane(cx);
|
||||
Pane::add_item(self, &new_pane, clone, true, true, None, cx);
|
||||
self.center.split(&pane, &new_pane, direction).unwrap();
|
||||
Some(new_pane)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let maybe_pane_handle = if let Some(clone) = item.clone_on_split(self.database_id(), cx) {
|
||||
let new_pane = self.add_pane(cx);
|
||||
Pane::add_item(self, &new_pane, clone, true, true, None, cx);
|
||||
self.center.split(&pane, &new_pane, direction).unwrap();
|
||||
Some(new_pane)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
cx.notify();
|
||||
maybe_pane_handle
|
||||
}
|
||||
@ -2067,7 +2068,7 @@ impl Workspace {
|
||||
|
||||
enum TitleBar {}
|
||||
ConstrainedBox::new(
|
||||
MouseEventHandler::<TitleBar>::new(0, cx, |_, cx| {
|
||||
MouseEventHandler::<TitleBar, _>::new(0, cx, |_, cx| {
|
||||
Container::new(
|
||||
Stack::new()
|
||||
.with_children(
|
||||
@ -2080,9 +2081,9 @@ impl Workspace {
|
||||
.with_style(container_theme)
|
||||
.boxed()
|
||||
})
|
||||
.on_click(MouseButton::Left, |event, cx| {
|
||||
.on_click(MouseButton::Left, |event, _, cx| {
|
||||
if event.click_count == 2 {
|
||||
cx.zoom_window(cx.window_id());
|
||||
cx.zoom_window();
|
||||
}
|
||||
})
|
||||
.boxed(),
|
||||
@ -2160,7 +2161,7 @@ impl Workspace {
|
||||
if self.project.read(cx).is_read_only() {
|
||||
enum DisconnectedOverlay {}
|
||||
Some(
|
||||
MouseEventHandler::<DisconnectedOverlay>::new(0, cx, |_, cx| {
|
||||
MouseEventHandler::<DisconnectedOverlay, _>::new(0, cx, |_, cx| {
|
||||
let theme = &cx.global::<Settings>().theme;
|
||||
Label::new(
|
||||
"Your connection to the remote project has been lost.",
|
||||
@ -2828,11 +2829,11 @@ impl View for Workspace {
|
||||
Some(
|
||||
ChildView::new(&self.left_sidebar, cx)
|
||||
.constrained()
|
||||
.dynamically(|constraint, cx| {
|
||||
.dynamically(|constraint, _, cx| {
|
||||
SizeConstraint::new(
|
||||
Vector2F::new(20., constraint.min.y()),
|
||||
Vector2F::new(
|
||||
cx.window_size.x() * 0.8,
|
||||
cx.window_size().x() * 0.8,
|
||||
constraint.max.y(),
|
||||
),
|
||||
)
|
||||
@ -2874,11 +2875,11 @@ impl View for Workspace {
|
||||
Some(
|
||||
ChildView::new(&self.right_sidebar, cx)
|
||||
.constrained()
|
||||
.dynamically(|constraint, cx| {
|
||||
.dynamically(|constraint, _, cx| {
|
||||
SizeConstraint::new(
|
||||
Vector2F::new(20., constraint.min.y()),
|
||||
Vector2F::new(
|
||||
cx.window_size.x() * 0.8,
|
||||
cx.window_size().x() * 0.8,
|
||||
constraint.max.y(),
|
||||
),
|
||||
)
|
||||
@ -2998,12 +2999,21 @@ pub fn activate_workspace_for_project(
|
||||
predicate: impl Fn(&mut Project, &mut ModelContext<Project>) -> bool,
|
||||
) -> Option<ViewHandle<Workspace>> {
|
||||
for window_id in cx.window_ids().collect::<Vec<_>>() {
|
||||
if let Some(workspace_handle) = cx.root_view(window_id)?.downcast_ref::<Workspace>() {
|
||||
let project = workspace_handle.read(cx).project.clone();
|
||||
if project.update(cx, &predicate) {
|
||||
cx.activate_window(window_id);
|
||||
return Some(workspace_handle.clone());
|
||||
}
|
||||
let handle = cx
|
||||
.update_window(window_id, |cx| {
|
||||
if let Some(workspace_handle) = cx.root_view().clone().downcast::<Workspace>() {
|
||||
let project = workspace_handle.read(cx).project.clone();
|
||||
if project.update(cx, &predicate) {
|
||||
cx.activate_window();
|
||||
return Some(workspace_handle.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.flatten();
|
||||
|
||||
if handle.is_some() {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
None
|
||||
|
Loading…
Reference in New Issue
Block a user