1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.common.model.geometry;
19
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import org.vectomatic.common.model.IShapeVisitor;
24 import org.vectomatic.common.model.Shape;
25
26 import com.google.gwt.user.client.rpc.IsSerializable;
27
28
29
30
31
32 public class ShapeGroup extends Shape implements IsSerializable {
33
34
35
36 protected List<Shape> _shapes;
37
38 public ShapeGroup() {
39
40 }
41 public ShapeGroup(List<Shape> shapes) {
42 super();
43 _bbox = new BoundingBox();
44 _shapes = new ArrayList<Shape>(shapes);
45 updateGroup();
46 }
47
48 public ShapeGroup(ShapeGroup group) {
49 super(group);
50 _shapes = group._shapes;
51 }
52
53 @Override
54 public String toString() {
55 StringBuffer buffer = new StringBuffer();
56 buffer.append("Group(m=");
57 buffer.append(getTransform().toString());
58 buffer.append(" members={");
59 buffer.append(_shapes.toString());
60 buffer.append("} atts=");
61 buffer.append(_attributes.toString());
62 buffer.append(")");
63 return buffer.toString();
64 }
65
66
67 @Override
68 public boolean isSame(Shape shape) {
69 if (shape instanceof ShapeGroup) {
70 ShapeGroup group = (ShapeGroup)shape;
71 if (getTransform().equals(group.getTransform())
72 && _shapes.size() == group._shapes.size()
73 && _attributes.equals(group._attributes)) {
74 for (int i = 0, size = _shapes.size(); i < size; i++) {
75 Shape shape1 = _shapes.get(i);
76 Shape shape2 = _shapes.get(i);
77 if (!shape1.isSame(shape2)) {
78 return false;
79 }
80 }
81 return true;
82 }
83 }
84 return false;
85 }
86
87 public void updateGroup() {
88 Point p = new Point();
89 if (_shapes.size() > 0) {
90 _bbox.xmin = _bbox.ymin = Float.MAX_VALUE;
91 _bbox.xmax = _bbox.ymax = -Float.MAX_VALUE;
92 for (int i = 0, size = _shapes.size(); i < size; i++) {
93 Shape shape = _shapes.get(i);
94 for (int j = BoundingBox.PT_NW; j <= BoundingBox.PT_NE; j++) {
95 shape.getBoundingBox().getPoint(j, p).transform(shape.getTransform());
96 if (p.x < _bbox.xmin) {
97 _bbox.xmin = p.x;
98 }
99 if (p.x > _bbox.xmax) {
100 _bbox.xmax = p.x;
101 }
102 if (p.y < _bbox.ymin) {
103 _bbox.ymin = p.y;
104 }
105 if (p.y > _bbox.ymax) {
106 _bbox.ymax = p.y;
107 }
108 }
109 }
110 _bbox.getPoint(BoundingBox.PT_C, p);
111 } else {
112 Point.ZERO.copyTo(p);
113 }
114 setScaling(Point.UNIT);
115 setRotation(0f);
116 setTranslation(p);
117 }
118
119 @Override
120 public void acceptVisitor(IShapeVisitor visitor) {
121 visitor.visitShapeGroup(this);
122 }
123
124 public List<Shape> getShapes() {
125 return _shapes;
126 }
127 public void setShapes(List<Shape> shapes) {
128 _shapes = shapes;
129 updateGroup();
130 }
131
132 public boolean containsRotatedShape() {
133 for (int i = 0, size = _shapes.size(); i < size; i++) {
134 Shape shape = _shapes.get(i);
135 if (shape.getRotation() != 0f) {
136 return true;
137 }
138 if (shape instanceof ShapeGroup && ((ShapeGroup)shape).containsRotatedShape()) {
139 return true;
140 }
141 }
142 return false;
143 }
144 }