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