My personal project and infrastructure archive
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
nomicon/prototypes/novelist/novelist-gtk/src/text_buffer.rs

57 lines
1.6 KiB

//! 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<Buffer>) -> TextBuffer {
let gtk_buffer = GtkBuffer(empty(text_tag_table));
buffer.populate_ui(&gtk_buffer);
gtk_buffer.0
}