dock: Simplify DockItem API. (#1732)
## Break Change - The `DockItem::tabs` has removed `active_ix` argument, use `.active_index()` method instead. ```diff - DockItem::tabs(vec![panel], Some(1), &weak_self, window, cx) + DockItem::tabs(vec![panel], &weak_self, window, cx).active_index(1) ```
This commit is contained in:
parent
e2f022cb59
commit
b70a0633ab
5 changed files with 109 additions and 43 deletions
|
|
@ -258,8 +258,7 @@ impl StoryWorkspace {
|
|||
fn reset_default_layout(dock_area: WeakEntity<DockArea>, window: &mut Window, cx: &mut App) {
|
||||
let dock_item = Self::init_default_layout(&dock_area, window, cx);
|
||||
|
||||
let left_panels = DockItem::split_with_sizes(
|
||||
Axis::Vertical,
|
||||
let left_panels = DockItem::v_split(
|
||||
vec![
|
||||
DockItem::tab(
|
||||
StoryContainer::panel::<ListStory>(window, cx),
|
||||
|
|
@ -272,38 +271,33 @@ impl StoryWorkspace {
|
|||
Arc::new(StoryContainer::panel::<ScrollbarStory>(window, cx)),
|
||||
Arc::new(StoryContainer::panel::<AccordionStory>(window, cx)),
|
||||
],
|
||||
None,
|
||||
&dock_area,
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
)
|
||||
.size(px(360.)),
|
||||
],
|
||||
vec![None, Some(px(360.))],
|
||||
&dock_area,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
||||
let bottom_panels = DockItem::split_with_sizes(
|
||||
Axis::Vertical,
|
||||
let bottom_panels = DockItem::v_split(
|
||||
vec![DockItem::tabs(
|
||||
vec![
|
||||
Arc::new(StoryContainer::panel::<TooltipStory>(window, cx)),
|
||||
Arc::new(StoryContainer::panel::<IconStory>(window, cx)),
|
||||
],
|
||||
None,
|
||||
&dock_area,
|
||||
window,
|
||||
cx,
|
||||
)],
|
||||
vec![None],
|
||||
&dock_area,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
||||
let right_panels = DockItem::split_with_sizes(
|
||||
Axis::Vertical,
|
||||
let right_panels = DockItem::v_split(
|
||||
vec![
|
||||
DockItem::tab(
|
||||
StoryContainer::panel::<ImageStory>(window, cx),
|
||||
|
|
@ -318,7 +312,6 @@ impl StoryWorkspace {
|
|||
cx,
|
||||
),
|
||||
],
|
||||
vec![None],
|
||||
&dock_area,
|
||||
window,
|
||||
cx,
|
||||
|
|
@ -340,8 +333,7 @@ impl StoryWorkspace {
|
|||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> DockItem {
|
||||
DockItem::split_with_sizes(
|
||||
Axis::Vertical,
|
||||
DockItem::v_split(
|
||||
vec![DockItem::tabs(
|
||||
vec![
|
||||
Arc::new(StoryContainer::panel::<ButtonStory>(window, cx)),
|
||||
|
|
@ -364,12 +356,10 @@ impl StoryWorkspace {
|
|||
Arc::new(StoryContainer::panel::<FormStory>(window, cx)),
|
||||
Arc::new(StoryContainer::panel::<NotificationStory>(window, cx)),
|
||||
],
|
||||
None,
|
||||
&dock_area,
|
||||
window,
|
||||
cx,
|
||||
)],
|
||||
vec![None],
|
||||
&dock_area,
|
||||
window,
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
use std::{ops::Deref, sync::Arc};
|
||||
|
||||
use gpui::{
|
||||
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,
|
||||
App, AppContext, Axis, Context, Element, Empty, Entity, IntoElement, MouseMoveEvent,
|
||||
MouseUpEvent, ParentElement as _, Pixels, Point, Render, Style, StyleRefinement, Styled as _,
|
||||
WeakEntity, Window, div, prelude::FluentBuilder as _, px,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
resizable::{resize_handle, PANEL_MIN_SIZE},
|
||||
StyledExt,
|
||||
resizable::{PANEL_MIN_SIZE, resize_handle},
|
||||
};
|
||||
|
||||
use super::{DockArea, DockItem, PanelView, TabPanel};
|
||||
|
|
@ -91,6 +91,7 @@ impl Dock {
|
|||
});
|
||||
|
||||
let panel = DockItem::Tabs {
|
||||
size: None,
|
||||
items: Vec::new(),
|
||||
active_ix: 0,
|
||||
view: panel.clone(),
|
||||
|
|
|
|||
|
|
@ -78,20 +78,31 @@ pub enum DockItem {
|
|||
/// Split layout
|
||||
Split {
|
||||
axis: Axis,
|
||||
/// Self size, only used for build split panels
|
||||
size: Option<Pixels>,
|
||||
items: Vec<DockItem>,
|
||||
/// Items sizes
|
||||
sizes: Vec<Option<Pixels>>,
|
||||
view: Entity<StackPanel>,
|
||||
},
|
||||
/// Tab layout
|
||||
Tabs {
|
||||
/// Self size, only used for build split panels
|
||||
size: Option<Pixels>,
|
||||
items: Vec<Arc<dyn PanelView>>,
|
||||
active_ix: usize,
|
||||
view: Entity<TabPanel>,
|
||||
},
|
||||
/// Panel layout
|
||||
Panel { view: Arc<dyn PanelView> },
|
||||
Panel {
|
||||
/// Self size, only used for build split panels
|
||||
size: Option<Pixels>,
|
||||
view: Arc<dyn PanelView>,
|
||||
},
|
||||
/// Tiles layout
|
||||
Tiles {
|
||||
/// Self size, only used for build split panels
|
||||
size: Option<Pixels>,
|
||||
items: Vec<TileItem>,
|
||||
view: Entity<Tiles>,
|
||||
},
|
||||
|
|
@ -122,7 +133,45 @@ impl std::fmt::Debug for DockItem {
|
|||
}
|
||||
|
||||
impl DockItem {
|
||||
/// Create DockItem with split layout, each item of panel have equal size.
|
||||
/// Get the size of the DockItem.
|
||||
fn get_size(&self) -> Option<Pixels> {
|
||||
match self {
|
||||
Self::Split { size, .. } => *size,
|
||||
Self::Tabs { size, .. } => *size,
|
||||
Self::Panel { size, .. } => *size,
|
||||
Self::Tiles { size, .. } => *size,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set size for the DockItem.
|
||||
pub fn size(mut self, new_size: impl Into<Pixels>) -> Self {
|
||||
let new_size: Option<Pixels> = Some(new_size.into());
|
||||
match self {
|
||||
Self::Split { ref mut size, .. } => *size = new_size,
|
||||
Self::Tabs { ref mut size, .. } => *size = new_size,
|
||||
Self::Tiles { ref mut size, .. } => *size = new_size,
|
||||
Self::Panel { ref mut size, .. } => *size = new_size,
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Set active index for the DockItem, only valid for [`DockItem::Tabs`].
|
||||
pub fn active_index(mut self, new_active_ix: usize) -> Self {
|
||||
debug_assert!(
|
||||
matches!(self, Self::Tabs { .. }),
|
||||
"active_ix can only be set for DockItem::Tabs"
|
||||
);
|
||||
|
||||
if let Self::Tabs {
|
||||
ref mut active_ix, ..
|
||||
} = self
|
||||
{
|
||||
*active_ix = new_active_ix;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Create DockItem::Split with given split layout.
|
||||
pub fn split(
|
||||
axis: Axis,
|
||||
items: Vec<DockItem>,
|
||||
|
|
@ -130,10 +179,30 @@ impl DockItem {
|
|||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
let sizes = vec![None; items.len()];
|
||||
let sizes = items.iter().map(|item| item.get_size()).collect();
|
||||
Self::split_with_sizes(axis, items, sizes, dock_area, window, cx)
|
||||
}
|
||||
|
||||
/// Create DockItem with vertical split layout.
|
||||
pub fn v_split(
|
||||
items: Vec<DockItem>,
|
||||
dock_area: &WeakEntity<DockArea>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
Self::split(Axis::Vertical, items, dock_area, window, cx)
|
||||
}
|
||||
|
||||
/// Create DockItem with horizontal split layout.
|
||||
pub fn h_split(
|
||||
items: Vec<DockItem>,
|
||||
dock_area: &WeakEntity<DockArea>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
Self::split(Axis::Horizontal, items, dock_area, window, cx)
|
||||
}
|
||||
|
||||
/// Create DockItem with split layout, each item of panel have specified size.
|
||||
///
|
||||
/// Please note that the `items` and `sizes` must have the same length.
|
||||
|
|
@ -176,6 +245,7 @@ impl DockItem {
|
|||
|
||||
Self::Split {
|
||||
axis,
|
||||
size: None,
|
||||
items,
|
||||
sizes,
|
||||
view: stack_panel,
|
||||
|
|
@ -184,7 +254,10 @@ impl DockItem {
|
|||
|
||||
/// Create DockItem with panel layout
|
||||
pub fn panel(panel: Arc<dyn PanelView>) -> Self {
|
||||
Self::Panel { view: panel }
|
||||
Self::Panel {
|
||||
size: None,
|
||||
view: panel,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create DockItem with tiles layout
|
||||
|
|
@ -209,7 +282,7 @@ impl DockItem {
|
|||
TileItem::new(Arc::new(view), meta.bounds).z_index(meta.z_index);
|
||||
tiles.add_item(tile_item, dock_area, window, cx);
|
||||
}
|
||||
DockItem::Panel { view } => {
|
||||
DockItem::Panel { view, .. } => {
|
||||
let meta: TileMeta = metas[ix].into();
|
||||
let tile_item =
|
||||
TileItem::new(view.clone(), meta.bounds).z_index(meta.z_index);
|
||||
|
|
@ -235,6 +308,7 @@ impl DockItem {
|
|||
});
|
||||
|
||||
Self::Tiles {
|
||||
size: None,
|
||||
items: tile_panel.read(cx).panels.clone(),
|
||||
view: tile_panel,
|
||||
}
|
||||
|
|
@ -245,7 +319,6 @@ impl DockItem {
|
|||
/// The `active_ix` is the index of the active tab, if `None` the first tab is active.
|
||||
pub fn tabs(
|
||||
items: Vec<Arc<dyn PanelView>>,
|
||||
active_ix: Option<usize>,
|
||||
dock_area: &WeakEntity<DockArea>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
|
|
@ -254,7 +327,7 @@ impl DockItem {
|
|||
for item in items.into_iter() {
|
||||
new_items.push(item)
|
||||
}
|
||||
Self::new_tabs(new_items, active_ix, dock_area, window, cx)
|
||||
Self::new_tabs(new_items, None, dock_area, window, cx)
|
||||
}
|
||||
|
||||
pub fn tab<P: Panel>(
|
||||
|
|
@ -284,6 +357,7 @@ impl DockItem {
|
|||
});
|
||||
|
||||
Self::Tabs {
|
||||
size: None,
|
||||
items,
|
||||
active_ix,
|
||||
view: tab_panel,
|
||||
|
|
@ -307,7 +381,7 @@ impl DockItem {
|
|||
items.iter().find_map(|item| item.find_panel(panel.clone()))
|
||||
}
|
||||
Self::Tabs { items, .. } => items.iter().find(|item| *item == &panel).cloned(),
|
||||
Self::Panel { view } => Some(view.clone()),
|
||||
Self::Panel { view, .. } => Some(view.clone()),
|
||||
Self::Tiles { items, .. } => items.iter().find_map(|item| {
|
||||
if &item.panel == &panel {
|
||||
Some(item.panel.clone())
|
||||
|
|
@ -346,13 +420,13 @@ impl DockItem {
|
|||
}
|
||||
|
||||
// Unable to find tabs, create new tabs
|
||||
let new_item = Self::tabs(vec![panel.clone()], None, dock_area, window, cx);
|
||||
let new_item = Self::tabs(vec![panel.clone()], dock_area, window, cx);
|
||||
items.push(new_item.clone());
|
||||
view.update(cx, |stack_panel, cx| {
|
||||
stack_panel.add_panel(new_item.view(), None, dock_area.clone(), window, cx);
|
||||
});
|
||||
}
|
||||
Self::Tiles { view, items } => {
|
||||
Self::Tiles { view, items, .. } => {
|
||||
let tile_item = TileItem::new(
|
||||
Arc::new(cx.new(|cx| {
|
||||
let mut tab_panel = TabPanel::new(None, dock_area.clone(), window, cx);
|
||||
|
|
@ -411,7 +485,7 @@ impl DockItem {
|
|||
}
|
||||
}
|
||||
DockItem::Tiles { .. } => {}
|
||||
DockItem::Panel { view } => view.set_active(!collapsed, window, cx),
|
||||
DockItem::Panel { view, .. } => view.set_active(!collapsed, window, cx),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -447,6 +521,7 @@ impl DockArea {
|
|||
|
||||
let dock_item = DockItem::Split {
|
||||
axis: Axis::Horizontal,
|
||||
size: None,
|
||||
items: vec![],
|
||||
sizes: vec![],
|
||||
view: stack_panel.clone(),
|
||||
|
|
@ -726,7 +801,7 @@ impl DockArea {
|
|||
dock.update(cx, |dock, cx| dock.add_panel(panel, window, cx))
|
||||
} else {
|
||||
self.set_left_dock(
|
||||
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
||||
DockItem::tabs(vec![panel], &weak_self, window, cx),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
|
|
@ -739,7 +814,7 @@ impl DockArea {
|
|||
dock.update(cx, |dock, cx| dock.add_panel(panel, window, cx))
|
||||
} else {
|
||||
self.set_bottom_dock(
|
||||
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
||||
DockItem::tabs(vec![panel], &weak_self, window, cx),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
|
|
@ -752,7 +827,7 @@ impl DockArea {
|
|||
dock.update(cx, |dock, cx| dock.add_panel(panel, window, cx))
|
||||
} else {
|
||||
self.set_right_dock(
|
||||
DockItem::tabs(vec![panel], None, &weak_self, window, cx),
|
||||
DockItem::tabs(vec![panel], &weak_self, window, cx),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use gpui::{point, px, size, App, AppContext, Axis, Bounds, Entity, Pixels, WeakEntity, Window};
|
||||
use gpui::{App, AppContext, Axis, Bounds, Entity, Pixels, WeakEntity, Window, point, px, size};
|
||||
use itertools::Itertools as _;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ impl PanelState {
|
|||
})
|
||||
.collect_vec();
|
||||
|
||||
DockItem::tabs(items, Some(active_index), &dock_area, window, cx)
|
||||
DockItem::tabs(items, &dock_area, window, cx).active_index(active_index)
|
||||
}
|
||||
PanelInfo::Panel(_) => {
|
||||
let view = PanelRegistry::build_panel(
|
||||
|
|
@ -230,7 +230,7 @@ impl PanelState {
|
|||
window,
|
||||
cx,
|
||||
);
|
||||
DockItem::tabs(vec![view.into()], None, &dock_area, window, cx)
|
||||
DockItem::tabs(vec![view.into()], &dock_area, window, cx)
|
||||
}
|
||||
PanelInfo::Tiles { metas } => DockItem::tiles(items, metas, &dock_area, window, cx),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ impl AppMenuBar {
|
|||
} else {
|
||||
selected_ix.saturating_sub(1)
|
||||
};
|
||||
self.set_selected_ix(Some(new_ix), window, cx);
|
||||
self.set_selected_index(Some(new_ix), window, cx);
|
||||
}
|
||||
|
||||
fn on_move_right(&mut self, _: &SelectRight, window: &mut Window, cx: &mut Context<Self>) {
|
||||
|
|
@ -70,14 +70,14 @@ impl AppMenuBar {
|
|||
} else {
|
||||
selected_ix + 1
|
||||
};
|
||||
self.set_selected_ix(Some(new_ix), window, cx);
|
||||
self.set_selected_index(Some(new_ix), window, cx);
|
||||
}
|
||||
|
||||
fn on_cancel(&mut self, _: &Cancel, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.set_selected_ix(None, window, cx);
|
||||
self.set_selected_index(None, window, cx);
|
||||
}
|
||||
|
||||
fn set_selected_ix(&mut self, ix: Option<usize>, _: &mut Window, cx: &mut Context<Self>) {
|
||||
fn set_selected_index(&mut self, ix: Option<usize>, _: &mut Window, cx: &mut Context<Self>) {
|
||||
self.selected_ix = ix;
|
||||
cx.notify();
|
||||
}
|
||||
|
|
@ -189,7 +189,7 @@ impl AppMenu {
|
|||
|
||||
_ = self.menu_bar.update(cx, |state, cx| {
|
||||
let new_ix = if is_selected { None } else { Some(self.ix) };
|
||||
state.set_selected_ix(new_ix, window, cx);
|
||||
state.set_selected_index(new_ix, window, cx);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ impl AppMenu {
|
|||
}
|
||||
|
||||
_ = self.menu_bar.update(cx, |state, cx| {
|
||||
state.set_selected_ix(Some(self.ix), window, cx);
|
||||
state.set_selected_index(Some(self.ix), window, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue