PageRenderTime 64ms CodeModel.GetById 31ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 1ms

/src/org/mt4j/components/visibleComponents/widgets/keyboard/MTTextKeyboard.java

http://mt4j.googlecode.com/
Java | 372 lines | 177 code | 64 blank | 131 comment | 24 complexity | 3e8aaa937eb585397d886bf8e8f874ea MD5 | raw file
  1/***********************************************************************
  2 * mt4j Copyright (c) 2008 - 2009, C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
  3 *  
  4 *   This program is free software: you can redistribute it and/or modify
  5 *   it under the terms of the GNU General Public License as published by
  6 *   the Free Software Foundation, either version 3 of the License, or
  7 *   (at your option) any later version.
  8 *
  9 *   This program is distributed in the hope that it will be useful,
 10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 *   GNU General Public License for more details.
 13 *
 14 *   You should have received a copy of the GNU General Public License
 15 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 16 *
 17 ***********************************************************************/
 18package org.mt4j.components.visibleComponents.widgets.keyboard;
 19
 20import java.awt.event.ActionEvent;
 21import java.awt.event.ActionListener;
 22
 23import org.mt4j.components.MTComponent;
 24import org.mt4j.components.StateChange;
 25import org.mt4j.components.StateChangeEvent;
 26import org.mt4j.components.StateChangeListener;
 27import org.mt4j.components.visibleComponents.font.FontManager;
 28import org.mt4j.components.visibleComponents.font.IFont;
 29import org.mt4j.components.visibleComponents.shapes.AbstractShape;
 30import org.mt4j.components.visibleComponents.widgets.MTTextArea;
 31import org.mt4j.components.visibleComponents.widgets.MTTextArea.ExpandDirection;
 32import org.mt4j.components.visibleComponents.widgets.buttons.MTSvgButton;
 33import org.mt4j.input.gestureAction.DefaultDragAction;
 34import org.mt4j.input.inputProcessors.MTGestureEvent;
 35import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragEvent;
 36import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
 37import org.mt4j.input.inputProcessors.componentProcessors.lassoProcessor.LassoProcessor;
 38import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateProcessor;
 39import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleProcessor;
 40import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapEvent;
 41import org.mt4j.util.MT4jSettings;
 42import org.mt4j.util.MTColor;
 43import org.mt4j.util.math.Matrix;
 44import org.mt4j.util.math.Vector3D;
 45
 46import processing.core.PApplet;
 47
 48/**
 49 * A multitouch keyboard with an attached textfield that can be written to.
 50 * 
 51 * @author Christopher Ruff
 52 */
 53public class MTTextKeyboard extends MTKeyboard {
 54	
 55	/** The font for text field. */
 56	private IFont fontForTextField;
 57	
 58	/** The parent to add new text area to. */
 59	private MTComponent parentToAddNewTextAreaTo;
 60	
 61	/** The clustering gesture analyzer. */
 62	private LassoProcessor lassoProcessor;
 63	
 64	//Gesture Actions
 65	/** The default drag action. */
 66	private DefaultDragAction defaultDragAction;
 67//	private DefaultRotateAction defaultRotateAction;
 68//	private DefaultScaleAction defaultScaleAction;
 69
 70	/** The drag from keyb action. */
 71	private DragTextAreaFromKeyboardAction dragFromKeybAction;
 72
 73	/** The pa. */
 74	private PApplet pa;
 75	
 76	private ITextInputListener textInputListener;
 77	
 78	
 79	/**
 80	 * Creates a new keyboard with a default font for its textarea.
 81	 * 
 82	 * @param pApplet the applet
 83	 */
 84	public MTTextKeyboard(PApplet pApplet) {
 85		this(pApplet, FontManager.getInstance().createFont(pApplet, 
 86				"arial.ttf", 35, MTColor.BLACK)); 
 87//		this(pApplet, FontManager.getInstance().createFont(pApplet, "Eureka90.vlw", 35, new Color(0,0,0,255), new Color(0,0,0,255))); 
 88//		this(pApplet, FontManager.getInstance().createFont(pApplet, "arial", 35, new Color(0,0,0,255), new Color(0,0,0,255))); 
 89	}
 90	
 91	
 92	/**
 93	 * Creates a new keyboard with the specified font for its textarea.
 94	 * 
 95	 * @param pApplet the applet
 96	 * @param fontForTextField the font for text field
 97	 */
 98	public MTTextKeyboard(PApplet pApplet, IFont fontForTextField) {
 99		super(pApplet);
100		this.pa = pApplet;
101		
102		this.fontForTextField = fontForTextField;
103		
104		lassoProcessor 	= null;
105		
106		//Set up gesture actions
107		defaultDragAction 	= new DefaultDragAction();
108//		defaultRotateAction = new DefaultRotateAction();
109//		defaultScaleAction 	= new DefaultScaleAction();
110		dragFromKeybAction 	= new DragTextAreaFromKeyboardAction();
111		
112		
113		MTSvgButton newTextFieldSvg = new MTSvgButton(pa, MT4jSettings.getInstance().getDefaultSVGPath()
114						+ "keybNewTextField.svg");
115		newTextFieldSvg.setBoundsPickingBehaviour(AbstractShape.BOUNDS_ONLY_CHECK);
116		newTextFieldSvg.scale(0.8f, 0.8f, 1, new Vector3D(0,0,0));
117		newTextFieldSvg.translate(new Vector3D(10,5,0));
118
119		newTextFieldSvg.addActionListener(new ActionListener() {
120				public void actionPerformed(ActionEvent arg0) {
121					if (arg0.getSource() instanceof MTComponent){
122						MTComponent clickedComp = (MTComponent)arg0.getSource();
123
124						switch (arg0.getID()) {
125						case TapEvent.TAPPED:
126							//should always be keyboard
127							MTComponent parent = clickedComp.getParent();
128							if (parent instanceof MTTextKeyboard){
129								MTTextKeyboard keyboard = (MTTextKeyboard)parent;
130
131								//Remove old Textfield from keyboard if there is any
132								if (textInputListener != null){
133									
134									if (textInputListener instanceof MTTextArea){
135										MTTextArea ta = (MTTextArea)textInputListener;
136										ta.setGestureAllowance(DragProcessor.class, true);
137										ta.setGestureAllowance(RotateProcessor.class, true);
138										ta.setGestureAllowance(ScaleProcessor.class, true);
139										
140										ta.setEnableCaret(false);
141										
142										//Add to clusteranylyzer for clustering the tarea
143										if (getLassoProcessor() != null){
144											getLassoProcessor().addClusterable(ta);
145										}
146
147//										keyboard.setTextInputAcceptor(null);
148										removeTextInputListener(textInputListener);
149										textInputListener = null;
150										
151										ta.removeAllGestureEventListeners(DragProcessor.class);
152										ta.addGestureListener(DragProcessor.class, defaultDragAction);
153//										ta.unassignGestureClassAndAction(DragGestureAnalyzer.class);
154//										ta.assignGestureClassAndAction(DragGestureAnalyzer.class, defaultDragAction);
155
156										//The direction, in which the textarea will float off 
157										Vector3D v = new Vector3D(0,-100, 0);
158
159										//Add the textarea to the set parent
160										if (getParentToAddNewTextAreaTo() != null){
161											//Transform the textarea so it appears at the same world coords after its added to another parent
162											Matrix m = MTComponent.getTransformToDestinationParentSpace(ta, getParentToAddNewTextAreaTo());
163											ta.transform(m);
164											//Transform the direction vector for the translation animation 
165											//to preserve the direction from the old reference frame to the new parents one
166//											v.transformNormal(m);
167											v.transformDirectionVector(m);
168
169											ta.tweenTranslate(v, 500, 0.3f, 0.7f);
170
171											getParentToAddNewTextAreaTo().addChild(ta);
172										}else{
173											//If that isnt set, try to add it to the keyboards parent
174											if (getParent() != null){
175												/////////////////////////
176												// Transform the textarea so it appears at the same place after its added to another parent
177												Matrix m = MTComponent.getTransformToDestinationParentSpace(ta, getParent());
178												ta.transform(m);
179												//Transform the direction vector to preserve the global direction
180												//from the old reference frame to the new parents one
181												//The translation part has to be removed from the matrix because we're transforming 
182												//a translation vector not a point vector
183												v.transformDirectionVector(m);
184
185												ta.tweenTranslate(v, 500, 0.3f, 0.7f);
186												/////////////////////
187												getParent().addChild(ta);
188											}else{
189												//do nothing..?
190												throw new RuntimeException("Dont know where to add text area to!");
191											}
192										}
193									}//if (text instanceof MTTextArea){
194								}//if (keyboard.getTextInputAcceptor() != null){
195								//Create a new textarea
196								keyboard.createNewTextArea();
197							}//if (parent instanceof MTTextKeyboard){
198							break;
199						default:
200							break;
201						}
202					}
203				}
204			});
205		this.addChild(newTextFieldSvg);
206	}
207	
208//	@Override
209//	protected void keyboardButtonDown(MTKey clickedKey, boolean shiftPressed){
210//		ITextInputAcceptor textArea = getTextInputAcceptor();
211//		if (textArea != null){
212//			if (clickedKey.getCharacterToWrite().equals("back")){
213//				textArea.removeLastCharacter();
214//			}else if (clickedKey.getCharacterToWrite().equals("shift")){
215//					//no nothing
216//			}else{
217//				String charToAdd = shiftPressed ? clickedKey.getCharacterToWriteShifted() : clickedKey.getCharacterToWrite();
218//				textArea.appendCharByUnicode(charToAdd);
219//			}
220//		}
221//	}
222	
223	
224	/**
225 * Creates a new textarea at the keyboard.
226 * Fails if there is still one attached to it.
227 */
228	public void createNewTextArea(){
229		if (this.textInputListener == null){
230			final MTTextArea t = new MTTextArea(pa, fontForTextField);
231			this.textInputListener = t;
232			
233			t.setExpandDirection(ExpandDirection.UP);
234			t.setStrokeColor(new MTColor(0,0 , 0, 255));
235			t.setFillColor(new MTColor(205,200,177, 255));
236			
237			t.setGestureAllowance(DragProcessor.class, true);
238			t.setGestureAllowance(RotateProcessor.class, false);
239			t.setGestureAllowance(ScaleProcessor.class, false);
240			
241			t.removeAllGestureEventListeners(DragProcessor.class);
242			t.addGestureListener(DragProcessor.class, dragFromKeybAction);
243			
244			t.setEnableCaret(true);
245			t.snapToKeyboard(this);
246			
247			this.addTextInputListener(this.textInputListener);
248			//Remove textarea from listening if destroyed
249			t.addStateChangeListener(StateChange.COMPONENT_DESTROYED, new StateChangeListener() {
250				public void stateChanged(StateChangeEvent evt) {
251					removeTextInputListener(t);
252				}
253			});
254		}else{
255			System.err.println("Cant create new textarea - Keyboard still has a textarea attached.");
256		}
257	}
258	
259
260
261	/**
262	 * Gets the parent to add new text area to.
263	 * 
264	 * @return the parent to add new text area to
265	 */
266	public MTComponent getParentToAddNewTextAreaTo() {
267		return parentToAddNewTextAreaTo;
268	}
269
270	/**
271	 * Determines to which parent the textarea of the keyboard will be added to after
272	 * decoupling it from the keyboard.
273	 * 
274	 * @param parentToAddNewTextAreaTo the parent to add new text area to
275	 */
276	public void setParentToAddNewTextAreaTo(MTComponent parentToAddNewTextAreaTo) {
277		this.parentToAddNewTextAreaTo = parentToAddNewTextAreaTo;
278	}
279
280	/**
281	 * Gets the clustering gesture analyzer.
282	 * 
283	 * @return the clustering gesture analyzer
284	 */
285	public LassoProcessor getLassoProcessor() {
286		return lassoProcessor;
287	}
288
289	/**
290	 * Sets the clustering gesture analyzer.
291	 * 
292	 * @param clusteringGestureAnalyzer the new clustering gesture analyzer
293	 */
294	public void setLassoProcessor(LassoProcessor clusteringGestureAnalyzer) {
295		this.lassoProcessor = clusteringGestureAnalyzer;
296	}
297	
298	
299	
300	/**
301	 * Gesture action class to be used when a textarea is dragged away from the keyboard.
302	 * 
303	 * @author C.Ruff
304	 */
305	private class DragTextAreaFromKeyboardAction extends DefaultDragAction {
306		
307		/* (non-Javadoc)
308		 * @see com.jMT.input.gestureAction.DefaultDragAction#processGesture(com.jMT.input.inputAnalyzers.GestureEvent)
309		 */
310		public boolean processGestureEvent(MTGestureEvent g) {
311			
312			super.processGestureEvent(g);
313			
314			if (g.getId() == MTGestureEvent.GESTURE_ENDED){
315				if (g instanceof DragEvent){
316					DragEvent dragEvent = (DragEvent)g;
317					
318					if (dragEvent.getTarget() instanceof MTTextArea){
319						MTTextArea text = (MTTextArea)dragEvent.getTarget();
320
321						//Add default gesture actions to textfield
322//						text.assignGestureClassAndAction(DragGestureAnalyzer.class, defaultDragAction);
323//						text.assignGestureClassAndAction(ScaleGestureAnalyzer.class, defaultScaleAction);
324//						text.assignGestureClassAndAction(RotateGestureAnalyzer.class, defaultRotateAction);
325						
326						text.setGestureAllowance(DragProcessor.class, true);
327						text.setGestureAllowance(RotateProcessor.class, true);
328						text.setGestureAllowance(ScaleProcessor.class, true);
329						
330						//Disable caret showing
331						text.setEnableCaret(false);
332						
333						//Add to clusteranylyzer for clustering the tarea
334						if (getLassoProcessor() != null){
335							getLassoProcessor().addClusterable(text);
336						}
337						
338						removeTextInputListener(textInputListener);
339						textInputListener = null;
340						
341						text.removeAllGestureEventListeners(DragProcessor.class);
342						text.addGestureListener(DragProcessor.class, defaultDragAction);
343						
344//						text.unassignGestureClassAndAction(DragGestureAnalyzer.class);
345//						text.assignGestureClassAndAction(DragGestureAnalyzer.class, defaultDragAction);
346						
347//						/*
348						//Add the textare to the set parent
349						if (getParentToAddNewTextAreaTo() != null){
350							text.transform(MTComponent.getTransformToDestinationParentSpace(text, getParentToAddNewTextAreaTo()));
351							getParentToAddNewTextAreaTo().addChild(text);
352						}else{
353							//If that isnt set, try to add it to the keyboards parent
354							if (getParent() != null){
355								text.transform(MTComponent.getTransformToDestinationParentSpace(text, getParent()));
356								getParent().addChild(text);
357							}else{
358								//do nothing..
359//								throw new RuntimeException("Dont know where to add text area to!");
360								System.err.println("Dont know where to add text area to!");
361							}
362						}
363//						*/
364					}
365				}
366			}
367			return false;
368		}
369	}
370	
371
372}