fixup! refactor(core): prepare for non mutable paint function

mmilata/non-mut-paint
Martin Milata 2 months ago
parent 4472a363ea
commit c9d959d856

@ -11,11 +11,9 @@ use super::{
op::OpTextLayout, op::OpTextLayout,
}; };
use core::cell::RefCell;
#[derive(Clone)] #[derive(Clone)]
pub struct FormattedText<T: StringType + Clone> { pub struct FormattedText<T: StringType + Clone> {
op_layout: RefCell<OpTextLayout<T>>, op_layout: OpTextLayout<T>,
vertical: Alignment, vertical: Alignment,
char_offset: usize, char_offset: usize,
y_offset: i16, y_offset: i16,
@ -24,7 +22,7 @@ pub struct FormattedText<T: StringType + Clone> {
impl<T: StringType + Clone> FormattedText<T> { impl<T: StringType + Clone> FormattedText<T> {
pub fn new(op_layout: OpTextLayout<T>) -> Self { pub fn new(op_layout: OpTextLayout<T>) -> Self {
Self { Self {
op_layout: RefCell::new(op_layout), op_layout,
vertical: Alignment::Start, vertical: Alignment::Start,
char_offset: 0, char_offset: 0,
y_offset: 0, y_offset: 0,
@ -36,14 +34,13 @@ impl<T: StringType + Clone> FormattedText<T> {
self self
} }
fn layout_content(&self, sink: &mut dyn LayoutSink) -> LayoutFit { pub(crate) fn layout_content(&self, sink: &mut dyn LayoutSink) -> LayoutFit {
self.op_layout self.op_layout
.borrow_mut()
.layout_ops(self.char_offset, Offset::y(self.y_offset), sink) .layout_ops(self.char_offset, Offset::y(self.y_offset), sink)
} }
fn align_vertically(&mut self, content_height: i16) { fn align_vertically(&mut self, content_height: i16) {
let bounds_height = self.op_layout.borrow().layout.bounds.height(); let bounds_height = self.op_layout.layout.bounds.height();
if content_height >= bounds_height { if content_height >= bounds_height {
self.y_offset = 0; self.y_offset = 0;
return; return;
@ -125,7 +122,7 @@ impl<T: StringType + Clone> Component for FormattedText<T> {
type Msg = Never; type Msg = Never;
fn place(&mut self, bounds: Rect) -> Rect { fn place(&mut self, bounds: Rect) -> Rect {
self.op_layout.borrow_mut().place(bounds); self.op_layout.place(bounds);
let height = self.layout_content(&mut TextNoOp).height(); let height = self.layout_content(&mut TextNoOp).height();
self.align_vertically(height); self.align_vertically(height);
bounds bounds
@ -141,27 +138,12 @@ impl<T: StringType + Clone> Component for FormattedText<T> {
#[cfg(feature = "ui_bounds")] #[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) { fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
sink(self.op_layout.borrow().layout.bounds) sink(self.op_layout.layout.bounds)
} }
} }
// DEBUG-ONLY SECTION BELOW // DEBUG-ONLY SECTION BELOW
#[cfg(feature = "ui_debug")]
impl<T: StringType + Clone> FormattedText<T> {
/// Is the same as layout_content, but does not use `&mut self`
/// to be compatible with `trace`.
/// Therefore it has to do the `clone` of `op_layout`.
pub fn layout_content_debug(&self, sink: &mut dyn LayoutSink) -> LayoutFit {
// TODO: how to solve it "properly", without the `clone`?
// (changing `trace` to `&mut self` had some other isses...)
self.op_layout
.borrow()
.clone()
.layout_content(self.char_offset, sink)
}
}
#[cfg(feature = "ui_debug")] #[cfg(feature = "ui_debug")]
impl<T: StringType + Clone> crate::trace::Trace for FormattedText<T> { impl<T: StringType + Clone> crate::trace::Trace for FormattedText<T> {
fn trace(&self, t: &mut dyn crate::trace::Tracer) { fn trace(&self, t: &mut dyn crate::trace::Tracer) {
@ -170,7 +152,7 @@ impl<T: StringType + Clone> crate::trace::Trace for FormattedText<T> {
let fit: Cell<Option<LayoutFit>> = Cell::new(None); let fit: Cell<Option<LayoutFit>> = Cell::new(None);
t.component("FormattedText"); t.component("FormattedText");
t.in_list("text", &|l| { t.in_list("text", &|l| {
let result = self.layout_content_debug(&mut TraceSink(l)); let result = self.layout_content(&mut TraceSink(l));
fit.set(Some(result)); fit.set(Some(result));
}); });
t.bool("fits", matches!(fit.get(), Some(LayoutFit::Fitting { .. }))); t.bool("fits", matches!(fit.get(), Some(LayoutFit::Fitting { .. })));

@ -56,7 +56,7 @@ impl<'a, T: StringType + Clone + 'a> OpTextLayout<T> {
/// Perform some operations defined on `Op` for a list of those `Op`s /// Perform some operations defined on `Op` for a list of those `Op`s
/// - e.g. changing the color, changing the font or rendering the text. /// - e.g. changing the color, changing the font or rendering the text.
pub fn layout_ops( pub fn layout_ops(
&mut self, &self,
skip_bytes: usize, skip_bytes: usize,
offset: Offset, offset: Offset,
sink: &mut dyn LayoutSink, sink: &mut dyn LayoutSink,
@ -65,25 +65,26 @@ impl<'a, T: StringType + Clone + 'a> OpTextLayout<T> {
let cursor = &mut (self.layout.initial_cursor() + offset); let cursor = &mut (self.layout.initial_cursor() + offset);
let init_cursor = *cursor; let init_cursor = *cursor;
let mut total_processed_chars = 0; let mut total_processed_chars = 0;
let mut layout = self.layout;
// Do something when it was not skipped // Do something when it was not skipped
for op in Self::filter_skipped_ops(self.ops.iter(), skip_bytes) { for op in Self::filter_skipped_ops(self.ops.iter(), skip_bytes) {
match op { match op {
// Changing color // Changing color
Op::Color(color) => { Op::Color(color) => {
self.layout.style.text_color = color; layout.style.text_color = color;
} }
// Changing font // Changing font
Op::Font(font) => { Op::Font(font) => {
self.layout.style.text_font = font; layout.style.text_font = font;
} }
// Changing line/text alignment // Changing line/text alignment
Op::Alignment(line_alignment) => { Op::Alignment(line_alignment) => {
self.layout.align = line_alignment; layout.align = line_alignment;
} }
// Changing line breaking // Changing line breaking
Op::LineBreaking(line_breaking) => { Op::LineBreaking(line_breaking) => {
self.layout.style.line_breaking = line_breaking; layout.style.line_breaking = line_breaking;
} }
// Moving the cursor // Moving the cursor
Op::CursorOffset(offset) => { Op::CursorOffset(offset) => {
@ -91,10 +92,10 @@ impl<'a, T: StringType + Clone + 'a> OpTextLayout<T> {
cursor.y += offset.y; cursor.y += offset.y;
} }
Op::Chunkify(chunks) => { Op::Chunkify(chunks) => {
self.layout.style.chunks = chunks; layout.style.chunks = chunks;
} }
Op::LineSpacing(line_spacing) => { Op::LineSpacing(line_spacing) => {
self.layout.style.line_spacing = line_spacing; layout.style.line_spacing = line_spacing;
} }
// Moving to the next page // Moving to the next page
Op::NextPage => { Op::NextPage => {
@ -103,7 +104,7 @@ impl<'a, T: StringType + Clone + 'a> OpTextLayout<T> {
total_processed_chars += PROCESSED_CHARS_ONE; total_processed_chars += PROCESSED_CHARS_ONE;
return LayoutFit::OutOfBounds { return LayoutFit::OutOfBounds {
processed_chars: total_processed_chars, processed_chars: total_processed_chars,
height: self.layout.layout_height(init_cursor, *cursor), height: layout.layout_height(init_cursor, *cursor),
}; };
} }
// Drawing text // Drawing text
@ -113,9 +114,9 @@ impl<'a, T: StringType + Clone + 'a> OpTextLayout<T> {
// Inserting the ellipsis at the very beginning of the text if needed // Inserting the ellipsis at the very beginning of the text if needed
// (just for incomplete texts that were separated) // (just for incomplete texts that were separated)
self.layout.continues_from_prev_page = continued; layout.continues_from_prev_page = continued;
let fit = self.layout.layout_text(text.as_ref(), cursor, sink); let fit = layout.layout_text(text.as_ref(), cursor, sink);
match fit { match fit {
LayoutFit::Fitting { LayoutFit::Fitting {
@ -130,7 +131,7 @@ impl<'a, T: StringType + Clone + 'a> OpTextLayout<T> {
return LayoutFit::OutOfBounds { return LayoutFit::OutOfBounds {
processed_chars: total_processed_chars, processed_chars: total_processed_chars,
height: self.layout.layout_height(init_cursor, *cursor), height: layout.layout_height(init_cursor, *cursor),
}; };
} }
} }
@ -140,7 +141,7 @@ impl<'a, T: StringType + Clone + 'a> OpTextLayout<T> {
LayoutFit::Fitting { LayoutFit::Fitting {
processed_chars: total_processed_chars, processed_chars: total_processed_chars,
height: self.layout.layout_height(init_cursor, *cursor), height: layout.layout_height(init_cursor, *cursor),
} }
} }

@ -243,7 +243,7 @@ where
t.int("active_page", self.current_page as i64); t.int("active_page", self.current_page as i64);
t.int("page_count", self.page_count as i64); t.int("page_count", self.page_count as i64);
t.in_list("text", &|l| { t.in_list("text", &|l| {
let result = self.formatted.layout_content_debug(&mut TraceSink(l)); let result = self.formatted.layout_content(&mut TraceSink(l));
fit.set(Some(result)); fit.set(Some(result));
}); });
} }

Loading…
Cancel
Save