From 81f06af5732d7cf72e0c8c25451872c7bfc8e9aa Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sat, 13 Jan 2024 17:29:50 +0000 Subject: [PATCH] Use mouse_area from iced fork --- .gitmodules | 3 +++ Cargo.lock | 24 +----------------------- Cargo.toml | 3 +++ iced | 1 + shalom/Cargo.toml | 2 +- shalom/src/pages/room/listen/search.rs | 6 +++--- shalom/src/widgets/media_player.rs | 4 ++-- shalom/src/widgets/mod.rs | 1 - shalom/src/widgets/mouse_area.rs | 347 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- shalom/src/widgets/room_navigation.rs | 5 +++-- shalom/src/widgets/toggle_card.rs | 11 ++++------- 11 files changed, 21 insertions(+), 386 deletions(-) create mode 100644 .gitmodules create mode 160000 iced delete mode 100644 shalom/src/widgets/mouse_area.rs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..281c2f5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "iced"] + path = iced + url = https://github.com/JordanForks/iced diff --git a/Cargo.lock b/Cargo.lock index fc3cb17..4a57cfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1268,8 +1268,6 @@ dependencies = [ [[package]] name = "iced" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c708807ec86f99dd729dc4d42db5239acf118cec14d3c5f57679dcfdbbc472b1" dependencies = [ "iced_core", "iced_futures", @@ -1283,8 +1281,6 @@ dependencies = [ [[package]] name = "iced_core" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d0bc4fbf018576d08d93f838e6058cc6f10bbc05e04ae249a2a44dffb4ebc8" dependencies = [ "bitflags 1.3.2", "instant", @@ -1297,8 +1293,6 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dab0054a9c7a1cbce227a8cd9ee4a094497b3d06094551ac6c1488d563802e" dependencies = [ "futures", "iced_core", @@ -1311,8 +1305,6 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ff14447a221e9e9205a13d84d7bbdf0636a3b1daa02cfca690ed09689c4d2b" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1330,8 +1322,6 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1033385b0db0099a0d13178c9ff93c1ce11e7d0177522acf578bf79febdb2af8" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -1344,8 +1334,6 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c6c89853e1250c6fac82c5015fa2144517be9b33d4b8e456f10e198b23e28bd" dependencies = [ "iced_core", "iced_futures", @@ -1355,8 +1343,6 @@ dependencies = [ [[package]] name = "iced_style" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d85c47d9d13e2281f75ddf98c865daf2101632bd2b855c401dd0b1c8b81a31a0" dependencies = [ "iced_core", "once_cell", @@ -1366,8 +1352,6 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7715f6222c9470bbbd75a39f70478fa0d1bdfb81a377a34fd1b090ffccc480b" dependencies = [ "bytemuck", "cosmic-text", @@ -1385,8 +1369,6 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f7c5de46b997ed7b18e05ec67059dcdf3beeac51e917c21071b021bb848b9" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1408,8 +1390,6 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a177219ae51c3ba08f228ab932354b360cc669e94aec50c01e7c9b675f074c7c" dependencies = [ "iced_renderer", "iced_runtime", @@ -1422,9 +1402,7 @@ dependencies = [ [[package]] name = "iced_winit" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ecea26fcc8074373f6011d2193d63445617d900a428eb4df66c0e5658408fb6" +version = "0.10.1" dependencies = [ "iced_graphics", "iced_runtime", diff --git a/Cargo.toml b/Cargo.toml index 277348f..d69797d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,9 @@ resolver = "2" members = [ "shalom" ] +exclude = [ + "iced" +] [profile.dev.package.image] opt-level = 3 diff --git a/iced b/iced new file mode 160000 index 0000000..c30197d --- /dev/null +++ b/iced @@ -0,0 +1 @@ +Subproject commit c30197d3c7e46dde933f6839662023222f07d30a diff --git a/shalom/Cargo.toml b/shalom/Cargo.toml index c808a0b..d5736d1 100644 --- a/shalom/Cargo.toml +++ b/shalom/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" atomic = "0.6" bytemuck = "1.14" bytes = "1" -iced = { version = "0.10", features = ["tokio", "svg", "lazy", "advanced", "image", "canvas"] } +iced = { path = "../iced", features = ["tokio", "svg", "lazy", "advanced", "image", "canvas"] } image = "0.24" once_cell = "1.18" parking_lot = "0.12" diff --git a/shalom/src/pages/room/listen/search.rs b/shalom/src/pages/room/listen/search.rs index 5e32ac2..4b683d2 100644 --- a/shalom/src/pages/room/listen/search.rs +++ b/shalom/src/pages/room/listen/search.rs @@ -4,13 +4,13 @@ use iced::{ alignment::Horizontal, theme, widget::{ - column, component, container, container::Appearance, image, image::Handle, row, text, - Column, Component, + column, component, container, container::Appearance, image, image::Handle, mouse_area, row, + text, Column, Component, }, Alignment, Background, Color, Element, Length, Renderer, Theme, }; -use crate::widgets::{mouse_area::mouse_area, spinner::CupertinoSpinner}; +use crate::widgets::spinner::CupertinoSpinner; pub fn search(theme: Theme, results: SearchState<'_>) -> Search<'_, M> { Search { diff --git a/shalom/src/widgets/media_player.rs b/shalom/src/widgets/media_player.rs index 06c374e..05d010a 100644 --- a/shalom/src/widgets/media_player.rs +++ b/shalom/src/widgets/media_player.rs @@ -8,7 +8,8 @@ use iced::{ alignment::Horizontal, theme::{Container, Slider, Svg, Text}, widget::{ - column as icolumn, component, container, image::Handle, row, slider, svg, text, Component, + column as icolumn, component, container, image::Handle, mouse_area, row, slider, svg, text, + Component, }, Alignment, Background, Color, Length, Renderer, Theme, }; @@ -20,7 +21,6 @@ use crate::{ colours::{SKY_500, SLATE_400}, Icon, }, - widgets::mouse_area::mouse_area, }; pub fn media_player(device: MediaPlayerSpeaker, album_art: Option) -> MediaPlayer { diff --git a/shalom/src/widgets/mod.rs b/shalom/src/widgets/mod.rs index 4265f44..d463c58 100644 --- a/shalom/src/widgets/mod.rs +++ b/shalom/src/widgets/mod.rs @@ -6,7 +6,6 @@ pub mod forced_rounded; pub mod image_background; pub mod image_card; pub mod media_player; -pub mod mouse_area; pub mod room_navigation; pub mod spinner; pub mod toggle_card; diff --git a/shalom/src/widgets/mouse_area.rs b/shalom/src/widgets/mouse_area.rs deleted file mode 100644 index a3aae21..0000000 --- a/shalom/src/widgets/mouse_area.rs +++ /dev/null @@ -1,347 +0,0 @@ -//! A container for capturing mouse events. -//! -//! Pretty much just a copy of [`iced::widget::mouse_area`] but with the ability -//! to trigger an event after a button has been held down for a set amount of -//! time. - -use std::time::{Duration, Instant}; - -use iced::{ - advanced::{ - layout, mouse, overlay, renderer, - widget::{tree, Operation, Tree}, - Clipboard, Layout, Shell, Widget, - }, - event, touch, - window::RedrawRequest, - Element, Event, Length, Rectangle, -}; - -pub fn mouse_area<'a, Message, Renderer>( - widget: impl Into>, -) -> MouseArea<'a, Message, Renderer> -where - Renderer: renderer::Renderer, -{ - MouseArea::new(widget) -} - -/// Emit messages on mouse events. -#[allow(missing_debug_implementations)] -pub struct MouseArea<'a, Message, Renderer> { - content: Element<'a, Message, Renderer>, - on_press: Option, - on_cancel: Option, - on_hold: Option<(Message, Duration)>, - on_release: Option, - on_right_press: Option, - on_right_release: Option, - on_middle_press: Option, - on_middle_release: Option, -} - -impl<'a, Message, Renderer> MouseArea<'a, Message, Renderer> { - /// The message to emit on a left button press. - #[must_use] - pub fn on_press(mut self, message: impl Into>) -> Self { - self.on_press = message.into(); - self - } - - /// The message to emit when holding down an item. - #[must_use] - pub fn on_hold(mut self, message: Message, duration: Duration) -> Self { - self.on_hold = Some((message, duration)); - self - } - - /// The message to emit when a user "cancels" a `press`. - #[must_use] - pub fn on_cancel(mut self, message: Message) -> Self { - self.on_cancel = Some(message); - self - } - - /// The message to emit on a left button release. - #[must_use] - pub fn on_release(mut self, message: Message) -> Self { - self.on_release = Some(message); - self - } - - /// The message to emit on a right button press. - #[must_use] - pub fn on_right_press(mut self, message: Message) -> Self { - self.on_right_press = Some(message); - self - } - - /// The message to emit on a right button release. - #[must_use] - pub fn on_right_release(mut self, message: Message) -> Self { - self.on_right_release = Some(message); - self - } - - /// The message to emit on a middle button press. - #[must_use] - pub fn on_middle_press(mut self, message: Message) -> Self { - self.on_middle_press = Some(message); - self - } - - /// The message to emit on a middle button release. - #[must_use] - pub fn on_middle_release(mut self, message: Message) -> Self { - self.on_middle_release = Some(message); - self - } -} - -/// Local state of the [`MouseArea`]. -#[derive(Default)] -struct State { - // TODO: Support on_mouse_enter and on_mouse_exit - held_since: Option, -} - -impl<'a, Message, Renderer> MouseArea<'a, Message, Renderer> { - /// Creates a [`MouseArea`] with the given content. - pub fn new(content: impl Into>) -> Self { - MouseArea { - content: content.into(), - on_press: None, - on_hold: None, - on_cancel: None, - on_release: None, - on_right_press: None, - on_right_release: None, - on_middle_press: None, - on_middle_release: None, - } - } -} - -impl<'a, Message, Renderer> Widget for MouseArea<'a, Message, Renderer> -where - Renderer: renderer::Renderer, - Message: Clone, -{ - fn tag(&self) -> tree::Tag { - tree::Tag::of::() - } - - fn state(&self) -> tree::State { - tree::State::new(State::default()) - } - - fn children(&self) -> Vec { - vec![Tree::new(&self.content)] - } - - fn diff(&self, tree: &mut Tree) { - tree.diff_children(std::slice::from_ref(&self.content)); - } - - fn width(&self) -> Length { - self.content.as_widget().width() - } - - fn height(&self) -> Length { - self.content.as_widget().height() - } - - fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node { - self.content.as_widget().layout(renderer, limits) - } - - fn operate( - &self, - tree: &mut Tree, - layout: Layout<'_>, - renderer: &Renderer, - operation: &mut dyn Operation, - ) { - self.content - .as_widget() - .operate(&mut tree.children[0], layout, renderer, operation); - } - - fn on_event( - &mut self, - tree: &mut Tree, - event: Event, - layout: Layout<'_>, - cursor: mouse::Cursor, - renderer: &Renderer, - clipboard: &mut dyn Clipboard, - shell: &mut Shell<'_, Message>, - viewport: &Rectangle, - ) -> event::Status { - if let event::Status::Captured = self.content.as_widget_mut().on_event( - &mut tree.children[0], - event.clone(), - layout, - cursor, - renderer, - clipboard, - shell, - viewport, - ) { - return event::Status::Captured; - } - - let state = tree.state.downcast_mut::(); - - update(self, state, &event, layout, cursor, shell) - } - - fn mouse_interaction( - &self, - tree: &Tree, - layout: Layout<'_>, - cursor: mouse::Cursor, - viewport: &Rectangle, - renderer: &Renderer, - ) -> mouse::Interaction { - self.content.as_widget().mouse_interaction( - &tree.children[0], - layout, - cursor, - viewport, - renderer, - ) - } - - fn draw( - &self, - tree: &Tree, - renderer: &mut Renderer, - theme: &Renderer::Theme, - renderer_style: &renderer::Style, - layout: Layout<'_>, - cursor: mouse::Cursor, - viewport: &Rectangle, - ) { - self.content.as_widget().draw( - &tree.children[0], - renderer, - theme, - renderer_style, - layout, - cursor, - viewport, - ); - } - - fn overlay<'b>( - &'b mut self, - tree: &'b mut Tree, - layout: Layout<'_>, - renderer: &Renderer, - ) -> Option> { - self.content - .as_widget_mut() - .overlay(&mut tree.children[0], layout, renderer) - } -} - -impl<'a, Message, Renderer> From> - for Element<'a, Message, Renderer> -where - Message: 'a + Clone, - Renderer: 'a + renderer::Renderer, -{ - fn from(area: MouseArea<'a, Message, Renderer>) -> Element<'a, Message, Renderer> { - Element::new(area) - } -} - -/// Processes the given [`Event`] and updates the [`State`] of an [`MouseArea`] -/// accordingly. -fn update( - widget: &mut MouseArea<'_, Message, Renderer>, - state: &mut State, - event: &Event, - layout: Layout<'_>, - cursor: mouse::Cursor, - shell: &mut Shell<'_, Message>, -) -> event::Status { - if !cursor.is_over(layout.bounds()) { - if let (Some(message), Some(_)) = (&widget.on_cancel, state.held_since) { - state.held_since = None; - shell.publish(message.clone()); - } - - return event::Status::Ignored; - } - - if let (Some((message, duration)), Some(held_since)) = - (widget.on_hold.as_ref(), state.held_since) - { - if held_since.elapsed() > *duration { - state.held_since = None; - shell.publish(message.clone()); - } - } - - if let Some(message) = widget.on_press.as_ref() { - if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(touch::Event::FingerPressed { .. }) = event - { - shell.publish(message.clone()); - - if let Some((_message, duration)) = widget.on_hold.clone() { - state.held_since = Some(Instant::now()); - shell.request_redraw(RedrawRequest::At(Instant::now() + duration)); - } - - return event::Status::Captured; - } - } - - if let Some(message) = widget.on_release.as_ref() { - if let Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) - | Event::Touch(touch::Event::FingerLifted { .. }) = event - { - shell.publish(message.clone()); - state.held_since = None; - - return event::Status::Captured; - } - } - - if let Some(message) = widget.on_right_press.as_ref() { - if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) = event { - shell.publish(message.clone()); - - return event::Status::Captured; - } - } - - if let Some(message) = widget.on_right_release.as_ref() { - if let Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Right)) = event { - shell.publish(message.clone()); - - return event::Status::Captured; - } - } - - if let Some(message) = widget.on_middle_press.as_ref() { - if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Middle)) = event { - shell.publish(message.clone()); - - return event::Status::Captured; - } - } - - if let Some(message) = widget.on_middle_release.as_ref() { - if let Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Middle)) = event { - shell.publish(message.clone()); - - return event::Status::Captured; - } - } - - event::Status::Ignored -} diff --git a/shalom/src/widgets/room_navigation.rs b/shalom/src/widgets/room_navigation.rs index d71dfba..a7c1e10 100644 --- a/shalom/src/widgets/room_navigation.rs +++ b/shalom/src/widgets/room_navigation.rs @@ -3,11 +3,12 @@ use iced::{ alignment::Vertical, font::{Stretch, Weight}, theme, - widget::{column, component, container, horizontal_rule, rule, svg, text, Component}, + widget::{ + column, component, container, horizontal_rule, mouse_area, rule, svg, text, Component, + }, Alignment, Background, Color, ContentFit, Font, Length, Renderer, Theme, }; -use super::mouse_area::mouse_area; use crate::theme::{ colours::{SKY_500, SLATE_200}, Icon, diff --git a/shalom/src/widgets/toggle_card.rs b/shalom/src/widgets/toggle_card.rs index 8b7d8ca..fc93fda 100644 --- a/shalom/src/widgets/toggle_card.rs +++ b/shalom/src/widgets/toggle_card.rs @@ -6,16 +6,13 @@ use iced::{ alignment::Vertical, font::Weight, theme::{Container, Svg}, - widget::{component, container, row, svg, text}, + widget::{component, container, mouse_area, row, svg, text}, Alignment, Background, Color, Element, Font, Length, Renderer, Theme, }; -use crate::{ - theme::{ - colours::{ORANGE, SYSTEM_GRAY6}, - Icon, - }, - widgets::mouse_area::mouse_area, +use crate::theme::{ + colours::{ORANGE, SYSTEM_GRAY6}, + Icon, }; pub const LONG_PRESS_LENGTH: Duration = Duration::from_millis(350); -- libgit2 1.7.2