1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.svg.edit.client;
19
20 import org.vectomatic.dom.svg.OMSVGGElement;
21 import org.vectomatic.dom.svg.OMSVGMatrix;
22 import org.vectomatic.dom.svg.OMSVGPoint;
23 import org.vectomatic.dom.svg.OMSVGRect;
24 import org.vectomatic.dom.svg.OMSVGSVGElement;
25 import org.vectomatic.dom.svg.OMSVGTransform;
26 import org.vectomatic.dom.svg.OMSVGTransformList;
27 import org.vectomatic.dom.svg.ui.SVGImage;
28 import org.vectomatic.dom.svg.utils.OMSVGParser;
29 import org.vectomatic.dom.svg.utils.SVGConstants;
30 import org.vectomatic.svg.edit.client.engine.SVGProcessor;
31 import org.vectomatic.svg.edit.client.event.RotationEvent;
32 import org.vectomatic.svg.edit.client.event.RotationHandler;
33 import org.vectomatic.svg.edit.client.gxt.AbsoluteLayerLayout;
34 import org.vectomatic.svg.edit.client.gxt.AbsoluteLayerLayoutData;
35 import org.vectomatic.svg.edit.client.widget.Compass;
36
37 import com.extjs.gxt.ui.client.Style;
38 import com.extjs.gxt.ui.client.event.DragEvent;
39 import com.extjs.gxt.ui.client.event.Events;
40 import com.extjs.gxt.ui.client.event.Listener;
41 import com.extjs.gxt.ui.client.event.SliderEvent;
42 import com.extjs.gxt.ui.client.widget.LayoutContainer;
43 import com.extjs.gxt.ui.client.widget.Slider;
44 import com.extjs.gxt.ui.client.widget.Window;
45 import com.extjs.gxt.ui.client.widget.layout.FitData;
46 import com.extjs.gxt.ui.client.widget.layout.FitLayout;
47 import com.google.gwt.core.client.GWT;
48 import com.google.gwt.dom.client.Element;
49 import com.google.gwt.dom.client.Node;
50 import com.google.gwt.dom.client.Style.Unit;
51
52
53
54
55
56
57
58
59
60 public class SVGWindow extends Window {
61
62
63
64 protected OMSVGSVGElement svg;
65
66
67
68
69 protected OMSVGGElement xformGroup;
70
71
72
73 protected OMSVGTransform xform;
74
75
76
77 protected float angle;
78
79
80
81 protected float scale;
82
83
84
85 protected Compass compass;
86
87
88
89 protected Slider scaleSlider;
90
91
92
93
94
95 public void setSvg(final OMSVGSVGElement svg) {
96 this.svg = svg;
97 setPlain(true);
98 setMaximizable(true);
99 setSize(500, 300);
100 setMinWidth(200);
101 setMinHeight(170);
102
103
104
105
106 LayoutContainer layersContainer = new LayoutContainer();
107 GWT.log("borders: " + getBorders());
108 layersContainer.setLayout(new AbsoluteLayerLayout());
109
110
111
112
113 LayoutContainer svgContainer = new LayoutContainer();
114 svgContainer.setScrollMode(Style.Scroll.AUTO);
115 svgContainer.setStyleAttribute("background-color", SVGConstants.CSS_WHITE_VALUE);
116 SVGProcessor.normalizeIds(svg);
117 SVGImage image = new SVGImage(svg) {
118 protected void onAttach() {
119 GWT.log("onAttach");
120 OMSVGRect viewBox = svg.getViewBox().getBaseVal();
121 if (viewBox.getWidth() == 0f || viewBox.getHeight() == 0f) {
122 GWT.log(svg.getBBox().getDescription());
123 OMSVGRect bbox = inset(svg.getBBox(), svg.createSVGRect(), -0.1f * svg.getBBox().getWidth(), -0.1f * svg.getBBox().getHeight());
124 viewBox.setWidth(bbox.getWidth());
125 viewBox.setHeight(bbox.getHeight());
126 setScale(scale);
127 }
128 }
129 };
130 svgContainer.add(image);
131 layersContainer.add(svgContainer, new AbsoluteLayerLayoutData(
132 AbsoluteLayerLayoutData.HORIZONTAL_ATTACH_LEFT | AbsoluteLayerLayoutData.VERTICAL_ATTACH_TOP,
133 0,
134 0,
135 0,
136 0,
137 10));
138
139
140
141
142 xformGroup = reparent(image.getSvgElement());
143 OMSVGTransformList xformList = xformGroup.getTransform().getBaseVal();
144 xform = svg.createSVGTransform();
145 xformList.appendItem(xform);
146 setScale(1f);
147
148
149
150
151
152
153 compass = GWT.create(Compass.class);
154 final OMSVGSVGElement compassSvg = compass.getSvgElement();
155 compassSvg.getStyle().setWidth(100, Unit.PCT);
156 compassSvg.getStyle().setHeight(100, Unit.PCT);
157 compass.addRotationHandler(new RotationHandler() {
158 @Override
159 public void onRotate(RotationEvent event) {
160 setRotation(event.getAngle());
161 }
162 });
163 layersContainer.add(new SVGImage(compassSvg), new AbsoluteLayerLayoutData(
164 AbsoluteLayerLayoutData.HORIZONTAL_ATTACH_RIGHT | AbsoluteLayerLayoutData.VERTICAL_ATTACH_TOP,
165 40,
166 5,
167 100,
168 100,
169 20));
170
171
172 scaleSlider = new Slider() {
173 @Override
174 protected String onFormatValue(int value) {
175 return Integer.toString((int)(scale * 100)) + "%";
176 }
177
178 };
179 scaleSlider.setHeight(100);
180 scaleSlider.setMinValue(0);
181 scaleSlider.setMaxValue(100);
182 scaleSlider.setIncrement(1);
183 scaleSlider.setValue(50);
184 scaleSlider.setVertical(true);
185 layersContainer.add(scaleSlider, new AbsoluteLayerLayoutData(
186 AbsoluteLayerLayoutData.HORIZONTAL_ATTACH_RIGHT | AbsoluteLayerLayoutData.VERTICAL_ATTACH_TOP,
187 20,
188 5,
189 20,
190 100,
191 20));
192 scaleSlider.addListener(Events.Change, new Listener<SliderEvent>() {
193 @Override
194 public void handleEvent(SliderEvent be) {
195
196 int value = be.getNewValue();
197 if (value >= 50) {
198 scale = 1f + (value - 50f) / 10f * 4 / 5;
199 } else {
200 scale = 1f / (1f + (49 - value) / 10f * 4 / 5);
201 }
202 setScale(scale);
203 }
204 });
205
206 setLayout(new FitLayout());
207 add(layersContainer, new FitData(4));
208 }
209
210 private static OMSVGRect inset(OMSVGRect src, OMSVGRect dest, float x, float y) {
211 dest.setX(src.getX() + x);
212 dest.setY(src.getY() + y);
213 dest.setWidth(src.getWidth() - x * 2);
214 dest.setHeight(src.getHeight() - y * 2);
215 return dest;
216 }
217
218
219
220
221
222
223 public void setScaleSlider(int value) {
224 scaleSlider.setValue(value);
225 }
226
227
228
229
230
231
232 protected void setScale(float scale) {
233 this.scale = scale;
234 OMSVGRect rect = svg.getViewBox().getBaseVal();
235 svg.getStyle().setWidth(rect.getWidth() * scale, Unit.PX);
236 svg.getStyle().setHeight(rect.getHeight() * scale, Unit.PX);
237 }
238
239
240
241
242
243
244
245
246 public void setRotationCompass(int angleDeg) {
247 compass.setRotation(angleDeg);
248 }
249
250
251
252
253
254
255 protected void setRotation(float angle) {
256 this.angle = angle;
257 OMSVGRect rect = svg.getViewBox().getBaseVal();
258 OMSVGPoint center = svg.createSVGPoint(rect.getCenterX(), rect.getCenterY());
259 OMSVGMatrix m1 = svg.createSVGMatrix().translate(center.getX(), center.getY());
260 OMSVGMatrix m2 = svg.createSVGMatrix().rotate(this.angle);
261 OMSVGMatrix m3 = svg.createSVGMatrix().translate(-center.getX(), -center.getY());
262 OMSVGMatrix m = m1.multiply(m2).multiply(m3);
263 xform.setMatrix(m);
264 }
265
266 private OMSVGGElement reparent(OMSVGSVGElement svg) {
267 OMSVGGElement g = OMSVGParser.currentDocument().createSVGGElement();
268 Element gElement = g.getElement();
269 Element svgElement = svg.getElement();
270 Node node;
271 while((node = svgElement.getFirstChild()) != null) {
272 gElement.appendChild(svgElement.removeChild(node));
273 }
274 svgElement.appendChild(gElement);
275 return g;
276 }
277
278 @Override
279 protected void moveDrag(DragEvent de) {
280 int windowBarHeight = VectomaticApp2.getWindowBarHeight();
281 if (de.getY() < windowBarHeight) {
282 de.setY(windowBarHeight);
283 }
284 }
285
286
287
288
289
290
291
292
293
294
295 }
296