summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector0193@gmail.com>2021-05-25 16:34:17 +0700
committerLibravatar GitHub <noreply@github.com>2021-05-25 16:34:17 +0700
commite292821c3780fc5a57c835815efc7a232ce4dc32 (patch)
tree8659fb678d989a2f97876b20aa501d5415af4b02
parentdf971ac99beedb41537763f95f7b14d8bf7475a8 (diff)
parentd4c5f3ee950262c578c7b9b2a4aab60d3c5edaed (diff)
downloadiced-e292821c3780fc5a57c835815efc7a232ce4dc32.tar.gz
iced-e292821c3780fc5a57c835815efc7a232ce4dc32.tar.bz2
iced-e292821c3780fc5a57c835815efc7a232ce4dc32.zip
Merge pull request #892 from clarkmoody/title-bar-events
PaneGrid Events in Title Bar Area
-rw-r--r--examples/pane_grid/src/main.rs106
-rw-r--r--graphics/src/widget/pane_grid.rs6
-rw-r--r--native/src/widget/pane_grid/title_bar.rs33
3 files changed, 119 insertions, 26 deletions
diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs
index 4b87a568..81cf1770 100644
--- a/examples/pane_grid/src/main.rs
+++ b/examples/pane_grid/src/main.rs
@@ -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 {
diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs
index d06f8c6c..93b4b672 100644
--- a/graphics/src/widget/pane_grid.rs
+++ b/graphics/src/widget/pane_grid.rs
@@ -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
},
diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs
index a1e5107e..8e42ce38 100644
--- a/native/src/widget/pane_grid/title_bar.rs
+++ b/native/src/widget/pane_grid/title_bar.rs
@@ -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)
}
}