From f8e30c6f5d9c02920d5f2e2b05f3366e5dc587d3 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 8 May 2025 16:29:55 +0800 Subject: [PATCH] dock: Revert `dock` to use absolute size. (#840) This change to revert `Dock` to use `Pixels` for size, not use ratio, because in most case we need to keep dock size, not wants it change when window resize, we just only want center dock to change. The `Panel` will keep the relative size changes. --- crates/story/examples/dock.rs | 6 ++-- crates/ui/src/dock/dock.rs | 49 +++++++++------------------- crates/ui/src/dock/mod.rs | 44 +++++++------------------ crates/ui/src/dock/state.rs | 23 +++++-------- crates/ui/tests/fixtures/layout.json | 1 - 5 files changed, 37 insertions(+), 86 deletions(-) diff --git a/crates/story/examples/dock.rs b/crates/story/examples/dock.rs index 77768649..4caa2518 100644 --- a/crates/story/examples/dock.rs +++ b/crates/story/examples/dock.rs @@ -279,7 +279,7 @@ impl StoryWorkspace { cx, ), ], - vec![None, Some(relative(0.2))], + vec![None, Some(0.2)], &dock_area, window, cx, @@ -328,8 +328,8 @@ impl StoryWorkspace { _ = dock_area.update(cx, |view, cx| { view.set_version(MAIN_DOCK_AREA.version, window, cx); view.set_center(dock_item, window, cx); - view.set_left_dock(left_panels, relative(0.3), true, window, cx); - view.set_bottom_dock(bottom_panels, relative(0.2), true, window, cx); + view.set_left_dock(left_panels, px(300.), true, window, cx); + view.set_bottom_dock(bottom_panels, px(200.), true, window, cx); view.set_right_dock(right_panels, px(320.), true, window, cx); Self::save_state(&view.dump(cx)).unwrap(); diff --git a/crates/ui/src/dock/dock.rs b/crates/ui/src/dock/dock.rs index e1ccb098..211ac9e6 100644 --- a/crates/ui/src/dock/dock.rs +++ b/crates/ui/src/dock/dock.rs @@ -3,9 +3,9 @@ use std::{ops::Deref, sync::Arc}; use gpui::{ - div, prelude::FluentBuilder as _, px, Along, App, AppContext, Axis, Context, DefiniteLength, - Element, Empty, Entity, IntoElement, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, - Point, Render, Style, StyleRefinement, Styled as _, WeakEntity, Window, + div, prelude::FluentBuilder as _, px, App, AppContext, Axis, Context, Element, Empty, Entity, + IntoElement, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Render, Style, + StyleRefinement, Styled as _, WeakEntity, Window, }; use serde::{Deserialize, Serialize}; @@ -14,7 +14,7 @@ use crate::{ StyledExt, }; -use super::{definite_length_to_window_ratio, DockArea, DockItem, PanelView, TabPanel}; +use super::{DockArea, DockItem, PanelView, TabPanel}; #[derive(Clone)] struct ResizePanel; @@ -66,8 +66,8 @@ pub struct Dock { pub(super) placement: DockPlacement, dock_area: WeakEntity, pub(crate) panel: DockItem, - /// The ratio of the dock. - pub(super) ratio: f32, + /// The size of the dock. + pub(super) size: Pixels, pub(super) open: bool, /// Whether the Dock is collapsible, default: true pub(super) collapsible: bool, @@ -104,7 +104,7 @@ impl Dock { panel, open: true, collapsible: true, - ratio: 0.2, + size: px(200.), resizing: false, } } @@ -147,7 +147,7 @@ impl Dock { pub(super) fn from_state( dock_area: WeakEntity, placement: DockPlacement, - ratio: f32, + size: impl Into, panel: DockItem, open: bool, window: &mut Window, @@ -176,7 +176,7 @@ impl Dock { dock_area, panel, open, - ratio, + size: size.into(), collapsible: true, resizing: false, } @@ -244,18 +244,13 @@ impl Dock { /// Returns the size of the Dock, the size is means the width or height of /// the Dock, if the placement is left or right, the size is width, /// otherwise the size is height. - pub fn ratio(&self) -> f32 { - self.ratio + pub fn size(&self) -> Pixels { + self.size } /// Set the size of the Dock. - pub fn set_size( - &mut self, - size: impl Into, - window: &mut Window, - cx: &mut Context, - ) { - self.ratio = definite_length_to_window_ratio(size, self.placement.axis(), window); + pub fn set_size(&mut self, size: impl Into, _: &mut Window, cx: &mut Context) { + self.size = size.into(); cx.notify(); } @@ -292,16 +287,6 @@ impl Dock { cx.notify(); } - fn container_size(&self, cx: &App) -> Pixels { - let dock_area = self - .dock_area - .upgrade() - .expect("DockArea is missing") - .read(cx); - let area_bounds = dock_area.bounds; - area_bounds.size.along(self.placement.axis()) - } - fn render_resize_handle(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { let axis = self.placement.axis(); let view = cx.entity().clone(); @@ -335,10 +320,7 @@ impl Dock { DockPlacement::Bottom => area_bounds.bottom() - mouse_position.y, DockPlacement::Center => unreachable!(), }; - let container_size = self.container_size(cx); - let ratio = size / container_size; - let min_ratio = PANEL_MIN_SIZE / container_size; - self.ratio = ratio.clamp(min_ratio, 1.); + self.size = size.max(PANEL_MIN_SIZE); cx.notify(); } @@ -355,8 +337,7 @@ impl Render for Dock { } let cache_style = StyleRefinement::default().absolute().size_full(); - let container_size = self.container_size(cx); - let dock_size = (self.ratio * container_size).max(PANEL_MIN_SIZE); + let dock_size = self.size; div() .relative() diff --git a/crates/ui/src/dock/mod.rs b/crates/ui/src/dock/mod.rs index 2e83a0e7..dfd48914 100644 --- a/crates/ui/src/dock/mod.rs +++ b/crates/ui/src/dock/mod.rs @@ -8,10 +8,9 @@ mod tiles; use anyhow::Result; use gpui::{ - actions, canvas, div, prelude::FluentBuilder, relative, Along, AnyElement, AnyView, App, - AppContext, Axis, Bounds, Context, DefiniteLength, Edges, Entity, EntityId, EventEmitter, - InteractiveElement as _, IntoElement, ParentElement as _, Pixels, Render, SharedString, Styled, - Subscription, WeakEntity, Window, + actions, canvas, div, prelude::FluentBuilder, px, AnyElement, AnyView, App, AppContext, Axis, + Bounds, Context, Edges, Entity, EntityId, EventEmitter, InteractiveElement as _, IntoElement, + ParentElement as _, Pixels, Render, SharedString, Styled, Subscription, WeakEntity, Window, }; use std::sync::Arc; @@ -28,22 +27,6 @@ pub fn init(cx: &mut App) { actions!(dock, [ToggleZoom, ClosePanel]); -/// Convert [`gpui::DefiniteLength`] to ratio of window. -pub(crate) fn definite_length_to_window_ratio( - length: impl Into, - axis: Axis, - window: &Window, -) -> f32 { - let length: DefiniteLength = length.into(); - match length { - DefiniteLength::Absolute(size) => { - let container_size = window.bounds().size.along(axis); - size.to_pixels(window.rem_size()) / container_size - } - DefiniteLength::Fraction(ratio) => ratio, - } -} - pub enum DockEvent { /// The layout of the dock has changed, subscribers this to save the layout. /// @@ -155,22 +138,17 @@ impl DockItem { /// Create DockItem with split layout, each item of panel have specified size. /// - /// Please note that the `items` and `sizes` must have the same length. + /// Please note that the `items` and `ratios` must have the same length. /// Set `None` in `sizes` to make the index of panel have auto size. pub fn split_with_sizes( axis: Axis, items: Vec, - sizes: Vec>, + ratios: Vec>, dock_area: &WeakEntity, window: &mut Window, cx: &mut App, ) -> Self { let mut items = items; - let ratios: Vec> = sizes - .into_iter() - .map(|size| size.map(|val| definite_length_to_window_ratio(val, axis, window))) - .collect(); - let stack_panel = cx.new(|cx| { let mut stack_panel = StackPanel::new(axis, window, cx); for (i, item) in items.iter_mut().enumerate() { @@ -552,7 +530,7 @@ impl DockArea { pub fn set_left_dock( &mut self, panel: DockItem, - size: impl Into, + size: impl Into, open: bool, window: &mut Window, cx: &mut Context, @@ -572,7 +550,7 @@ impl DockArea { pub fn set_bottom_dock( &mut self, panel: DockItem, - size: impl Into, + size: impl Into, open: bool, window: &mut Window, cx: &mut Context, @@ -592,7 +570,7 @@ impl DockArea { pub fn set_right_dock( &mut self, panel: DockItem, - size: impl Into, + size: impl Into, open: bool, window: &mut Window, cx: &mut Context, @@ -745,7 +723,7 @@ impl DockArea { } else { self.set_left_dock( DockItem::tabs(vec![panel], None, &weak_self, window, cx), - relative(0.2), + px(200.), true, window, cx, @@ -758,7 +736,7 @@ impl DockArea { } else { self.set_bottom_dock( DockItem::tabs(vec![panel], None, &weak_self, window, cx), - relative(0.2), + px(200.), true, window, cx, @@ -771,7 +749,7 @@ impl DockArea { } else { self.set_right_dock( DockItem::tabs(vec![panel], None, &weak_self, window, cx), - relative(0.2), + px(200.), true, window, cx, diff --git a/crates/ui/src/dock/state.rs b/crates/ui/src/dock/state.rs index d9952d21..af63068d 100644 --- a/crates/ui/src/dock/state.rs +++ b/crates/ui/src/dock/state.rs @@ -1,6 +1,4 @@ -use gpui::{ - point, px, relative, size, App, AppContext, Axis, Bounds, Entity, Pixels, WeakEntity, Window, -}; +use gpui::{point, px, size, App, AppContext, Axis, Bounds, Entity, Pixels, WeakEntity, Window}; use itertools::Itertools as _; use serde::{Deserialize, Serialize}; @@ -28,22 +26,17 @@ pub struct DockAreaState { pub struct DockState { panel: PanelState, placement: DockPlacement, - #[serde(default = "default_ratio")] - ratio: f32, + size: Pixels, open: bool, } -fn default_ratio() -> f32 { - 0.2 -} - impl DockState { pub fn new(dock: Entity, cx: &App) -> Self { let dock = dock.read(cx); Self { placement: dock.placement, - ratio: dock.ratio, + size: dock.size, open: dock.open, panel: dock.panel.view().dump(cx), } @@ -61,7 +54,7 @@ impl DockState { Dock::from_state( dock_area.clone(), self.placement, - self.ratio, + self.size, item, self.open, window, @@ -208,7 +201,7 @@ impl PanelState { } else { Axis::Vertical }; - let ratios = ratios.iter().map(|&ratio| Some(relative(ratio))).collect(); + let ratios = ratios.iter().map(|&ratio| Some(ratio)).collect(); DockItem::split_with_sizes(axis, items, ratios, &dock_area, window, cx) } PanelInfo::Tabs { active_index } => { @@ -265,7 +258,7 @@ mod tests { let left_dock = state.left_dock.unwrap(); assert_eq!(left_dock.open, true); - assert_eq!(left_dock.ratio, 0.2); + assert_eq!(left_dock.size, px(350.)); assert_eq!(left_dock.placement, DockPlacement::Left); assert_eq!(left_dock.panel.panel_name, "TabPanel"); assert_eq!(left_dock.panel.children.len(), 1); @@ -273,14 +266,14 @@ mod tests { let bottom_dock = state.bottom_dock.unwrap(); assert_eq!(bottom_dock.open, true); - assert_eq!(bottom_dock.ratio, 0.32); + assert_eq!(bottom_dock.size, px(200.)); assert_eq!(bottom_dock.panel.panel_name, "TabPanel"); assert_eq!(bottom_dock.panel.children.len(), 2); assert_eq!(bottom_dock.panel.children[0].panel_name, "StoryContainer"); let right_dock = state.right_dock.unwrap(); assert_eq!(right_dock.open, true); - assert_eq!(right_dock.ratio, 0.2); + assert_eq!(right_dock.size, px(320.)); assert_eq!(right_dock.panel.panel_name, "TabPanel"); assert_eq!(right_dock.panel.children.len(), 1); assert_eq!(right_dock.panel.children[0].panel_name, "StoryContainer"); diff --git a/crates/ui/tests/fixtures/layout.json b/crates/ui/tests/fixtures/layout.json index a8224510..f1205509 100644 --- a/crates/ui/tests/fixtures/layout.json +++ b/crates/ui/tests/fixtures/layout.json @@ -255,7 +255,6 @@ }, "placement": "bottom", "size": 200.0, - "ratio": 0.32, "open": true, "resizeable": true }