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