wip
This commit is contained in:
parent
6c60853842
commit
ba50b35de6
9 changed files with 634 additions and 525 deletions
File diff suppressed because it is too large
Load diff
|
@ -3816,6 +3816,12 @@ impl<T> PartialEq for ViewHandle<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> PartialEq<AnyViewHandle> for ViewHandle<T> {
|
||||||
|
fn eq(&self, other: &AnyViewHandle) -> bool {
|
||||||
|
self.window_id == other.window_id && self.view_id == other.view_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
|
impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
|
||||||
fn eq(&self, other: &WeakViewHandle<T>) -> bool {
|
fn eq(&self, other: &WeakViewHandle<T>) -> bool {
|
||||||
self.window_id == other.window_id && self.view_id == other.view_id
|
self.window_id == other.window_id && self.view_id == other.view_id
|
||||||
|
|
|
@ -33,8 +33,11 @@ use crate::{
|
||||||
rect::RectF,
|
rect::RectF,
|
||||||
vector::{vec2f, Vector2F},
|
vector::{vec2f, Vector2F},
|
||||||
},
|
},
|
||||||
json, Action, LayoutContext, SceneBuilder, SizeConstraint, View, ViewContext, WeakViewHandle,
|
json,
|
||||||
WindowContext,
|
platform::MouseButton,
|
||||||
|
scene::MouseDown,
|
||||||
|
Action, EventContext, LayoutContext, SceneBuilder, SizeConstraint, View, ViewContext,
|
||||||
|
WeakViewHandle, WindowContext,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
@ -198,6 +201,13 @@ pub trait Element<V: View>: 'static {
|
||||||
{
|
{
|
||||||
Resizable::new(self.into_any(), side, size, on_resize)
|
Resizable::new(self.into_any(), side, size, on_resize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mouse<Tag>(self, region_id: usize) -> MouseEventHandler<Tag, V>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
MouseEventHandler::for_child(self.into_any(), region_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait AnyElementState<V: View> {
|
trait AnyElementState<V: View> {
|
||||||
|
|
|
@ -32,10 +32,25 @@ pub struct MouseEventHandler<Tag: 'static, V: View> {
|
||||||
/// Element which provides a render_child callback with a MouseState and paints a mouse
|
/// Element which provides a render_child callback with a MouseState and paints a mouse
|
||||||
/// region under (or above) it for easy mouse event handling.
|
/// region under (or above) it for easy mouse event handling.
|
||||||
impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
impl<Tag, V: View> MouseEventHandler<Tag, V> {
|
||||||
pub fn new<D, F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
|
pub fn for_child(child: impl Element<V>, region_id: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
child: child.into_any(),
|
||||||
|
region_id,
|
||||||
|
cursor_style: None,
|
||||||
|
handlers: Default::default(),
|
||||||
|
notify_on_hover: false,
|
||||||
|
notify_on_click: false,
|
||||||
|
hoverable: false,
|
||||||
|
above: false,
|
||||||
|
padding: Default::default(),
|
||||||
|
_tag: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new<E, F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
|
||||||
where
|
where
|
||||||
D: Element<V>,
|
E: Element<V>,
|
||||||
F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> D,
|
F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> E,
|
||||||
{
|
{
|
||||||
let mut mouse_state = cx.mouse_state::<Tag>(region_id);
|
let mut mouse_state = cx.mouse_state::<Tag>(region_id);
|
||||||
let child = render_child(&mut mouse_state, cx).into_any();
|
let child = render_child(&mut mouse_state, cx).into_any();
|
||||||
|
|
|
@ -68,6 +68,8 @@ pub struct Workspace {
|
||||||
pub breadcrumbs: Interactive<ContainedText>,
|
pub breadcrumbs: Interactive<ContainedText>,
|
||||||
pub disconnected_overlay: ContainedText,
|
pub disconnected_overlay: ContainedText,
|
||||||
pub modal: ContainerStyle,
|
pub modal: ContainerStyle,
|
||||||
|
pub zoomed_foreground: ContainerStyle,
|
||||||
|
pub zoomed_background: ContainerStyle,
|
||||||
pub notification: ContainerStyle,
|
pub notification: ContainerStyle,
|
||||||
pub notifications: Notifications,
|
pub notifications: Notifications,
|
||||||
pub joining_project_avatar: ImageStyle,
|
pub joining_project_avatar: ImageStyle,
|
||||||
|
|
|
@ -69,6 +69,7 @@ actions!(
|
||||||
SplitUp,
|
SplitUp,
|
||||||
SplitRight,
|
SplitRight,
|
||||||
SplitDown,
|
SplitDown,
|
||||||
|
ToggleZoom,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
|
||||||
pub type BackgroundActions = fn() -> &'static [(&'static str, &'static dyn Action)];
|
pub type BackgroundActions = fn() -> &'static [(&'static str, &'static dyn Action)];
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
|
cx.add_action(Pane::toggle_zoom);
|
||||||
cx.add_action(|pane: &mut Pane, action: &ActivateItem, cx| {
|
cx.add_action(|pane: &mut Pane, action: &ActivateItem, cx| {
|
||||||
pane.activate_item(action.0, true, true, cx);
|
pane.activate_item(action.0, true, true, cx);
|
||||||
});
|
});
|
||||||
|
@ -132,12 +134,15 @@ pub enum Event {
|
||||||
Split(SplitDirection),
|
Split(SplitDirection),
|
||||||
ChangeItemTitle,
|
ChangeItemTitle,
|
||||||
Focus,
|
Focus,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Pane {
|
pub struct Pane {
|
||||||
items: Vec<Box<dyn ItemHandle>>,
|
items: Vec<Box<dyn ItemHandle>>,
|
||||||
activation_history: Vec<usize>,
|
activation_history: Vec<usize>,
|
||||||
is_active: bool,
|
is_active: bool,
|
||||||
|
zoomed: bool,
|
||||||
active_item_index: usize,
|
active_item_index: usize,
|
||||||
last_focused_view_by_item: HashMap<usize, AnyWeakViewHandle>,
|
last_focused_view_by_item: HashMap<usize, AnyWeakViewHandle>,
|
||||||
autoscroll: bool,
|
autoscroll: bool,
|
||||||
|
@ -236,6 +241,7 @@ impl Pane {
|
||||||
items: Vec::new(),
|
items: Vec::new(),
|
||||||
activation_history: Vec::new(),
|
activation_history: Vec::new(),
|
||||||
is_active: true,
|
is_active: true,
|
||||||
|
zoomed: false,
|
||||||
active_item_index: 0,
|
active_item_index: 0,
|
||||||
last_focused_view_by_item: Default::default(),
|
last_focused_view_by_item: Default::default(),
|
||||||
autoscroll: false,
|
autoscroll: false,
|
||||||
|
@ -655,6 +661,14 @@ impl Pane {
|
||||||
self.items.iter().position(|i| i.id() == item.id())
|
self.items.iter().position(|i| i.id() == item.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext<Self>) {
|
||||||
|
if self.zoomed {
|
||||||
|
cx.emit(Event::ZoomOut);
|
||||||
|
} else {
|
||||||
|
cx.emit(Event::ZoomIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn activate_item(
|
pub fn activate_item(
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -1546,6 +1560,15 @@ impl Pane {
|
||||||
.with_background_color(background)
|
.with_background_color(background)
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext<Self>) {
|
||||||
|
self.zoomed = zoomed;
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_zoomed(&self) -> bool {
|
||||||
|
self.zoomed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for Pane {
|
impl Entity for Pane {
|
||||||
|
|
|
@ -142,6 +142,12 @@ impl Member {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Member::Pane(pane) => {
|
Member::Pane(pane) => {
|
||||||
|
let pane_element = if pane.read(cx).is_zoomed() {
|
||||||
|
Empty::new().into_any()
|
||||||
|
} else {
|
||||||
|
ChildView::new(pane, cx).into_any()
|
||||||
|
};
|
||||||
|
|
||||||
let leader = follower_states
|
let leader = follower_states
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(leader_id, follower_states)| {
|
.find_map(|(leader_id, follower_states)| {
|
||||||
|
@ -258,7 +264,7 @@ impl Member {
|
||||||
};
|
};
|
||||||
|
|
||||||
Stack::new()
|
Stack::new()
|
||||||
.with_child(ChildView::new(pane, cx).contained().with_border(border))
|
.with_child(pane_element.contained().with_border(border))
|
||||||
.with_children(leader_status_box)
|
.with_children(leader_status_box)
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,6 +441,7 @@ pub struct Workspace {
|
||||||
weak_self: WeakViewHandle<Self>,
|
weak_self: WeakViewHandle<Self>,
|
||||||
remote_entity_subscription: Option<client::Subscription>,
|
remote_entity_subscription: Option<client::Subscription>,
|
||||||
modal: Option<AnyViewHandle>,
|
modal: Option<AnyViewHandle>,
|
||||||
|
zoomed: Option<AnyViewHandle>,
|
||||||
center: PaneGroup,
|
center: PaneGroup,
|
||||||
left_dock: ViewHandle<Dock>,
|
left_dock: ViewHandle<Dock>,
|
||||||
bottom_dock: ViewHandle<Dock>,
|
bottom_dock: ViewHandle<Dock>,
|
||||||
|
@ -627,8 +628,9 @@ impl Workspace {
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut this = Workspace {
|
let mut this = Workspace {
|
||||||
modal: None,
|
|
||||||
weak_self: weak_handle.clone(),
|
weak_self: weak_handle.clone(),
|
||||||
|
modal: None,
|
||||||
|
zoomed: None,
|
||||||
center: PaneGroup::new(center_pane.clone()),
|
center: PaneGroup::new(center_pane.clone()),
|
||||||
panes: vec![center_pane.clone()],
|
panes: vec![center_pane.clone()],
|
||||||
panes_by_item: Default::default(),
|
panes_by_item: Default::default(),
|
||||||
|
@ -1303,6 +1305,16 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn zoom_in(&mut self, view: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
|
self.zoomed = Some(view);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn zoom_out(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
|
self.zoomed.take();
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn items<'a>(
|
pub fn items<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
cx: &'a AppContext,
|
cx: &'a AppContext,
|
||||||
|
@ -1685,6 +1697,16 @@ impl Workspace {
|
||||||
pane::Event::Focus => {
|
pane::Event::Focus => {
|
||||||
self.handle_pane_focused(pane.clone(), cx);
|
self.handle_pane_focused(pane.clone(), cx);
|
||||||
}
|
}
|
||||||
|
pane::Event::ZoomIn => {
|
||||||
|
pane.update(cx, |pane, cx| pane.set_zoomed(true, cx));
|
||||||
|
self.zoom_in(pane.into_any(), cx);
|
||||||
|
}
|
||||||
|
pane::Event::ZoomOut => {
|
||||||
|
if self.zoomed.as_ref().map_or(false, |zoomed| *zoomed == pane) {
|
||||||
|
pane.update(cx, |pane, cx| pane.set_zoomed(false, cx));
|
||||||
|
self.zoom_out(cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.serialize_workspace(cx);
|
self.serialize_workspace(cx);
|
||||||
|
@ -2735,6 +2757,21 @@ impl View for Workspace {
|
||||||
})
|
})
|
||||||
.with_child(Overlay::new(
|
.with_child(Overlay::new(
|
||||||
Stack::new()
|
Stack::new()
|
||||||
|
.with_children(self.zoomed.as_ref().map(|zoomed| {
|
||||||
|
enum ZoomBackground {}
|
||||||
|
|
||||||
|
ChildView::new(zoomed, cx)
|
||||||
|
.contained()
|
||||||
|
.with_style(theme.workspace.zoomed_foreground)
|
||||||
|
.aligned()
|
||||||
|
.contained()
|
||||||
|
.with_style(theme.workspace.zoomed_background)
|
||||||
|
.mouse::<ZoomBackground>(0)
|
||||||
|
.capture_all()
|
||||||
|
.on_down(MouseButton::Left, |_, this: &mut Self, cx| {
|
||||||
|
this.zoom_out(cx);
|
||||||
|
})
|
||||||
|
}))
|
||||||
.with_children(self.modal.as_ref().map(|modal| {
|
.with_children(self.modal.as_ref().map(|modal| {
|
||||||
ChildView::new(modal, cx)
|
ChildView::new(modal, cx)
|
||||||
.contained()
|
.contained()
|
||||||
|
|
|
@ -118,6 +118,15 @@ export default function workspace(colorScheme: ColorScheme) {
|
||||||
},
|
},
|
||||||
cursor: "Arrow",
|
cursor: "Arrow",
|
||||||
},
|
},
|
||||||
|
zoomedBackground: {
|
||||||
|
padding: 10,
|
||||||
|
cursor: "Arrow",
|
||||||
|
background: withOpacity(background(colorScheme.lowest), 0.5)
|
||||||
|
},
|
||||||
|
zoomedForeground: {
|
||||||
|
shadow: colorScheme.modalShadow,
|
||||||
|
border: border(colorScheme.highest, { overlay: true }),
|
||||||
|
},
|
||||||
dock: {
|
dock: {
|
||||||
initialSize: 240,
|
initialSize: 240,
|
||||||
border: border(layer, { left: true, right: true }),
|
border: border(layer, { left: true, right: true }),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue