Merge pull request #892 from clarkmoody/title-bar-events

PaneGrid Events in Title Bar Area
This commit is contained in:
Héctor Ramón 2021-05-25 16:34:17 +07:00 committed by GitHub
commit e292821c37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 119 additions and 26 deletions

View File

@ -11,7 +11,7 @@ pub fn main() -> iced::Result {
} }
struct Example { struct Example {
panes: pane_grid::State<Content>, panes: pane_grid::State<Pane>,
panes_created: usize, panes_created: usize,
focus: Option<pane_grid::Pane>, focus: Option<pane_grid::Pane>,
} }
@ -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,
} }
@ -34,7 +35,7 @@ impl Application for Example {
type Flags = (); type Flags = ();
fn new(_flags: ()) -> (Self, Command<Message>) { fn new(_flags: ()) -> (Self, Command<Message>) {
let (panes, _) = pane_grid::State::new(Content::new(0)); let (panes, _) = pane_grid::State::new(Pane::new(0));
( (
Example { Example {
@ -60,7 +61,7 @@ impl Application for Example {
let result = self.panes.split( let result = self.panes.split(
axis, axis,
&pane, &pane,
Content::new(self.panes_created), Pane::new(self.panes_created),
); );
if let Some((pane, _)) = result { if let Some((pane, _)) = result {
@ -74,7 +75,7 @@ impl Application for Example {
let result = self.panes.split( let result = self.panes.split(
axis, axis,
&pane, &pane,
Content::new(self.panes_created), Pane::new(self.panes_created),
); );
if let Some((pane, _)) = result { if let Some((pane, _)) = result {
@ -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,8 +120,14 @@ 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)
self.focus = Some(sibling); {
if !is_pinned {
if let Some((_, sibling)) = self.panes.close(&pane)
{
self.focus = Some(sibling);
}
}
} }
} }
} }
@ -143,12 +156,20 @@ impl Application for Example {
let focus = self.focus; let focus = self.focus;
let total_panes = self.panes.len(); let total_panes = self.panes.len();
let pane_grid = PaneGrid::new(&mut self.panes, |pane, content| { let pane_grid = PaneGrid::new(&mut self.panes, |id, pane| {
let is_focused = focus == Some(pane); 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(content.id.to_string()) Text::new(pane.content.id.to_string())
.color(if is_focused { .color(if is_focused {
PANE_ID_COLOR_FOCUSED PANE_ID_COLOR_FOCUSED
} else { } else {
@ -159,12 +180,17 @@ 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, pane.is_pinned))
.padding(10) .padding(10)
.style(style::TitleBar { is_focused }); .style(style::TitleBar { is_focused });
pane_grid::Content::new(content.view(pane, total_panes)) pane_grid::Content::new(pane.content.view(
.title_bar(title_bar) id,
.style(style::Pane { is_focused }) total_panes,
pane.is_pinned,
))
.title_bar(title_bar)
.style(style::Pane { is_focused })
}) })
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
@ -212,6 +238,13 @@ fn handle_hotkey(key_code: keyboard::KeyCode) -> Option<Message> {
} }
} }
struct Pane {
pub is_pinned: bool,
pub pin_button: button::State,
pub content: Content,
pub controls: Controls,
}
struct Content { struct Content {
id: usize, id: usize,
scroll: scrollable::State, scroll: scrollable::State,
@ -220,6 +253,21 @@ struct Content {
close: button::State, close: button::State,
} }
struct Controls {
close: button::State,
}
impl Pane {
fn new(id: usize) -> Self {
Self {
is_pinned: false,
pin_button: button::State::new(),
content: Content::new(id),
controls: Controls::new(),
}
}
}
impl Content { impl Content {
fn new(id: usize) -> Self { fn new(id: usize) -> Self {
Content { Content {
@ -234,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,
@ -273,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",
@ -297,7 +346,32 @@ impl Content {
} }
} }
impl Controls {
fn new() -> Self {
Self {
close: button::State::new(),
}
}
pub fn view(
&mut self,
pane: pane_grid::Pane,
total_panes: usize,
is_pinned: bool,
) -> Element<Message> {
let mut button =
Button::new(&mut self.close, Text::new("Close").size(14))
.style(style::Button::Control)
.padding(3);
if total_panes > 1 && !is_pinned {
button = button.on_press(Message::Close(pane));
}
button.into()
}
}
mod style { mod style {
use crate::PANE_ID_COLOR_FOCUSED;
use iced::{button, container, Background, Color, Vector}; use iced::{button, container, Background, Color, Vector};
const SURFACE: Color = Color::from_rgb( const SURFACE: Color = Color::from_rgb(
@ -359,6 +433,8 @@ mod style {
pub enum Button { pub enum Button {
Primary, Primary,
Destructive, Destructive,
Control,
Pin,
} }
impl button::StyleSheet for Button { impl button::StyleSheet for Button {
@ -368,6 +444,8 @@ mod style {
Button::Destructive => { Button::Destructive => {
(None, Color::from_rgb8(0xFF, 0x47, 0x47)) (None, Color::from_rgb8(0xFF, 0x47, 0x47))
} }
Button::Control => (Some(PANE_ID_COLOR_FOCUSED), Color::WHITE),
Button::Pin => (Some(ACTIVE), Color::WHITE),
}; };
button::Style { button::Style {
@ -388,6 +466,8 @@ mod style {
a: 0.2, a: 0.2,
..active.text_color ..active.text_color
}), }),
Button::Control => Some(PANE_ID_COLOR_FOCUSED),
Button::Pin => Some(HOVERED),
}; };
button::Style { button::Style {

View File

@ -218,10 +218,10 @@ where
body_primitive, body_primitive,
], ],
}, },
if is_over_pick_area { if title_bar_interaction > body_interaction {
mouse::Interaction::Grab
} else if title_bar_interaction > body_interaction {
title_bar_interaction title_bar_interaction
} else if is_over_pick_area {
mouse::Interaction::Grab
} else { } else {
body_interaction body_interaction
}, },

View File

@ -129,15 +129,16 @@ where
if layout.bounds().contains(cursor_position) { if layout.bounds().contains(cursor_position) {
let mut children = layout.children(); let mut children = layout.children();
let padded = children.next().unwrap(); let padded = children.next().unwrap();
let mut children = padded.children();
let title_layout = children.next().unwrap();
if self.controls.is_some() { if self.controls.is_some() {
let mut children = padded.children();
let _ = children.next().unwrap();
let controls_layout = children.next().unwrap(); let controls_layout = children.next().unwrap();
!controls_layout.bounds().contains(cursor_position) !controls_layout.bounds().contains(cursor_position)
&& !title_layout.bounds().contains(cursor_position)
} else { } else {
true !title_layout.bounds().contains(cursor_position)
} }
} else { } else {
false false
@ -205,16 +206,17 @@ where
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
messages: &mut Vec<Message>, messages: &mut Vec<Message>,
) -> event::Status { ) -> event::Status {
if let Some(controls) = &mut self.controls { let mut children = layout.children();
let mut children = layout.children(); let padded = children.next().unwrap();
let padded = children.next().unwrap();
let mut children = padded.children(); let mut children = padded.children();
let _ = children.next(); let title_layout = children.next().unwrap();
let control_status = if let Some(controls) = &mut self.controls {
let controls_layout = children.next().unwrap(); let controls_layout = children.next().unwrap();
controls.on_event( controls.on_event(
event, event.clone(),
controls_layout, controls_layout,
cursor_position, cursor_position,
renderer, renderer,
@ -223,6 +225,17 @@ where
) )
} else { } else {
event::Status::Ignored event::Status::Ignored
} };
let title_status = self.content.on_event(
event,
title_layout,
cursor_position,
renderer,
clipboard,
messages,
);
control_status.merge(title_status)
} }
} }