dock: Add set_dock_collapsible to support setting the Docks to be collapsible or not. (#445)
Close #442 In this case, the left Dock is not collapsible: <img width="1165" alt="image" src="https://github.com/user-attachments/assets/21422cdd-d686-4931-9285-925b8e8d3343">
This commit is contained in:
parent
7fe91e4e12
commit
36dcc53824
5 changed files with 80 additions and 17 deletions
|
|
@ -204,6 +204,15 @@ impl StoryWorkspace {
|
|||
|
||||
dock_area.update(cx, |dock_area, cx| {
|
||||
dock_area.load(state, cx).context("load layout")?;
|
||||
dock_area.set_dock_collapsible(
|
||||
Edges {
|
||||
left: true,
|
||||
bottom: true,
|
||||
right: true,
|
||||
..Default::default()
|
||||
},
|
||||
cx,
|
||||
);
|
||||
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ pub struct 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(super) size: Pixels,
|
||||
pub(super) open: bool,
|
||||
/// Whether the Dock is collapsible, default: true
|
||||
pub(super) collapsible: bool,
|
||||
|
||||
// Runtime state
|
||||
/// Whether the Dock is resizing
|
||||
is_resizing: bool,
|
||||
}
|
||||
|
||||
|
|
@ -93,6 +98,7 @@ impl Dock {
|
|||
dock_area,
|
||||
panel,
|
||||
open: true,
|
||||
collapsible: true,
|
||||
size: px(200.0),
|
||||
is_resizing: false,
|
||||
}
|
||||
|
|
@ -110,6 +116,17 @@ impl Dock {
|
|||
Self::new(dock_area, DockPlacement::Right, cx)
|
||||
}
|
||||
|
||||
/// Update the Dock to be collapsible or not.
|
||||
///
|
||||
/// And if the Dock is not collapsible, it will be open.
|
||||
pub fn set_collapsible(&mut self, collapsible: bool, cx: &mut ViewContext<Self>) {
|
||||
self.collapsible = collapsible;
|
||||
if !collapsible {
|
||||
self.open = true
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub(super) fn from_state(
|
||||
dock_area: WeakView<DockArea>,
|
||||
placement: DockPlacement,
|
||||
|
|
@ -137,6 +154,7 @@ impl Dock {
|
|||
panel,
|
||||
open,
|
||||
size,
|
||||
collapsible: true,
|
||||
is_resizing: false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,6 +435,55 @@ impl DockArea {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the dock at the given placement to be open or closed.
|
||||
///
|
||||
/// Only the left, bottom, right dock can be toggled.
|
||||
pub fn set_dock_collapsible(
|
||||
&mut self,
|
||||
collapsible_edges: Edges<bool>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
if let Some(left_dock) = self.left_dock.as_ref() {
|
||||
left_dock.update(cx, |dock, cx| {
|
||||
dock.set_collapsible(collapsible_edges.left, cx);
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(bottom_dock) = self.bottom_dock.as_ref() {
|
||||
bottom_dock.update(cx, |dock, cx| {
|
||||
dock.set_collapsible(collapsible_edges.bottom, cx);
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(right_dock) = self.right_dock.as_ref() {
|
||||
right_dock.update(cx, |dock, cx| {
|
||||
dock.set_collapsible(collapsible_edges.right, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Determine if the dock at the given placement is collapsible.
|
||||
pub fn is_dock_collapsible(&self, placement: DockPlacement, cx: &AppContext) -> bool {
|
||||
match placement {
|
||||
DockPlacement::Left => self
|
||||
.left_dock
|
||||
.as_ref()
|
||||
.map(|dock| dock.read(cx).collapsible)
|
||||
.unwrap_or(false),
|
||||
DockPlacement::Bottom => self
|
||||
.bottom_dock
|
||||
.as_ref()
|
||||
.map(|dock| dock.read(cx).collapsible)
|
||||
.unwrap_or(false),
|
||||
DockPlacement::Right => self
|
||||
.right_dock
|
||||
.as_ref()
|
||||
.map(|dock| dock.read(cx).collapsible)
|
||||
.unwrap_or(false),
|
||||
DockPlacement::Center => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_dock(&self, placement: DockPlacement, cx: &mut ViewContext<Self>) {
|
||||
let dock = match placement {
|
||||
DockPlacement::Left => &self.left_dock,
|
||||
|
|
|
|||
|
|
@ -57,11 +57,6 @@ pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
|
|||
true
|
||||
}
|
||||
|
||||
/// Return true if the panel is collapsible, default is `false`.
|
||||
fn collapsible(&self, _cx: &WindowContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The addition popup menu of the panel, default is `None`.
|
||||
fn popup_menu(&self, this: PopupMenu, _cx: &WindowContext) -> PopupMenu {
|
||||
this
|
||||
|
|
@ -84,7 +79,6 @@ pub trait PanelView: 'static + Send + Sync {
|
|||
fn title_style(&self, _cx: &WindowContext) -> Option<TitleStyle>;
|
||||
fn closeable(&self, cx: &WindowContext) -> bool;
|
||||
fn zoomable(&self, cx: &WindowContext) -> bool;
|
||||
fn collapsible(&self, cx: &WindowContext) -> bool;
|
||||
fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu;
|
||||
fn toolbar_buttons(&self, cx: &WindowContext) -> Vec<Button>;
|
||||
fn view(&self) -> AnyView;
|
||||
|
|
@ -113,10 +107,6 @@ impl<T: Panel> PanelView for View<T> {
|
|||
self.read(cx).zoomable(cx)
|
||||
}
|
||||
|
||||
fn collapsible(&self, cx: &WindowContext) -> bool {
|
||||
self.read(cx).collapsible(cx)
|
||||
}
|
||||
|
||||
fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu {
|
||||
self.read(cx).popup_menu(menu, cx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,12 +109,6 @@ impl Panel for TabPanel {
|
|||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn collapsible(&self, cx: &WindowContext) -> bool {
|
||||
self.active_panel()
|
||||
.map(|panel| panel.collapsible(cx))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu {
|
||||
if let Some(panel) = self.active_panel() {
|
||||
panel.popup_menu(menu, cx)
|
||||
|
|
@ -383,9 +377,12 @@ impl TabPanel {
|
|||
return None;
|
||||
}
|
||||
|
||||
let view_entity_id = cx.view().entity_id();
|
||||
let dock_area = self.dock_area.upgrade()?.read(cx);
|
||||
if !dock_area.is_dock_collapsible(placement, cx) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let view_entity_id = cx.view().entity_id();
|
||||
let toggle_button_panels = dock_area.toggle_button_panels;
|
||||
|
||||
// Check if current TabPanel's entity_id matches the one stored in DockArea for this placement
|
||||
|
|
|
|||
Loading…
Reference in a new issue