summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-11-10 02:32:57 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-11-10 02:32:57 +0100
commitd6d5cf0294b1231f4909a782e90b491cc6838fae (patch)
tree41e746cb2559df2e2c8c94715cd6bd1c9c10617e
parentc53022e8dff6fc6286b60bc897232fe4cb6e6202 (diff)
downloadiced-d6d5cf0294b1231f4909a782e90b491cc6838fae.tar.gz
iced-d6d5cf0294b1231f4909a782e90b491cc6838fae.tar.bz2
iced-d6d5cf0294b1231f4909a782e90b491cc6838fae.zip
Restore hotkeys in `pane_grid` example
- Implement `subscription::events_with` - Remove `pane_grid::KeyPressEvent` - Return closest sibling in `pane_grid::State::close`
-rw-r--r--examples/pane_grid/Cargo.toml1
-rw-r--r--examples/pane_grid/src/main.rs54
-rw-r--r--glow/src/widget/pane_grid.rs4
-rw-r--r--graphics/src/widget/pane_grid.rs4
-rw-r--r--native/src/subscription.rs22
-rw-r--r--native/src/subscription/events.rs19
-rw-r--r--native/src/widget/pane_grid.rs16
-rw-r--r--native/src/widget/pane_grid/state.rs9
-rw-r--r--wgpu/src/widget/pane_grid.rs4
9 files changed, 88 insertions, 45 deletions
diff --git a/examples/pane_grid/Cargo.toml b/examples/pane_grid/Cargo.toml
index 3d1631f1..e489f210 100644
--- a/examples/pane_grid/Cargo.toml
+++ b/examples/pane_grid/Cargo.toml
@@ -7,3 +7,4 @@ publish = false
[dependencies]
iced = { path = "../..", features = ["debug"] }
+iced_native = { path = "../../native" }
diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs
index 36485e9a..d149f9c6 100644
--- a/examples/pane_grid/src/main.rs
+++ b/examples/pane_grid/src/main.rs
@@ -1,8 +1,9 @@
use iced::{
- button, keyboard, pane_grid, scrollable, Align, Button, Column, Container,
- Element, HorizontalAlignment, Length, PaneGrid, Sandbox, Scrollable,
- Settings, Text,
+ button, executor, keyboard, pane_grid, scrollable, Align, Application,
+ Button, Column, Command, Container, Element, HorizontalAlignment, Length,
+ PaneGrid, Scrollable, Settings, Subscription, Text,
};
+use iced_native::{subscription, Event};
pub fn main() -> iced::Result {
Example::run(Settings::default())
@@ -26,24 +27,29 @@ enum Message {
CloseFocused,
}
-impl Sandbox for Example {
+impl Application for Example {
type Message = Message;
+ type Executor = executor::Default;
+ type Flags = ();
- fn new() -> Self {
+ fn new(_flags: ()) -> (Self, Command<Message>) {
let (panes, _) = pane_grid::State::new(Content::new(0));
- Example {
- panes,
- panes_created: 1,
- focus: None,
- }
+ (
+ Example {
+ panes,
+ panes_created: 1,
+ focus: None,
+ },
+ Command::none(),
+ )
}
fn title(&self) -> String {
String::from("Pane grid - Iced")
}
- fn update(&mut self, message: Message) {
+ fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::Split(axis, pane) => {
let result = self.panes.split(
@@ -96,14 +102,30 @@ impl Sandbox for Example {
}
Message::Dragged(_) => {}
Message::Close(pane) => {
- let _ = self.panes.close(&pane);
+ if let Some((_, sibling)) = self.panes.close(&pane) {
+ self.focus = Some(sibling);
+ }
}
Message::CloseFocused => {
if let Some(pane) = self.focus {
- let _ = self.panes.close(&pane);
+ if let Some((_, sibling)) = self.panes.close(&pane) {
+ self.focus = Some(sibling);
+ }
}
}
}
+
+ Command::none()
+ }
+
+ fn subscription(&self) -> Subscription<Message> {
+ subscription::events_with(|event| match event {
+ Event::Keyboard(keyboard::Event::KeyPressed {
+ modifiers,
+ key_code,
+ }) if modifiers.control => handle_hotkey(key_code),
+ _ => None,
+ })
}
fn view(&mut self) -> Element<Message> {
@@ -137,11 +159,11 @@ impl Sandbox for Example {
}
}
-fn handle_hotkey(event: pane_grid::KeyPressEvent) -> Option<Message> {
+fn handle_hotkey(key_code: keyboard::KeyCode) -> Option<Message> {
use keyboard::KeyCode;
use pane_grid::{Axis, Direction};
- let direction = match event.key_code {
+ let direction = match key_code {
KeyCode::Up => Some(Direction::Up),
KeyCode::Down => Some(Direction::Down),
KeyCode::Left => Some(Direction::Left),
@@ -149,7 +171,7 @@ fn handle_hotkey(event: pane_grid::KeyPressEvent) -> Option<Message> {
_ => None,
};
- match event.key_code {
+ match key_code {
KeyCode::V => Some(Message::SplitFocused(Axis::Vertical)),
KeyCode::H => Some(Message::SplitFocused(Axis::Horizontal)),
KeyCode::W => Some(Message::CloseFocused),
diff --git a/glow/src/widget/pane_grid.rs b/glow/src/widget/pane_grid.rs
index 3c47b562..9e6d27d0 100644
--- a/glow/src/widget/pane_grid.rs
+++ b/glow/src/widget/pane_grid.rs
@@ -11,8 +11,8 @@
use crate::Renderer;
pub use iced_native::pane_grid::{
- Axis, Configuration, Direction, DragEvent, Focus, KeyPressEvent, Node,
- Pane, ResizeEvent, Split, State,
+ Axis, Configuration, Direction, DragEvent, Focus, Node, Pane, ResizeEvent,
+ Split, State,
};
/// A collection of panes distributed using either vertical or horizontal splits
diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs
index 5b0eb391..1bc01c03 100644
--- a/graphics/src/widget/pane_grid.rs
+++ b/graphics/src/widget/pane_grid.rs
@@ -20,8 +20,8 @@ use iced_native::{
};
pub use iced_native::pane_grid::{
- Axis, Configuration, Content, Direction, DragEvent, Focus, KeyPressEvent,
- Pane, ResizeEvent, Split, State, TitleBar,
+ Axis, Configuration, Content, Direction, DragEvent, Focus, Pane,
+ ResizeEvent, Split, State, TitleBar,
};
/// A collection of panes distributed using either vertical or horizontal splits
diff --git a/native/src/subscription.rs b/native/src/subscription.rs
index 0d002c6c..18750abf 100644
--- a/native/src/subscription.rs
+++ b/native/src/subscription.rs
@@ -43,5 +43,25 @@ use events::Events;
/// [`Subscription`]: type.Subscription.html
/// [`Event`]: ../enum.Event.html
pub fn events() -> Subscription<Event> {
- Subscription::from_recipe(Events)
+ Subscription::from_recipe(Events { f: Some })
+}
+
+/// Returns a [`Subscription`] that filters all the runtime events with the
+/// provided function, producing messages accordingly.
+///
+/// This subscription will call the provided function for every [`Event`]
+/// handled by the runtime. If the function:
+///
+/// - Returns `None`, the [`Event`] will be discarded.
+/// - Returns `Some` message, the `Message` will be produced.
+///
+/// [`Subscription`]: type.Subscription.html
+/// [`Event`]: ../enum.Event.html
+pub fn events_with<Message>(
+ f: fn(Event) -> Option<Message>,
+) -> Subscription<Message>
+where
+ Message: 'static + Send,
+{
+ Subscription::from_recipe(Events { f })
}
diff --git a/native/src/subscription/events.rs b/native/src/subscription/events.rs
index ceae467d..a1ae6051 100644
--- a/native/src/subscription/events.rs
+++ b/native/src/subscription/events.rs
@@ -2,17 +2,26 @@ use crate::{
subscription::{EventStream, Recipe},
Event, Hasher,
};
+use iced_futures::futures::future;
+use iced_futures::futures::StreamExt;
use iced_futures::BoxStream;
-pub struct Events;
+pub struct Events<Message> {
+ pub(super) f: fn(Event) -> Option<Message>,
+}
-impl Recipe<Hasher, Event> for Events {
- type Output = Event;
+impl<Message> Recipe<Hasher, Event> for Events<Message>
+where
+ Message: 'static + Send,
+{
+ type Output = Message;
fn hash(&self, state: &mut Hasher) {
use std::hash::Hash;
- std::any::TypeId::of::<Self>().hash(state);
+ struct Marker;
+ std::any::TypeId::of::<Marker>().hash(state);
+ self.f.hash(state);
}
fn stream(
@@ -20,5 +29,7 @@ impl Recipe<Hasher, Event> for Events {
event_stream: EventStream,
) -> BoxStream<Self::Output> {
event_stream
+ .filter_map(move |event| future::ready((self.f)(event)))
+ .boxed()
}
}
diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs
index 584b2ba4..7d9659e9 100644
--- a/native/src/widget/pane_grid.rs
+++ b/native/src/widget/pane_grid.rs
@@ -29,8 +29,8 @@ pub use state::{Focus, State};
pub use title_bar::TitleBar;
use crate::{
- container, keyboard, layout, mouse, overlay, row, text, Clipboard, Element,
- Event, Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget,
+ container, layout, mouse, overlay, row, text, Clipboard, Element, Event,
+ Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget,
};
/// A collection of panes distributed using either vertical or horizontal splits
@@ -336,18 +336,6 @@ pub struct ResizeEvent {
pub ratio: f32,
}
-/// An event produced during a key press interaction of a [`PaneGrid`].
-///
-/// [`PaneGrid`]: struct.PaneGrid.html
-#[derive(Debug, Clone, Copy)]
-pub struct KeyPressEvent {
- /// The key that was pressed.
- pub key_code: keyboard::KeyCode,
-
- /// The state of the modifier keys when the key was pressed.
- pub modifiers: keyboard::ModifiersState,
-}
-
impl<'a, Message, Renderer> Widget<Message, Renderer>
for PaneGrid<'a, Message, Renderer>
where
diff --git a/native/src/widget/pane_grid/state.rs b/native/src/widget/pane_grid/state.rs
index e2793641..be36b070 100644
--- a/native/src/widget/pane_grid/state.rs
+++ b/native/src/widget/pane_grid/state.rs
@@ -227,12 +227,13 @@ impl<T> State<T> {
let _ = self.internal.layout.resize(split, ratio);
}
- /// Closes the given [`Pane`] and returns its internal state, if it exists.
+ /// Closes the given [`Pane`] and returns its internal state and its closest
+ /// sibling, if it exists.
///
/// [`Pane`]: struct.Pane.html
- pub fn close(&mut self, pane: &Pane) -> Option<T> {
- if let Some(_) = self.internal.layout.remove(pane) {
- self.panes.remove(pane)
+ pub fn close(&mut self, pane: &Pane) -> Option<(T, Pane)> {
+ if let Some(sibling) = self.internal.layout.remove(pane) {
+ self.panes.remove(pane).map(|state| (state, sibling))
} else {
None
}
diff --git a/wgpu/src/widget/pane_grid.rs b/wgpu/src/widget/pane_grid.rs
index 3c47b562..9e6d27d0 100644
--- a/wgpu/src/widget/pane_grid.rs
+++ b/wgpu/src/widget/pane_grid.rs
@@ -11,8 +11,8 @@
use crate::Renderer;
pub use iced_native::pane_grid::{
- Axis, Configuration, Direction, DragEvent, Focus, KeyPressEvent, Node,
- Pane, ResizeEvent, Split, State,
+ Axis, Configuration, Direction, DragEvent, Focus, Node, Pane, ResizeEvent,
+ Split, State,
};
/// A collection of panes distributed using either vertical or horizontal splits