Mercurial > hg > ccmieditor
view java/src/uk/ac/qmul/eecs/ccmi/gui/HapticKindle.java @ 0:9418ab7b7f3f
Initial import
author | Fiore Martin <fiore@eecs.qmul.ac.uk> |
---|---|
date | Fri, 16 Dec 2011 17:35:51 +0000 |
parents | |
children | 9e67171477bc |
line wrap: on
line source
/* CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.qmul.eecs.ccmi.gui; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import javax.swing.SwingUtilities; import uk.ac.qmul.eecs.ccmi.diagrammodel.CollectionModel; import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramElement; import uk.ac.qmul.eecs.ccmi.haptics.HapticListener; import uk.ac.qmul.eecs.ccmi.haptics.HapticListenerCommand; import uk.ac.qmul.eecs.ccmi.sound.SoundFactory; import uk.ac.qmul.eecs.ccmi.sound.SoundEvent; import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory; import uk.ac.qmul.eecs.ccmi.utils.InteractionLog; /** * * An instance of HapticListener for the diagram editor. By this class visual diagrams * can be manipulated by an haptic device. * */ public class HapticKindle extends HapticListener { public HapticKindle(){ super(); unselectRunnable = new Runnable(){ @Override public void run(){ frame.selectHapticHighligh(null); } }; frameBackupRunnable = new Runnable(){ @Override public void run(){ frame.backupOpenDiagrams(); } }; } public void setEditorFrame(EditorFrame frame){ this.frame = frame; } @Override public void executeCommand(HapticListenerCommand cmd, int ID, final double x, final double y, final double startX, final double startY) { if((frame == null)||(frame.getActiveTab() == null)) return; CollectionModel<Node,Edge> collectionModel = frame.getActiveTab().getDiagram().getCollectionModel(); Object monitor = collectionModel.getMonitor(); DiagramElement de = null; switch(cmd){ case PLAY_ELEMENT_SOUND : synchronized(monitor){ de = Finder.findElementByHashcode(ID, collectionModel.getElements()); } /* can be null if the tab has been switched or closed in the meantime */ if(de == null) return; SoundFactory.getInstance().play(de.getSound()); break; case PLAY_ELEMENT_SPEECH : synchronized(monitor){ de = Finder.findElementByHashcode(ID, collectionModel.getElements()); } if(de == null) return; SoundFactory.getInstance().play(de.getSound()); NarratorFactory.getInstance().speak(de.getName()); iLog("touch",((de instanceof Node) ? "node " : "edge ")+de.getName()); break; case SELECT : synchronized(monitor){ de = Finder.findElementByHashcode(ID, collectionModel.getElements()); } if(de == null) return; final DiagramElement selectedElement = de; SwingUtilities.invokeLater(new Runnable(){ @Override public void run(){ frame.selectHapticHighligh(selectedElement); } }); break; case UNSELECT : SwingUtilities.invokeLater(unselectRunnable); break; case MOVE : DiagramPanel dPanel = frame.getActiveTab(); if(dPanel == null) return; synchronized(monitor){ de = Finder.findElementByHashcode(ID, collectionModel.getElements()); } if(de == null) return; final DiagramElement moveSelectedElement = de; final DiagramModelUpdater modelUpdater = dPanel.getDiagram().getModelUpdater(); if(!modelUpdater.getLock(moveSelectedElement, Lock.MOVE)){ iLog("Could not get lock on element for motion", DiagramElement.toLogString(moveSelectedElement)); NarratorFactory.getInstance().speak("Object is being moved by another user"); return; } try { SwingUtilities.invokeAndWait(new Runnable(){ @Override public void run(){ if(moveSelectedElement instanceof Node){ Node n = (Node)moveSelectedElement; Rectangle2D bounds = n.getBounds(); Point2D.Double p = new Point2D.Double(bounds.getCenterX(),bounds.getCenterY()); double dx = x - p.getX(); double dy = y - p.getY(); modelUpdater.translate(n, p, dx, dy); modelUpdater.stopMove(n); StringBuilder builder = new StringBuilder(); builder.append(DiagramElement.toLogString(n)).append(" ").append(p.getX()) .append(' ').append(p.getY()); iLog("move node start",builder.toString()); builder = new StringBuilder(); builder.append(DiagramElement.toLogString(n)).append(' ') .append(x).append(' ').append(y); iLog("move node end",builder.toString()); }else{ Edge e = (Edge)moveSelectedElement; modelUpdater.startMove(e, new Point2D.Double(startX,startY)); Point2D p = new Point2D.Double(x,y); modelUpdater.bend(e, p); modelUpdater.stopMove(e); StringBuilder builder = new StringBuilder(); builder.append(DiagramElement.toLogString(e)).append(' ').append(startX) .append(' ').append(startY); iLog("bend edge start",builder.toString()); builder = new StringBuilder(); builder.append(DiagramElement.toLogString(e)).append(' ') .append(x).append(' ').append(y); iLog("bend edge end",builder.toString()); } } }); } catch (Exception e) { throw new RuntimeException(e); } SoundFactory.getInstance().play(SoundEvent.HOOK_OFF); modelUpdater.yieldLock(moveSelectedElement, Lock.MOVE); break; case INFO : synchronized(monitor){ de = Finder.findElementByHashcode(ID, collectionModel.getElements()); } if(de == null) return; SoundFactory.getInstance().stop(); NarratorFactory.getInstance().speak(de.detailedSpokenText()); iLog("request detailed info",((de instanceof Node) ? "node " : "edge ")+de.getName()); break; case PLAY_SOUND : switch(HapticListenerCommand.Sound.fromInt(ID) ){ case MAGNET_OFF : SoundFactory.getInstance().play(SoundEvent.MAGNET_OFF); iLog("sticky mode off",""); break; case MAGNET_ON : SoundFactory.getInstance().play(SoundEvent.MAGNET_ON); iLog("sticky mode on",""); break; case HOOK_ON : SoundFactory.getInstance().play(SoundEvent.HOOK_ON); iLog("hook on",""); break; case DRAG : SoundFactory.getInstance().play(SoundEvent.DRAG); break; } break; case ERROR : /* no synchronization necessary as the XMLManager looks after it*/ SwingUtilities.invokeLater(frameBackupRunnable); NarratorFactory.getInstance().speak("Haptic device crashed. " + "Unsaved diagrams saved in backup directory"); break; } } private void iLog(String action, String args){ InteractionLog.log(INTERACTION_LOG_SOURCE,action,args); } private Runnable unselectRunnable; private Runnable frameBackupRunnable; private static String INTERACTION_LOG_SOURCE = "HAPTIC"; private EditorFrame frame; }