update dock
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
//! Dock is a fixed container that places at left, bottom, right of the Windows.
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
||||
+4
-11
@@ -15,7 +15,7 @@ use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
AnyElement, AnyView, App, AppContext, Axis, Bounds, Context, Edges, Entity, EntityId,
|
||||
EventEmitter, InteractiveElement as _, IntoElement, ParentElement as _, Pixels, Render,
|
||||
SharedString, Styled, Subscription, WeakEntity, Window, actions, div,
|
||||
SharedString, Styled, Subscription, WeakEntity, Window, actions, div, px,
|
||||
};
|
||||
use gpui_component::{ElementExt, Placement};
|
||||
pub use panel::*;
|
||||
@@ -52,6 +52,9 @@ pub(crate) fn t(key: &'static str) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
/// The fixed height of the tab bar, which doubles as the window title bar.
|
||||
pub(crate) const TAB_BAR_HEIGHT: Pixels = px(44.);
|
||||
|
||||
/// A host-owned drag item, dragged into the dock by the application.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AnyDrag {
|
||||
@@ -115,9 +118,6 @@ pub struct DockArea {
|
||||
/// Lock panels layout, but allow to resize.
|
||||
locked: bool,
|
||||
|
||||
/// The panel style, default is [`PanelStyle::Default`](PanelStyle::Default).
|
||||
pub(crate) panel_style: PanelStyle,
|
||||
|
||||
_subscriptions: Vec<Subscription>,
|
||||
}
|
||||
|
||||
@@ -509,7 +509,6 @@ impl DockArea {
|
||||
toggle_button_panels: Edges::default(),
|
||||
toggle_button_visible: true,
|
||||
locked: false,
|
||||
panel_style: PanelStyle::default(),
|
||||
_subscriptions: vec![],
|
||||
};
|
||||
|
||||
@@ -523,12 +522,6 @@ impl DockArea {
|
||||
self.bounds
|
||||
}
|
||||
|
||||
/// Set the panel style of the dock area.
|
||||
pub fn panel_style(mut self, style: PanelStyle) -> Self {
|
||||
self.panel_style = style;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set version of the dock area.
|
||||
pub fn set_version(&mut self, version: usize, _: &mut Window, cx: &mut Context<Self>) {
|
||||
self.version = Some(version);
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||
|
||||
use gpui::{
|
||||
AnyElement, AnyView, App, AppContext as _, Context, Entity, EntityId, EventEmitter,
|
||||
FocusHandle, Focusable, Global, Hsla, IntoElement, Render, SharedString, WeakEntity, Window,
|
||||
FocusHandle, Focusable, Global, IntoElement, Render, SharedString, WeakEntity, Window,
|
||||
};
|
||||
use gpui_component::button::Button;
|
||||
use gpui_component::menu::PopupMenu;
|
||||
@@ -18,21 +18,6 @@ pub enum PanelEvent {
|
||||
LayoutChanged,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub enum PanelStyle {
|
||||
/// Display the TabBar when there are multiple tabs, otherwise display the simple title.
|
||||
#[default]
|
||||
Auto,
|
||||
/// Always display the tab bar.
|
||||
TabBar,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct TitleStyle {
|
||||
pub background: Hsla,
|
||||
pub foreground: Hsla,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub enum PanelControl {
|
||||
Both,
|
||||
@@ -74,11 +59,6 @@ pub trait Panel: EventEmitter<PanelEvent> + Render + Focusable {
|
||||
t("Dock.Unnamed")
|
||||
}
|
||||
|
||||
/// The theme of the panel title, default is `None`.
|
||||
fn title_style(&self, cx: &App) -> Option<TitleStyle> {
|
||||
None
|
||||
}
|
||||
|
||||
/// The suffix of the panel title, default is `None`.
|
||||
///
|
||||
/// This is used to add a suffix element to the panel title.
|
||||
@@ -182,7 +162,6 @@ pub trait PanelView: 'static + Send + Sync {
|
||||
fn tab_name(&self, cx: &App) -> Option<SharedString>;
|
||||
fn title(&self, window: &mut Window, cx: &mut App) -> AnyElement;
|
||||
fn title_suffix(&self, window: &mut Window, cx: &mut App) -> Option<AnyElement>;
|
||||
fn title_style(&self, cx: &App) -> Option<TitleStyle>;
|
||||
fn closable(&self, cx: &App) -> bool;
|
||||
fn zoomable(&self, cx: &App) -> Option<PanelControl>;
|
||||
fn visible(&self, cx: &App) -> bool;
|
||||
@@ -222,10 +201,6 @@ impl<T: Panel> PanelView for Entity<T> {
|
||||
})
|
||||
}
|
||||
|
||||
fn title_style(&self, cx: &App) -> Option<TitleStyle> {
|
||||
self.read(cx).title_style(cx)
|
||||
}
|
||||
|
||||
fn closable(&self, cx: &App) -> bool {
|
||||
self.read(cx).closable(cx)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use gpui::{
|
||||
DragMoveEvent, Empty, Entity, EntityId, EventEmitter, FocusHandle, Focusable,
|
||||
InteractiveElement as _, IntoElement, MouseButton, ParentElement, Pixels, Point, Render,
|
||||
ScrollHandle, SharedString, Stateful, StatefulInteractiveElement, StyleRefinement, Styled,
|
||||
WeakEntity, Window, WindowControlArea, div, point, px, rems,
|
||||
WeakEntity, Window, WindowControlArea, div, point, px,
|
||||
};
|
||||
use gpui_component::animation::{Lerp, ease_out_cubic};
|
||||
use gpui_component::button::{Button, ButtonVariants as _};
|
||||
@@ -23,9 +23,9 @@ use gpui_component::{
|
||||
|
||||
use super::{
|
||||
AnyDrag, ClosePanel, DockArea, DockEvent, DockPlacement, DropTarget, Panel, PanelControl,
|
||||
PanelEvent, PanelState, PanelStyle, PanelView, StackPanel, ToggleZoom,
|
||||
PanelEvent, PanelState, PanelView, StackPanel, ToggleZoom,
|
||||
};
|
||||
use crate::{PanelInfo, t, window_controls};
|
||||
use crate::{PanelInfo, TAB_BAR_HEIGHT, t, window_controls};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct TabState {
|
||||
@@ -640,7 +640,7 @@ impl TabPanel {
|
||||
this.children(
|
||||
buttons
|
||||
.into_iter()
|
||||
.map(|btn| btn.xsmall().ghost().tab_stop(false)),
|
||||
.map(|btn| btn.small().ghost().tab_stop(false)),
|
||||
)
|
||||
})
|
||||
.map(|this| {
|
||||
@@ -656,7 +656,7 @@ impl TabPanel {
|
||||
this.child(
|
||||
Button::new(id)
|
||||
.icon(icon)
|
||||
.xsmall()
|
||||
.small()
|
||||
.ghost()
|
||||
.tab_stop(false)
|
||||
.tooltip_with_action(tooltip, &ToggleZoom, None)
|
||||
@@ -672,7 +672,7 @@ impl TabPanel {
|
||||
.child(
|
||||
Button::new("menu")
|
||||
.icon(IconName::Ellipsis)
|
||||
.xsmall()
|
||||
.small()
|
||||
.ghost()
|
||||
.tab_stop(false)
|
||||
.dropdown_menu({
|
||||
@@ -743,7 +743,7 @@ impl TabPanel {
|
||||
Some(
|
||||
Button::new(SharedString::from(format!("toggle-dock:{:?}", placement)))
|
||||
.icon(icon)
|
||||
.xsmall()
|
||||
.small()
|
||||
.ghost()
|
||||
.tab_stop(false)
|
||||
.tooltip(match is_open {
|
||||
@@ -769,10 +769,6 @@ impl TabPanel {
|
||||
) -> impl IntoElement {
|
||||
let view = cx.entity().clone();
|
||||
|
||||
let Some(dock_area) = self.dock_area.upgrade() else {
|
||||
return div().into_any_element();
|
||||
};
|
||||
|
||||
let left_dock_button = self.render_dock_toggle_button(DockPlacement::Left, window, cx);
|
||||
let has_extend_dock_button = left_dock_button.is_some();
|
||||
|
||||
@@ -786,75 +782,6 @@ impl TabPanel {
|
||||
.and_then(|area| area.read(cx).left_dock.clone())
|
||||
.is_none_or(|dock| !dock.read(cx).is_open());
|
||||
|
||||
let panel_style = dock_area.read(cx).panel_style;
|
||||
let visible_panels = self.visible_panels(cx).collect::<Vec<_>>();
|
||||
|
||||
if visible_panels.len() == 1 && panel_style == PanelStyle::default() {
|
||||
let panel = visible_panels.first().unwrap();
|
||||
|
||||
if !panel.visible(cx) {
|
||||
return div().into_any_element();
|
||||
}
|
||||
|
||||
let title_style = panel.title_style(cx);
|
||||
|
||||
return title_bar_drag_handlers(
|
||||
h_flex()
|
||||
.id(("tab-panel-simple-title", cx.entity().entity_id()))
|
||||
.justify_between()
|
||||
.line_height(rems(1.0))
|
||||
.h(px(30.))
|
||||
.py_2()
|
||||
.pl_3()
|
||||
.pr_2()
|
||||
.when(left_dock_button.is_some(), |this| this.pl_2())
|
||||
.when(needs_traffic_light_padding, |this| this.pl(px(80.)))
|
||||
.when_some(title_style, |this, theme| {
|
||||
this.bg(theme.background).text_color(theme.foreground)
|
||||
})
|
||||
.when(has_extend_dock_button, |this| {
|
||||
this.child(
|
||||
h_flex()
|
||||
.flex_shrink_0()
|
||||
.mr_1()
|
||||
.gap_1()
|
||||
.children(left_dock_button),
|
||||
)
|
||||
})
|
||||
.child(
|
||||
div()
|
||||
.id("tab")
|
||||
.flex_1()
|
||||
.min_w_16()
|
||||
.overflow_hidden()
|
||||
.text_ellipsis()
|
||||
.whitespace_nowrap()
|
||||
.child(panel.title(window, cx))
|
||||
.when(state.draggable, |this| {
|
||||
this.on_drag(
|
||||
DragPanel::new(panel.clone(), view),
|
||||
|drag, offset, _, cx| {
|
||||
cx.stop_propagation();
|
||||
drag.drag_offset.set(offset);
|
||||
cx.new(|_| drag.clone())
|
||||
},
|
||||
)
|
||||
}),
|
||||
)
|
||||
.children(panel.title_suffix(window, cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.flex_shrink_0()
|
||||
.ml_1()
|
||||
.gap_1()
|
||||
.child(self.render_toolbar(state, window, cx)),
|
||||
),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.into_any_element();
|
||||
}
|
||||
|
||||
if let Some(panel_ix) = self.pending_scroll_to_ix.take()
|
||||
&& let Some(visible_ix) = self
|
||||
.panels
|
||||
@@ -920,6 +847,9 @@ impl TabPanel {
|
||||
})
|
||||
.child(
|
||||
TabBar::new("tab-bar")
|
||||
.h(TAB_BAR_HEIGHT)
|
||||
.pill()
|
||||
.small()
|
||||
.track_scroll(&self.tab_bar_scroll_handle)
|
||||
.when(
|
||||
has_extend_dock_button || needs_traffic_light_padding,
|
||||
@@ -931,7 +861,6 @@ impl TabPanel {
|
||||
// Right -1 for avoid border overlap with the first tab
|
||||
.right(-px(1.))
|
||||
.h_full()
|
||||
.bg(cx.theme().tokens.tab_bar)
|
||||
.px_2()
|
||||
.when(needs_traffic_light_padding, |this| {
|
||||
this.pl(px(80.))
|
||||
@@ -1073,7 +1002,6 @@ impl TabPanel {
|
||||
.top_0()
|
||||
.right_0()
|
||||
.h_full()
|
||||
.bg(cx.theme().tokens.tab_bar)
|
||||
.px_2()
|
||||
.gap_1()
|
||||
.on_prepaint({
|
||||
@@ -1116,7 +1044,7 @@ impl TabPanel {
|
||||
return Empty {}.into_any_element();
|
||||
};
|
||||
|
||||
let is_render_in_tabs = self.panels.len() > 1 && self.inner_padding(cx);
|
||||
let has_inner_padding = self.inner_padding(cx);
|
||||
|
||||
let placeholder = self.drop_placeholder_animation;
|
||||
let placeholder_animation_name = self.drop_placeholder_animation_name.clone();
|
||||
@@ -1125,7 +1053,7 @@ impl TabPanel {
|
||||
.id("active-panel")
|
||||
.group("")
|
||||
.flex_1()
|
||||
.when(is_render_in_tabs, |this| this.pt_2())
|
||||
.when(has_inner_padding, |this| this.pt_2())
|
||||
.child(
|
||||
div()
|
||||
.id("tab-content")
|
||||
|
||||
@@ -5,6 +5,8 @@ use gpui::{
|
||||
};
|
||||
use gpui_component::{ActiveTheme, Icon, IconName, Sizable as _, h_flex};
|
||||
|
||||
use crate::TAB_BAR_HEIGHT;
|
||||
|
||||
/// The standard width of a window control button.
|
||||
const CONTROL_WIDTH: f32 = 34.;
|
||||
|
||||
@@ -145,6 +147,11 @@ pub(crate) fn window_controls(window: &mut Window, cx: &mut App) -> impl IntoEle
|
||||
.items_center()
|
||||
.flex_shrink_0()
|
||||
.h_full()
|
||||
// Like native windows apps, the controls span the title bar but never
|
||||
// grow past the tab bar height.
|
||||
.when(cfg!(target_os = "windows"), |this| {
|
||||
this.max_h(TAB_BAR_HEIGHT)
|
||||
})
|
||||
.border_l_1()
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().border)
|
||||
|
||||
@@ -19,9 +19,7 @@ pub struct Workspace {
|
||||
|
||||
impl Workspace {
|
||||
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let dock = cx.new(|cx| {
|
||||
DockArea::new("dock", Some(1), window, cx).panel_style(dock::PanelStyle::TabBar)
|
||||
});
|
||||
let dock = cx.new(|cx| DockArea::new("dock", Some(1), window, cx));
|
||||
let weak_dock = dock.downgrade();
|
||||
|
||||
let sidebar = cx.new(|cx| SidebarPanel::new(weak_dock.clone(), cx));
|
||||
|
||||
Reference in New Issue
Block a user