1use crate::oxml::shape::Sp as OxmlSp;
28use crate::oxml::simpletypes::PresetGeometry;
29use crate::oxml::txbody::{Paragraph, TextBody};
30use crate::shape::autoshape::AutoShape;
31use crate::shape::base::Shape;
32use crate::units::Emu;
33
34#[derive(Clone, Debug, Default)]
36pub struct TextBox {
37 pub(crate) shape: AutoShape,
39}
40
41impl TextBox {
42 pub fn new(name: impl Into<String>) -> Self {
44 let mut s = AutoShape::new(name, PresetGeometry::Rectangle);
45 s.sp_mut().text = TextBody::new();
47 TextBox { shape: s }
48 }
49
50 pub fn from_sp(sp: OxmlSp) -> Self {
52 TextBox {
53 shape: AutoShape::from_sp(sp),
54 }
55 }
56
57 pub fn text_frame(&self) -> &TextBody {
59 &self.shape.sp.text
60 }
61 pub fn text_frame_mut(&mut self) -> &mut TextBody {
63 &mut self.shape.sp_mut().text
64 }
65
66 pub fn set_text(&mut self, text: &str) -> &mut TextBody {
71 let tb = self.text_frame_mut();
72 tb.paragraphs.clear();
73 for line in text.split('\n') {
74 let mut p = Paragraph::new();
75 p.runs.push(crate::oxml::txbody::Run::new(line));
76 tb.paragraphs.push(p);
77 }
78 tb
79 }
80
81 pub fn text(&self) -> String {
83 let mut out = String::new();
84 let mut first = true;
85 for p in &self.text_frame().paragraphs {
86 if !first {
87 out.push('\n');
88 }
89 first = false;
90 for r in &p.runs {
91 out.push_str(&r.text);
92 }
93 }
94 out
95 }
96
97 pub fn set_word_wrap(&mut self, v: bool) {
99 self.text_frame_mut().set_word_wrap(v);
100 }
101
102 pub fn set_auto_size(&mut self, v: crate::oxml::simpletypes::MsoAutoSize) {
104 self.text_frame_mut().set_auto_size(v);
105 }
106
107 pub fn set_vertical_anchor(&mut self, v: crate::oxml::simpletypes::MsoAnchor) {
109 self.text_frame_mut().set_vertical_anchor(v);
110 }
111
112 pub fn set_outer_shadow(&mut self, shadow: crate::oxml::sppr::ShadowEffect) {
121 self.shape.set_outer_shadow(shadow);
122 }
123
124 pub fn set_inner_shadow(&mut self, shadow: crate::oxml::sppr::ShadowEffect) {
126 self.shape.set_inner_shadow(shadow);
127 }
128
129 pub fn set_glow(&mut self, glow: crate::oxml::sppr::GlowEffect) {
131 self.shape.set_glow(glow);
132 }
133
134 pub fn set_soft_edge(&mut self, rad: i64) {
136 self.shape.set_soft_edge(rad);
137 }
138
139 pub fn set_reflection(&mut self, reflection: crate::oxml::sppr::ReflectionEffect) {
141 self.shape.set_reflection(reflection);
142 }
143
144 pub fn clear_effects(&mut self) {
146 self.shape.clear_effects();
147 }
148
149 pub fn set_3d_rotation(&mut self, lat_deg: f64, lon_deg: f64, rev_deg: f64) {
151 self.shape.set_3d_rotation(lat_deg, lon_deg, rev_deg);
152 }
153
154 pub fn set_3d_extrusion(&mut self, height_emu: i32, color: Option<crate::oxml::color::Color>) {
156 self.shape.set_3d_extrusion(height_emu, color);
157 }
158
159 pub fn set_3d_bevel(&mut self, top_w: i32, top_h: i32, bottom_w: i32, bottom_h: i32) {
161 self.shape.set_3d_bevel(top_w, top_h, bottom_w, bottom_h);
162 }
163
164 pub fn set_3d_material(&mut self, material: crate::oxml::sppr::MaterialPreset) {
166 self.shape.set_3d_material(material);
167 }
168
169 pub fn clear_3d(&mut self) {
171 self.shape.clear_3d();
172 }
173
174 pub fn scene_3d(&self) -> Option<&crate::oxml::sppr::Scene3d> {
176 self.shape.scene_3d()
177 }
178
179 pub fn scene_3d_mut(&mut self) -> &mut Option<crate::oxml::sppr::Scene3d> {
181 self.shape.scene_3d_mut()
182 }
183
184 pub fn sp_3d(&self) -> Option<&crate::oxml::sppr::Sp3d> {
186 self.shape.sp_3d()
187 }
188
189 pub fn sp_3d_mut(&mut self) -> &mut Option<crate::oxml::sppr::Sp3d> {
191 self.shape.sp_3d_mut()
192 }
193
194 pub fn locks(&self) -> Option<&crate::oxml::shape::ShapeLocks> {
196 self.shape.locks()
197 }
198
199 pub fn locks_mut(&mut self) -> &mut crate::oxml::shape::ShapeLocks {
201 self.shape.locks_mut()
202 }
203
204 pub fn lock_select(&mut self, locked: bool) {
206 self.shape.lock_select(locked);
207 }
208
209 pub fn lock_move(&mut self, locked: bool) {
211 self.shape.lock_move(locked);
212 }
213
214 pub fn lock_resize(&mut self, locked: bool) {
216 self.shape.lock_resize(locked);
217 }
218
219 pub fn lock_rotate(&mut self, locked: bool) {
221 self.shape.lock_rotate(locked);
222 }
223
224 pub fn lock_group(&mut self, locked: bool) {
226 self.shape.lock_group(locked);
227 }
228
229 pub fn clear_locks(&mut self) {
231 self.shape.clear_locks();
232 }
233
234 pub fn set_lock(&mut self, lock_type: crate::oxml::shape::LockType, locked: bool) {
237 self.shape.set_lock(lock_type, locked);
238 }
239
240 pub fn style(&self) -> Option<&crate::oxml::shape::ShapeStyle> {
242 self.shape.style()
243 }
244
245 pub fn set_style(&mut self, style: crate::oxml::shape::ShapeStyle) {
247 self.shape.set_style(style);
248 }
249
250 pub fn clear_style(&mut self) {
252 self.shape.clear_style();
253 }
254}
255
256impl Shape for TextBox {
257 fn id(&self) -> u32 {
258 self.shape.id()
259 }
260 fn set_id(&mut self, id: u32) {
261 self.shape.set_id(id);
262 }
263 fn name(&self) -> &str {
264 self.shape.name()
265 }
266 fn set_name(&mut self, name: String) {
267 self.shape.set_name(name);
268 }
269 fn shape_type(&self) -> &'static str {
270 "text_box"
271 }
272
273 fn left(&self) -> Emu {
274 self.shape.left()
275 }
276 fn set_left(&mut self, emu: Emu) {
277 self.shape.set_left(emu);
278 }
279 fn top(&self) -> Emu {
280 self.shape.top()
281 }
282 fn set_top(&mut self, emu: Emu) {
283 self.shape.set_top(emu);
284 }
285 fn width(&self) -> Emu {
286 self.shape.width()
287 }
288 fn set_width(&mut self, emu: Emu) {
289 self.shape.set_width(emu);
290 }
291 fn height(&self) -> Emu {
292 self.shape.height()
293 }
294 fn set_height(&mut self, emu: Emu) {
295 self.shape.set_height(emu);
296 }
297
298 fn rotation(&self) -> f64 {
299 self.shape.rotation()
300 }
301 fn set_rotation(&mut self, deg: f64) {
302 self.shape.set_rotation(deg);
303 }
304}