//! A text buffer abstraction //! //! Because of the separation between novelist-data and novelist-gtk //! the storage buffer can't rely on the Gtk buffer to fill data and //! set tag data. This module wraps this relationship use gtk4::{prelude::TextBufferExt, TextBuffer, TextTagTable}; use novelist_data::{Buffer, Format, PopulateBuffer, TagEntry}; use std::sync::Arc; pub struct GtkBuffer(TextBuffer); impl GtkBuffer { pub fn new(tb: TextBuffer) -> Self { Self(tb) } pub fn consume(self) -> TextBuffer { self.0 } } impl PopulateBuffer for GtkBuffer { fn populate(&self, storage: &Buffer) { let content = storage.content.lock().unwrap(); self.0.set_text(&content); storage .tags .lock() .unwrap() .iter() .for_each(|TagEntry { start, end, style }| { self.0.apply_tag_by_name( match style { Format::Bold => "bold", Format::Italics => "italics", _ => unimplemented!(), }, &self.0.iter_at_offset(*start), &self.0.iter_at_offset(*end), ) }) } } /// Create an empty text buffer pub fn empty(text_tag_table: &TextTagTable) -> TextBuffer { TextBuffer::new(Some(&text_tag_table)) } /// Load a text buffer from a store pub fn from_store(text_tag_table: &TextTagTable, buffer: &Arc) -> TextBuffer { let gtk_buffer = GtkBuffer(empty(text_tag_table)); buffer.populate_ui(>k_buffer); gtk_buffer.0 }