Allow dragging and dropping tabs

Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
Max Brunsfeld 2023-12-12 15:02:31 -08:00
parent a4a501603e
commit a579713a45
9 changed files with 82 additions and 535 deletions

View file

@ -288,7 +288,11 @@ impl ChatPanel {
),
),
)
.child(div().grow().child(self.render_active_channel_messages(cx)))
.child(
div()
.flex_grow()
.child(self.render_active_channel_messages(cx)),
)
.child(
div()
.z_index(1)

View file

@ -61,6 +61,10 @@ pub trait InteractiveElement: Sized {
}
fn hover(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self {
debug_assert!(
self.interactivity().hover_style.is_none(),
"hover style already set"
);
self.interactivity().hover_style = Some(Box::new(f(StyleRefinement::default())));
self
}
@ -1313,16 +1317,16 @@ where
impl<E> IntoElement for Focusable<E>
where
E: Element,
E: IntoElement,
{
type Element = E;
type Element = E::Element;
fn element_id(&self) -> Option<ElementId> {
self.element.element_id()
}
fn into_element(self) -> Self::Element {
self.element
self.element.into_element()
}
}

View file

@ -303,7 +303,7 @@ pub trait Styled: Sized {
/// Sets the element to allow a flex item to grow to fill any available space.
/// [Docs](https://tailwindcss.com/docs/flex-grow)
fn grow(mut self) -> Self {
fn flex_grow(mut self) -> Self {
self.style().flex_grow = Some(1.);
self
}

View file

@ -228,7 +228,7 @@ impl<D: PickerDelegate> Render for Picker<D> {
.when(self.delegate.match_count() > 0, |el| {
el.child(
v_stack()
.grow()
.flex_grow()
.child(
uniform_list(
cx.view().clone(),

View file

@ -61,7 +61,7 @@ impl ComponentStory {
Self::Scroll => ScrollStory::view(cx).into(),
Self::Text => TextStory::view(cx).into(),
Self::Tab => cx.build_view(|_| ui::TabStory).into(),
Self::TabBar => cx.build_view(|cx| ui::TabBarStory::new(cx)).into(),
Self::TabBar => cx.build_view(|_| ui::TabBarStory).into(),
Self::ViewportUnits => cx.build_view(|_| crate::stories::ViewportUnitsStory).into(),
Self::ZIndex => cx.build_view(|_| ZIndexStory).into(),
Self::Picker => PickerStory::new(cx).into(),

View file

@ -54,14 +54,6 @@ impl ListItem {
self
}
pub fn on_drag(
mut self,
handler: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static,
) -> Self {
self.on_secondary_mouse_down = Some(Box::new(handler));
self
}
pub fn tooltip(mut self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self {
self.tooltip = Some(Box::new(tooltip));
self

View file

@ -1,19 +1,9 @@
use gpui::{Div, FocusHandle, Render};
use gpui::{Div, Render};
use story::Story;
use crate::{prelude::*, Tab, TabBar, TabPosition};
pub struct TabBarStory {
tab_bar_focus_handle: FocusHandle,
}
impl TabBarStory {
pub fn new(cx: &mut ViewContext<Self>) -> Self {
Self {
tab_bar_focus_handle: cx.focus_handle(),
}
}
}
pub struct TabBarStory;
impl Render for TabBarStory {
type Element = Div;
@ -48,7 +38,7 @@ impl Render for TabBarStory {
.child(Story::label("Default"))
.child(
h_stack().child(
TabBar::new("tab_bar_1", self.tab_bar_focus_handle.clone())
TabBar::new("tab_bar_1")
.start_child(
IconButton::new("navigate_backward", Icon::ArrowLeft)
.icon_size(IconSize::Small),

View file

@ -1,22 +1,20 @@
use gpui::{AnyElement, FocusHandle, Focusable, Stateful};
use gpui::{AnyElement, Stateful};
use smallvec::SmallVec;
use crate::prelude::*;
#[derive(IntoElement)]
pub struct TabBar {
id: ElementId,
focus_handle: FocusHandle,
div: Stateful<Div>,
start_children: SmallVec<[AnyElement; 2]>,
children: SmallVec<[AnyElement; 2]>,
end_children: SmallVec<[AnyElement; 2]>,
}
impl TabBar {
pub fn new(id: impl Into<ElementId>, focus_handle: FocusHandle) -> Self {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
id: id.into(),
focus_handle,
div: div().id(id),
start_children: SmallVec::new(),
children: SmallVec::new(),
end_children: SmallVec::new(),
@ -83,16 +81,22 @@ impl ParentElement for TabBar {
}
}
impl InteractiveElement for TabBar {
fn interactivity(&mut self) -> &mut gpui::Interactivity {
self.div.interactivity()
}
}
impl StatefulInteractiveElement for TabBar {}
impl RenderOnce for TabBar {
type Rendered = Focusable<Stateful<Div>>;
type Rendered = Stateful<Div>;
fn render(self, cx: &mut WindowContext) -> Self::Rendered {
const HEIGHT_IN_REMS: f32 = 30. / 16.;
div()
.id(self.id)
self.div
.group("tab_bar")
.track_focus(&self.focus_handle)
.flex()
.flex_none()
.w_full()
@ -128,6 +132,7 @@ impl RenderOnce for TabBar {
h_stack()
.id("tabs")
.z_index(2)
.flex_grow()
.overflow_x_scroll()
.children(self.children),
),

View file

@ -7,10 +7,10 @@ use crate::{
use anyhow::Result;
use collections::{HashMap, HashSet, VecDeque};
use gpui::{
actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyDrag, AnyWeakView,
AppContext, AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle,
Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel,
Render, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyWeakView, AppContext,
AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle, Focusable,
FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, Render,
Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
};
use parking_lot::Mutex;
use project::{Project, ProjectEntryId, ProjectPath};
@ -32,7 +32,7 @@ use ui::{
Indicator, Label, Tab, TabBar, TabPosition, Tooltip,
};
use ui::{v_stack, ContextMenu};
use util::{maybe, truncate_and_remove_front};
use util::{maybe, truncate_and_remove_front, ResultExt};
#[derive(PartialEq, Clone, Copy, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
@ -235,6 +235,7 @@ pub struct NavigationEntry {
struct DraggedTab {
pub pane: View<Pane>,
pub ix: usize,
pub item_id: EntityId,
pub detail: usize,
pub is_active: bool,
}
@ -1486,8 +1487,7 @@ impl Pane {
Some(Indicator::dot().color(indicator_color))
});
let id = item.item_id();
let item_id = item.item_id();
let is_first_item = ix == 0;
let is_last_item = ix == self.items.len() - 1;
let position_relative_to_active_item = ix.cmp(&self.active_item_index);
@ -1515,15 +1515,18 @@ impl Pane {
cx.build_view(|cx| DraggedTab {
pane: pane.clone(),
detail,
item_id,
is_active,
ix,
})
}
})
// .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
// .on_drop(|_view, state: View<DraggedTab>, cx| {
// eprintln!("{:?}", state.read(cx));
// })
.drag_over::<DraggedTab>(|tab| tab.bg(cx.theme().colors().tab_active_background))
.on_drop(
cx.listener(move |this, dragged_tab: &View<DraggedTab>, cx| {
this.handle_tab_drop(dragged_tab, ix, cx)
}),
)
.when_some(item.tab_tooltip_text(cx), |tab, text| {
tab.tooltip(move |cx| Tooltip::text(text.clone(), cx))
})
@ -1534,7 +1537,7 @@ impl Pane {
.size(ButtonSize::None)
.icon_size(IconSize::XSmall)
.on_click(cx.listener(move |pane, _, cx| {
pane.close_item_by_id(id, SaveIntent::Close, cx)
pane.close_item_by_id(item_id, SaveIntent::Close, cx)
.detach_and_log_err(cx);
})),
)
@ -1580,7 +1583,7 @@ impl Pane {
}
fn render_tab_bar(&mut self, cx: &mut ViewContext<'_, Pane>) -> impl IntoElement {
TabBar::new("tab_bar", self.tab_bar_focus_handle.clone())
TabBar::new("tab_bar")
.start_child(
IconButton::new("navigate_backward", Icon::ArrowLeft)
.icon_size(IconSize::Small)
@ -1653,6 +1656,20 @@ impl Pane {
.zip(self.tab_details(cx))
.map(|((ix, item), detail)| self.render_tab(ix, item, detail, cx)),
)
.child(
div()
.h_full()
.flex_grow()
.drag_over::<DraggedTab>(|bar| {
bar.bg(cx.theme().colors().tab_active_background)
})
.on_drop(
cx.listener(move |this, dragged_tab: &View<DraggedTab>, cx| {
this.handle_tab_drop(dragged_tab, this.items.len(), cx)
}),
),
)
.track_focus(&self.tab_bar_focus_handle)
}
fn render_menu_overlay(menu: &View<ContextMenu>) -> Div {
@ -1665,161 +1682,6 @@ impl Pane {
.child(overlay().anchor(AnchorCorner::TopRight).child(menu.clone()))
}
// fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Element<Self> {
// let theme = theme::current(cx).clone();
// let pane = cx.handle().downgrade();
// let autoscroll = if mem::take(&mut self.autoscroll) {
// Some(self.active_item_index)
// } else {
// None
// };
// let pane_active = self.has_focus;
// enum Tabs {}
// let mut row = Flex::row().scrollable::<Tabs>(1, autoscroll, cx);
// for (ix, (item, detail)) in self
// .items
// .iter()
// .cloned()
// .zip(self.tab_details(cx))
// .enumerate()
// {
// let git_status = item
// .project_path(cx)
// .and_then(|path| self.project.read(cx).entry_for_path(&path, cx))
// .and_then(|entry| entry.git_status());
// let detail = if detail == 0 { None } else { Some(detail) };
// let tab_active = ix == self.active_item_index;
// row.add_child({
// enum TabDragReceiver {}
// let mut receiver =
// dragged_item_receiver::<TabDragReceiver, _, _>(self, ix, ix, true, None, cx, {
// let item = item.clone();
// let pane = pane.clone();
// let detail = detail.clone();
// let theme = theme::current(cx).clone();
// let mut tooltip_theme = theme.tooltip.clone();
// tooltip_theme.max_text_width = None;
// let tab_tooltip_text =
// item.tab_tooltip_text(cx).map(|text| text.into_owned());
// let mut tab_style = theme
// .workspace
// .tab_bar
// .tab_style(pane_active, tab_active)
// .clone();
// let should_show_status = settings::get::<ItemSettings>(cx).git_status;
// if should_show_status && git_status != None {
// tab_style.label.text.color = match git_status.unwrap() {
// GitFileStatus::Added => tab_style.git.inserted,
// GitFileStatus::Modified => tab_style.git.modified,
// GitFileStatus::Conflict => tab_style.git.conflict,
// };
// }
// move |mouse_state, cx| {
// let hovered = mouse_state.hovered();
// enum Tab {}
// let mouse_event_handler =
// MouseEventHandler::new::<Tab, _>(ix, cx, |_, cx| {
// Self::render_tab(
// &item,
// pane.clone(),
// ix == 0,
// detail,
// hovered,
// &tab_style,
// cx,
// )
// })
// .on_down(MouseButton::Left, move |_, this, cx| {
// this.activate_item(ix, true, true, cx);
// })
// .on_click(MouseButton::Middle, {
// let item_id = item.id();
// move |_, pane, cx| {
// pane.close_item_by_id(item_id, SaveIntent::Close, cx)
// .detach_and_log_err(cx);
// }
// })
// .on_down(
// MouseButton::Right,
// move |event, pane, cx| {
// pane.deploy_tab_context_menu(event.position, item.id(), cx);
// },
// );
// if let Some(tab_tooltip_text) = tab_tooltip_text {
// mouse_event_handler
// .with_tooltip::<Self>(
// ix,
// tab_tooltip_text,
// None,
// tooltip_theme,
// cx,
// )
// .into_any()
// } else {
// mouse_event_handler.into_any()
// }
// }
// });
// if !pane_active || !tab_active {
// receiver = receiver.with_cursor_style(CursorStyle::PointingHand);
// }
// receiver.as_draggable(
// DraggedItem {
// handle: item,
// pane: pane.clone(),
// },
// {
// let theme = theme::current(cx).clone();
// let detail = detail.clone();
// move |_, dragged_item: &DraggedItem, cx: &mut ViewContext<Workspace>| {
// let tab_style = &theme.workspace.tab_bar.dragged_tab;
// Self::render_dragged_tab(
// &dragged_item.handle,
// dragged_item.pane.clone(),
// false,
// detail,
// false,
// &tab_style,
// cx,
// )
// }
// },
// )
// })
// }
// // Use the inactive tab style along with the current pane's active status to decide how to render
// // the filler
// let filler_index = self.items.len();
// let filler_style = theme.workspace.tab_bar.tab_style(pane_active, false);
// enum Filler {}
// row.add_child(
// dragged_item_receiver::<Filler, _, _>(self, 0, filler_index, true, None, cx, |_, _| {
// Empty::new()
// .contained()
// .with_style(filler_style.container)
// .with_border(filler_style.container.border)
// })
// .flex(1., true)
// .into_any_named("filler"),
// );
// row
// }
fn tab_details(&self, cx: &AppContext) -> Vec<usize> {
let mut tab_details = self.items.iter().map(|_| 0).collect::<Vec<_>>();
@ -1857,192 +1719,6 @@ impl Pane {
tab_details
}
// fn render_tab(
// item: &Box<dyn ItemHandle>,
// pane: WeakView<Pane>,
// first: bool,
// detail: Option<usize>,
// hovered: bool,
// tab_style: &theme::Tab,
// cx: &mut ViewContext<Self>,
// ) -> AnyElement<Self> {
// let title = item.tab_content(detail, &tab_style, cx);
// Self::render_tab_with_title(title, item, pane, first, hovered, tab_style, cx)
// }
// fn render_dragged_tab(
// item: &Box<dyn ItemHandle>,
// pane: WeakView<Pane>,
// first: bool,
// detail: Option<usize>,
// hovered: bool,
// tab_style: &theme::Tab,
// cx: &mut ViewContext<Workspace>,
// ) -> AnyElement<Workspace> {
// let title = item.dragged_tab_content(detail, &tab_style, cx);
// Self::render_tab_with_title(title, item, pane, first, hovered, tab_style, cx)
// }
// fn render_tab_with_title<T: View>(
// title: AnyElement<T>,
// item: &Box<dyn ItemHandle>,
// pane: WeakView<Pane>,
// first: bool,
// hovered: bool,
// tab_style: &theme::Tab,
// cx: &mut ViewContext<T>,
// ) -> AnyElement<T> {
// let mut container = tab_style.container.clone();
// if first {
// container.border.left = false;
// }
// let buffer_jewel_element = {
// let diameter = 7.0;
// let icon_color = if item.has_conflict(cx) {
// Some(tab_style.icon_conflict)
// } else if item.is_dirty(cx) {
// Some(tab_style.icon_dirty)
// } else {
// None
// };
// Canvas::new(move |bounds, _, _, cx| {
// if let Some(color) = icon_color {
// let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
// cx.scene().push_quad(Quad {
// bounds: square,
// background: Some(color),
// border: Default::default(),
// corner_radii: (diameter / 2.).into(),
// });
// }
// })
// .constrained()
// .with_width(diameter)
// .with_height(diameter)
// .aligned()
// };
// let title_element = title.aligned().contained().with_style(ContainerStyle {
// margin: Margin {
// left: tab_style.spacing,
// right: tab_style.spacing,
// ..Default::default()
// },
// ..Default::default()
// });
// let close_element = if hovered {
// let item_id = item.id();
// enum TabCloseButton {}
// let icon = Svg::new("icons/x.svg");
// MouseEventHandler::new::<TabCloseButton, _>(item_id, cx, |mouse_state, _| {
// if mouse_state.hovered() {
// icon.with_color(tab_style.icon_close_active)
// } else {
// icon.with_color(tab_style.icon_close)
// }
// })
// .with_padding(Padding::uniform(4.))
// .with_cursor_style(CursorStyle::PointingHand)
// .on_click(MouseButton::Left, {
// let pane = pane.clone();
// move |_, _, cx| {
// let pane = pane.clone();
// cx.window_context().defer(move |cx| {
// if let Some(pane) = pane.upgrade(cx) {
// pane.update(cx, |pane, cx| {
// pane.close_item_by_id(item_id, SaveIntent::Close, cx)
// .detach_and_log_err(cx);
// });
// }
// });
// }
// })
// .into_any_named("close-tab-icon")
// .constrained()
// } else {
// Empty::new().constrained()
// }
// .with_width(tab_style.close_icon_width)
// .aligned();
// let close_right = settings::get::<ItemSettings>(cx).close_position.right();
// if close_right {
// Flex::row()
// .with_child(buffer_jewel_element)
// .with_child(title_element)
// .with_child(close_element)
// } else {
// Flex::row()
// .with_child(close_element)
// .with_child(title_element)
// .with_child(buffer_jewel_element)
// }
// .contained()
// .with_style(container)
// .constrained()
// .with_height(tab_style.height)
// .into_any()
// }
// pub fn render_tab_bar_button<
// F1: 'static + Fn(&mut Pane, &mut EventContext<Pane>),
// F2: 'static + Fn(&mut Pane, &mut EventContext<Pane>),
// >(
// index: usize,
// icon: &'static str,
// is_active: bool,
// tooltip: Option<(&'static str, Option<Box<dyn Action>>)>,
// cx: &mut ViewContext<Pane>,
// on_click: F1,
// on_down: F2,
// context_menu: Option<ViewHandle<ContextMenu>>,
// ) -> AnyElement<Pane> {
// enum TabBarButton {}
// let mut button = MouseEventHandler::new::<TabBarButton, _>(index, cx, |mouse_state, cx| {
// let theme = &settings2::get::<ThemeSettings>(cx).theme.workspace.tab_bar;
// let style = theme.pane_button.in_state(is_active).style_for(mouse_state);
// Svg::new(icon)
// .with_color(style.color)
// .constrained()
// .with_width(style.icon_width)
// .aligned()
// .constrained()
// .with_width(style.button_width)
// .with_height(style.button_width)
// })
// .with_cursor_style(CursorStyle::PointingHand)
// .on_down(MouseButton::Left, move |_, pane, cx| on_down(pane, cx))
// .on_click(MouseButton::Left, move |_, pane, cx| on_click(pane, cx))
// .into_any();
// if let Some((tooltip, action)) = tooltip {
// let tooltip_style = settings::get::<ThemeSettings>(cx).theme.tooltip.clone();
// button = button
// .with_tooltip::<TabBarButton>(index, tooltip, action, tooltip_style, cx)
// .into_any();
// }
// Stack::new()
// .with_child(button)
// .with_children(
// context_menu.map(|menu| ChildView::new(&menu, cx).aligned().bottom().right()),
// )
// .flex(1., false)
// .into_any_named("tab bar button")
// }
// fn render_blank_pane(&self, theme: &Theme, _cx: &mut ViewContext<Self>) -> AnyElement<Self> {
// let background = theme.workspace.background;
// Empty::new()
// .contained()
// .with_background_color(background)
// .into_any()
// }
pub fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext<Self>) {
self.zoomed = zoomed;
cx.notify();
@ -2051,6 +1727,25 @@ impl Pane {
pub fn is_zoomed(&self) -> bool {
self.zoomed
}
fn handle_tab_drop(
&mut self,
dragged_tab: &View<DraggedTab>,
ix: usize,
cx: &mut ViewContext<'_, Pane>,
) {
let dragged_tab = dragged_tab.read(cx);
let item_id = dragged_tab.item_id;
let from_pane = dragged_tab.pane.clone();
let to_pane = cx.view().clone();
self.workspace
.update(cx, |workspace, cx| {
cx.defer(move |workspace, cx| {
workspace.move_item(from_pane, to_pane, item_id, ix, cx);
});
})
.log_err();
}
}
impl FocusableView for Pane {
@ -2152,148 +1847,6 @@ impl Render for Pane {
.justify_center()
.child(Label::new("Open a file or project to get started.").color(Color::Muted))
})
// enum MouseNavigationHandler {}
// MouseEventHandler::new::<MouseNavigationHandler, _>(0, cx, |_, cx| {
// let active_item_index = self.active_item_index;
// if let Some(active_item) = self.active_item() {
// Flex::column()
// .with_child({
// let theme = theme::current(cx).clone();
// let mut stack = Stack::new();
// enum TabBarEventHandler {}
// stack.add_child(
// MouseEventHandler::new::<TabBarEventHandler, _>(0, cx, |_, _| {
// Empty::new()
// .contained()
// .with_style(theme.workspace.tab_bar.container)
// })
// .on_down(
// MouseButton::Left,
// move |_, this, cx| {
// this.activate_item(active_item_index, true, true, cx);
// },
// ),
// );
// let tooltip_style = theme.tooltip.clone();
// let tab_bar_theme = theme.workspace.tab_bar.clone();
// let nav_button_height = tab_bar_theme.height;
// let button_style = tab_bar_theme.nav_button;
// let border_for_nav_buttons = tab_bar_theme
// .tab_style(false, false)
// .container
// .border
// .clone();
// let mut tab_row = Flex::row()
// .with_child(nav_button(
// "icons/arrow_left.svg",
// button_style.clone(),
// nav_button_height,
// tooltip_style.clone(),
// self.can_navigate_backward(),
// {
// move |pane, cx| {
// if let Some(workspace) = pane.workspace.upgrade(cx) {
// let pane = cx.weak_handle();
// cx.window_context().defer(move |cx| {
// workspace.update(cx, |workspace, cx| {
// workspace
// .go_back(pane, cx)
// .detach_and_log_err(cx)
// })
// })
// }
// }
// },
// super::GoBack,
// "Go Back",
// cx,
// ))
// .with_child(
// nav_button(
// "icons/arrow_right.svg",
// button_style.clone(),
// nav_button_height,
// tooltip_style,
// self.can_navigate_forward(),
// {
// move |pane, cx| {
// if let Some(workspace) = pane.workspace.upgrade(cx) {
// let pane = cx.weak_handle();
// cx.window_context().defer(move |cx| {
// workspace.update(cx, |workspace, cx| {
// workspace
// .go_forward(pane, cx)
// .detach_and_log_err(cx)
// })
// })
// }
// }
// },
// super::GoForward,
// "Go Forward",
// cx,
// )
// .contained()
// .with_border(border_for_nav_buttons),
// )
// .with_child(self.render_tabs(cx).flex(1., true).into_any_named("tabs"));
// if self.has_focus {
// let render_tab_bar_buttons = self.render_tab_bar_buttons.clone();
// tab_row.add_child(
// (render_tab_bar_buttons)(self, cx)
// .contained()
// .with_style(theme.workspace.tab_bar.pane_button_container)
// .flex(1., false)
// .into_any(),
// )
// }
// stack.add_child(tab_row);
// stack
// .constrained()
// .with_height(theme.workspace.tab_bar.height)
// .flex(1., false)
// .into_any_named("tab bar")
// })
// .with_child({
// enum PaneContentTabDropTarget {}
// dragged_item_receiver::<PaneContentTabDropTarget, _, _>(
// self,
// 0,
// self.active_item_index + 1,
// !self.can_split,
// if self.can_split { Some(100.) } else { None },
// cx,
// {
// let toolbar = self.toolbar.clone();
// let toolbar_hidden = toolbar.read(cx).hidden();
// move |_, cx| {
// Flex::column()
// .with_children(
// (!toolbar_hidden)
// .then(|| ChildView::new(&toolbar, cx).expanded()),
// )
// .with_child(
// ChildView::new(active_item.as_any(), cx).flex(1., true),
// )
// }
// },
// )
// .flex(1., true)
// })
// .with_child(ChildView::new(&self.tab_context_menu, cx))
// .into_any()
// } else {
// enum EmptyPane {}
// let theme = theme::current(cx).clone();
// dragged_item_receiver::<EmptyPane, _, _>(self, 0, 0, false, None, cx, |_, cx| {
// self.render_blank_pane(&theme, cx)
// })
// .on_down(MouseButton::Left, |_, _, cx| {
// cx.focus_parent();
// })
// .into_any()
// }
// })
.on_mouse_down(
MouseButton::Navigate(NavigationDirection::Back),
cx.listener(|pane, _, cx| {
@ -2320,7 +1873,6 @@ impl Render for Pane {
}
}),
)
// .into_any_named("pane")
}
// fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {