Merge pull request #431 from hecrj/feature/pane-grid-splits

Splits iterator for `PaneGrid` and minor improvements
This commit is contained in:
Héctor Ramón 2020-07-01 22:44:37 +02:00 committed by GitHub
commit 99a50d6b2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 14 deletions

View File

@ -273,8 +273,6 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
self.state.focus(pane); self.state.focus(pane);
} }
} }
} else {
self.state.unfocus();
} }
} }
@ -288,7 +286,7 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
if let Some((split, _)) = self.state.picked_split() { if let Some((split, _)) = self.state.picked_split() {
let bounds = layout.bounds(); let bounds = layout.bounds();
let splits = self.state.splits( let splits = self.state.split_regions(
f32::from(self.spacing), f32::from(self.spacing),
Size::new(bounds.width, bounds.height), Size::new(bounds.width, bounds.height),
); );
@ -410,7 +408,7 @@ where
let limits = limits.width(self.width).height(self.height); let limits = limits.width(self.width).height(self.height);
let size = limits.resolve(Size::ZERO); let size = limits.resolve(Size::ZERO);
let regions = self.state.regions(f32::from(self.spacing), size); let regions = self.state.pane_regions(f32::from(self.spacing), size);
let children = self let children = self
.elements .elements
@ -453,7 +451,7 @@ where
cursor_position.y - bounds.y, cursor_position.y - bounds.y,
); );
let splits = self.state.splits( let splits = self.state.split_regions(
f32::from(self.spacing), f32::from(self.spacing),
Size::new(bounds.width, bounds.height), Size::new(bounds.width, bounds.height),
); );
@ -482,6 +480,8 @@ where
); );
} }
} }
} else {
self.state.unfocus();
} }
} }
mouse::Event::ButtonReleased(mouse::Button::Left) => { mouse::Event::ButtonReleased(mouse::Button::Left) => {
@ -588,7 +588,7 @@ where
let splits = self let splits = self
.state .state
.splits(f32::from(self.spacing), bounds.size()); .split_regions(f32::from(self.spacing), bounds.size());
hovered_split( hovered_split(
splits.iter(), splits.iter(),

View File

@ -43,12 +43,36 @@ pub enum Node {
} }
impl Node { impl Node {
/// Returns an iterator over each [`Split`] in this [`Node`].
///
/// [`Split`]: struct.Split.html
/// [`Node`]: enum.Node.html
pub fn splits(&self) -> impl Iterator<Item = &Split> {
let mut unvisited_nodes = vec![self];
std::iter::from_fn(move || {
while let Some(node) = unvisited_nodes.pop() {
match node {
Node::Split { id, a, b, .. } => {
unvisited_nodes.push(a);
unvisited_nodes.push(b);
return Some(id);
}
_ => {}
}
}
None
})
}
/// Returns the rectangular region for each [`Pane`] in the [`Node`] given /// Returns the rectangular region for each [`Pane`] in the [`Node`] given
/// the spacing between panes and the total available space. /// the spacing between panes and the total available space.
/// ///
/// [`Pane`]: struct.Pane.html /// [`Pane`]: struct.Pane.html
/// [`Node`]: enum.Node.html /// [`Node`]: enum.Node.html
pub fn regions( pub fn pane_regions(
&self, &self,
spacing: f32, spacing: f32,
size: Size, size: Size,
@ -75,7 +99,7 @@ impl Node {
/// ///
/// [`Split`]: struct.Split.html /// [`Split`]: struct.Split.html
/// [`Node`]: enum.Node.html /// [`Node`]: enum.Node.html
pub fn splits( pub fn split_regions(
&self, &self,
spacing: f32, spacing: f32,
size: Size, size: Size,

View File

@ -154,8 +154,10 @@ impl<T> State<T> {
/// [`Pane`]: struct.Pane.html /// [`Pane`]: struct.Pane.html
/// [`State::active`]: struct.State.html#method.active /// [`State::active`]: struct.State.html#method.active
pub fn adjacent(&self, pane: &Pane, direction: Direction) -> Option<Pane> { pub fn adjacent(&self, pane: &Pane, direction: Direction) -> Option<Pane> {
let regions = let regions = self
self.internal.layout.regions(0.0, Size::new(4096.0, 4096.0)); .internal
.layout
.pane_regions(0.0, Size::new(4096.0, 4096.0));
let current_region = regions.get(pane)?; let current_region = regions.get(pane)?;
@ -191,6 +193,13 @@ impl<T> State<T> {
self.internal.focus(pane); self.internal.focus(pane);
} }
/// Unfocuses the current focused [`Pane`].
///
/// [`Pane`]: struct.Pane.html
pub fn unfocus(&mut self) {
self.internal.unfocus();
}
/// Splits the given [`Pane`] into two in the given [`Axis`] and /// Splits the given [`Pane`] into two in the given [`Axis`] and
/// initializing the new [`Pane`] with the provided internal state. /// initializing the new [`Pane`] with the provided internal state.
/// ///
@ -362,20 +371,20 @@ impl Internal {
} }
} }
pub fn regions( pub fn pane_regions(
&self, &self,
spacing: f32, spacing: f32,
size: Size, size: Size,
) -> HashMap<Pane, Rectangle> { ) -> HashMap<Pane, Rectangle> {
self.layout.regions(spacing, size) self.layout.pane_regions(spacing, size)
} }
pub fn splits( pub fn split_regions(
&self, &self,
spacing: f32, spacing: f32,
size: Size, size: Size,
) -> HashMap<Split, (Axis, Rectangle, f32)> { ) -> HashMap<Split, (Axis, Rectangle, f32)> {
self.layout.splits(spacing, size) self.layout.split_regions(spacing, size)
} }
pub fn focus(&mut self, pane: &Pane) { pub fn focus(&mut self, pane: &Pane) {