1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.client.rep.view;
19
20 import java.util.Iterator;
21
22 import org.vectomatic.client.rep.RepApplication;
23 import org.vectomatic.client.rep.controller.Compass;
24 import org.vectomatic.client.rep.controller.IController;
25 import org.vectomatic.client.rep.controller.RepresentationController;
26 import org.vectomatic.common.model.DrawingModel;
27 import org.vectomatic.common.model.IStyleVisitor;
28 import org.vectomatic.common.model.Shape;
29 import org.vectomatic.common.model.geometry.Point;
30 import org.vectomatic.common.model.geometry.TransformMatrix;
31 import org.vectomatic.common.model.style.Color;
32 import org.vectomatic.common.model.style.NoneStyle;
33
34 import com.google.gwt.user.client.ui.KeyboardListener;
35 import com.google.gwt.user.client.ui.MouseListenerAdapter;
36 import com.google.gwt.user.client.ui.MouseWheelListener;
37 import com.google.gwt.user.client.ui.MouseWheelVelocity;
38 import com.google.gwt.user.client.ui.Widget;
39 import com.gwt.components.client.Canvas;
40 import com.gwtext.client.widgets.Resizable;
41 import com.gwtext.client.widgets.ResizableConfig;
42 import com.gwtext.client.widgets.event.ResizableListenerAdapter;
43
44
45
46
47
48
49 public class DrawingView extends Canvas {
50 private static final int MARGIN = 5;
51 private float _r;
52 private Point _s;
53 private Point _t;
54 private transient boolean _dirty;
55 private transient TransformMatrix _m;
56 private TransformMatrix _mInv;
57
58 private RepresentationController _repController;
59 private IController _controller;
60 private RenderVisitor _renderer;
61 private PickVisitor _picker;
62 private Cursor _cursor;
63 private DrawingModel _model;
64 private Compass _compass;
65 private boolean _compassMode;
66 private IStyleVisitor _strokeStyleVisitor = new IStyleVisitor() {
67
68 public void visitColor(Color color) {
69 String style = color.toString();
70 if (!style.equals(getStrokeStyle())) {
71 setStrokeStyle(style);
72 }
73 }
74
75 public void visitNoneStyle(NoneStyle none) {
76
77
78 }
79
80 };
81 private IStyleVisitor _fillStyleVisitor = new IStyleVisitor() {
82
83 public void visitColor(Color color) {
84 String style = color.toString();
85 if (!style.equals(getFillStyle())) {
86 setFillStyle(style);
87 }
88 }
89
90 public void visitNoneStyle(NoneStyle none) {
91
92
93 }
94
95 };
96
97 public DrawingView(RepresentationController repController, DrawingModel model, int width, int height) {
98 super(width, height);
99 saveContext();
100 _t = new Point();
101 _s = new Point(Point.UNIT);
102 _m = new TransformMatrix();
103
104 _repController = repController;
105 _model = model;
106 _mInv = new TransformMatrix();
107 _compass = new Compass(this);
108 _compass.setPosition(new Point(width - 70, 50));
109 _compass.setRadius(45);
110 _renderer = new RenderVisitor(this);
111 _picker = new PickVisitor(this);
112 addMouseListener(new MouseListenerAdapter() {
113 Point p = new Point();
114 @Override
115 public void onMouseDown(Widget sender, int x, int y) {
116 p.x = x;
117 p.y = y;
118
119 if (_compass.pick(p) != Compass.NONE) {
120 _compassMode = true;
121 _compass.mouseDown(p);
122 } else {
123 _compassMode = false;
124
125 RepApplication.app.debugPrint("x=" + p.x + " y=" + p.y);
126 _controller.mouseDown(DrawingView.this, p, modifiers);
127 }
128 }
129 @Override
130 public void onMouseMove(Widget sender, int x, int y) {
131 p.x = x;
132 p.y = y;
133 if (_compassMode) {
134 _compass.mouseMove(p);
135 } else {
136 _compass.pick(p);
137
138 _controller.mouseMove(DrawingView.this, p, modifiers);
139 }
140 }
141 @Override
142 public void onMouseUp(Widget sender, int x, int y) {
143 p.x = x;
144 p.y = y;
145 if (_compassMode) {
146 _compass.mouseUp();
147 _compassMode = false;
148 } else {
149
150 _controller.mouseUp(DrawingView.this, p, modifiers);
151 }
152 }
153 });
154 addKeyboardListener(new KeyboardListener() {
155 public void onKeyDown(Widget sender, char keyCode, int modifiers) {
156 _controller.keyDown(DrawingView.this,keyCode, modifiers);
157 }
158 public void onKeyPress(Widget sender, char keyCode, int modifiers) {
159 _controller.keyPress(DrawingView.this,keyCode, modifiers);
160 }
161 public void onKeyUp(Widget sender, char keyCode, int modifiers) {
162 _controller.keyUp(DrawingView.this,keyCode, modifiers);
163 }
164 });
165 addMouseWheelListener(new MouseWheelListener() {
166 Point p = new Point();
167 public void onMouseWheel(Widget sender, MouseWheelVelocity velocity) {
168 int delta = 10 * velocity.getDeltaY();
169 if ((modifiers & KeyboardListener.MODIFIER_CTRL) != 0) {
170 if (delta > 0) {
171 float s = _compass.getScaling();
172 _compass.setScaling(s + 0.1f * (1 - s));
173 } else {
174 float s = _compass.getScaling();
175 _compass.setScaling(s - 0.1f * s);
176 }
177 } else {
178 if ((modifiers & KeyboardListener.MODIFIER_ALT) != 0) {
179 p.x = delta;
180 p.y = 0f;
181 } else {
182 p.x = 0f;
183 p.y = delta;
184 }
185 _compass.translate(p);
186 }
187 }
188 });
189 }
190
191 public float getRotation() {
192 return _r;
193 }
194
195 public void setRotation(float r) {
196 _r = r;
197 _dirty = true;
198 }
199
200 public Point getScaling(Point s) {
201 _s.copyTo(s);
202 return s;
203 }
204
205 public void setScaling(Point s) {
206 s.copyTo(_s);
207 _dirty = true;
208 }
209
210 public Point getTranslation(Point t) {
211 _t.copyTo(t);
212 return t;
213 }
214
215 public void setTranslation(Point t) {
216 t.copyTo(_t);
217 _dirty = true;
218 }
219
220 public TransformMatrix getTransform() {
221 if (_dirty) {
222 updateTransform();
223 }
224 return _m;
225 }
226 public TransformMatrix getInverseTransform() {
227 return _mInv;
228 }
229
230 protected void updateTransform() {
231 float cos = (float)Math.cos(_r);
232 float sin = (float)Math.sin(_r);
233 float x1 = _t.x - 0.5f * getWidth();
234 float y1 = _t.y - 0.5f * getHeight();
235 _m.m11 = _s.x * cos; _m.m12 = -_s.y * sin; _m.m13 = _s.x * cos * x1 - _s.y * sin * y1 + 0.5f * getWidth();
236 _m.m21 = _s.x * sin; _m.m22 = _s.y * cos; _m.m23 = _s.x * sin * x1 + _s.y * cos * y1 + 0.5f * getHeight();
237 _dirty = false;
238 }
239
240 public void reset() {
241 setTranslation(Point.ZERO);
242 _compass.setRotation(0f);
243 _compass.setScaling(0.5f);
244 }
245
246 public void render() {
247
248
249 restoreContext();
250 clearRect(0, 0, getWidth(), getHeight());
251
252
253
254 saveContext();
255 translate(0.5f * getWidth(), 0.5f * getHeight());
256 rotate(_r);
257 scale(_s.x, _s.y);
258 translate(-0.5f * getWidth() + _t.x, -0.5f * getHeight() + _t.y);
259 getTransform().invert(_mInv);
260
261
262 int width = _repController.getCurrentRep().getWidth();
263 int height = _repController.getCurrentRep().getHeight();
264 setFillStyle(Color.DARK_GRAY.toString());
265 fillRect(MARGIN, height, width, MARGIN);
266 fillRect(width, MARGIN, MARGIN, height);
267 setStrokeStyle(Color.LIGHT_GRAY.toString());
268 strokeRect(0, 0, width, height);
269
270
271 Iterator<Shape> iterator = _model.iterator();
272 while (iterator.hasNext()) {
273 Shape shape = iterator.next();
274 shape.acceptVisitor(_renderer);
275 }
276
277 getController().render(this);
278
279
280
281 restoreContext();
282 _compass.render();
283
284
285 saveContext();
286 }
287
288
289
290
291
292
293
294 public float convertToReferenceLength(int screenLength) {
295 Point p0 = new Point(0, 0);
296 p0.transform(_mInv);
297 Point p1 = new Point(screenLength, 0);
298 p1.transform(_mInv);
299 return p1.subtract(p0).length();
300 }
301
302 public Point vectorToRefCoordinates(Point v) {
303 return vectorToRefCoordinates(v, v);
304 }
305
306 public Point vectorToRefCoordinates(Point v, Point dest) {
307 v.transform(_mInv, dest);
308 dest.x -= _mInv.m13;
309 dest.y -= _mInv.m23;
310 return dest;
311 }
312
313
314
315
316
317
318
319
320 public Point toModelCoordinates(Point p) {
321 return toModelCoordinates(p, p);
322 }
323
324 public Point toModelCoordinates(Point p, Point dest) {
325 return p.transform(_mInv, dest);
326 }
327
328 public Point toScreenCoordinates(Point p) {
329 return toScreenCoordinates(p, p);
330 }
331
332
333
334
335
336
337
338
339 public Point toScreenCoordinates(Point p, Point dest) {
340 return p.transform(_m, dest);
341 }
342
343 public void setCursor(Cursor cursor) {
344 if (_cursor != cursor) {
345 if (_cursor != null) {
346 removeStyleName(_cursor.getCssText());
347 }
348 if (cursor != null) {
349 addStyleName(cursor.getCssText());
350 }
351 _cursor = cursor;
352 }
353 }
354
355 public void setController(IController controller) {
356 _controller = controller;
357 }
358
359 public IController getController() {
360 return _controller;
361 }
362
363 public RenderVisitor getRenderer() {
364 return _renderer;
365 }
366
367 public PickVisitor getPicker() {
368 return _picker;
369 }
370
371 public IStyleVisitor getStrokeStyleVisitor() {
372 return _strokeStyleVisitor;
373 }
374 public IStyleVisitor getFillStyleVisitor() {
375 return _fillStyleVisitor;
376 }
377
378 @Override
379 protected void onLoad() {
380 ResizableConfig config = new ResizableConfig();
381 config.setPinned(true);
382 config.setHandles(Resizable.SOUTH_EAST);
383 config.setMinWidth(320);
384 config.setMinHeight(200);
385 final Resizable resizable = new Resizable(getElement(), config);
386 resizable.addListener(new ResizableListenerAdapter() {
387 public void onResize(Resizable self, int width, int height) {
388 setWidth(width);
389 setHeight(height);
390
391
392
393 saveContext();
394 _compass.setPosition(new Point(width - 70, 50));
395 _compass.setRadius(45);
396 }
397 });
398 }
399 }