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 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}