use hjkl_clipboard::{Capabilities, Clipboard, MimeType, Selection};
use hjkl_engine::{CursorShape, Host, Viewport};
use std::time::Instant;
pub struct TuiHost {
last_cursor_shape: CursorShape,
started: Instant,
cancel: bool,
clipboard: Option<Clipboard>,
viewport: Viewport,
}
impl TuiHost {
pub fn new() -> Self {
Self {
last_cursor_shape: CursorShape::Block,
started: Instant::now(),
cancel: false,
clipboard: Clipboard::new().ok(),
viewport: Viewport {
top_row: 0,
top_col: 0,
width: 80,
height: 24,
..Viewport::default()
},
}
}
#[allow(dead_code)] pub fn cursor_shape(&self) -> CursorShape {
self.last_cursor_shape
}
#[allow(dead_code)] pub fn set_cancel(&mut self, cancel: bool) {
self.cancel = cancel;
}
pub fn clipboard(&self) -> Option<&Clipboard> {
self.clipboard.as_ref()
}
}
impl Default for TuiHost {
fn default() -> Self {
Self::new()
}
}
impl Host for TuiHost {
type Intent = ();
fn write_clipboard(&mut self, text: String) {
if let Some(cb) = &self.clipboard
&& cb.capabilities().contains(Capabilities::WRITE)
{
let _ = cb.set(Selection::Clipboard, MimeType::Text, text.as_bytes());
}
}
fn read_clipboard(&mut self) -> Option<String> {
let cb = self.clipboard.as_ref()?;
if !cb.capabilities().contains(Capabilities::READ) {
return None;
}
let bytes = cb.get(Selection::Clipboard, MimeType::Text).ok()?;
String::from_utf8(bytes).ok()
}
fn now(&self) -> std::time::Duration {
self.started.elapsed()
}
fn should_cancel(&self) -> bool {
self.cancel
}
fn prompt_search(&mut self) -> Option<String> {
None
}
fn emit_cursor_shape(&mut self, shape: CursorShape) {
self.last_cursor_shape = shape;
}
fn emit_intent(&mut self, _intent: Self::Intent) {
}
fn viewport(&self) -> &Viewport {
&self.viewport
}
fn viewport_mut(&mut self) -> &mut Viewport {
&mut self.viewport
}
}