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.
This commit is contained in:
parent
a26311dc0e
commit
f8e30c6f5d
5 changed files with 37 additions and 86 deletions
|
|
@ -279,7 +279,7 @@ impl StoryWorkspace {
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![None, Some(relative(0.2))],
|
vec![None, Some(0.2)],
|
||||||
&dock_area,
|
&dock_area,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
|
|
@ -328,8 +328,8 @@ impl StoryWorkspace {
|
||||||
_ = dock_area.update(cx, |view, cx| {
|
_ = dock_area.update(cx, |view, cx| {
|
||||||
view.set_version(MAIN_DOCK_AREA.version, window, cx);
|
view.set_version(MAIN_DOCK_AREA.version, window, cx);
|
||||||
view.set_center(dock_item, window, cx);
|
view.set_center(dock_item, window, cx);
|
||||||
view.set_left_dock(left_panels, relative(0.3), true, window, cx);
|
view.set_left_dock(left_panels, px(300.), true, window, cx);
|
||||||
view.set_bottom_dock(bottom_panels, relative(0.2), 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);
|
view.set_right_dock(right_panels, px(320.), true, window, cx);
|
||||||
|
|
||||||
Self::save_state(&view.dump(cx)).unwrap();
|
Self::save_state(&view.dump(cx)).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
use std::{ops::Deref, sync::Arc};
|
use std::{ops::Deref, sync::Arc};
|
||||||
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, prelude::FluentBuilder as _, px, Along, App, AppContext, Axis, Context, DefiniteLength,
|
div, prelude::FluentBuilder as _, px, App, AppContext, Axis, Context, Element, Empty, Entity,
|
||||||
Element, Empty, Entity, IntoElement, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels,
|
IntoElement, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Render, Style,
|
||||||
Point, Render, Style, StyleRefinement, Styled as _, WeakEntity, Window,
|
StyleRefinement, Styled as _, WeakEntity, Window,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
StyledExt,
|
StyledExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{definite_length_to_window_ratio, DockArea, DockItem, PanelView, TabPanel};
|
use super::{DockArea, DockItem, PanelView, TabPanel};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct ResizePanel;
|
struct ResizePanel;
|
||||||
|
|
@ -66,8 +66,8 @@ pub struct Dock {
|
||||||
pub(super) placement: DockPlacement,
|
pub(super) placement: DockPlacement,
|
||||||
dock_area: WeakEntity<DockArea>,
|
dock_area: WeakEntity<DockArea>,
|
||||||
pub(crate) panel: DockItem,
|
pub(crate) panel: DockItem,
|
||||||
/// The ratio of the dock.
|
/// The size of the dock.
|
||||||
pub(super) ratio: f32,
|
pub(super) size: Pixels,
|
||||||
pub(super) open: bool,
|
pub(super) open: bool,
|
||||||
/// Whether the Dock is collapsible, default: true
|
/// Whether the Dock is collapsible, default: true
|
||||||
pub(super) collapsible: bool,
|
pub(super) collapsible: bool,
|
||||||
|
|
@ -104,7 +104,7 @@ impl Dock {
|
||||||
panel,
|
panel,
|
||||||
open: true,
|
open: true,
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
ratio: 0.2,
|
size: px(200.),
|
||||||
resizing: false,
|
resizing: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +147,7 @@ impl Dock {
|
||||||
pub(super) fn from_state(
|
pub(super) fn from_state(
|
||||||
dock_area: WeakEntity<DockArea>,
|
dock_area: WeakEntity<DockArea>,
|
||||||
placement: DockPlacement,
|
placement: DockPlacement,
|
||||||
ratio: f32,
|
size: impl Into<Pixels>,
|
||||||
panel: DockItem,
|
panel: DockItem,
|
||||||
open: bool,
|
open: bool,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
|
|
@ -176,7 +176,7 @@ impl Dock {
|
||||||
dock_area,
|
dock_area,
|
||||||
panel,
|
panel,
|
||||||
open,
|
open,
|
||||||
ratio,
|
size: size.into(),
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
resizing: false,
|
resizing: false,
|
||||||
}
|
}
|
||||||
|
|
@ -244,18 +244,13 @@ impl Dock {
|
||||||
/// Returns the size of the Dock, the size is means the width or height of
|
/// 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,
|
/// the Dock, if the placement is left or right, the size is width,
|
||||||
/// otherwise the size is height.
|
/// otherwise the size is height.
|
||||||
pub fn ratio(&self) -> f32 {
|
pub fn size(&self) -> Pixels {
|
||||||
self.ratio
|
self.size
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the size of the Dock.
|
/// Set the size of the Dock.
|
||||||
pub fn set_size(
|
pub fn set_size(&mut self, size: impl Into<Pixels>, _: &mut Window, cx: &mut Context<Self>) {
|
||||||
&mut self,
|
self.size = size.into();
|
||||||
size: impl Into<DefiniteLength>,
|
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut Context<Self>,
|
|
||||||
) {
|
|
||||||
self.ratio = definite_length_to_window_ratio(size, self.placement.axis(), window);
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,16 +287,6 @@ impl Dock {
|
||||||
cx.notify();
|
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<Self>) -> impl IntoElement {
|
fn render_resize_handle(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let axis = self.placement.axis();
|
let axis = self.placement.axis();
|
||||||
let view = cx.entity().clone();
|
let view = cx.entity().clone();
|
||||||
|
|
@ -335,10 +320,7 @@ impl Dock {
|
||||||
DockPlacement::Bottom => area_bounds.bottom() - mouse_position.y,
|
DockPlacement::Bottom => area_bounds.bottom() - mouse_position.y,
|
||||||
DockPlacement::Center => unreachable!(),
|
DockPlacement::Center => unreachable!(),
|
||||||
};
|
};
|
||||||
let container_size = self.container_size(cx);
|
self.size = size.max(PANEL_MIN_SIZE);
|
||||||
let ratio = size / container_size;
|
|
||||||
let min_ratio = PANEL_MIN_SIZE / container_size;
|
|
||||||
self.ratio = ratio.clamp(min_ratio, 1.);
|
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
@ -355,8 +337,7 @@ impl Render for Dock {
|
||||||
}
|
}
|
||||||
|
|
||||||
let cache_style = StyleRefinement::default().absolute().size_full();
|
let cache_style = StyleRefinement::default().absolute().size_full();
|
||||||
let container_size = self.container_size(cx);
|
let dock_size = self.size;
|
||||||
let dock_size = (self.ratio * container_size).max(PANEL_MIN_SIZE);
|
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.relative()
|
.relative()
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,9 @@ mod tiles;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, canvas, div, prelude::FluentBuilder, relative, Along, AnyElement, AnyView, App,
|
actions, canvas, div, prelude::FluentBuilder, px, AnyElement, AnyView, App, AppContext, Axis,
|
||||||
AppContext, Axis, Bounds, Context, DefiniteLength, Edges, Entity, EntityId, EventEmitter,
|
Bounds, Context, Edges, Entity, EntityId, EventEmitter, InteractiveElement as _, IntoElement,
|
||||||
InteractiveElement as _, IntoElement, ParentElement as _, Pixels, Render, SharedString, Styled,
|
ParentElement as _, Pixels, Render, SharedString, Styled, Subscription, WeakEntity, Window,
|
||||||
Subscription, WeakEntity, Window,
|
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
@ -28,22 +27,6 @@ pub fn init(cx: &mut App) {
|
||||||
|
|
||||||
actions!(dock, [ToggleZoom, ClosePanel]);
|
actions!(dock, [ToggleZoom, ClosePanel]);
|
||||||
|
|
||||||
/// Convert [`gpui::DefiniteLength`] to ratio of window.
|
|
||||||
pub(crate) fn definite_length_to_window_ratio(
|
|
||||||
length: impl Into<DefiniteLength>,
|
|
||||||
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 {
|
pub enum DockEvent {
|
||||||
/// The layout of the dock has changed, subscribers this to save the layout.
|
/// 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.
|
/// 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.
|
/// Set `None` in `sizes` to make the index of panel have auto size.
|
||||||
pub fn split_with_sizes(
|
pub fn split_with_sizes(
|
||||||
axis: Axis,
|
axis: Axis,
|
||||||
items: Vec<DockItem>,
|
items: Vec<DockItem>,
|
||||||
sizes: Vec<Option<DefiniteLength>>,
|
ratios: Vec<Option<f32>>,
|
||||||
dock_area: &WeakEntity<DockArea>,
|
dock_area: &WeakEntity<DockArea>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut items = items;
|
let mut items = items;
|
||||||
let ratios: Vec<Option<f32>> = sizes
|
|
||||||
.into_iter()
|
|
||||||
.map(|size| size.map(|val| definite_length_to_window_ratio(val, axis, window)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let stack_panel = cx.new(|cx| {
|
let stack_panel = cx.new(|cx| {
|
||||||
let mut stack_panel = StackPanel::new(axis, window, cx);
|
let mut stack_panel = StackPanel::new(axis, window, cx);
|
||||||
for (i, item) in items.iter_mut().enumerate() {
|
for (i, item) in items.iter_mut().enumerate() {
|
||||||
|
|
@ -552,7 +530,7 @@ impl DockArea {
|
||||||
pub fn set_left_dock(
|
pub fn set_left_dock(
|
||||||
&mut self,
|
&mut self,
|
||||||
panel: DockItem,
|
panel: DockItem,
|
||||||
size: impl Into<DefiniteLength>,
|
size: impl Into<Pixels>,
|
||||||
open: bool,
|
open: bool,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
|
|
@ -572,7 +550,7 @@ impl DockArea {
|
||||||
pub fn set_bottom_dock(
|
pub fn set_bottom_dock(
|
||||||
&mut self,
|
&mut self,
|
||||||
panel: DockItem,
|
panel: DockItem,
|
||||||
size: impl Into<DefiniteLength>,
|
size: impl Into<Pixels>,
|
||||||
open: bool,
|
open: bool,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
|
|
@ -592,7 +570,7 @@ impl DockArea {
|
||||||
pub fn set_right_dock(
|
pub fn set_right_dock(
|
||||||
&mut self,
|
&mut self,
|
||||||
panel: DockItem,
|
panel: DockItem,
|
||||||
size: impl Into<DefiniteLength>,
|
size: impl Into<Pixels>,
|
||||||
open: bool,
|
open: bool,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
|
|
@ -745,7 +723,7 @@ impl DockArea {
|
||||||
} else {
|
} else {
|
||||||
self.set_left_dock(
|
self.set_left_dock(
|
||||||
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
||||||
relative(0.2),
|
px(200.),
|
||||||
true,
|
true,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
|
|
@ -758,7 +736,7 @@ impl DockArea {
|
||||||
} else {
|
} else {
|
||||||
self.set_bottom_dock(
|
self.set_bottom_dock(
|
||||||
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
||||||
relative(0.2),
|
px(200.),
|
||||||
true,
|
true,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
|
|
@ -771,7 +749,7 @@ impl DockArea {
|
||||||
} else {
|
} else {
|
||||||
self.set_right_dock(
|
self.set_right_dock(
|
||||||
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
||||||
relative(0.2),
|
px(200.),
|
||||||
true,
|
true,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
use gpui::{
|
use gpui::{point, px, size, App, AppContext, Axis, Bounds, Entity, Pixels, WeakEntity, Window};
|
||||||
point, px, relative, size, App, AppContext, Axis, Bounds, Entity, Pixels, WeakEntity, Window,
|
|
||||||
};
|
|
||||||
use itertools::Itertools as _;
|
use itertools::Itertools as _;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
@ -28,22 +26,17 @@ pub struct DockAreaState {
|
||||||
pub struct DockState {
|
pub struct DockState {
|
||||||
panel: PanelState,
|
panel: PanelState,
|
||||||
placement: DockPlacement,
|
placement: DockPlacement,
|
||||||
#[serde(default = "default_ratio")]
|
size: Pixels,
|
||||||
ratio: f32,
|
|
||||||
open: bool,
|
open: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_ratio() -> f32 {
|
|
||||||
0.2
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DockState {
|
impl DockState {
|
||||||
pub fn new(dock: Entity<Dock>, cx: &App) -> Self {
|
pub fn new(dock: Entity<Dock>, cx: &App) -> Self {
|
||||||
let dock = dock.read(cx);
|
let dock = dock.read(cx);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
placement: dock.placement,
|
placement: dock.placement,
|
||||||
ratio: dock.ratio,
|
size: dock.size,
|
||||||
open: dock.open,
|
open: dock.open,
|
||||||
panel: dock.panel.view().dump(cx),
|
panel: dock.panel.view().dump(cx),
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +54,7 @@ impl DockState {
|
||||||
Dock::from_state(
|
Dock::from_state(
|
||||||
dock_area.clone(),
|
dock_area.clone(),
|
||||||
self.placement,
|
self.placement,
|
||||||
self.ratio,
|
self.size,
|
||||||
item,
|
item,
|
||||||
self.open,
|
self.open,
|
||||||
window,
|
window,
|
||||||
|
|
@ -208,7 +201,7 @@ impl PanelState {
|
||||||
} else {
|
} else {
|
||||||
Axis::Vertical
|
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)
|
DockItem::split_with_sizes(axis, items, ratios, &dock_area, window, cx)
|
||||||
}
|
}
|
||||||
PanelInfo::Tabs { active_index } => {
|
PanelInfo::Tabs { active_index } => {
|
||||||
|
|
@ -265,7 +258,7 @@ mod tests {
|
||||||
|
|
||||||
let left_dock = state.left_dock.unwrap();
|
let left_dock = state.left_dock.unwrap();
|
||||||
assert_eq!(left_dock.open, true);
|
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.placement, DockPlacement::Left);
|
||||||
assert_eq!(left_dock.panel.panel_name, "TabPanel");
|
assert_eq!(left_dock.panel.panel_name, "TabPanel");
|
||||||
assert_eq!(left_dock.panel.children.len(), 1);
|
assert_eq!(left_dock.panel.children.len(), 1);
|
||||||
|
|
@ -273,14 +266,14 @@ mod tests {
|
||||||
|
|
||||||
let bottom_dock = state.bottom_dock.unwrap();
|
let bottom_dock = state.bottom_dock.unwrap();
|
||||||
assert_eq!(bottom_dock.open, true);
|
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.panel_name, "TabPanel");
|
||||||
assert_eq!(bottom_dock.panel.children.len(), 2);
|
assert_eq!(bottom_dock.panel.children.len(), 2);
|
||||||
assert_eq!(bottom_dock.panel.children[0].panel_name, "StoryContainer");
|
assert_eq!(bottom_dock.panel.children[0].panel_name, "StoryContainer");
|
||||||
|
|
||||||
let right_dock = state.right_dock.unwrap();
|
let right_dock = state.right_dock.unwrap();
|
||||||
assert_eq!(right_dock.open, true);
|
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.panel_name, "TabPanel");
|
||||||
assert_eq!(right_dock.panel.children.len(), 1);
|
assert_eq!(right_dock.panel.children.len(), 1);
|
||||||
assert_eq!(right_dock.panel.children[0].panel_name, "StoryContainer");
|
assert_eq!(right_dock.panel.children[0].panel_name, "StoryContainer");
|
||||||
|
|
|
||||||
1
crates/ui/tests/fixtures/layout.json
vendored
1
crates/ui/tests/fixtures/layout.json
vendored
|
|
@ -255,7 +255,6 @@
|
||||||
},
|
},
|
||||||
"placement": "bottom",
|
"placement": "bottom",
|
||||||
"size": 200.0,
|
"size": 200.0,
|
||||||
"ratio": 0.32,
|
|
||||||
"open": true,
|
"open": true,
|
||||||
"resizeable": true
|
"resizeable": true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue