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.
78 lines
2.4 KiB
78 lines
2.4 KiB
pub mod file;
|
|
mod tags;
|
|
|
|
use std::collections::VecDeque;
|
|
use std::sync::{Arc, Mutex};
|
|
use tags::RangeState;
|
|
pub use tags::{BoundState, Format, TagEntry};
|
|
|
|
/// Main content buffer of a Novelist file
|
|
///
|
|
/// The content is a simple text buffer of UTF-8 strings. Formatting
|
|
/// tags are applied independently via the tags abstraction.
|
|
pub struct Buffer {
|
|
// TODO: how does mixed RTL and LTR text get handled here?
|
|
pub content: Mutex<String>,
|
|
pub tags: Mutex<VecDeque<TagEntry>>,
|
|
}
|
|
|
|
/// A glue trait to connect the storage buffer to a UI toolkit
|
|
pub trait PopulateBuffer {
|
|
/// Populate a UI text buffer from a storage buffer
|
|
fn populate(&self, buffer: &Buffer);
|
|
}
|
|
|
|
impl Buffer {
|
|
/// Create a new empty Buffer
|
|
pub fn new() -> Arc<Self> {
|
|
Arc::new(Self {
|
|
content: Mutex::new(String::new()),
|
|
tags: Mutex::new(vec![].into()),
|
|
})
|
|
}
|
|
|
|
/// Pass a UI buffer to populate from this storage buffer
|
|
pub fn populate_ui(self: &Arc<Self>, hook: &impl PopulateBuffer) {
|
|
hook.populate(self)
|
|
}
|
|
|
|
/// Toggle a style for a particular range of characters
|
|
///
|
|
/// This function MUST handle specific corner cases around
|
|
/// overlapping ranges.
|
|
///
|
|
/// Returns a set of styles that MUST be applied to the TextBuffer
|
|
pub fn toggle_style(
|
|
self: &Arc<Self>,
|
|
(start, end): (i32, i32),
|
|
style: Format,
|
|
) -> Vec<(i32, i32, Format)> {
|
|
// 1. Go through linked list and compare list-pos to new-pos
|
|
// 2. If NoOverlap, continue
|
|
// 3. If BeforeOverlap, expand start-number
|
|
// 4. If FullOverlap, ignore (return)
|
|
// 5. If AfterOverlap, expand end-number
|
|
// 6. If no match was found: insert && sort
|
|
|
|
// The action we would like to apply
|
|
let target = TagEntry { start, end, style };
|
|
|
|
// Lock existing tags and iterate through them
|
|
let mut tags = self.tags.lock().unwrap();
|
|
for entry in tags.iter_mut() {
|
|
// First perform a simple boundry check
|
|
match entry.in_range(&target) {
|
|
RangeState::Under => continue,
|
|
RangeState::Over => break,
|
|
RangeState::InRange => {},
|
|
}
|
|
|
|
// If full-overlap we invert the desired action
|
|
|
|
// Then handle before and after overlapjjjjjjtncthgki.iidukntxgbeubyx.ixptxddcdpexe
|
|
|
|
}
|
|
|
|
todo!()
|
|
}
|
|
}
|
|
|