Example: Add Pin button to prevent closing a pane

Functionality will not work until PaneGrid implementation is updated
to support events within the title area.
This commit is contained in:
Clark Moody 2021-05-24 15:53:20 -05:00
parent e6f8b32583
commit 1a2fd4e743
1 changed files with 42 additions and 8 deletions

View File

@ -24,6 +24,7 @@ enum Message {
Clicked(pane_grid::Pane), Clicked(pane_grid::Pane),
Dragged(pane_grid::DragEvent), Dragged(pane_grid::DragEvent),
Resized(pane_grid::ResizeEvent), Resized(pane_grid::ResizeEvent),
TogglePin(pane_grid::Pane),
Close(pane_grid::Pane), Close(pane_grid::Pane),
CloseFocused, CloseFocused,
} }
@ -106,6 +107,12 @@ impl Application for Example {
self.panes.swap(&pane, &target); self.panes.swap(&pane, &target);
} }
Message::Dragged(_) => {} Message::Dragged(_) => {}
Message::TogglePin(pane) => {
if let Some(Pane { is_pinned, .. }) = self.panes.get_mut(&pane)
{
*is_pinned = !*is_pinned;
}
}
Message::Close(pane) => { Message::Close(pane) => {
if let Some((_, sibling)) = self.panes.close(&pane) { if let Some((_, sibling)) = self.panes.close(&pane) {
self.focus = Some(sibling); self.focus = Some(sibling);
@ -113,12 +120,18 @@ impl Application for Example {
} }
Message::CloseFocused => { Message::CloseFocused => {
if let Some(pane) = self.focus { if let Some(pane) = self.focus {
if let Some((_, sibling)) = self.panes.close(&pane) { if let Some(Pane { is_pinned, .. }) = self.panes.get(&pane)
{
if !is_pinned {
if let Some((_, sibling)) = self.panes.close(&pane)
{
self.focus = Some(sibling); self.focus = Some(sibling);
} }
} }
} }
} }
}
}
Command::none() Command::none()
} }
@ -146,7 +159,15 @@ impl Application for Example {
let pane_grid = PaneGrid::new(&mut self.panes, |id, pane| { let pane_grid = PaneGrid::new(&mut self.panes, |id, pane| {
let is_focused = focus == Some(id); let is_focused = focus == Some(id);
let text = if pane.is_pinned { "Unpin" } else { "Pin" };
let pin_button =
Button::new(&mut pane.pin_button, Text::new(text).size(14))
.on_press(Message::TogglePin(id))
.style(style::Button::Pin)
.padding(3);
let title = Row::with_children(vec![ let title = Row::with_children(vec![
pin_button.into(),
Text::new("Pane").into(), Text::new("Pane").into(),
Text::new(pane.content.id.to_string()) Text::new(pane.content.id.to_string())
.color(if is_focused { .color(if is_focused {
@ -159,11 +180,15 @@ impl Application for Example {
.spacing(5); .spacing(5);
let title_bar = pane_grid::TitleBar::new(title) let title_bar = pane_grid::TitleBar::new(title)
.controls(pane.controls.view(id, total_panes)) .controls(pane.controls.view(id, total_panes, pane.is_pinned))
.padding(10) .padding(10)
.style(style::TitleBar { is_focused }); .style(style::TitleBar { is_focused });
pane_grid::Content::new(pane.content.view(id, total_panes)) pane_grid::Content::new(pane.content.view(
id,
total_panes,
pane.is_pinned,
))
.title_bar(title_bar) .title_bar(title_bar)
.style(style::Pane { is_focused }) .style(style::Pane { is_focused })
}) })
@ -214,6 +239,8 @@ fn handle_hotkey(key_code: keyboard::KeyCode) -> Option<Message> {
} }
struct Pane { struct Pane {
pub is_pinned: bool,
pub pin_button: button::State,
pub content: Content, pub content: Content,
pub controls: Controls, pub controls: Controls,
} }
@ -233,6 +260,8 @@ struct Controls {
impl Pane { impl Pane {
fn new(id: usize) -> Self { fn new(id: usize) -> Self {
Self { Self {
is_pinned: false,
pin_button: button::State::new(),
content: Content::new(id), content: Content::new(id),
controls: Controls::new(), controls: Controls::new(),
} }
@ -253,6 +282,7 @@ impl Content {
&mut self, &mut self,
pane: pane_grid::Pane, pane: pane_grid::Pane,
total_panes: usize, total_panes: usize,
is_pinned: bool,
) -> Element<Message> { ) -> Element<Message> {
let Content { let Content {
scroll, scroll,
@ -292,7 +322,7 @@ impl Content {
style::Button::Primary, style::Button::Primary,
)); ));
if total_panes > 1 { if total_panes > 1 && !is_pinned {
controls = controls.push(button( controls = controls.push(button(
close, close,
"Close", "Close",
@ -327,12 +357,13 @@ impl Controls {
&mut self, &mut self,
pane: pane_grid::Pane, pane: pane_grid::Pane,
total_panes: usize, total_panes: usize,
is_pinned: bool,
) -> Element<Message> { ) -> Element<Message> {
let mut button = let mut button =
Button::new(&mut self.close, Text::new("Close").size(14)) Button::new(&mut self.close, Text::new("Close").size(14))
.style(style::Button::Control) .style(style::Button::Control)
.padding(3); .padding(3);
if total_panes > 1 { if total_panes > 1 && !is_pinned {
button = button.on_press(Message::Close(pane)); button = button.on_press(Message::Close(pane));
} }
button.into() button.into()
@ -403,6 +434,7 @@ mod style {
Primary, Primary,
Destructive, Destructive,
Control, Control,
Pin,
} }
impl button::StyleSheet for Button { impl button::StyleSheet for Button {
@ -413,6 +445,7 @@ mod style {
(None, Color::from_rgb8(0xFF, 0x47, 0x47)) (None, Color::from_rgb8(0xFF, 0x47, 0x47))
} }
Button::Control => (Some(PANE_ID_COLOR_FOCUSED), Color::WHITE), Button::Control => (Some(PANE_ID_COLOR_FOCUSED), Color::WHITE),
Button::Pin => (Some(ACTIVE), Color::WHITE),
}; };
button::Style { button::Style {
@ -434,6 +467,7 @@ mod style {
..active.text_color ..active.text_color
}), }),
Button::Control => Some(PANE_ID_COLOR_FOCUSED), Button::Control => Some(PANE_ID_COLOR_FOCUSED),
Button::Pin => Some(HOVERED),
}; };
button::Style { button::Style {