Skip to content

Commit e292821

Browse files
authored
Merge pull request #892 from clarkmoody/title-bar-events
PaneGrid Events in Title Bar Area
2 parents df971ac + d4c5f3e commit e292821

File tree

3 files changed

+119
-26
lines changed

3 files changed

+119
-26
lines changed

examples/pane_grid/src/main.rs

Lines changed: 93 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub fn main() -> iced::Result {
1111
}
1212

1313
struct Example {
14-
panes: pane_grid::State<Content>,
14+
panes: pane_grid::State<Pane>,
1515
panes_created: usize,
1616
focus: Option<pane_grid::Pane>,
1717
}
@@ -24,6 +24,7 @@ enum Message {
2424
Clicked(pane_grid::Pane),
2525
Dragged(pane_grid::DragEvent),
2626
Resized(pane_grid::ResizeEvent),
27+
TogglePin(pane_grid::Pane),
2728
Close(pane_grid::Pane),
2829
CloseFocused,
2930
}
@@ -34,7 +35,7 @@ impl Application for Example {
3435
type Flags = ();
3536

3637
fn new(_flags: ()) -> (Self, Command<Message>) {
37-
let (panes, _) = pane_grid::State::new(Content::new(0));
38+
let (panes, _) = pane_grid::State::new(Pane::new(0));
3839

3940
(
4041
Example {
@@ -60,7 +61,7 @@ impl Application for Example {
6061
let result = self.panes.split(
6162
axis,
6263
&pane,
63-
Content::new(self.panes_created),
64+
Pane::new(self.panes_created),
6465
);
6566

6667
if let Some((pane, _)) = result {
@@ -74,7 +75,7 @@ impl Application for Example {
7475
let result = self.panes.split(
7576
axis,
7677
&pane,
77-
Content::new(self.panes_created),
78+
Pane::new(self.panes_created),
7879
);
7980

8081
if let Some((pane, _)) = result {
@@ -106,15 +107,27 @@ impl Application for Example {
106107
self.panes.swap(&pane, &target);
107108
}
108109
Message::Dragged(_) => {}
110+
Message::TogglePin(pane) => {
111+
if let Some(Pane { is_pinned, .. }) = self.panes.get_mut(&pane)
112+
{
113+
*is_pinned = !*is_pinned;
114+
}
115+
}
109116
Message::Close(pane) => {
110117
if let Some((_, sibling)) = self.panes.close(&pane) {
111118
self.focus = Some(sibling);
112119
}
113120
}
114121
Message::CloseFocused => {
115122
if let Some(pane) = self.focus {
116-
if let Some((_, sibling)) = self.panes.close(&pane) {
117-
self.focus = Some(sibling);
123+
if let Some(Pane { is_pinned, .. }) = self.panes.get(&pane)
124+
{
125+
if !is_pinned {
126+
if let Some((_, sibling)) = self.panes.close(&pane)
127+
{
128+
self.focus = Some(sibling);
129+
}
130+
}
118131
}
119132
}
120133
}
@@ -143,12 +156,20 @@ impl Application for Example {
143156
let focus = self.focus;
144157
let total_panes = self.panes.len();
145158

146-
let pane_grid = PaneGrid::new(&mut self.panes, |pane, content| {
147-
let is_focused = focus == Some(pane);
159+
let pane_grid = PaneGrid::new(&mut self.panes, |id, pane| {
160+
let is_focused = focus == Some(id);
161+
162+
let text = if pane.is_pinned { "Unpin" } else { "Pin" };
163+
let pin_button =
164+
Button::new(&mut pane.pin_button, Text::new(text).size(14))
165+
.on_press(Message::TogglePin(id))
166+
.style(style::Button::Pin)
167+
.padding(3);
148168

149169
let title = Row::with_children(vec![
170+
pin_button.into(),
150171
Text::new("Pane").into(),
151-
Text::new(content.id.to_string())
172+
Text::new(pane.content.id.to_string())
152173
.color(if is_focused {
153174
PANE_ID_COLOR_FOCUSED
154175
} else {
@@ -159,12 +180,17 @@ impl Application for Example {
159180
.spacing(5);
160181

161182
let title_bar = pane_grid::TitleBar::new(title)
183+
.controls(pane.controls.view(id, total_panes, pane.is_pinned))
162184
.padding(10)
163185
.style(style::TitleBar { is_focused });
164186

165-
pane_grid::Content::new(content.view(pane, total_panes))
166-
.title_bar(title_bar)
167-
.style(style::Pane { is_focused })
187+
pane_grid::Content::new(pane.content.view(
188+
id,
189+
total_panes,
190+
pane.is_pinned,
191+
))
192+
.title_bar(title_bar)
193+
.style(style::Pane { is_focused })
168194
})
169195
.width(Length::Fill)
170196
.height(Length::Fill)
@@ -212,6 +238,13 @@ fn handle_hotkey(key_code: keyboard::KeyCode) -> Option<Message> {
212238
}
213239
}
214240

241+
struct Pane {
242+
pub is_pinned: bool,
243+
pub pin_button: button::State,
244+
pub content: Content,
245+
pub controls: Controls,
246+
}
247+
215248
struct Content {
216249
id: usize,
217250
scroll: scrollable::State,
@@ -220,6 +253,21 @@ struct Content {
220253
close: button::State,
221254
}
222255

256+
struct Controls {
257+
close: button::State,
258+
}
259+
260+
impl Pane {
261+
fn new(id: usize) -> Self {
262+
Self {
263+
is_pinned: false,
264+
pin_button: button::State::new(),
265+
content: Content::new(id),
266+
controls: Controls::new(),
267+
}
268+
}
269+
}
270+
223271
impl Content {
224272
fn new(id: usize) -> Self {
225273
Content {
@@ -234,6 +282,7 @@ impl Content {
234282
&mut self,
235283
pane: pane_grid::Pane,
236284
total_panes: usize,
285+
is_pinned: bool,
237286
) -> Element<Message> {
238287
let Content {
239288
scroll,
@@ -273,7 +322,7 @@ impl Content {
273322
style::Button::Primary,
274323
));
275324

276-
if total_panes > 1 {
325+
if total_panes > 1 && !is_pinned {
277326
controls = controls.push(button(
278327
close,
279328
"Close",
@@ -297,7 +346,32 @@ impl Content {
297346
}
298347
}
299348

349+
impl Controls {
350+
fn new() -> Self {
351+
Self {
352+
close: button::State::new(),
353+
}
354+
}
355+
356+
pub fn view(
357+
&mut self,
358+
pane: pane_grid::Pane,
359+
total_panes: usize,
360+
is_pinned: bool,
361+
) -> Element<Message> {
362+
let mut button =
363+
Button::new(&mut self.close, Text::new("Close").size(14))
364+
.style(style::Button::Control)
365+
.padding(3);
366+
if total_panes > 1 && !is_pinned {
367+
button = button.on_press(Message::Close(pane));
368+
}
369+
button.into()
370+
}
371+
}
372+
300373
mod style {
374+
use crate::PANE_ID_COLOR_FOCUSED;
301375
use iced::{button, container, Background, Color, Vector};
302376

303377
const SURFACE: Color = Color::from_rgb(
@@ -359,6 +433,8 @@ mod style {
359433
pub enum Button {
360434
Primary,
361435
Destructive,
436+
Control,
437+
Pin,
362438
}
363439

364440
impl button::StyleSheet for Button {
@@ -368,6 +444,8 @@ mod style {
368444
Button::Destructive => {
369445
(None, Color::from_rgb8(0xFF, 0x47, 0x47))
370446
}
447+
Button::Control => (Some(PANE_ID_COLOR_FOCUSED), Color::WHITE),
448+
Button::Pin => (Some(ACTIVE), Color::WHITE),
371449
};
372450

373451
button::Style {
@@ -388,6 +466,8 @@ mod style {
388466
a: 0.2,
389467
..active.text_color
390468
}),
469+
Button::Control => Some(PANE_ID_COLOR_FOCUSED),
470+
Button::Pin => Some(HOVERED),
391471
};
392472

393473
button::Style {

graphics/src/widget/pane_grid.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,10 @@ where
218218
body_primitive,
219219
],
220220
},
221-
if is_over_pick_area {
222-
mouse::Interaction::Grab
223-
} else if title_bar_interaction > body_interaction {
221+
if title_bar_interaction > body_interaction {
224222
title_bar_interaction
223+
} else if is_over_pick_area {
224+
mouse::Interaction::Grab
225225
} else {
226226
body_interaction
227227
},

native/src/widget/pane_grid/title_bar.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,16 @@ where
129129
if layout.bounds().contains(cursor_position) {
130130
let mut children = layout.children();
131131
let padded = children.next().unwrap();
132+
let mut children = padded.children();
133+
let title_layout = children.next().unwrap();
132134

133135
if self.controls.is_some() {
134-
let mut children = padded.children();
135-
let _ = children.next().unwrap();
136136
let controls_layout = children.next().unwrap();
137137

138138
!controls_layout.bounds().contains(cursor_position)
139+
&& !title_layout.bounds().contains(cursor_position)
139140
} else {
140-
true
141+
!title_layout.bounds().contains(cursor_position)
141142
}
142143
} else {
143144
false
@@ -205,16 +206,17 @@ where
205206
clipboard: &mut dyn Clipboard,
206207
messages: &mut Vec<Message>,
207208
) -> event::Status {
208-
if let Some(controls) = &mut self.controls {
209-
let mut children = layout.children();
210-
let padded = children.next().unwrap();
209+
let mut children = layout.children();
210+
let padded = children.next().unwrap();
211211

212-
let mut children = padded.children();
213-
let _ = children.next();
212+
let mut children = padded.children();
213+
let title_layout = children.next().unwrap();
214+
215+
let control_status = if let Some(controls) = &mut self.controls {
214216
let controls_layout = children.next().unwrap();
215217

216218
controls.on_event(
217-
event,
219+
event.clone(),
218220
controls_layout,
219221
cursor_position,
220222
renderer,
@@ -223,6 +225,17 @@ where
223225
)
224226
} else {
225227
event::Status::Ignored
226-
}
228+
};
229+
230+
let title_status = self.content.on_event(
231+
event,
232+
title_layout,
233+
cursor_position,
234+
renderer,
235+
clipboard,
236+
messages,
237+
);
238+
239+
control_status.merge(title_status)
227240
}
228241
}

0 commit comments

Comments
 (0)