View Javadoc

1   /**********************************************
2    * Copyright (C) 2010 Lukas Laag
3    * This file is part of svgreal.
4    * 
5    * svgreal 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   * svgreal 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 svgreal.  If not, see http://www.gnu.org/licenses/
17   **********************************************/
18  package org.vectomatic.svg.edit.client.gxt.widget;
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.OMSVGSVGElement;
24  import org.vectomatic.dom.svg.utils.DOMHelper;
25  import org.vectomatic.dom.svg.utils.SVGPrefixResolver;
26  import org.vectomatic.svg.edit.client.AppBundle;
27  import org.vectomatic.svg.edit.client.SvgrealApp;
28  import org.vectomatic.svg.edit.client.engine.SVGProcessor;
29  import org.vectomatic.svg.edit.client.event.HasRotationHandlers;
30  import org.vectomatic.svg.edit.client.event.RotationEvent;
31  import org.vectomatic.svg.edit.client.event.RotationHandler;
32  
33  import com.google.gwt.core.client.GWT;
34  import com.google.gwt.event.dom.client.MouseDownEvent;
35  import com.google.gwt.event.dom.client.MouseDownHandler;
36  import com.google.gwt.event.dom.client.MouseEvent;
37  import com.google.gwt.event.dom.client.MouseMoveEvent;
38  import com.google.gwt.event.dom.client.MouseMoveHandler;
39  import com.google.gwt.event.dom.client.MouseUpEvent;
40  import com.google.gwt.event.dom.client.MouseUpHandler;
41  import com.google.gwt.event.shared.EventHandler;
42  import com.google.gwt.event.shared.GwtEvent;
43  import com.google.gwt.event.shared.HandlerRegistration;
44  
45  /**
46   * An compass widget implemented using an SVG image.
47   * @author laaglu
48   */
49  public class Compass implements HasRotationHandlers {
50  	private static final String COMPASS_PREFIX="compass";
51  	protected boolean rotate;
52  	protected int angle;
53  	protected OMSVGSVGElement compass;
54  	protected OMSVGGElement textGroup;
55  	
56  	/**
57  	 * Constructor.
58  	 */
59  	public Compass() {
60  		compass = AppBundle.INSTANCE.compass().getSvg();
61  		textGroup = (OMSVGGElement)DOMHelper.evaluateXPath(compass, ".//svg:g[@id='textGroup']", new SVGPrefixResolver()).next();
62  		SVGProcessor.normalizeIds(compass, COMPASS_PREFIX);
63  		compass.addMouseDownHandler(new MouseDownHandler()  {
64  			@Override
65  			public void onMouseDown(MouseDownEvent event) {
66  				rotate = true;
67  				DOMHelper.setCaptureElement(compass, null);
68  				event.preventDefault();
69  				event.stopPropagation();
70  			}
71  		});
72  		compass.addMouseMoveHandler(new MouseMoveHandler() {
73  			@Override
74  			public void onMouseMove(MouseMoveEvent event) {
75  				if (rotate) {
76  					OMSVGPoint p = getLocalCoordinates(event).substract(compass.createSVGPoint(50,50));
77  					GWT.log(p.getDescription() + " " + Float.toString(-p.getY() / p.length()));
78  					double a = Math.acos(-p.getY() / p.length());
79  					if (p.getX() < 0) {
80  						a = 2 * Math.PI - a;
81  					}
82  					setRotation((((int)toDeg(a)) / 6) * 6);
83  					event.preventDefault();
84  					event.stopPropagation();
85  				}
86  			}
87  		});
88  		compass.addMouseUpHandler(new MouseUpHandler() {
89  			@Override
90  			public void onMouseUp(MouseUpEvent event) {
91  				if (rotate) {
92  					rotate = false;
93  					DOMHelper.releaseCaptureElement();
94  					event.preventDefault();
95  					event.stopPropagation();
96  				}
97  			}
98  		});
99  	}
100 	
101 	public void setRotation(int angle) {
102 		this.angle = angle;
103 		textGroup.getTransform().getBaseVal().getItem(0).setRotate(angle, 50, 50);
104 		fireEvent(new RotationEvent(angle)); 
105 	}
106 	
107 	public OMSVGSVGElement getSvgElement() {
108 		return compass;
109 	}
110 
111 	private static final float toDeg(double rad) {
112 		return (float)(rad * 180 / Math.PI);
113 	}
114 
115     /**
116      * Returns the coordinates of a mouse event, converted
117      * to the compass coordinate system
118      * @param e
119      * A mouse event
120      * @return
121      * The coordinates of the mouse event, converted
122      * to the compass coordinate system
123      */
124     public OMSVGPoint getLocalCoordinates(MouseEvent<? extends EventHandler> e) {
125         OMSVGPoint p = compass.createSVGPoint(e.getClientX(), e.getClientY());
126         OMSVGMatrix m = compass.getScreenCTM().inverse();
127         return p.matrixTransform(m);
128     }
129     
130 	@Override
131 	public void fireEvent(GwtEvent<?> event) {
132 		SvgrealApp.getApp().getEventBus().fireEventFromSource(event, this);
133 	}
134 
135 	@Override
136 	public HandlerRegistration addRotationHandler(RotationHandler handler) {
137 		return SvgrealApp.getApp().getEventBus().addHandlerToSource(RotationEvent.getType(), this, handler);
138 	}
139 }