panes 0.19.0

Renderer-agnostic layout engine with declarative ergonomics
Documentation
use super::types::{LayoutRuntime, strategy_ref};
use crate::breakpoint;
use crate::error::PaneError;

impl LayoutRuntime {
    pub(crate) fn maybe_switch_breakpoint(&mut self, width: f32) -> Result<(), PaneError> {
        let breakpoints = match self.breakpoints.as_ref() {
            Some(bp) => bp,
            None => return Ok(()),
        };
        let new_idx = breakpoint::select_breakpoint(breakpoints, width);
        match new_idx == self.active_bp_idx {
            true => Ok(()),
            false => self.apply_breakpoint_switch(new_idx),
        }
    }

    fn apply_breakpoint_switch(&mut self, new_idx: usize) -> Result<(), PaneError> {
        let Some(breakpoints) = self.breakpoints.as_ref() else {
            return Ok(());
        };

        // Save state by sequence index for deterministic restore with repeated kinds.
        let focused_seq_idx = self
            .viewport
            .focus
            .and_then(|pid| self.sequence.index_of(pid));
        let collapsed_seq_indices: Box<[usize]> = self
            .viewport
            .collapsed
            .iter()
            .filter_map(|&pid| self.sequence.index_of(pid))
            .collect();

        breakpoint::rebuild_for_breakpoint(
            breakpoints,
            new_idx,
            &mut self.tree,
            &mut self.sequence,
        )?;

        self.invalidate_topology();
        self.viewport.collapsed.clear();
        self.viewport.saved_constraints.clear();

        // active_bp_idx must be updated before strategy() is called
        self.active_bp_idx = new_idx;

        breakpoint::restore_breakpoint_viewport(
            &mut self.tree,
            &mut self.sequence,
            &mut self.viewport,
            strategy_ref(&self.strategy_source, &self.breakpoints, self.active_bp_idx),
            focused_seq_idx,
            &collapsed_seq_indices,
        )?;

        Ok(())
    }
}