mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-16 07:11:18 +00:00
Allow dragging and dropping tabs
Co-authored-by: Nathan <nathan@zed.dev> Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
parent
a4a501603e
commit
a579713a45
9 changed files with 82 additions and 535 deletions
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
|
|
|
@ -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>) {
|
||||
|
|
Loading…
Reference in a new issue