pub struct PaneTree { /* private fields */ }Expand description
Everything gpui_base::dock exports, so a consumer never has to depend
on the foundation crate directly to write a skin or read a container’s
state. Kept in step with base’s own list by
every_base_dock_export_is_reachable_from_here.
Two names are handled elsewhere and one is deliberately absent:
base’s Panel and PanelView arrive as BasePanel and BasePanelView
because this module’s Panel/PanelView are the presentation halves that
extend them, and base’s Dock — a plain state struct holding one dock’s
open, collapsible, size and resizing flags — is not re-exported at all,
because the name meant a panel container in every released version of this
crate and handing it back with a different meaning is worse than dropping
it. A skin reads a dock through DockContext.
One region’s layout, as pure data.
A DockArea owns one of these per region — the center plus each dock it
has. Containers are addressed by NodeId and panels by PanelId;
no entity handle lives in here, so a tree can be built, edited, compared
and serialized with no App in sight.
Every edit method normalizes before returning and reports what it did as
an EditResult, so there is no window in which a
caller can observe a tree with an empty container, a one-child split, or an
out-of-range active index.
Implementations§
Source§impl PaneTree
impl PaneTree
pub fn insert_panel( &mut self, panel: PanelId, target: InsertTarget, ) -> EditResult
pub fn remove_panel(&mut self, panel: PanelId) -> EditResult
Sourcepub fn move_panel(&mut self, panel: PanelId, target: InsertTarget) -> EditResult
pub fn move_panel(&mut self, panel: PanelId, target: InsertTarget) -> EditResult
Move a panel to a new home without ever removing it from the tree’s
perspective, so the caller never fires on_removed for a drag.
pub fn split( &mut self, at: NodeId, panel: PanelId, placement: Placement, size: Option<Pixels>, ) -> EditResult
pub fn set_active(&mut self, node: NodeId, ix: usize) -> EditResult
Sourcepub fn set_sizes(
&mut self,
node: NodeId,
new_sizes: Vec<Option<Pixels>>,
) -> EditResult
pub fn set_sizes( &mut self, node: NodeId, new_sizes: Vec<Option<Pixels>>, ) -> EditResult
Replace a split’s slot sizes wholesale.
A no-op, like every other operation given input it cannot resolve, if
new_sizes.len() does not match the split’s child count: no rule in
normalize repairs a length mismatch, so applying it would otherwise
leave children.len() != sizes.len() and trip normalize’s
debug_assert!.
pub fn set_tile_bounds( &mut self, panel: PanelId, bounds: Bounds<Pixels>, ) -> EditResult
pub fn bring_to_front(&mut self, panel: PanelId) -> EditResult
Source§impl PaneTree
impl PaneTree
Sourcepub fn contains_panel(&self, panel: PanelId) -> bool
pub fn contains_panel(&self, panel: PanelId) -> bool
Whether panel is anywhere in this tree.
Source§impl PaneTree
impl PaneTree
Sourcepub fn normalize(&mut self)
pub fn normalize(&mut self)
Collapse the tree to canonical shape.
One post-order pass repeated to a fixpoint. This is the only place a
container is removed for being empty, replacing the mutually recursive
remove_self_if_empty pair the old implementation used. It needs no
parent pointers and no deferred work, so the tree is self-consistent
the instant an edit returns.
Rules, applied bottom up:
- An empty
Tabs,Tiles, orSplitis removed from its parent. - A
Splitwith one child is replaced by that child. The child keeps its ownNodeIdand inherits the split’s slot size. - A
Splitwhose child is aSplitof the same axis splices that child’s children into itself. active_ixis clamped.- The root is preserved according to
RootKind.
Idempotent: normalize(normalize(t)) == normalize(t).
Source§impl PaneTree
impl PaneTree
Source§impl PaneTree
impl PaneTree
pub fn to_state(&self, source: &dyn PanelSource) -> PanelState
Source§impl PaneTree
impl PaneTree
Sourcepub fn from_state(
state: &PanelState,
root_kind: RootKind,
builder: &mut dyn PanelBuilder,
) -> PaneTree
pub fn from_state( state: &PanelState, root_kind: RootKind, builder: &mut dyn PanelBuilder, ) -> PaneTree
Read a persisted layout.
Compatibility rules, all previously implicit in PanelState::to_item:
- a
Tabswhose children are themselvesTabsis flattened; - a bare
Panelleaf appearing where a container belongs is wrapped in aTabs; - a node named
TabPanelcarryingPanelInfo::Panelis read as an empty tab group, recovering data written by the old dump defect (an emptyTabPanelnever entered the loop that set itsinfotoTabs, so it keptPanelState’s defaultPanel(Value::Null)). The old reader had no such rule: it looked “TabPanel” up in the panel registry, found nothing, and rendered anInvalidPanelplaceholder where an empty tab group belonged. This rule is a genuine fix, not a preserved behavior; - a
Tileschild without a matching meta keeps the default placement. The old writer’s counterpart (DockItem::tiles) hard-asserteditems.len() == metas.len()and panicked the whole load on a shortmetaslist, so this rule is a new safety net, not a preserved graceful-degradation path.
Trait Implementations§
impl StructuralPartialEq for PaneTree
Auto Trait Implementations§
impl Freeze for PaneTree
impl RefUnwindSafe for PaneTree
impl Send for PaneTree
impl Sync for PaneTree
impl Unpin for PaneTree
impl UnsafeUnpin for PaneTree
impl UnwindSafe for PaneTree
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more