text_document/
frame.rs

1use crate::format::FormatChangeResult;
2use crate::text_document::{Element, ElementManager, ElementTrait, ModelError};
3use std::cell::Cell;
4use std::cell::RefCell;
5use std::rc::Weak;
6
7use crate::format::FormattedElement;
8use crate::format::FrameFormat;
9use crate::format::IsFormat;
10
11#[derive(Clone, Debug)]
12pub struct Frame {
13    uuid: Cell<usize>,
14    element_manager: Weak<ElementManager>,
15    /// Describes frame-specific properties
16    frame_format: RefCell<FrameFormat>,
17}
18
19impl PartialEq for Frame {
20    fn eq(&self, other: &Self) -> bool {
21        self.uuid == other.uuid && self.frame_format == other.frame_format
22    }
23}
24
25impl Frame {
26    pub(crate) fn new(element_manager: Weak<ElementManager>) -> Self {
27        Frame {
28            element_manager,
29            uuid: Default::default(),
30            frame_format: RefCell::new(FrameFormat {
31                ..Default::default()
32            }),
33        }
34    }
35
36    pub fn uuid(&self) -> usize {
37        self.uuid.get()
38    }
39
40    pub fn frame_format(&self) -> FrameFormat {
41        self.format()
42    }
43
44    pub fn first_cursor_position(&self) -> usize {
45        let element_manager = self.element_manager.upgrade().unwrap();
46        element_manager
47            .next_element(self.uuid())
48            .unwrap()
49            .start_of_element()
50    }
51
52    pub fn list_all_direct_children(&self) -> Vec<Element> {
53        let element_manager = self.element_manager.upgrade().unwrap();
54        element_manager.list_all_direct_children(self.uuid())
55    }
56
57    pub fn list_all_children(&self) -> Vec<Element> {
58        let element_manager = self.element_manager.upgrade().unwrap();
59        element_manager.list_all_children(self.uuid())
60    }
61
62    pub fn text_length(&self) -> usize {
63        let char_count: usize = self
64            .list_all_direct_children()
65            .iter()
66            .map(|element| -> usize {
67                match element {
68                    Element::FrameElement(frame) => frame.text_length() + 1,
69                    Element::BlockElement(block) => block.text_length() + 1,
70                    _ => 0,
71                }
72            })
73            .sum();
74
75        char_count - 1
76    }
77
78    pub fn start(&self) -> usize {
79        self.first_cursor_position()
80    }
81
82    pub fn end(&self) -> usize {
83        self.start() + self.text_length()
84    }
85}
86
87impl ElementTrait for Frame {
88    fn set_uuid(&self, uuid: usize) {
89        self.uuid.set(uuid);
90    }
91
92    fn verify_rule_with_parent(&self, parent_element: &Element) -> Result<(), ModelError> {
93        match parent_element {
94            Element::FrameElement(_) => Ok(()),
95            Element::BlockElement(_) => Err(ModelError::WrongParent),
96            Element::TextElement(_) => Err(ModelError::WrongParent),
97            Element::ImageElement(_) => Err(ModelError::WrongParent),
98        }
99    }
100}
101
102impl FormattedElement<FrameFormat> for Frame {
103    fn format(&self) -> FrameFormat {
104        self.frame_format.borrow().clone()
105    }
106    fn set_format(&self, format: &FrameFormat) -> FormatChangeResult {
107        if &*self.frame_format.borrow() == format {
108            Ok(None)
109        } else {
110            self.frame_format.replace(format.clone());
111            Ok(Some(()))
112        }
113    }
114
115    fn merge_format(&self, format: &FrameFormat) -> Result<Option<()>, ModelError> {
116        self.frame_format.borrow_mut().merge_with(format)
117    }
118}