Expose pane_grid::Focus for state-based styling
This commit is contained in:
parent
f11397c31a
commit
df6e3f8da9
2 changed files with 88 additions and 29 deletions
|
|
@ -116,7 +116,7 @@ impl Application for Launcher {
|
||||||
fn view(&mut self) -> Element<Message> {
|
fn view(&mut self) -> Element<Message> {
|
||||||
let Self { panes } = self;
|
let Self { panes } = self;
|
||||||
|
|
||||||
PaneGrid::new(panes, |pane, example| match example {
|
PaneGrid::new(panes, |pane, example, _| match example {
|
||||||
Example::Clock(clock) => clock
|
Example::Clock(clock) => clock
|
||||||
.view()
|
.view()
|
||||||
.map(move |message| Message::Clock(pane, message)),
|
.map(move |message| Message::Clock(pane, message)),
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,31 @@ pub struct PaneGrid<'a, Message, Renderer> {
|
||||||
impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
|
impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
|
||||||
pub fn new<T>(
|
pub fn new<T>(
|
||||||
state: &'a mut State<T>,
|
state: &'a mut State<T>,
|
||||||
view: impl Fn(Pane, &'a mut T) -> Element<'a, Message, Renderer>,
|
view: impl Fn(
|
||||||
|
Pane,
|
||||||
|
&'a mut T,
|
||||||
|
Option<Focus>,
|
||||||
|
) -> Element<'a, Message, Renderer>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let elements = state
|
let elements = {
|
||||||
.panes
|
let focused_pane = state.internal.focused_pane;
|
||||||
.iter_mut()
|
|
||||||
.map(|(pane, state)| (*pane, view(*pane, state)))
|
state
|
||||||
.collect();
|
.panes
|
||||||
|
.iter_mut()
|
||||||
|
.map(move |(pane, pane_state)| {
|
||||||
|
let focus = match focused_pane {
|
||||||
|
FocusedPane::Some {
|
||||||
|
pane: focused_pane,
|
||||||
|
focus,
|
||||||
|
} if *pane == focused_pane => Some(focus),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
(*pane, view(*pane, pane_state, focus))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
state: &mut state.internal,
|
state: &mut state.internal,
|
||||||
|
|
@ -129,18 +147,28 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(((pane, _), _)) = clicked_region.next() {
|
if let Some(((pane, _), _)) = clicked_region.next() {
|
||||||
self.state.focus = if self.on_drop.is_some()
|
self.state.focused_pane = if self.on_drop.is_some()
|
||||||
&& self.state.modifiers.alt
|
&& self.state.modifiers.alt
|
||||||
{
|
{
|
||||||
Some(Focus::Dragging(*pane))
|
FocusedPane::Some {
|
||||||
|
pane: *pane,
|
||||||
|
focus: Focus::Dragging,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Some(Focus::Idle(*pane))
|
FocusedPane::Some {
|
||||||
|
pane: *pane,
|
||||||
|
focus: Focus::Idle,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ButtonState::Released => {
|
ButtonState::Released => {
|
||||||
if let Some(on_drop) = &self.on_drop {
|
if let Some(on_drop) = &self.on_drop {
|
||||||
if let Some(Focus::Dragging(pane)) = self.state.focus {
|
if let FocusedPane::Some {
|
||||||
|
pane,
|
||||||
|
focus: Focus::Dragging,
|
||||||
|
} = self.state.focused_pane
|
||||||
|
{
|
||||||
let mut dropped_region = self
|
let mut dropped_region = self
|
||||||
.elements
|
.elements
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -160,7 +188,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state.focus = Some(Focus::Idle(pane));
|
self.state.focused_pane = FocusedPane::Some {
|
||||||
|
pane,
|
||||||
|
focus: Focus::Idle,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -171,8 +202,11 @@ where
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.state.focus {
|
match self.state.focused_pane {
|
||||||
Some(Focus::Dragging(_)) => {}
|
FocusedPane::Some {
|
||||||
|
focus: Focus::Dragging,
|
||||||
|
..
|
||||||
|
} => {}
|
||||||
_ => {
|
_ => {
|
||||||
self.elements.iter_mut().zip(layout.children()).for_each(
|
self.elements.iter_mut().zip(layout.children()).for_each(
|
||||||
|((_, pane), layout)| {
|
|((_, pane), layout)| {
|
||||||
|
|
@ -197,8 +231,11 @@ where
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
let dragging = match self.state.focus {
|
let dragging = match self.state.focused_pane {
|
||||||
Some(Focus::Dragging(pane)) => Some(pane),
|
FocusedPane::Some {
|
||||||
|
pane,
|
||||||
|
focus: Focus::Dragging,
|
||||||
|
} => Some(pane),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -244,14 +281,20 @@ pub struct State<T> {
|
||||||
struct Internal {
|
struct Internal {
|
||||||
layout: Node,
|
layout: Node,
|
||||||
last_pane: usize,
|
last_pane: usize,
|
||||||
focus: Option<Focus>,
|
focused_pane: FocusedPane,
|
||||||
modifiers: keyboard::ModifiersState,
|
modifiers: keyboard::ModifiersState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum Focus {
|
pub enum Focus {
|
||||||
Idle(Pane),
|
Idle,
|
||||||
Dragging(Pane),
|
Dragging,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
enum FocusedPane {
|
||||||
|
None,
|
||||||
|
Some { pane: Pane, focus: Focus },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> State<T> {
|
impl<T> State<T> {
|
||||||
|
|
@ -267,7 +310,7 @@ impl<T> State<T> {
|
||||||
internal: Internal {
|
internal: Internal {
|
||||||
layout: Node::Pane(first_pane),
|
layout: Node::Pane(first_pane),
|
||||||
last_pane: 0,
|
last_pane: 0,
|
||||||
focus: None,
|
focused_pane: FocusedPane::None,
|
||||||
modifiers: keyboard::ModifiersState::default(),
|
modifiers: keyboard::ModifiersState::default(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -292,15 +335,24 @@ impl<T> State<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focused_pane(&self) -> Option<Pane> {
|
pub fn focused_pane(&self) -> Option<Pane> {
|
||||||
match self.internal.focus {
|
match self.internal.focused_pane {
|
||||||
Some(Focus::Idle(pane)) => Some(pane),
|
FocusedPane::Some {
|
||||||
Some(Focus::Dragging(_)) => None,
|
pane,
|
||||||
None => None,
|
focus: Focus::Idle,
|
||||||
|
} => Some(pane),
|
||||||
|
FocusedPane::Some {
|
||||||
|
focus: Focus::Dragging,
|
||||||
|
..
|
||||||
|
} => None,
|
||||||
|
FocusedPane::None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focus(&mut self, pane: Pane) {
|
pub fn focus(&mut self, pane: Pane) {
|
||||||
self.internal.focus = Some(Focus::Idle(pane));
|
self.internal.focused_pane = FocusedPane::Some {
|
||||||
|
pane,
|
||||||
|
focus: Focus::Idle,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split_vertically(&mut self, pane: &Pane, state: T) -> Option<Pane> {
|
pub fn split_vertically(&mut self, pane: &Pane, state: T) -> Option<Pane> {
|
||||||
|
|
@ -332,7 +384,10 @@ impl<T> State<T> {
|
||||||
node.split(kind, new_pane);
|
node.split(kind, new_pane);
|
||||||
|
|
||||||
let _ = self.panes.insert(new_pane, state);
|
let _ = self.panes.insert(new_pane, state);
|
||||||
self.internal.focus = Some(Focus::Idle(new_pane));
|
self.internal.focused_pane = FocusedPane::Some {
|
||||||
|
pane: new_pane,
|
||||||
|
focus: Focus::Idle,
|
||||||
|
};
|
||||||
|
|
||||||
Some(new_pane)
|
Some(new_pane)
|
||||||
}
|
}
|
||||||
|
|
@ -352,7 +407,11 @@ impl<T> State<T> {
|
||||||
|
|
||||||
pub fn close(&mut self, pane: &Pane) -> Option<T> {
|
pub fn close(&mut self, pane: &Pane) -> Option<T> {
|
||||||
if let Some(sibling) = self.internal.layout.remove(pane) {
|
if let Some(sibling) = self.internal.layout.remove(pane) {
|
||||||
self.internal.focus = Some(Focus::Idle(sibling));
|
self.internal.focused_pane = FocusedPane::Some {
|
||||||
|
pane: sibling,
|
||||||
|
focus: Focus::Idle,
|
||||||
|
};
|
||||||
|
|
||||||
self.panes.remove(pane)
|
self.panes.remove(pane)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue