1use crate::oxml::shape::Group as OxmlGroup;
24use crate::oxml::shape::GroupChild as OxmlGroupChild;
25use crate::shape::autoshape::AutoShape;
26use crate::shape::base::Shape;
27use crate::shape::connector::Connector;
28use crate::shape::picture::Picture;
29use crate::shape::table::TableShape;
30use crate::units::Emu;
31
32#[derive(Clone, Debug, Default)]
34pub struct Group {
35 pub(crate) group: OxmlGroup,
37}
38
39impl Group {
40 pub fn from_group(g: OxmlGroup) -> Self {
42 Group { group: g }
43 }
44 pub fn group(&self) -> &OxmlGroup {
46 &self.group
47 }
48 pub fn group_mut(&mut self) -> &mut OxmlGroup {
50 &mut self.group
51 }
52
53 pub fn children(&self) -> Vec<GroupChild> {
55 self.group
56 .children
57 .iter()
58 .map(|c| match c {
59 OxmlGroupChild::Sp(s) => GroupChild::Sp(AutoShape::from_sp(s.clone())),
60 OxmlGroupChild::Pic(p) => GroupChild::Pic(Picture::from_pic(p.clone())),
61 OxmlGroupChild::CxnSp(c) => GroupChild::Cx(Connector::from_cxn(c.clone())),
62 OxmlGroupChild::Group(g) => {
63 GroupChild::Grp(Box::new(Group::from_group((**g).clone())))
64 }
65 OxmlGroupChild::GraphicFrame(g) => {
68 GroupChild::Gfx(TableShape::from_frame(g.clone()))
69 }
70 })
71 .collect()
72 }
73
74 pub fn len(&self) -> usize {
76 self.group.children.len()
77 }
78 pub fn is_empty(&self) -> bool {
80 self.group.children.is_empty()
81 }
82
83 pub fn add_autoshape(&mut self, shape: AutoShape) -> &mut Self {
91 self.group
92 .children
93 .push(OxmlGroupChild::Sp(shape.sp.clone()));
94 self
95 }
96
97 pub fn add_picture(&mut self, pic: Picture) -> &mut Self {
99 self.group
100 .children
101 .push(OxmlGroupChild::Pic(pic.pic.clone()));
102 self
103 }
104
105 pub fn add_connector(&mut self, cxn: Connector) -> &mut Self {
107 self.group
108 .children
109 .push(OxmlGroupChild::CxnSp(cxn.cxn.clone()));
110 self
111 }
112
113 pub fn add_table(&mut self, table: TableShape) -> &mut Self {
115 self.group
116 .children
117 .push(OxmlGroupChild::GraphicFrame(table.frame.clone()));
118 self
119 }
120
121 pub fn add_group(&mut self, grp: Group) -> &mut Self {
123 self.group
124 .children
125 .push(OxmlGroupChild::Group(Box::new(grp.group.clone())));
126 self
127 }
128
129 pub fn remove_child(&mut self, id: u32) -> bool {
133 let pos = self.group.children.iter().position(|c| match c {
135 OxmlGroupChild::Sp(s) => s.id == id,
136 OxmlGroupChild::Pic(p) => p.id == id,
137 OxmlGroupChild::CxnSp(c) => c.id == id,
138 OxmlGroupChild::Group(g) => g.id == id,
139 OxmlGroupChild::GraphicFrame(g) => g.id == id,
140 });
141 if let Some(p) = pos {
142 self.group.children.remove(p);
143 return true;
144 }
145 for c in &mut self.group.children {
147 if let OxmlGroupChild::Group(g) = c {
148 let mut sub = Group::from_group((**g).clone());
149 if sub.remove_child(id) {
150 **g = sub.group;
151 return true;
152 }
153 }
154 }
155 false
156 }
157
158 pub fn clear(&mut self) {
160 self.group.children.clear();
161 }
162}
163
164#[derive(Clone, Debug)]
170pub enum GroupChild {
171 Sp(AutoShape),
173 Pic(Picture),
175 Cx(Connector),
177 Grp(Box<Group>),
179 Gfx(TableShape),
181}
182
183impl Shape for Group {
184 fn id(&self) -> u32 {
185 self.group.id
186 }
187 fn set_id(&mut self, id: u32) {
188 self.group.id = id;
189 }
190 fn name(&self) -> &str {
191 &self.group.name
192 }
193 fn set_name(&mut self, name: String) {
194 self.group.name = name;
195 }
196 fn shape_type(&self) -> &'static str {
197 "group"
198 }
199
200 fn left(&self) -> Emu {
201 Emu::new(self.group.off.0.value())
202 }
203 fn set_left(&mut self, emu: Emu) {
204 self.group.off.0 = emu;
205 }
206 fn top(&self) -> Emu {
207 Emu::new(self.group.off.1.value())
208 }
209 fn set_top(&mut self, emu: Emu) {
210 self.group.off.1 = emu;
211 }
212 fn width(&self) -> Emu {
213 Emu::new(self.group.ext.0.value())
214 }
215 fn set_width(&mut self, emu: Emu) {
216 self.group.ext.0 = emu;
217 }
218 fn height(&self) -> Emu {
219 Emu::new(self.group.ext.1.value())
220 }
221 fn set_height(&mut self, emu: Emu) {
222 self.group.ext.1 = emu;
223 }
224
225 fn rotation(&self) -> f64 {
226 self.group.properties.rot_deg.unwrap_or(0.0)
227 }
228 fn set_rotation(&mut self, deg: f64) {
229 self.group.properties.rot_deg = Some(deg);
230 let rot = (deg * 60_000.0) as i32;
231 self.group.properties.xfrm.rot = Some(rot);
232 }
233}