use std::time::Duration;
use super::Engine;
use crate::event::Event;
use crate::runtime::App;
use crate::runtime::clipboard::{ClipboardEvent, ReadStep};
pub(super) enum ClipboardRead<Msg> {
Paste,
Message(Box<dyn FnOnce(Option<String>) -> Msg>),
Probe,
}
impl<A: App> Engine<A> {
pub(super) fn paste(&mut self, text: String, now: Duration) {
let targets = self.keyboard_targets();
self.dirty = true;
if self.dispatch(&targets, &Event::Paste(text.clone()), now).is_none()
&& let Some(message) = self.app.clipboard(&ClipboardEvent::Pasted(text))
{
self.update(message);
}
}
pub(super) fn store_copy(&mut self, text: String) {
self.clipboard_text = Some(text.clone());
self.clipboard.push(text);
self.interaction.can_paste = true;
}
pub(super) fn read_clipboard(&mut self, read: ClipboardRead<A::Msg>, now: Duration) {
self.clipboard_reads.push(read);
if self.clipboard_reader.is_reading() {
return;
}
let step = self.clipboard_reader.start();
self.clipboard_step(step, now);
}
pub(super) fn clipboard_step(&mut self, step: ReadStep, now: Duration) {
match step {
ReadStep::Waiting => {}
ReadStep::AskTerminal => self.terminal_query = true,
ReadStep::Done(text) => self.finish_clipboard(text, now),
}
}
pub(crate) fn poll_clipboard(&mut self, now: Duration) {
if self.clipboard_reader.is_reading() {
let step = self.clipboard_reader.poll();
self.clipboard_step(step, now);
}
}
pub(crate) fn terminal_clipboard(&mut self, text: Option<String>, now: Duration) {
let step = self.clipboard_reader.terminal_answer(text);
self.clipboard_step(step, now);
}
pub(super) fn finish_clipboard(&mut self, text: Option<String>, now: Duration) {
let text = text.or_else(|| self.clipboard_text.clone());
self.interaction.can_paste = text.is_some();
self.dirty = true;
for read in std::mem::take(&mut self.clipboard_reads) {
match read {
ClipboardRead::Paste => {
if let Some(text) = &text {
self.paste(text.clone(), now);
}
}
ClipboardRead::Message(message) => {
let message = message(text.clone());
self.update(message);
}
ClipboardRead::Probe => {}
}
}
}
pub(super) fn copy_from_ui(&mut self, text: String) {
self.store_copy(text.clone());
if let Some(message) = self.app.clipboard(&ClipboardEvent::Copied(text)) {
self.update(message);
}
}
}