use crate::enums::shapes::PresetGeometry;
use crate::shapes::autoshape::AutoShape;
use crate::shapes::connector::Connector;
use crate::shapes::graphfrm::{self, GraphicFrame};
use crate::shapes::picture::Picture;
use crate::shapes::Shape;
use crate::units::Emu;
use super::GroupShape;
impl GroupShape {
pub fn add_textbox(&mut self, left: Emu, top: Emu, width: Emu, height: Emu) -> &mut Shape {
let shape_id = self.next_shape_id();
let count = self.count_shapes_with_prefix("TextBox") + 1;
let name = format!("TextBox {count}");
let shape = Shape::AutoShape(Box::new(AutoShape {
shape_id,
name,
left,
top,
width,
height,
rotation: 0.0,
prst_geom: Some(PresetGeometry::Rect),
is_textbox: true,
placeholder: None,
tx_body_xml: None,
fill: None,
line: None,
text_frame: None,
click_action: None,
hover_action: None,
adjustments: Vec::new(),
shadow: None,
custom_geometry: None,
scene_3d: None,
shape_3d: None,
}));
self.shapes.push(shape);
let idx = self.shapes.len() - 1;
&mut self.shapes[idx]
}
pub fn add_autoshape(
&mut self,
shape_type: &str,
left: Emu,
top: Emu,
width: Emu,
height: Emu,
) -> &mut Shape {
let shape_id = self.next_shape_id();
let base_name = shape_name_for_prst(shape_type);
let count = self.count_shapes_with_prefix(base_name) + 1;
let name = format!("{base_name} {count}");
let shape = Shape::AutoShape(Box::new(AutoShape {
shape_id,
name,
left,
top,
width,
height,
rotation: 0.0,
prst_geom: Some(PresetGeometry::from_xml_str(shape_type)),
is_textbox: false,
placeholder: None,
tx_body_xml: None,
fill: None,
line: None,
text_frame: None,
click_action: None,
hover_action: None,
adjustments: Vec::new(),
shadow: None,
custom_geometry: None,
scene_3d: None,
shape_3d: None,
}));
self.shapes.push(shape);
let idx = self.shapes.len() - 1;
&mut self.shapes[idx]
}
pub fn add_picture(
&mut self,
image_r_id: &str,
left: Emu,
top: Emu,
width: Emu,
height: Emu,
) -> &mut Shape {
let shape_id = self.next_shape_id();
let count = self.count_shapes_with_prefix("Picture") + 1;
let name = format!("Picture {count}");
let shape = Shape::Picture(Box::new(Picture {
shape_id,
name,
left,
top,
width,
height,
rotation: 0.0,
image_r_id: Some(image_r_id.to_string()),
description: None,
placeholder: None,
crop_left: 0.0,
crop_right: 0.0,
crop_top: 0.0,
crop_bottom: 0.0,
line: None,
click_action: None,
hover_action: None,
shadow: None,
auto_shape_type: None,
image_data: None,
image_content_type: None,
scene_3d: None,
shape_3d: None,
}));
self.shapes.push(shape);
let idx = self.shapes.len() - 1;
&mut self.shapes[idx]
}
pub fn add_connector(
&mut self,
connector_type: &str,
begin_x: Emu,
begin_y: Emu,
end_x: Emu,
end_y: Emu,
) -> &mut Shape {
let shape_id = self.next_shape_id();
let count = self.count_shapes_with_prefix("Connector") + 1;
let name = format!("Connector {count}");
let (left, width, flip_h) = if begin_x.0 <= end_x.0 {
(begin_x, Emu(end_x.0 - begin_x.0), false)
} else {
(end_x, Emu(begin_x.0 - end_x.0), true)
};
let (top, height, flip_v) = if begin_y.0 <= end_y.0 {
(begin_y, Emu(end_y.0 - begin_y.0), false)
} else {
(end_y, Emu(begin_y.0 - end_y.0), true)
};
let shape = Shape::Connector(Connector {
shape_id,
name,
left,
top,
width,
height,
rotation: 0.0,
flip_h,
flip_v,
prst_geom: Some(PresetGeometry::from_xml_str(connector_type)),
line: None,
begin_shape_id: None,
begin_cxn_idx: None,
end_shape_id: None,
end_cxn_idx: None,
});
self.shapes.push(shape);
let idx = self.shapes.len() - 1;
&mut self.shapes[idx]
}
pub fn add_table(
&mut self,
rows: usize,
_cols: usize,
left: Emu,
top: Emu,
width: Emu,
row_height: Emu,
) -> &mut Shape {
let shape_id = self.next_shape_id();
let count = self.count_shapes_with_prefix("Table") + 1;
let name = format!("Table {count}");
let height = Emu(row_height.0 * i64::try_from(rows).unwrap_or(i64::MAX));
let shape = Shape::GraphicFrame(Box::new(GraphicFrame {
shape_id,
name,
left,
top,
width,
height,
rotation: 0.0,
has_table: true,
has_chart: false,
graphic_data_uri: Some(graphfrm::graphic_data_uri::TABLE.to_string()),
placeholder: None,
smartart_r_id: None,
}));
self.shapes.push(shape);
let idx = self.shapes.len() - 1;
&mut self.shapes[idx]
}
pub fn add_group_shape(&mut self) -> &mut Shape {
let shape_id = self.next_shape_id();
let count = self.count_shapes_with_prefix("Group") + 1;
let name = format!("Group {count}");
let shape = Shape::GroupShape(Box::new(Self {
shape_id,
name,
left: Emu(0),
top: Emu(0),
width: Emu(0),
height: Emu(0),
rotation: 0.0,
shapes: Vec::new(),
}));
self.shapes.push(shape);
let idx = self.shapes.len() - 1;
&mut self.shapes[idx]
}
}
fn shape_name_for_prst(prst: &str) -> &'static str {
match prst {
"rect" => "Rectangle",
"roundRect" => "Rounded Rectangle",
"ellipse" => "Oval",
"diamond" => "Diamond",
"triangle" => "Isosceles Triangle",
"rtTriangle" => "Right Triangle",
"parallelogram" => "Parallelogram",
"trapezoid" => "Trapezoid",
"pentagon" => "Regular Pentagon",
"hexagon" => "Hexagon",
"octagon" => "Octagon",
"star4" => "4-Point Star",
"star5" => "5-Point Star",
"star6" => "6-Point Star",
"cloud" => "Cloud",
"heart" => "Heart",
"sun" => "Sun",
"moon" => "Moon",
"arc" => "Arc",
"donut" => "Donut",
"plus" => "Cross",
"can" => "Can",
"cube" => "Cube",
"frame" => "Frame",
"leftArrow" => "Left Arrow",
"rightArrow" => "Right Arrow",
"upArrow" => "Up Arrow",
"downArrow" => "Down Arrow",
_ => "Freeform",
}
}