Merge pull request #892 from clarkmoody/title-bar-events
PaneGrid Events in Title Bar Area
This commit is contained in:
commit
e292821c37
|
@ -11,7 +11,7 @@ pub fn main() -> iced::Result {
|
|||
}
|
||||
|
||||
struct Example {
|
||||
panes: pane_grid::State<Content>,
|
||||
panes: pane_grid::State<Pane>,
|
||||
panes_created: usize,
|
||||
focus: Option<pane_grid::Pane>,
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ enum Message {
|
|||
Clicked(pane_grid::Pane),
|
||||
Dragged(pane_grid::DragEvent),
|
||||
Resized(pane_grid::ResizeEvent),
|
||||
TogglePin(pane_grid::Pane),
|
||||
Close(pane_grid::Pane),
|
||||
CloseFocused,
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ impl Application for Example {
|
|||
type Flags = ();
|
||||
|
||||
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 {
|
||||
|
@ -60,7 +61,7 @@ impl Application for Example {
|
|||
let result = self.panes.split(
|
||||
axis,
|
||||
&pane,
|
||||
Content::new(self.panes_created),
|
||||
Pane::new(self.panes_created),
|
||||
);
|
||||
|
||||
if let Some((pane, _)) = result {
|
||||
|
@ -74,7 +75,7 @@ impl Application for Example {
|
|||
let result = self.panes.split(
|
||||
axis,
|
||||
&pane,
|
||||
Content::new(self.panes_created),
|
||||
Pane::new(self.panes_created),
|
||||
);
|
||||
|
||||
if let Some((pane, _)) = result {
|
||||
|
@ -106,6 +107,12 @@ impl Application for Example {
|
|||
self.panes.swap(&pane, &target);
|
||||
}
|
||||
Message::Dragged(_) => {}
|
||||
Message::TogglePin(pane) => {
|
||||
if let Some(Pane { is_pinned, .. }) = self.panes.get_mut(&pane)
|
||||
{
|
||||
*is_pinned = !*is_pinned;
|
||||
}
|
||||
}
|
||||
Message::Close(pane) => {
|
||||
if let Some((_, sibling)) = self.panes.close(&pane) {
|
||||
self.focus = Some(sibling);
|
||||
|
@ -113,8 +120,14 @@ impl Application for Example {
|
|||
}
|
||||
Message::CloseFocused => {
|
||||
if let Some(pane) = self.focus {
|
||||
if let Some((_, sibling)) = self.panes.close(&pane) {
|
||||
self.focus = Some(sibling);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,12 +156,20 @@ impl Application for Example {
|
|||
let focus = self.focus;
|
||||
let total_panes = self.panes.len();
|
||||
|
||||
let pane_grid = PaneGrid::new(&mut self.panes, |pane, content| {
|
||||
let is_focused = focus == Some(pane);
|
||||
let pane_grid = PaneGrid::new(&mut self.panes, |id, 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![
|
||||
pin_button.into(),
|
||||
Text::new("Pane").into(),
|
||||
Text::new(content.id.to_string())
|
||||
Text::new(pane.content.id.to_string())
|
||||
.color(if is_focused {
|
||||
PANE_ID_COLOR_FOCUSED
|
||||
} else {
|
||||
|
@ -159,12 +180,17 @@ impl Application for Example {
|
|||
.spacing(5);
|
||||
|
||||
let title_bar = pane_grid::TitleBar::new(title)
|
||||
.controls(pane.controls.view(id, total_panes, pane.is_pinned))
|
||||
.padding(10)
|
||||
.style(style::TitleBar { is_focused });
|
||||
|
||||
pane_grid::Content::new(content.view(pane, total_panes))
|
||||
.title_bar(title_bar)
|
||||
.style(style::Pane { is_focused })
|
||||
pane_grid::Content::new(pane.content.view(
|
||||
id,
|
||||
total_panes,
|
||||
pane.is_pinned,
|
||||
))
|
||||
.title_bar(title_bar)
|
||||
.style(style::Pane { is_focused })
|
||||
})
|
||||
.width(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 {
|
||||
id: usize,
|
||||
scroll: scrollable::State,
|
||||
|
@ -220,6 +253,21 @@ struct Content {
|
|||
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 {
|
||||
fn new(id: usize) -> Self {
|
||||
Content {
|
||||
|
@ -234,6 +282,7 @@ impl Content {
|
|||
&mut self,
|
||||
pane: pane_grid::Pane,
|
||||
total_panes: usize,
|
||||
is_pinned: bool,
|
||||
) -> Element<Message> {
|
||||
let Content {
|
||||
scroll,
|
||||
|
@ -273,7 +322,7 @@ impl Content {
|
|||
style::Button::Primary,
|
||||
));
|
||||
|
||||
if total_panes > 1 {
|
||||
if total_panes > 1 && !is_pinned {
|
||||
controls = controls.push(button(
|
||||
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 {
|
||||
use crate::PANE_ID_COLOR_FOCUSED;
|
||||
use iced::{button, container, Background, Color, Vector};
|
||||
|
||||
const SURFACE: Color = Color::from_rgb(
|
||||
|
@ -359,6 +433,8 @@ mod style {
|
|||
pub enum Button {
|
||||
Primary,
|
||||
Destructive,
|
||||
Control,
|
||||
Pin,
|
||||
}
|
||||
|
||||
impl button::StyleSheet for Button {
|
||||
|
@ -368,6 +444,8 @@ mod style {
|
|||
Button::Destructive => {
|
||||
(None, Color::from_rgb8(0xFF, 0x47, 0x47))
|
||||
}
|
||||
Button::Control => (Some(PANE_ID_COLOR_FOCUSED), Color::WHITE),
|
||||
Button::Pin => (Some(ACTIVE), Color::WHITE),
|
||||
};
|
||||
|
||||
button::Style {
|
||||
|
@ -388,6 +466,8 @@ mod style {
|
|||
a: 0.2,
|
||||
..active.text_color
|
||||
}),
|
||||
Button::Control => Some(PANE_ID_COLOR_FOCUSED),
|
||||
Button::Pin => Some(HOVERED),
|
||||
};
|
||||
|
||||
button::Style {
|
||||
|
|
|
@ -218,10 +218,10 @@ where
|
|||
body_primitive,
|
||||
],
|
||||
},
|
||||
if is_over_pick_area {
|
||||
mouse::Interaction::Grab
|
||||
} else if title_bar_interaction > body_interaction {
|
||||
if title_bar_interaction > body_interaction {
|
||||
title_bar_interaction
|
||||
} else if is_over_pick_area {
|
||||
mouse::Interaction::Grab
|
||||
} else {
|
||||
body_interaction
|
||||
},
|
||||
|
|
|
@ -129,15 +129,16 @@ where
|
|||
if layout.bounds().contains(cursor_position) {
|
||||
let mut children = layout.children();
|
||||
let padded = children.next().unwrap();
|
||||
let mut children = padded.children();
|
||||
let title_layout = children.next().unwrap();
|
||||
|
||||
if self.controls.is_some() {
|
||||
let mut children = padded.children();
|
||||
let _ = children.next().unwrap();
|
||||
let controls_layout = children.next().unwrap();
|
||||
|
||||
!controls_layout.bounds().contains(cursor_position)
|
||||
&& !title_layout.bounds().contains(cursor_position)
|
||||
} else {
|
||||
true
|
||||
!title_layout.bounds().contains(cursor_position)
|
||||
}
|
||||
} else {
|
||||
false
|
||||
|
@ -205,16 +206,17 @@ where
|
|||
clipboard: &mut dyn Clipboard,
|
||||
messages: &mut Vec<Message>,
|
||||
) -> event::Status {
|
||||
if let Some(controls) = &mut self.controls {
|
||||
let mut children = layout.children();
|
||||
let padded = children.next().unwrap();
|
||||
let mut children = layout.children();
|
||||
let padded = children.next().unwrap();
|
||||
|
||||
let mut children = padded.children();
|
||||
let _ = children.next();
|
||||
let mut children = padded.children();
|
||||
let title_layout = children.next().unwrap();
|
||||
|
||||
let control_status = if let Some(controls) = &mut self.controls {
|
||||
let controls_layout = children.next().unwrap();
|
||||
|
||||
controls.on_event(
|
||||
event,
|
||||
event.clone(),
|
||||
controls_layout,
|
||||
cursor_position,
|
||||
renderer,
|
||||
|
@ -223,6 +225,17 @@ where
|
|||
)
|
||||
} else {
|
||||
event::Status::Ignored
|
||||
}
|
||||
};
|
||||
|
||||
let title_status = self.content.on_event(
|
||||
event,
|
||||
title_layout,
|
||||
cursor_position,
|
||||
renderer,
|
||||
clipboard,
|
||||
messages,
|
||||
);
|
||||
|
||||
control_status.merge(title_status)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue