Merge branch 'main' into project_search_design
This commit is contained in:
commit
afebe3faf8
133 changed files with 9714 additions and 2998 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::{StatusItemView, Workspace};
|
||||
use crate::{StatusItemView, Workspace, WorkspaceBounds};
|
||||
use context_menu::{ContextMenu, ContextMenuItem};
|
||||
use gpui::{
|
||||
elements::*, platform::CursorStyle, platform::MouseButton, Action, AnyViewHandle, AppContext,
|
||||
|
@ -13,20 +13,30 @@ pub trait Panel: View {
|
|||
fn position_is_valid(&self, position: DockPosition) -> bool;
|
||||
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
|
||||
fn size(&self, cx: &WindowContext) -> f32;
|
||||
fn set_size(&mut self, size: f32, cx: &mut ViewContext<Self>);
|
||||
fn icon_path(&self) -> &'static str;
|
||||
fn set_size(&mut self, size: Option<f32>, cx: &mut ViewContext<Self>);
|
||||
fn icon_path(&self, cx: &WindowContext) -> Option<&'static str>;
|
||||
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>);
|
||||
fn icon_label(&self, _: &WindowContext) -> Option<String> {
|
||||
None
|
||||
}
|
||||
fn should_change_position_on_event(_: &Self::Event) -> bool;
|
||||
fn should_zoom_in_on_event(_: &Self::Event) -> bool;
|
||||
fn should_zoom_out_on_event(_: &Self::Event) -> bool;
|
||||
fn is_zoomed(&self, cx: &WindowContext) -> bool;
|
||||
fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext<Self>);
|
||||
fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>);
|
||||
fn should_activate_on_event(_: &Self::Event) -> bool;
|
||||
fn should_close_on_event(_: &Self::Event) -> bool;
|
||||
fn should_zoom_in_on_event(_: &Self::Event) -> bool {
|
||||
false
|
||||
}
|
||||
fn should_zoom_out_on_event(_: &Self::Event) -> bool {
|
||||
false
|
||||
}
|
||||
fn is_zoomed(&self, _cx: &WindowContext) -> bool {
|
||||
false
|
||||
}
|
||||
fn set_zoomed(&mut self, _zoomed: bool, _cx: &mut ViewContext<Self>) {}
|
||||
fn set_active(&mut self, _active: bool, _cx: &mut ViewContext<Self>) {}
|
||||
fn should_activate_on_event(_: &Self::Event) -> bool {
|
||||
false
|
||||
}
|
||||
fn should_close_on_event(_: &Self::Event) -> bool {
|
||||
false
|
||||
}
|
||||
fn has_focus(&self, cx: &WindowContext) -> bool;
|
||||
fn is_focus_event(_: &Self::Event) -> bool;
|
||||
}
|
||||
|
@ -40,8 +50,8 @@ pub trait PanelHandle {
|
|||
fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext);
|
||||
fn set_active(&self, active: bool, cx: &mut WindowContext);
|
||||
fn size(&self, cx: &WindowContext) -> f32;
|
||||
fn set_size(&self, size: f32, cx: &mut WindowContext);
|
||||
fn icon_path(&self, cx: &WindowContext) -> &'static str;
|
||||
fn set_size(&self, size: Option<f32>, cx: &mut WindowContext);
|
||||
fn icon_path(&self, cx: &WindowContext) -> Option<&'static str>;
|
||||
fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option<Box<dyn Action>>);
|
||||
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
|
||||
fn has_focus(&self, cx: &WindowContext) -> bool;
|
||||
|
@ -72,7 +82,7 @@ where
|
|||
self.read(cx).size(cx)
|
||||
}
|
||||
|
||||
fn set_size(&self, size: f32, cx: &mut WindowContext) {
|
||||
fn set_size(&self, size: Option<f32>, cx: &mut WindowContext) {
|
||||
self.update(cx, |this, cx| this.set_size(size, cx))
|
||||
}
|
||||
|
||||
|
@ -88,8 +98,8 @@ where
|
|||
self.update(cx, |this, cx| this.set_active(active, cx))
|
||||
}
|
||||
|
||||
fn icon_path(&self, cx: &WindowContext) -> &'static str {
|
||||
self.read(cx).icon_path()
|
||||
fn icon_path(&self, cx: &WindowContext) -> Option<&'static str> {
|
||||
self.read(cx).icon_path(cx)
|
||||
}
|
||||
|
||||
fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option<Box<dyn Action>>) {
|
||||
|
@ -363,7 +373,7 @@ impl Dock {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn resize_active_panel(&mut self, size: f32, cx: &mut ViewContext<Self>) {
|
||||
pub fn resize_active_panel(&mut self, size: Option<f32>, cx: &mut ViewContext<Self>) {
|
||||
if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) {
|
||||
entry.panel.set_size(size, cx);
|
||||
cx.notify();
|
||||
|
@ -376,7 +386,7 @@ impl Dock {
|
|||
.into_any()
|
||||
.contained()
|
||||
.with_style(self.style(cx))
|
||||
.resizable(
|
||||
.resizable::<WorkspaceBounds>(
|
||||
self.position.to_resize_handle_side(),
|
||||
active_entry.panel.size(cx),
|
||||
|_, _, _| {},
|
||||
|
@ -413,7 +423,7 @@ impl View for Dock {
|
|||
ChildView::new(active_entry.panel.as_any(), cx)
|
||||
.contained()
|
||||
.with_style(style)
|
||||
.resizable(
|
||||
.resizable::<WorkspaceBounds>(
|
||||
self.position.to_resize_handle_side(),
|
||||
active_entry.panel.size(cx),
|
||||
|dock: &mut Self, size, cx| dock.resize_active_panel(size, cx),
|
||||
|
@ -480,8 +490,9 @@ impl View for PanelButtons {
|
|||
.map(|item| (item.panel.clone(), item.context_menu.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
Flex::row()
|
||||
.with_children(panels.into_iter().enumerate().map(
|
||||
.with_children(panels.into_iter().enumerate().filter_map(
|
||||
|(panel_ix, (view, context_menu))| {
|
||||
let icon_path = view.icon_path(cx)?;
|
||||
let is_active = is_open && panel_ix == active_ix;
|
||||
let (tooltip, tooltip_action) = if is_active {
|
||||
(
|
||||
|
@ -495,92 +506,95 @@ impl View for PanelButtons {
|
|||
} else {
|
||||
view.icon_tooltip(cx)
|
||||
};
|
||||
Stack::new()
|
||||
.with_child(
|
||||
MouseEventHandler::new::<Self, _>(panel_ix, cx, |state, cx| {
|
||||
let style = button_style.in_state(is_active);
|
||||
let style = style.style_for(state);
|
||||
Flex::row()
|
||||
.with_child(
|
||||
Svg::new(view.icon_path(cx))
|
||||
.with_color(style.icon_color)
|
||||
.constrained()
|
||||
.with_width(style.icon_size)
|
||||
.aligned(),
|
||||
)
|
||||
.with_children(if let Some(label) = view.icon_label(cx) {
|
||||
Some(
|
||||
Label::new(label, style.label.text.clone())
|
||||
.contained()
|
||||
.with_style(style.label.container)
|
||||
Some(
|
||||
Stack::new()
|
||||
.with_child(
|
||||
MouseEventHandler::new::<Self, _>(panel_ix, cx, |state, cx| {
|
||||
let style = button_style.in_state(is_active);
|
||||
|
||||
let style = style.style_for(state);
|
||||
Flex::row()
|
||||
.with_child(
|
||||
Svg::new(icon_path)
|
||||
.with_color(style.icon_color)
|
||||
.constrained()
|
||||
.with_width(style.icon_size)
|
||||
.aligned(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.constrained()
|
||||
.with_height(style.icon_size)
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, {
|
||||
let tooltip_action =
|
||||
tooltip_action.as_ref().map(|action| action.boxed_clone());
|
||||
move |_, this, cx| {
|
||||
if let Some(tooltip_action) = &tooltip_action {
|
||||
let window = cx.window();
|
||||
let view_id = this.workspace.id();
|
||||
let tooltip_action = tooltip_action.boxed_clone();
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
window.dispatch_action(
|
||||
view_id,
|
||||
&*tooltip_action,
|
||||
&mut cx,
|
||||
);
|
||||
.with_children(if let Some(label) = view.icon_label(cx) {
|
||||
Some(
|
||||
Label::new(label, style.label.text.clone())
|
||||
.contained()
|
||||
.with_style(style.label.container)
|
||||
.aligned(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.detach();
|
||||
.constrained()
|
||||
.with_height(style.icon_size)
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, {
|
||||
let tooltip_action =
|
||||
tooltip_action.as_ref().map(|action| action.boxed_clone());
|
||||
move |_, this, cx| {
|
||||
if let Some(tooltip_action) = &tooltip_action {
|
||||
let window = cx.window();
|
||||
let view_id = this.workspace.id();
|
||||
let tooltip_action = tooltip_action.boxed_clone();
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
window.dispatch_action(
|
||||
view_id,
|
||||
&*tooltip_action,
|
||||
&mut cx,
|
||||
);
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.on_click(MouseButton::Right, {
|
||||
let view = view.clone();
|
||||
let menu = context_menu.clone();
|
||||
move |_, _, cx| {
|
||||
const POSITIONS: [DockPosition; 3] = [
|
||||
DockPosition::Left,
|
||||
DockPosition::Right,
|
||||
DockPosition::Bottom,
|
||||
];
|
||||
})
|
||||
.on_click(MouseButton::Right, {
|
||||
let view = view.clone();
|
||||
let menu = context_menu.clone();
|
||||
move |_, _, cx| {
|
||||
const POSITIONS: [DockPosition; 3] = [
|
||||
DockPosition::Left,
|
||||
DockPosition::Right,
|
||||
DockPosition::Bottom,
|
||||
];
|
||||
|
||||
menu.update(cx, |menu, cx| {
|
||||
let items = POSITIONS
|
||||
.into_iter()
|
||||
.filter(|position| {
|
||||
*position != dock_position
|
||||
&& view.position_is_valid(*position, cx)
|
||||
})
|
||||
.map(|position| {
|
||||
let view = view.clone();
|
||||
ContextMenuItem::handler(
|
||||
format!("Dock {}", position.to_label()),
|
||||
move |cx| view.set_position(position, cx),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
menu.show(Default::default(), menu_corner, items, cx);
|
||||
})
|
||||
}
|
||||
})
|
||||
.with_tooltip::<Self>(
|
||||
panel_ix,
|
||||
tooltip,
|
||||
tooltip_action,
|
||||
tooltip_style.clone(),
|
||||
cx,
|
||||
),
|
||||
)
|
||||
.with_child(ChildView::new(&context_menu, cx))
|
||||
menu.update(cx, |menu, cx| {
|
||||
let items = POSITIONS
|
||||
.into_iter()
|
||||
.filter(|position| {
|
||||
*position != dock_position
|
||||
&& view.position_is_valid(*position, cx)
|
||||
})
|
||||
.map(|position| {
|
||||
let view = view.clone();
|
||||
ContextMenuItem::handler(
|
||||
format!("Dock {}", position.to_label()),
|
||||
move |cx| view.set_position(position, cx),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
menu.show(Default::default(), menu_corner, items, cx);
|
||||
})
|
||||
}
|
||||
})
|
||||
.with_tooltip::<Self>(
|
||||
panel_ix,
|
||||
tooltip,
|
||||
tooltip_action,
|
||||
tooltip_style.clone(),
|
||||
cx,
|
||||
),
|
||||
)
|
||||
.with_child(ChildView::new(&context_menu, cx)),
|
||||
)
|
||||
},
|
||||
))
|
||||
.contained()
|
||||
|
@ -686,12 +700,12 @@ pub mod test {
|
|||
self.size
|
||||
}
|
||||
|
||||
fn set_size(&mut self, size: f32, _: &mut ViewContext<Self>) {
|
||||
self.size = size;
|
||||
fn set_size(&mut self, size: Option<f32>, _: &mut ViewContext<Self>) {
|
||||
self.size = size.unwrap_or(300.);
|
||||
}
|
||||
|
||||
fn icon_path(&self) -> &'static str {
|
||||
"icons/test_panel.svg"
|
||||
fn icon_path(&self, _: &WindowContext) -> Option<&'static str> {
|
||||
Some("icons/test_panel.svg")
|
||||
}
|
||||
|
||||
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
||||
|
|
|
@ -14,7 +14,7 @@ use anyhow::{anyhow, Context, Result};
|
|||
use call::ActiveCall;
|
||||
use client::{
|
||||
proto::{self, PeerId},
|
||||
Client, TypedEnvelope, UserStore,
|
||||
ChannelStore, Client, TypedEnvelope, UserStore,
|
||||
};
|
||||
use collections::{hash_map, HashMap, HashSet};
|
||||
use drag_and_drop::DragAndDrop;
|
||||
|
@ -400,8 +400,9 @@ pub fn register_deserializable_item<I: Item>(cx: &mut AppContext) {
|
|||
|
||||
pub struct AppState {
|
||||
pub languages: Arc<LanguageRegistry>,
|
||||
pub client: Arc<client::Client>,
|
||||
pub user_store: ModelHandle<client::UserStore>,
|
||||
pub client: Arc<Client>,
|
||||
pub user_store: ModelHandle<UserStore>,
|
||||
pub channel_store: ModelHandle<ChannelStore>,
|
||||
pub fs: Arc<dyn fs::Fs>,
|
||||
pub build_window_options:
|
||||
fn(Option<WindowBounds>, Option<uuid::Uuid>, &dyn Platform) -> WindowOptions<'static>,
|
||||
|
@ -424,6 +425,8 @@ impl AppState {
|
|||
let http_client = util::http::FakeHttpClient::with_404_response();
|
||||
let client = Client::new(http_client.clone(), cx);
|
||||
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx));
|
||||
let channel_store =
|
||||
cx.add_model(|cx| ChannelStore::new(client.clone(), user_store.clone(), cx));
|
||||
|
||||
theme::init((), cx);
|
||||
client::init(&client, cx);
|
||||
|
@ -434,6 +437,7 @@ impl AppState {
|
|||
fs,
|
||||
languages,
|
||||
user_store,
|
||||
channel_store,
|
||||
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||
build_window_options: |_, _, _| Default::default(),
|
||||
background_actions: || &[],
|
||||
|
@ -549,6 +553,8 @@ struct FollowerState {
|
|||
items_by_leader_view_id: HashMap<ViewId, Box<dyn FollowableItemHandle>>,
|
||||
}
|
||||
|
||||
enum WorkspaceBounds {}
|
||||
|
||||
impl Workspace {
|
||||
pub fn new(
|
||||
workspace_id: WorkspaceId,
|
||||
|
@ -3403,10 +3409,16 @@ impl Workspace {
|
|||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn test_new(project: ModelHandle<Project>, cx: &mut ViewContext<Self>) -> Self {
|
||||
let client = project.read(cx).client();
|
||||
let user_store = project.read(cx).user_store();
|
||||
|
||||
let channel_store =
|
||||
cx.add_model(|cx| ChannelStore::new(client.clone(), user_store.clone(), cx));
|
||||
let app_state = Arc::new(AppState {
|
||||
languages: project.read(cx).languages().clone(),
|
||||
client: project.read(cx).client(),
|
||||
user_store: project.read(cx).user_store(),
|
||||
client,
|
||||
user_store,
|
||||
channel_store,
|
||||
fs: project.read(cx).fs().clone(),
|
||||
build_window_options: |_, _, _| Default::default(),
|
||||
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||
|
@ -3750,14 +3762,23 @@ impl View for Workspace {
|
|||
)
|
||||
}))
|
||||
.with_children(self.modal.as_ref().map(|modal| {
|
||||
ChildView::new(modal.view.as_any(), cx)
|
||||
.contained()
|
||||
.with_style(theme.workspace.modal)
|
||||
.aligned()
|
||||
.top()
|
||||
// Prevent clicks within the modal from falling
|
||||
// through to the rest of the workspace.
|
||||
enum ModalBackground {}
|
||||
MouseEventHandler::new::<ModalBackground, _>(
|
||||
0,
|
||||
cx,
|
||||
|_, cx| ChildView::new(modal.view.as_any(), cx),
|
||||
)
|
||||
.on_click(MouseButton::Left, |_, _, _| {})
|
||||
.contained()
|
||||
.with_style(theme.workspace.modal)
|
||||
.aligned()
|
||||
.top()
|
||||
}))
|
||||
.with_children(self.render_notifications(&theme.workspace, cx)),
|
||||
))
|
||||
.provide_resize_bounds::<WorkspaceBounds>()
|
||||
.flex(1.0, true),
|
||||
)
|
||||
.with_child(ChildView::new(&self.status_bar, cx))
|
||||
|
@ -4841,7 +4862,9 @@ mod tests {
|
|||
panel_1.size(cx)
|
||||
);
|
||||
|
||||
left_dock.update(cx, |left_dock, cx| left_dock.resize_active_panel(1337., cx));
|
||||
left_dock.update(cx, |left_dock, cx| {
|
||||
left_dock.resize_active_panel(Some(1337.), cx)
|
||||
});
|
||||
assert_eq!(
|
||||
workspace
|
||||
.right_dock()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue