zng/
clipboard.rs

1#![cfg(feature = "clipboard")]
2
3//! Clipboard service, commands and other types.
4//!
5//! This module provides the [`CLIPBOARD`] service and clipboard related commands and command handlers.
6//! The service does not implement the commands, widgets implement the commands and optionally use the service.
7//!
8//! Note that the [`CLIPBOARD`] service uses the view-process the interact with the system clipboard, so it will only
9//! work if a headed app or headless app with renderer is running.
10//!
11//! # Text
12//!
13//! The example below uses the service to copy text to the clipboard:
14//!
15//! ```
16//! use zng::prelude::*;
17//!
18//! # fn example() {
19//! let txt = var(Txt::from(""));
20//! let copied = var(false);
21//! # let _ =
22//! Container! {
23//!     child = TextInput!(txt.clone());
24//!     child_spacing = 5;
25//!     child_end = Button! {
26//!         child = Text!(copied.map(|&c| if !c { "Copy" } else { "Copied!" }.into()));
27//!         on_click = async_hn!(txt, copied, |_| {
28//!             if zng::clipboard::CLIPBOARD.set_text(txt.get()).wait_rsp().await.is_ok() {
29//!                 copied.set(true);
30//!             }
31//!         });
32//!     };
33//! }
34//! # ; }
35//! ```
36//!
37//! The `TextInput` widget also implements the clipboard commands, the example below requests clipboard paste to the
38//! text input, that widget uses the clipboard service to get the text.
39//!
40//! ```
41//! use zng::prelude::*;
42//!
43//! # fn example() {
44//! # let _ =
45//! Container! {
46//!     child = TextInput! {
47//!         id = "input-1";
48//!         txt = var(Txt::from(""));
49//!     };
50//!     child_spacing = 4;
51//!     child_end = Button!(zng::clipboard::PASTE_CMD.scoped(WidgetId::named("input-1")));
52//! }
53//! # ; }
54//! ```
55//!
56//! # File List
57//!
58//! The example below modifies the paste button to paste file paths, the paths can be used to read or move
59//! the each file, in the example they are converted to a text list.
60//!
61//! ```
62//! use zng::prelude::*;
63//!
64//! # fn example() {
65//! # let txt = var(Txt::from(""));
66//! # let _ =
67//! Button! {
68//!     child = Text!("Paste");
69//!     on_click = hn!(|_| {
70//!         if let Ok(Some(f)) = zng::clipboard::CLIPBOARD.file_list() {
71//!             txt.modify(move |txt| {
72//!                 let txt = txt.to_mut();
73//!                 txt.clear();
74//!                 for f in f {
75//!                     use std::fmt::Write as _;
76//!                     let _ = writeln!(txt, "{}", f.display());
77//!                 }
78//!             });
79//!         }
80//!     });
81//! }
82//! # ; }
83//! ```
84//!
85//! # Image
86//!
87//! The example below pastes an image from the clipboard. The example also demonstrates how to separate the
88//! paste button from the paste action, the button only needs to know that the window handles the paste command,
89//! the window implements the paste by setting an image variable.
90//!
91//! ```
92//! use zng::clipboard;
93//! use zng::prelude::*;
94//!
95//! # let mut app = APP.defaults().run_headless(false);
96//! # app.doc_test_window(async {
97//! let img_source = var(ImageSource::flood(layout::PxSize::splat(layout::Px(1)), colors::BLACK, None));
98//! Window! {
99//!     # widget::on_init = hn_once!(|_| {WINDOW.close();});
100//!     child_top = Button!(clipboard::PASTE_CMD.scoped(WINDOW.id()));
101//!     child = Image!(img_source.clone());
102//!     clipboard::on_paste = hn!(|_| {
103//!         if let Ok(Some(img)) = clipboard::CLIPBOARD.image() {
104//!             img_source.set(img);
105//!         }
106//!     });
107//! }
108//! # });
109//! ```
110//!
111//! # Full API
112//!
113//! See [`zng_ext_clipboard`] for the full clipboard API.
114
115pub use zng_ext_clipboard::{CLIPBOARD, COPY_CMD, CUT_CMD, ClipboardError, PASTE_CMD};
116pub use zng_wgt_input::cmd::{can_copy, can_cut, can_paste, on_copy, on_cut, on_paste, on_pre_copy, on_pre_cut, on_pre_paste};