View Javadoc

1   /**********************************************
2    * Copyright (C) 2011 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.command;
19  
20  import java.util.List;
21  
22  import org.vectomatic.dom.svg.OMSVGElement;
23  import org.vectomatic.dom.svg.impl.SVGElement;
24  import org.vectomatic.dom.svg.utils.SVGConstants;
25  import org.vectomatic.svg.edit.client.SvgrealApp;
26  import org.vectomatic.svg.edit.client.command.edit.EditManipulatorBase;
27  import org.vectomatic.svg.edit.client.engine.SVGModel;
28  import org.vectomatic.svg.edit.client.event.KeyPressProcessor;
29  import org.vectomatic.svg.edit.client.event.MouseDownProcessor;
30  import org.vectomatic.svg.edit.client.event.MouseMoveProcessor;
31  import org.vectomatic.svg.edit.client.event.MouseUpProcessor;
32  import org.vectomatic.svg.edit.client.event.SelectionChangedProcessor;
33  import org.vectomatic.svg.edit.client.gxt.widget.CommandFactoryMenuItem;
34  import org.vectomatic.svg.edit.client.model.svg.SVGElementModel;
35  
36  import com.extjs.gxt.ui.client.binding.FieldBinding;
37  import com.extjs.gxt.ui.client.event.ComponentEvent;
38  import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
39  import com.google.gwt.core.client.GWT;
40  import com.google.gwt.dom.client.Element;
41  import com.google.gwt.event.dom.client.MouseDownEvent;
42  import com.google.gwt.event.dom.client.MouseMoveEvent;
43  import com.google.gwt.event.dom.client.MouseUpEvent;
44  
45  /**
46   * Base class for command factories which display a graphical
47   * manipulator to let the end-user interact with an SVG element
48   * @author laaglu
49   */
50  public abstract class ManipulatorCommandFactoryBase extends EditCommandFactoryBase implements SelectionChangedProcessor<SVGElementModel>, MouseDownProcessor, MouseMoveProcessor, MouseUpProcessor, KeyPressProcessor {
51  	/**
52  	 * A filter to determine if the selection represents
53  	 * suitable input for this command factory
54  	 */
55  	protected IModelFilter filter;
56  	/**
57  	 * The manipulator used to interact with the SVG element
58  	 */
59  	protected EditManipulatorBase manipulator;
60  	/**
61  	 * If the command factory is invoked from the context menu,
62  	 * the corresponding model
63  	 */
64  	protected SVGElementModel focusModel;
65  	protected String state1;
66  	protected String state2;
67  	
68  	@Override
69  	public void start(Object requester) {
70  		GWT.log("ManipulatorCommandFactoryBase.start(" + requester + ")");
71  		super.start(requester);
72  		
73  		SVGModel svgModel = SvgrealApp.getApp().getActiveModel();
74  		if (svgModel != null) {
75  			List<SVGElementModel> elements = svgModel.getSelectionModel().getSelectedItems();
76  			if (!(requester instanceof FieldBinding)) {
77  				// No manipulator is required for changes through the inspector
78  				showManipulator(elements);
79  			}
80  			
81  			// If the request comes from the context menu, stop the command
82  			// if the selection changes
83  			if (requester instanceof CommandFactoryMenuItem && elements.size() == 1) {
84  				focusModel = elements.get(0);
85  			}
86  		}
87  	}
88  
89  	@Override
90  	public void stop() {
91  		GWT.log("ManipulatorCommandFactoryBase.stop()");
92  		super.stop();
93  		hideManipulator();
94  		focusModel = null;
95  	}
96  	
97  	public void showManipulator(List<SVGElementModel> models) {
98  		if (filter.accept(models)) {
99  			SVGElementModel model = models.get(0);
100 			manipulator = getManipulator(model);
101 			OMSVGElement manipulatorRep = manipulator.bind(model.getRecord());
102 			Element twinGroup = model.getOwner().getTwinGroup().getElement();
103 			twinGroup.appendChild(manipulatorRep.getElement());
104 			updateStatus(state2);
105 		}
106 	}
107 	
108 	public void hideManipulator() {
109 		if (manipulator != null) {
110 			manipulator.unbind();
111 			manipulator = null;
112 			updateStatus(state1);
113 		}
114 	}
115 	
116 	@Override
117 	public boolean processSelectionChanged(SelectionChangedEvent<SVGElementModel> se) {
118 		List<SVGElementModel> models = se.getSelection();
119 		GWT.log("ManipulatorCommandFactoryBase.processSelectionChanged: " + models);
120 		hideManipulator();
121 		if (focusModel != null && (models.size() != 1 || models.get(0) != focusModel)) {
122 			stop();
123 		} else {
124 			showManipulator(models);
125 		}
126 		return true;
127 	}
128 	
129 	@Override
130 	public boolean processMouseUp(MouseUpEvent event) {
131 		if (manipulator != null) {
132 			return manipulator.processMouseUp(event);
133 		}
134 		return false;
135 	}
136 
137 	@Override
138 	public boolean processMouseMove(MouseMoveEvent event) {
139 		if (manipulator != null) {
140 			return manipulator.processMouseMove(event);
141 		}
142 		return false;
143 	}
144 	
145 	@Override
146 	public boolean processKeyPress(ComponentEvent event) {
147 		if (manipulator != null) {
148 			return manipulator.processKeyPress(event);
149 		}
150 		return false;
151 	}
152 
153 	@Override
154 	public boolean processMouseDown(MouseDownEvent event) {
155 		GWT.log("ManipulatorCommandFactoryBase.processMouseDown");
156 		// If the user clicks in the background or on another
157 		// element, do not process the event.
158 		SVGElement target = event.getNativeEvent().getEventTarget().cast();
159 		if (SVGConstants.SVG_SVG_TAG.equals(target.getTagName())) {
160 			return false;
161 		}
162 		
163 		// If the user clicks on an model svg element instead
164 		// of a manipulator svg element, do not process the event.
165 		SVGModel svgModel = SvgrealApp.getApp().getActiveModel();
166 		SVGElementModel model = svgModel.convert(target);			
167 		if (model != null) {
168 			return false;
169 		}
170 		
171 		if (manipulator != null) {
172 			return manipulator.processMouseDown(event);
173 		}
174 
175 		return false;
176 	}
177 
178 	protected abstract EditManipulatorBase getManipulator(SVGElementModel model);
179 }