use std::cell::RefCell;
use std::rc::Rc;
use crate::signal::Signal;
use crate::widget::EventContext;
use crate::widget_id::WidgetId;
pub trait TextSurface {
fn can_undo(&self) -> bool;
fn can_redo(&self) -> bool;
fn undo(&self);
fn redo(&self);
fn history_frozen(&self) -> bool {
false
}
fn has_selection(&self) -> bool;
fn is_read_only(&self) -> bool;
fn allows_copy(&self) -> bool;
fn cut(&self, ctx: &EventContext<'_>);
fn copy(&self, ctx: &EventContext<'_>);
fn paste(&self, ctx: &EventContext<'_>);
fn paste_plain(&self, ctx: &EventContext<'_>);
fn select_all(&self);
}
#[derive(Clone)]
pub struct TextSurfaces {
entries: Rc<RefCell<Vec<(WidgetId, Rc<dyn TextSurface>)>>>,
focused: Signal<Option<WidgetId>>,
}
impl std::fmt::Debug for TextSurfaces {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TextSurfaces")
.field("registered", &self.entries.borrow().len())
.field("focused_is_text", &self.focused_is_text_surface())
.finish()
}
}
impl TextSurfaces {
pub(crate) fn new(focused: Signal<Option<WidgetId>>) -> Self {
Self {
entries: Rc::new(RefCell::new(Vec::new())),
focused,
}
}
pub(crate) fn insert(&self, owner: WidgetId, surface: Rc<dyn TextSurface>) {
let mut entries = self.entries.borrow_mut();
entries.retain(|(id, _)| *id != owner);
entries.push((owner, surface));
}
pub(crate) fn remove(&self, owner: WidgetId) {
self.entries.borrow_mut().retain(|(id, _)| *id != owner);
}
pub fn focused(&self) -> Option<Rc<dyn TextSurface>> {
let focused = self.focused.get()?;
self.entries
.borrow()
.iter()
.find(|(id, _)| *id == focused)
.map(|(_, s)| Rc::clone(s))
}
pub fn focused_is_text_surface(&self) -> bool {
self.focused().is_some()
}
pub fn focus_signal(&self) -> Signal<Option<WidgetId>> {
self.focused.clone()
}
}