From a14b39555e5c480422c24df7d708dd1addd0a67b Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Wed, 18 Dec 2019 07:45:49 +0100
Subject: Allow clipboard access in `Widget::on_event`

---
 native/src/clipboard.rs         |  8 ++++++++
 native/src/element.rs           |  7 ++++++-
 native/src/lib.rs               |  2 ++
 native/src/user_interface.rs    | 10 +++++++---
 native/src/widget.rs            |  5 +++--
 native/src/widget/button.rs     |  5 +++--
 native/src/widget/checkbox.rs   |  3 ++-
 native/src/widget/column.rs     |  5 ++++-
 native/src/widget/container.rs  |  5 ++++-
 native/src/widget/radio.rs      |  3 ++-
 native/src/widget/row.rs        |  5 ++++-
 native/src/widget/scrollable.rs |  6 ++++--
 native/src/widget/slider.rs     |  5 +++--
 native/src/widget/text_input.rs |  5 +++--
 14 files changed, 55 insertions(+), 19 deletions(-)
 create mode 100644 native/src/clipboard.rs

(limited to 'native')

diff --git a/native/src/clipboard.rs b/native/src/clipboard.rs
new file mode 100644
index 00000000..4c574590
--- /dev/null
+++ b/native/src/clipboard.rs
@@ -0,0 +1,8 @@
+/// A buffer for short-term storage and transfer within and between
+/// applications.
+pub trait Clipboard {
+    /// Returns the current content of the [`Clipboard`] as text.
+    ///
+    /// [`Clipboard`]: trait.Clipboard.html
+    fn content(&self) -> Option<String>;
+}
diff --git a/native/src/element.rs b/native/src/element.rs
index d4237fd0..63d2de0c 100644
--- a/native/src/element.rs
+++ b/native/src/element.rs
@@ -1,5 +1,6 @@
 use crate::{
-    layout, renderer, Color, Event, Hasher, Layout, Length, Point, Widget,
+    layout, renderer, Clipboard, Color, Event, Hasher, Layout, Length, Point,
+    Widget,
 };
 
 /// A generic [`Widget`].
@@ -293,6 +294,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<B>,
         renderer: &Renderer,
+        clipboard: Option<&dyn Clipboard>,
     ) {
         let mut original_messages = Vec::new();
 
@@ -302,6 +304,7 @@ where
             cursor_position,
             &mut original_messages,
             renderer,
+            clipboard,
         );
 
         original_messages
@@ -366,6 +369,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         renderer: &Renderer,
+        clipboard: Option<&dyn Clipboard>,
     ) {
         self.element.widget.on_event(
             event,
@@ -373,6 +377,7 @@ where
             cursor_position,
             messages,
             renderer,
+            clipboard,
         )
     }
 
diff --git a/native/src/lib.rs b/native/src/lib.rs
index c4d72df8..8dcacb2b 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -45,6 +45,7 @@ pub mod renderer;
 pub mod subscription;
 pub mod widget;
 
+mod clipboard;
 mod element;
 mod event;
 mod hasher;
@@ -57,6 +58,7 @@ pub use iced_core::{
     Point, Rectangle, Vector, VerticalAlignment,
 };
 
+pub use clipboard::Clipboard;
 pub use element::Element;
 pub use event::Event;
 pub use hasher::Hasher;
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs
index 9833c815..07b936a9 100644
--- a/native/src/user_interface.rs
+++ b/native/src/user_interface.rs
@@ -1,4 +1,6 @@
-use crate::{input::mouse, layout, Element, Event, Layout, Point, Size};
+use crate::{
+    input::mouse, layout, Clipboard, Element, Event, Layout, Point, Size,
+};
 
 use std::hash::Hasher;
 
@@ -185,7 +187,7 @@ where
     ///     );
     ///
     ///     // Update the user interface
-    ///     let messages = user_interface.update(&renderer, events.drain(..));
+    ///     let messages = user_interface.update(&renderer, None, events.drain(..));
     ///
     ///     cache = user_interface.into_cache();
     ///
@@ -198,6 +200,7 @@ where
     pub fn update(
         &mut self,
         renderer: &Renderer,
+        clipboard: Option<&dyn Clipboard>,
         events: impl Iterator<Item = Event>,
     ) -> Vec<Message> {
         let mut messages = Vec::new();
@@ -213,6 +216,7 @@ where
                 self.cursor_position,
                 &mut messages,
                 renderer,
+                clipboard,
             );
         }
 
@@ -282,7 +286,7 @@ where
     ///         &mut renderer,
     ///     );
     ///
-    ///     let messages = user_interface.update(&renderer, events.drain(..));
+    ///     let messages = user_interface.update(&renderer, None, events.drain(..));
     ///
     ///     // Draw the user interface
     ///     let mouse_cursor = user_interface.draw(&mut renderer);
diff --git a/native/src/widget.rs b/native/src/widget.rs
index ee7232cb..26889280 100644
--- a/native/src/widget.rs
+++ b/native/src/widget.rs
@@ -24,12 +24,12 @@ pub mod button;
 pub mod checkbox;
 pub mod column;
 pub mod container;
-pub mod svg;
 pub mod image;
 pub mod radio;
 pub mod row;
 pub mod scrollable;
 pub mod slider;
+pub mod svg;
 pub mod text;
 pub mod text_input;
 
@@ -58,7 +58,7 @@ pub use text::Text;
 #[doc(no_inline)]
 pub use text_input::TextInput;
 
-use crate::{layout, Event, Hasher, Layout, Length, Point};
+use crate::{layout, Clipboard, Event, Hasher, Layout, Length, Point};
 
 /// A component that displays information and allows interaction.
 ///
@@ -142,6 +142,7 @@ where
         _cursor_position: Point,
         _messages: &mut Vec<Message>,
         _renderer: &Renderer,
+        _clipboard: Option<&dyn Clipboard>,
     ) {
     }
 }
diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs
index 67b49dc6..2881105f 100644
--- a/native/src/widget/button.rs
+++ b/native/src/widget/button.rs
@@ -6,8 +6,8 @@
 //! [`State`]: struct.State.html
 use crate::{
     input::{mouse, ButtonState},
-    layout, Background, Element, Event, Hasher, Layout, Length, Point,
-    Rectangle, Widget,
+    layout, Background, Clipboard, Element, Event, Hasher, Layout, Length,
+    Point, Rectangle, Widget,
 };
 use std::hash::Hash;
 
@@ -192,6 +192,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         _renderer: &Renderer,
+        _clipboard: Option<&dyn Clipboard>,
     ) {
         match event {
             Event::Mouse(mouse::Event::Input {
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs
index ca4410b9..0dcac712 100644
--- a/native/src/widget/checkbox.rs
+++ b/native/src/widget/checkbox.rs
@@ -3,7 +3,7 @@ use std::hash::Hash;
 
 use crate::{
     input::{mouse, ButtonState},
-    layout, row, text, Align, Color, Element, Event, Font, Hasher,
+    layout, row, text, Align, Clipboard, Color, Element, Event, Font, Hasher,
     HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text,
     VerticalAlignment, Widget,
 };
@@ -114,6 +114,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         _renderer: &Renderer,
+        _clipboard: Option<&dyn Clipboard>,
     ) {
         match event {
             Event::Mouse(mouse::Event::Input {
diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs
index cdcf25af..4b5d631c 100644
--- a/native/src/widget/column.rs
+++ b/native/src/widget/column.rs
@@ -2,7 +2,8 @@
 use std::hash::Hash;
 
 use crate::{
-    layout, Align, Element, Event, Hasher, Layout, Length, Point, Widget,
+    layout, Align, Clipboard, Element, Event, Hasher, Layout, Length, Point,
+    Widget,
 };
 
 use std::u32;
@@ -153,6 +154,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         renderer: &Renderer,
+        clipboard: Option<&dyn Clipboard>,
     ) {
         self.children.iter_mut().zip(layout.children()).for_each(
             |(child, layout)| {
@@ -162,6 +164,7 @@ where
                     cursor_position,
                     messages,
                     renderer,
+                    clipboard,
                 )
             },
         );
diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs
index 7852eecf..74f0e0ef 100644
--- a/native/src/widget/container.rs
+++ b/native/src/widget/container.rs
@@ -2,7 +2,8 @@
 use std::hash::Hash;
 
 use crate::{
-    layout, Align, Element, Event, Hasher, Layout, Length, Point, Widget,
+    layout, Align, Clipboard, Element, Event, Hasher, Layout, Length, Point,
+    Widget,
 };
 
 use std::u32;
@@ -131,6 +132,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         renderer: &Renderer,
+        clipboard: Option<&dyn Clipboard>,
     ) {
         self.content.widget.on_event(
             event,
@@ -138,6 +140,7 @@ where
             cursor_position,
             messages,
             renderer,
+            clipboard,
         )
     }
 
diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs
index a9d145db..a9995b86 100644
--- a/native/src/widget/radio.rs
+++ b/native/src/widget/radio.rs
@@ -1,7 +1,7 @@
 //! Create choices using radio buttons.
 use crate::{
     input::{mouse, ButtonState},
-    layout, row, text, Align, Color, Element, Event, Font, Hasher,
+    layout, row, text, Align, Clipboard, Color, Element, Event, Font, Hasher,
     HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text,
     VerticalAlignment, Widget,
 };
@@ -113,6 +113,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         _renderer: &Renderer,
+        _clipboard: Option<&dyn Clipboard>,
     ) {
         match event {
             Event::Mouse(mouse::Event::Input {
diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs
index c854aff7..3de65deb 100644
--- a/native/src/widget/row.rs
+++ b/native/src/widget/row.rs
@@ -2,7 +2,8 @@
 use std::hash::Hash;
 
 use crate::{
-    layout, Align, Element, Event, Hasher, Layout, Length, Point, Widget,
+    layout, Align, Clipboard, Element, Event, Hasher, Layout, Length, Point,
+    Widget,
 };
 
 use std::u32;
@@ -154,6 +155,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         renderer: &Renderer,
+        clipboard: Option<&dyn Clipboard>,
     ) {
         self.children.iter_mut().zip(layout.children()).for_each(
             |(child, layout)| {
@@ -163,6 +165,7 @@ where
                     cursor_position,
                     messages,
                     renderer,
+                    clipboard,
                 )
             },
         );
diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs
index 3c2625b7..872c59cb 100644
--- a/native/src/widget/scrollable.rs
+++ b/native/src/widget/scrollable.rs
@@ -2,8 +2,8 @@
 use crate::{
     column,
     input::{mouse, ButtonState},
-    layout, Align, Column, Element, Event, Hasher, Layout, Length, Point,
-    Rectangle, Size, Widget,
+    layout, Align, Clipboard, Column, Element, Event, Hasher, Layout, Length,
+    Point, Rectangle, Size, Widget,
 };
 
 use std::{f32, hash::Hash, u32};
@@ -143,6 +143,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         renderer: &Renderer,
+        clipboard: Option<&dyn Clipboard>,
     ) {
         let bounds = layout.bounds();
         let is_mouse_over = bounds.contains(cursor_position);
@@ -247,6 +248,7 @@ where
             cursor_position,
             messages,
             renderer,
+            clipboard,
         )
     }
 
diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs
index f07ea7cd..f446f7e8 100644
--- a/native/src/widget/slider.rs
+++ b/native/src/widget/slider.rs
@@ -6,8 +6,8 @@
 //! [`State`]: struct.State.html
 use crate::{
     input::{mouse, ButtonState},
-    layout, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size,
-    Widget,
+    layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
+    Rectangle, Size, Widget,
 };
 
 use std::{hash::Hash, ops::RangeInclusive};
@@ -133,6 +133,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         _renderer: &Renderer,
+        _clipboard: Option<&dyn Clipboard>,
     ) {
         let mut change = || {
             let bounds = layout.bounds();
diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs
index f0bb9f87..3890e9c6 100644
--- a/native/src/widget/text_input.rs
+++ b/native/src/widget/text_input.rs
@@ -6,8 +6,8 @@
 //! [`State`]: struct.State.html
 use crate::{
     input::{keyboard, mouse, ButtonState},
-    layout, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size,
-    Widget,
+    layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
+    Rectangle, Size, Widget,
 };
 use unicode_segmentation::UnicodeSegmentation;
 
@@ -172,6 +172,7 @@ where
         cursor_position: Point,
         messages: &mut Vec<Message>,
         renderer: &Renderer,
+        _clipboard: Option<&dyn Clipboard>,
     ) {
         match event {
             Event::Mouse(mouse::Event::Input {
-- 
cgit