co-authored-by: conrad <conrad@zed.dev>
co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Mikayla
2023-11-20 14:46:01 -08:00
co-authored by conrad Nathan
parent 6985b70859
commit 2c4d83c9af
96 changed files with 1926 additions and 1955 deletions
+26 -23
View File
@@ -8,9 +8,7 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use theme2::ActiveTheme;
use ui::{
h_stack, menu_handle, ContextMenu, IconButton, InteractionState, Label, ListEntry, Tooltip,
};
use ui::{h_stack, menu_handle, ContextMenu, IconButton, InteractionState, Tooltip};
pub enum PanelEvent {
ChangePosition,
@@ -476,8 +474,8 @@ impl Dock {
}
}
impl Render<Self> for Dock {
type Element = Div<Self>;
impl Render for Dock {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
if let Some(entry) = self.visible_entry() {
@@ -662,8 +660,8 @@ impl PanelButtons {
// }
// here be kittens
impl Render<Self> for PanelButtons {
type Element = Div<Self>;
impl Render for PanelButtons {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
// todo!()
@@ -688,45 +686,50 @@ impl Render<Self> for PanelButtons {
let name = entry.panel.persistent_name();
let panel = entry.panel.clone();
let mut button: IconButton<Self> = if i == active_index && is_open {
let mut button: IconButton = if i == active_index && is_open {
let action = dock.toggle_action();
let tooltip: SharedString =
format!("Close {} dock", dock.position.to_label()).into();
IconButton::new(name, icon)
.state(InteractionState::Active)
.action(action.boxed_clone())
.tooltip(move |_, cx| Tooltip::for_action(tooltip.clone(), &*action, cx))
.tooltip(move |cx| Tooltip::for_action(tooltip.clone(), &*action, cx))
} else {
let action = entry.panel.toggle_action(cx);
IconButton::new(name, icon)
.action(action.boxed_clone())
.tooltip(move |_, cx| Tooltip::for_action(name, &*action, cx))
.tooltip(move |cx| Tooltip::for_action(name, &*action, cx))
};
Some(
menu_handle(name)
.menu(move |_, cx| {
.menu(move |cx| {
const POSITIONS: [DockPosition; 3] = [
DockPosition::Left,
DockPosition::Right,
DockPosition::Bottom,
];
//CX: Pane
ContextMenu::build(cx, |mut menu, cx| {
// CX: Menu
for position in POSITIONS {
if position != dock_position
&& panel.position_is_valid(position, cx)
{
let panel = panel.clone();
menu = menu.entry(
ListEntry::new(Label::new(format!(
"Dock {}",
position.to_label()
))),
move |_, cx| {
panel.set_position(position, cx);
},
)
// let panel = panel.clone();
todo!()
// menu = menu.entry(
// ListEntry::new(Label::new(format!(
// "Dock {}",
// position.to_label()
// ))),
// cx.listener(move |_, cx| {
// //What should CX be? CX: Pane
// panel.set_position(position, cx);
// }),
//)
}
}
menu
@@ -780,8 +783,8 @@ pub mod test {
}
}
impl Render<Self> for TestPanel {
type Element = Div<Self>;
impl Render for TestPanel {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
div()
+5 -5
View File
@@ -104,7 +104,7 @@ pub trait Item: FocusableView + EventEmitter<ItemEvent> {
fn tab_description(&self, _: usize, _: &AppContext) -> Option<SharedString> {
None
}
fn tab_content<V: 'static>(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<V>;
fn tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement;
/// (model id, Item)
fn for_each_project_item(
@@ -214,8 +214,8 @@ pub trait ItemHandle: 'static + Send {
) -> gpui::Subscription;
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<SharedString>;
fn tab_description(&self, detail: usize, cx: &AppContext) -> Option<SharedString>;
fn tab_content(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<Pane>;
fn dragged_tab_content(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<Workspace>;
fn tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement;
fn dragged_tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement;
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]>;
fn project_item_model_ids(&self, cx: &AppContext) -> SmallVec<[EntityId; 3]>;
@@ -307,11 +307,11 @@ impl<T: Item> ItemHandle for View<T> {
self.read(cx).tab_description(detail, cx)
}
fn tab_content(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<Pane> {
fn tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement {
self.read(cx).tab_content(detail, cx)
}
fn dragged_tab_content(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<Workspace> {
fn dragged_tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement {
self.read(cx).tab_content(detail, cx)
}
+6 -6
View File
@@ -71,8 +71,8 @@ impl ModalLayer {
}
}
impl Render<Self> for ModalLayer {
type Element = Div<Self>;
impl Render for ModalLayer {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let Some(active_modal) = &self.active_modal else {
@@ -97,11 +97,11 @@ impl Render<Self> for ModalLayer {
h_stack()
// needed to prevent mouse events leaking to the
// UI below. // todo! for gpui3.
.on_any_mouse_down(|_, _, cx| cx.stop_propagation())
.on_any_mouse_up(|_, _, cx| cx.stop_propagation())
.on_mouse_down_out(|this: &mut Self, event, cx| {
.on_any_mouse_down(|_, cx| cx.stop_propagation())
.on_any_mouse_up(|_, cx| cx.stop_propagation())
.on_mouse_down_out(cx.listener(|this, _, cx| {
this.hide_modal(cx);
})
}))
.child(active_modal.modal.clone()),
),
)
+6 -6
View File
@@ -13,9 +13,9 @@ pub enum NotificationEvent {
Dismiss,
}
pub trait Notification: EventEmitter<NotificationEvent> + Render<Self> {}
pub trait Notification: EventEmitter<NotificationEvent> + Render {}
impl<V: EventEmitter<NotificationEvent> + Render<Self>> Notification for V {}
impl<V: EventEmitter<NotificationEvent> + Render> Notification for V {}
pub trait NotificationHandle: Send {
fn id(&self) -> EntityId;
@@ -198,7 +198,7 @@ pub mod simple_message_notification {
enum NotificationMessage {
Text(Cow<'static, str>),
Element(fn(TextStyle, &AppContext) -> AnyElement<MessageNotification>),
Element(fn(TextStyle, &AppContext) -> AnyElement),
}
pub struct MessageNotification {
@@ -222,7 +222,7 @@ pub mod simple_message_notification {
}
pub fn new_element(
message: fn(TextStyle, &AppContext) -> AnyElement<MessageNotification>,
message: fn(TextStyle, &AppContext) -> AnyElement,
) -> MessageNotification {
Self {
message: NotificationMessage::Element(message),
@@ -253,8 +253,8 @@ pub mod simple_message_notification {
// }
}
impl Render<Self> for MessageNotification {
type Element = Div<Self>;
impl Render for MessageNotification {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
todo!()
+35 -23
View File
@@ -594,7 +594,7 @@ impl Pane {
self.items.iter()
}
pub fn items_of_type<T: Render<T>>(&self) -> impl '_ + Iterator<Item = View<T>> {
pub fn items_of_type<T: Render>(&self) -> impl '_ + Iterator<Item = View<T>> {
self.items
.iter()
.filter_map(|item| item.to_any().downcast().ok())
@@ -1344,7 +1344,7 @@ impl Pane {
item: &Box<dyn ItemHandle>,
detail: usize,
cx: &mut ViewContext<'_, Pane>,
) -> impl RenderOnce<Self> {
) -> impl RenderOnce {
let label = item.tab_content(Some(detail), cx);
let close_icon = || {
let id = item.item_id();
@@ -1353,12 +1353,14 @@ impl Pane {
.id(item.item_id())
.invisible()
.group_hover("", |style| style.visible())
.child(IconButton::new("close_tab", Icon::Close).on_click(
move |pane: &mut Self, cx| {
pane.close_item_by_id(id, SaveIntent::Close, cx)
.detach_and_log_err(cx);
},
))
.child(
IconButton::new("close_tab", Icon::Close).on_click(cx.listener(
move |pane, _, cx| {
pane.close_item_by_id(id, SaveIntent::Close, cx)
.detach_and_log_err(cx);
},
)),
)
};
let (text_color, tab_bg, tab_hover_bg, tab_active_bg) = match ix == self.active_item_index {
@@ -1383,9 +1385,9 @@ impl Pane {
.id(item.item_id())
.cursor_pointer()
.when_some(item.tab_tooltip_text(cx), |div, text| {
div.tooltip(move |_, cx| cx.build_view(|cx| Tooltip::new(text.clone())).into())
div.tooltip(move |cx| cx.build_view(|cx| Tooltip::new(text.clone())).into())
})
.on_click(move |v: &mut Self, e, cx| v.activate_item(ix, true, true, cx))
.on_click(cx.listener(move |v: &mut Self, e, cx| v.activate_item(ix, true, true, cx)))
// .on_drag(move |pane, cx| pane.render_tab(ix, item.boxed_clone(), detail, cx))
// .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
// .on_drop(|_view, state: View<DraggedTab>, cx| {
@@ -1437,7 +1439,7 @@ impl Pane {
)
}
fn render_tab_bar(&mut self, cx: &mut ViewContext<'_, Pane>) -> impl RenderOnce<Self> {
fn render_tab_bar(&mut self, cx: &mut ViewContext<'_, Pane>) -> impl RenderOnce {
div()
.group("tab_bar")
.id("tab_bar")
@@ -1891,17 +1893,25 @@ impl FocusableView for Pane {
}
}
impl Render<Self> for Pane {
type Element = Focusable<Self, Div<Self>>;
impl Render for Pane {
type Element = Focusable<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
v_stack()
.key_context("Pane")
.track_focus(&self.focus_handle)
.on_action(|pane: &mut Pane, _: &SplitLeft, cx| pane.split(SplitDirection::Left, cx))
.on_action(|pane: &mut Pane, _: &SplitUp, cx| pane.split(SplitDirection::Up, cx))
.on_action(|pane: &mut Pane, _: &SplitRight, cx| pane.split(SplitDirection::Right, cx))
.on_action(|pane: &mut Pane, _: &SplitDown, cx| pane.split(SplitDirection::Down, cx))
.on_action(cx.listener(|pane: &mut Pane, _: &SplitLeft, cx| {
pane.split(SplitDirection::Left, cx)
}))
.on_action(
cx.listener(|pane: &mut Pane, _: &SplitUp, cx| pane.split(SplitDirection::Up, cx)),
)
.on_action(cx.listener(|pane: &mut Pane, _: &SplitRight, cx| {
pane.split(SplitDirection::Right, cx)
}))
.on_action(cx.listener(|pane: &mut Pane, _: &SplitDown, cx| {
pane.split(SplitDirection::Down, cx)
}))
// cx.add_action(Pane::toggle_zoom);
// cx.add_action(|pane: &mut Pane, action: &ActivateItem, cx| {
// pane.activate_item(action.0, true, true, cx);
@@ -1922,10 +1932,12 @@ impl Render<Self> for Pane {
// cx.add_async_action(Pane::close_items_to_the_right);
// cx.add_async_action(Pane::close_all_items);
.size_full()
.on_action(|pane: &mut Self, action: &CloseActiveItem, cx| {
pane.close_active_item(action, cx)
.map(|task| task.detach_and_log_err(cx));
})
.on_action(
cx.listener(|pane: &mut Self, action: &CloseActiveItem, cx| {
pane.close_active_item(action, cx)
.map(|task| task.detach_and_log_err(cx));
}),
)
.child(self.render_tab_bar(cx))
// .child(
// div()
@@ -2947,8 +2959,8 @@ struct DraggedTab {
title: String,
}
impl Render<Self> for DraggedTab {
type Element = Div<Self>;
impl Render for DraggedTab {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
div().w_8().h_4().bg(gpui::red())
+3 -3
View File
@@ -132,7 +132,7 @@ impl PaneGroup {
zoomed: Option<&AnyWeakView>,
app_state: &Arc<AppState>,
cx: &mut ViewContext<Workspace>,
) -> impl RenderOnce<Workspace> {
) -> impl RenderOnce {
self.root.render(
project,
0,
@@ -204,7 +204,7 @@ impl Member {
zoomed: Option<&AnyWeakView>,
app_state: &Arc<AppState>,
cx: &mut ViewContext<Workspace>,
) -> impl RenderOnce<Workspace> {
) -> impl RenderOnce {
match self {
Member::Pane(pane) => {
// todo!()
@@ -561,7 +561,7 @@ impl PaneAxis {
zoomed: Option<&AnyWeakView>,
app_state: &Arc<AppState>,
cx: &mut ViewContext<Workspace>,
) -> Div<Workspace> {
) -> Div {
debug_assert!(self.members.len() == self.flexes.lock().len());
div()
+5 -5
View File
@@ -9,7 +9,7 @@ use theme2::ActiveTheme;
use ui::h_stack;
use util::ResultExt;
pub trait StatusItemView: Render<Self> {
pub trait StatusItemView: Render {
fn set_active_pane_item(
&mut self,
active_pane_item: Option<&dyn crate::ItemHandle>,
@@ -34,8 +34,8 @@ pub struct StatusBar {
_observe_active_pane: Subscription,
}
impl Render<Self> for StatusBar {
type Element = Div<Self>;
impl Render for StatusBar {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
div()
@@ -53,14 +53,14 @@ impl Render<Self> for StatusBar {
}
impl StatusBar {
fn render_left_tools(&self, cx: &mut ViewContext<Self>) -> impl RenderOnce<Self> {
fn render_left_tools(&self, cx: &mut ViewContext<Self>) -> impl RenderOnce {
h_stack()
.items_center()
.gap_2()
.children(self.left_items.iter().map(|item| item.to_any()))
}
fn render_right_tools(&self, cx: &mut ViewContext<Self>) -> impl RenderOnce<Self> {
fn render_right_tools(&self, cx: &mut ViewContext<Self>) -> impl RenderOnce {
h_stack()
.items_center()
.gap_2()
+3 -3
View File
@@ -7,7 +7,7 @@ pub enum ToolbarItemEvent {
ChangeLocation(ToolbarItemLocation),
}
pub trait ToolbarItemView: Render<Self> + EventEmitter<ToolbarItemEvent> {
pub trait ToolbarItemView: Render + EventEmitter<ToolbarItemEvent> {
fn set_active_pane_item(
&mut self,
active_pane_item: Option<&dyn crate::ItemHandle>,
@@ -51,8 +51,8 @@ pub struct Toolbar {
items: Vec<(Box<dyn ToolbarItemViewHandle>, ToolbarItemLocation)>,
}
impl Render<Self> for Toolbar {
type Element = Div<Self>;
impl Render for Toolbar {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
todo!()
+56 -44
View File
@@ -411,7 +411,7 @@ pub enum Event {
pub struct Workspace {
window_self: WindowHandle<Self>,
weak_self: WeakView<Self>,
workspace_actions: Vec<Box<dyn Fn(Div<Workspace>) -> Div<Workspace>>>,
workspace_actions: Vec<Box<dyn Fn(Div, &mut ViewContext<Self>) -> Div>>,
zoomed: Option<AnyWeakView>,
zoomed_position: Option<DockPosition>,
center: PaneGroup,
@@ -3204,53 +3204,63 @@ impl Workspace {
})
}
fn actions(&self, div: Div<Self>) -> Div<Self> {
self.add_workspace_actions_listeners(div)
fn actions(&self, div: Div, cx: &mut ViewContext<Self>) -> Div {
self.add_workspace_actions_listeners(div, cx)
// cx.add_async_action(Workspace::open);
// cx.add_async_action(Workspace::follow_next_collaborator);
// cx.add_async_action(Workspace::close);
.on_action(Self::close_inactive_items_and_panes)
.on_action(Self::close_all_items_and_panes)
.on_action(cx.listener(Self::close_inactive_items_and_panes))
.on_action(cx.listener(Self::close_all_items_and_panes))
// cx.add_global_action(Workspace::close_global);
// cx.add_global_action(restart);
.on_action(Self::save_all)
.on_action(Self::add_folder_to_project)
.on_action(|workspace, _: &Unfollow, cx| {
.on_action(cx.listener(Self::save_all))
.on_action(cx.listener(Self::add_folder_to_project))
.on_action(cx.listener(|workspace, _: &Unfollow, cx| {
let pane = workspace.active_pane().clone();
workspace.unfollow(&pane, cx);
})
.on_action(|workspace, action: &Save, cx| {
}))
.on_action(cx.listener(|workspace, action: &Save, cx| {
workspace
.save_active_item(action.save_intent.unwrap_or(SaveIntent::Save), cx)
.detach_and_log_err(cx);
})
.on_action(|workspace, _: &SaveAs, cx| {
}))
.on_action(cx.listener(|workspace, _: &SaveAs, cx| {
workspace
.save_active_item(SaveIntent::SaveAs, cx)
.detach_and_log_err(cx);
})
.on_action(|workspace, _: &ActivatePreviousPane, cx| {
}))
.on_action(cx.listener(|workspace, _: &ActivatePreviousPane, cx| {
workspace.activate_previous_pane(cx)
})
.on_action(|workspace, _: &ActivateNextPane, cx| workspace.activate_next_pane(cx))
.on_action(|workspace, action: &ActivatePaneInDirection, cx| {
workspace.activate_pane_in_direction(action.0, cx)
})
.on_action(|workspace, action: &SwapPaneInDirection, cx| {
}))
.on_action(
cx.listener(|workspace, _: &ActivateNextPane, cx| workspace.activate_next_pane(cx)),
)
.on_action(
cx.listener(|workspace, action: &ActivatePaneInDirection, cx| {
workspace.activate_pane_in_direction(action.0, cx)
}),
)
.on_action(cx.listener(|workspace, action: &SwapPaneInDirection, cx| {
workspace.swap_pane_in_direction(action.0, cx)
})
.on_action(|this, e: &ToggleLeftDock, cx| {
}))
.on_action(cx.listener(|this, e: &ToggleLeftDock, cx| {
this.toggle_dock(DockPosition::Left, cx);
})
.on_action(|workspace: &mut Workspace, _: &ToggleRightDock, cx| {
workspace.toggle_dock(DockPosition::Right, cx);
})
.on_action(|workspace: &mut Workspace, _: &ToggleBottomDock, cx| {
workspace.toggle_dock(DockPosition::Bottom, cx);
})
.on_action(|workspace: &mut Workspace, _: &CloseAllDocks, cx| {
workspace.close_all_docks(cx);
})
}))
.on_action(
cx.listener(|workspace: &mut Workspace, _: &ToggleRightDock, cx| {
workspace.toggle_dock(DockPosition::Right, cx);
}),
)
.on_action(
cx.listener(|workspace: &mut Workspace, _: &ToggleBottomDock, cx| {
workspace.toggle_dock(DockPosition::Bottom, cx);
}),
)
.on_action(
cx.listener(|workspace: &mut Workspace, _: &CloseAllDocks, cx| {
workspace.close_all_docks(cx);
}),
)
// cx.add_action(Workspace::activate_pane_at_index);
// cx.add_action(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| {
// workspace.reopen_closed_item(cx).detach();
@@ -3346,22 +3356,24 @@ impl Workspace {
) -> &mut Self {
let callback = Arc::new(callback);
self.workspace_actions.push(Box::new(move |div| {
self.workspace_actions.push(Box::new(move |div, cx| {
let callback = callback.clone();
div.on_action(move |workspace, event, cx| (callback.clone())(workspace, event, cx))
div.on_action(
cx.listener(move |workspace, event, cx| (callback.clone())(workspace, event, cx)),
)
}));
self
}
fn add_workspace_actions_listeners(&self, mut div: Div<Workspace>) -> Div<Workspace> {
fn add_workspace_actions_listeners(&self, mut div: Div, cx: &mut ViewContext<Self>) -> Div {
let mut div = div
.on_action(Self::close_inactive_items_and_panes)
.on_action(Self::close_all_items_and_panes)
.on_action(Self::add_folder_to_project)
.on_action(Self::save_all)
.on_action(Self::open);
.on_action(cx.listener(Self::close_inactive_items_and_panes))
.on_action(cx.listener(Self::close_all_items_and_panes))
.on_action(cx.listener(Self::add_folder_to_project))
.on_action(cx.listener(Self::save_all))
.on_action(cx.listener(Self::open));
for action in self.workspace_actions.iter() {
div = (action)(div)
div = (action)(div, cx)
}
div
}
@@ -3594,8 +3606,8 @@ impl FocusableView for Workspace {
}
}
impl Render<Self> for Workspace {
type Element = Div<Self>;
impl Render for Workspace {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let mut context = KeyContext::default();
@@ -3611,7 +3623,7 @@ impl Render<Self> for Workspace {
cx.set_rem_size(ui_font_size);
self.actions(div())
self.actions(div(), cx)
.key_context(context)
.relative()
.size_full()