View Javadoc

1   /**********************************************
2    * Copyright (C) 2009 Lukas Laag
3    * This file is part of Vectomatic.
4    * 
5    * Vectomatic is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * Vectomatic is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with Vectomatic.  If not, see http://www.gnu.org/licenses/
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   * Class to represent a group of shapes (composite
30   * design pattern)
31   */
32  public class ShapeGroup extends Shape implements IsSerializable {
33  	/**
34  	 * A List of palettes.
35  	 */
36  	protected List<Shape> _shapes;
37  	
38  	public ShapeGroup() {
39  		// For GWT serialization
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 }