use zenith_core::{Diagnostic, Document, Node, Point};
use crate::op::OpPoint;
use super::{find_node_any_mut, node_kind_str, px, record_affected};
fn node_visible_mut(node: &mut Node) -> Option<&mut Option<bool>> {
match node {
Node::Rect(n) => Some(&mut n.visible),
Node::Ellipse(n) => Some(&mut n.visible),
Node::Line(n) => Some(&mut n.visible),
Node::Text(n) => Some(&mut n.visible),
Node::Code(n) => Some(&mut n.visible),
Node::Frame(n) => Some(&mut n.visible),
Node::Group(n) => Some(&mut n.visible),
Node::Image(n) => Some(&mut n.visible),
Node::Polygon(n) => Some(&mut n.visible),
Node::Polyline(n) => Some(&mut n.visible),
Node::Instance(n) => Some(&mut n.visible),
Node::Field(n) => Some(&mut n.visible),
Node::Toc(n) => Some(&mut n.visible),
Node::Table(n) => Some(&mut n.visible),
Node::Shape(n) => Some(&mut n.visible),
Node::Connector(n) => Some(&mut n.visible),
Node::Pattern(n) => Some(&mut n.visible),
Node::Chart(n) => Some(&mut n.visible),
Node::Footnote(_) => None,
Node::Unknown(_) => None,
}
}
fn node_locked_mut(node: &mut Node) -> Option<&mut Option<bool>> {
match node {
Node::Rect(n) => Some(&mut n.locked),
Node::Ellipse(n) => Some(&mut n.locked),
Node::Line(n) => Some(&mut n.locked),
Node::Text(n) => Some(&mut n.locked),
Node::Code(n) => Some(&mut n.locked),
Node::Frame(n) => Some(&mut n.locked),
Node::Group(n) => Some(&mut n.locked),
Node::Image(n) => Some(&mut n.locked),
Node::Polygon(n) => Some(&mut n.locked),
Node::Polyline(n) => Some(&mut n.locked),
Node::Instance(n) => Some(&mut n.locked),
Node::Field(n) => Some(&mut n.locked),
Node::Toc(n) => Some(&mut n.locked),
Node::Table(n) => Some(&mut n.locked),
Node::Shape(n) => Some(&mut n.locked),
Node::Connector(n) => Some(&mut n.locked),
Node::Pattern(n) => Some(&mut n.locked),
Node::Chart(n) => Some(&mut n.locked),
Node::Footnote(_) => None,
Node::Unknown(_) => None,
}
}
fn node_points_mut(node: &mut Node) -> Option<&mut Vec<Point>> {
match node {
Node::Polygon(p) => Some(&mut p.points),
Node::Polyline(p) => Some(&mut p.points),
Node::Rect(_)
| Node::Ellipse(_)
| Node::Line(_)
| Node::Text(_)
| Node::Code(_)
| Node::Frame(_)
| Node::Group(_)
| Node::Image(_)
| Node::Instance(_)
| Node::Field(_)
| Node::Footnote(_)
| Node::Toc(_)
| Node::Table(_)
| Node::Shape(_)
| Node::Connector(_)
| Node::Pattern(_)
| Node::Chart(_)
| Node::Unknown(_) => None,
}
}
fn apply_set_bool_field(
node_id: &str,
value: bool,
op_label: &str,
accessor: fn(&mut Node) -> Option<&mut Option<bool>>,
doc: &mut Document,
diagnostics: &mut Vec<Diagnostic>,
affected: &mut Vec<String>,
) {
match find_node_any_mut(doc, node_id) {
None => {
diagnostics.push(Diagnostic::error(
"tx.unknown_node",
format!("node {:?} not found in document", node_id),
None,
Some(node_id.to_owned()),
));
}
Some(node) => {
let kind = node_kind_str(node);
match accessor(node) {
Some(slot) => {
*slot = Some(value);
record_affected(node_id, affected);
}
None => {
diagnostics.push(Diagnostic::error(
"tx.unsupported_property",
format!("{} is not supported on a {} node", op_label, kind),
None,
Some(node_id.to_owned()),
));
}
}
}
}
}
pub(super) fn apply_set_visible(
node_id: &str,
visible: bool,
doc: &mut Document,
diagnostics: &mut Vec<Diagnostic>,
affected: &mut Vec<String>,
) {
apply_set_bool_field(
node_id,
visible,
"set_visible",
node_visible_mut,
doc,
diagnostics,
affected,
);
}
pub(super) fn apply_set_locked(
node_id: &str,
locked: bool,
doc: &mut Document,
diagnostics: &mut Vec<Diagnostic>,
affected: &mut Vec<String>,
) {
apply_set_bool_field(
node_id,
locked,
"set_locked",
node_locked_mut,
doc,
diagnostics,
affected,
);
}
pub(super) fn apply_set_points(
node_id: &str,
points: &[OpPoint],
doc: &mut Document,
diagnostics: &mut Vec<Diagnostic>,
affected: &mut Vec<String>,
) {
match find_node_any_mut(doc, node_id) {
None => {
diagnostics.push(Diagnostic::error(
"tx.unknown_node",
format!("node {:?} not found in document", node_id),
None,
Some(node_id.to_owned()),
));
}
Some(node) => {
let kind = node_kind_str(node);
match node_points_mut(node) {
None => {
diagnostics.push(Diagnostic::error(
"tx.unsupported_property",
format!("set_points is not supported on a {} node", kind),
None,
Some(node_id.to_owned()),
));
}
Some(pts) => {
*pts = points
.iter()
.map(|p| Point {
x: Some(px(p.x)),
y: Some(px(p.y)),
})
.collect();
record_affected(node_id, affected);
}
}
}
}
}