Merge branch 'main' into project_search_design

This commit is contained in:
Mikayla 2023-08-17 01:56:05 -07:00
commit afebe3faf8
No known key found for this signature in database
133 changed files with 9714 additions and 2998 deletions

View file

@ -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>>) {

View file

@ -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()