/* * RoombaRecorder -- * * Copyright (c) 2006 Tod E. Kurt, tod@todbot.com, ThingM * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * */ package roombacomm; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import javax.swing.filechooser.*; import java.util.*; import java.io.*; /** * A simple wrapper for multiple MacroRecorderPanels * */ public class RoombaRecorder extends JFrame implements WindowListener,ActionListener { static final String helpMsg = ""+ //"

"+ "

Roomba Movement Keyboard Shortcuts

"+ ""+ "

Application Control Keyboard Shortcuts

"+ ""+ ""; JPanel contentPane; JPanel recordPanel; JTabbedPane tabbedPane; JButton stopButton,recordButton,playButton; JCheckBox loopButton; JCheckBox playAllButton; JFileChooser fc; File file; boolean hwhandshake = false; int maxRoombas = 16; int lastTab = 0; HashMap clipboard; RoombaRecorderPanel rrpanel; // just to make some of code lines shorter boolean movingForward = false; // is roomba moving forward or not boolean vacuuming = false; // is roomba vacuuming or not int turnval = 0; public static void main(String[] args) { new RoombaRecorder(args); } public RoombaRecorder(String[] args) { super("RoombaRecorder"); addWindowListener(this); for(int i=0; i < args.length; i++) { if(args[i].endsWith("hwhandshake")) hwhandshake = true; } clipboard = new HashMap(); fc = new JFileChooser(); setResizable(false); makeMenu(); makeRecordPanel(); // Create and set up the content pane. tabbedPane = new JTabbedPane(); tabbedPane.setOpaque(true); //content panes must be opaque openNewTab(); contentPane = new JPanel(new BorderLayout()); contentPane.add(recordPanel, BorderLayout.NORTH); contentPane.add(tabbedPane, BorderLayout.CENTER); //Container content = getContentPane(); setContentPane(contentPane); addBindings(); bindKeys(); // Display the window. pack(); //setSize(400, 400); setVisible(true); //setFocusableWindowState(false); // prevent focus } void makeMenu() { JMenuBar menubar = new JMenuBar(); JMenuItem item; JMenu file = new JMenu("File"); JMenu edit = new JMenu("Edit"); JMenu help = new JMenu("Help"); file.setMnemonic(KeyEvent.VK_F); edit.setMnemonic(KeyEvent.VK_E); help.setMnemonic(KeyEvent.VK_H); item = new JMenuItem("New Tab"); item.addActionListener(this); file.add(item); item = new JMenuItem("Close Tab"); item.addActionListener(this); file.add(item); item = new JMenuItem("Open Set"); item.addActionListener(this); file.add(item); item = new JMenuItem("Save Set"); item.addActionListener(this); file.add(item); item = new JMenuItem("Quit"); item.addActionListener(this); file.add(item); item = new JMenuItem("Cut"); item.addActionListener(this); edit.add(item); item = new JMenuItem("Copy"); item.addActionListener(this); edit.add(item); item = new JMenuItem("Paste"); item.addActionListener(this); edit.add(item); item = new JMenuItem("Help"); item.addActionListener(this); help.add(item); menubar.add(file); menubar.add(edit); menubar.add(help); setJMenuBar(menubar); } void makeRecordPanel() { recordPanel = new JPanel(); recordPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Action Record"), BorderFactory.createEmptyBorder())); //1,1,1,1))); stopButton = new JButton(createImageIcon("images/but_transport_stop.png","stop")); stopButton.setActionCommand("stop"); stopButton.addActionListener(this); recordPanel.add(stopButton); playButton = new JButton(createImageIcon("images/but_transport_play.png","play")); playButton.setSelectedIcon(createImageIcon("images/but_transport_play_push.png","play")); playButton.setActionCommand("play"); playButton.addActionListener(this); recordPanel.add(playButton); recordButton = new JButton(createImageIcon("images/but_transport_record.png","record")); recordButton.setSelectedIcon(createImageIcon("images/but_transport_record_push.png","record")); recordButton.setActionCommand("record"); recordButton.addActionListener(this); recordPanel.add(recordButton); loopButton = new JCheckBox("loop"); loopButton.setText("loop"); loopButton.setActionCommand("loop"); loopButton.addActionListener(this); recordPanel.add(loopButton); playAllButton = new JCheckBox("play all"); playAllButton.addActionListener(this); recordPanel.add(playAllButton); } void addBindings() { InputMap inputMap = contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); KeyStroke key; //key = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0); //contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).remove(key); key = KeyStroke.getKeyStroke('T',KeyEvent.CTRL_MASK); inputMap.put(key, "new-tab"); key = KeyStroke.getKeyStroke('T',KeyEvent.META_MASK); inputMap.put(key, "new-tab"); key = KeyStroke.getKeyStroke('N',KeyEvent.CTRL_MASK); inputMap.put(key, "new-tab"); key = KeyStroke.getKeyStroke('N',KeyEvent.META_MASK); inputMap.put(key, "new-tab"); key = KeyStroke.getKeyStroke('W',KeyEvent.CTRL_MASK); inputMap.put(key, "close-tab"); key = KeyStroke.getKeyStroke('W',KeyEvent.META_MASK); inputMap.put(key, "close-tab"); key = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,KeyEvent.CTRL_MASK); inputMap.put(key, "right-tab"); key = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,KeyEvent.CTRL_MASK); inputMap.put(key, "left-tab"); key = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,KeyEvent.META_MASK); inputMap.put(key, "right-tab"); key = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,KeyEvent.META_MASK); inputMap.put(key, "left-tab"); key = KeyStroke.getKeyStroke('X',KeyEvent.CTRL_MASK); inputMap.put(key, "cut"); key = KeyStroke.getKeyStroke('X',KeyEvent.META_MASK); inputMap.put(key, "cut"); key = KeyStroke.getKeyStroke('C',KeyEvent.CTRL_MASK); inputMap.put(key, "copy"); key = KeyStroke.getKeyStroke('C',KeyEvent.META_MASK); inputMap.put(key, "copy"); key = KeyStroke.getKeyStroke('V',KeyEvent.CTRL_MASK); inputMap.put(key, "paste"); key = KeyStroke.getKeyStroke('V',KeyEvent.META_MASK); inputMap.put(key, "paste"); ActionMap actionMap = contentPane.getActionMap(); actionMap.put("new-tab", new AbstractAction() { public void actionPerformed(ActionEvent e) { openNewTab(); } }); actionMap.put("close-tab",new AbstractAction() { public void actionPerformed(ActionEvent e) { closeCurrentTab(); } }); actionMap.put("left-tab",new AbstractAction() { public void actionPerformed(ActionEvent e) { cycleTabLeft(); } }); actionMap.put("right-tab",new AbstractAction() { public void actionPerformed(ActionEvent e) { cycleTabRight(); } }); actionMap.put("cut",new AbstractAction() { public void actionPerformed(ActionEvent e) { clipboard = getCurrentTab().cut(); } }); actionMap.put("copy",new AbstractAction() { public void actionPerformed(ActionEvent e) { clipboard = getCurrentTab().copy(); } }); actionMap.put("paste",new AbstractAction() { public void actionPerformed(ActionEvent e) { getCurrentTab().paste(clipboard); } }); } /** * Bind keys to actions using a custom KeyEventPostProcessor * (fixme: why can't this go in the panel?) */ void bindKeys() { // ahh, the succinctness of java KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); kfm.addKeyEventDispatcher( new KeyEventDispatcher() { public boolean dispatchKeyEvent(KeyEvent e) { String action=null; if(e.getID() != KeyEvent.KEY_PRESSED) return false; if(e.getModifiers() != 0) return false; switch(e.getKeyCode()) { case KeyEvent.VK_UP: action = "forward"; movingForward=true; turnval = 0; break; case KeyEvent.VK_DOWN: action="backward"; movingForward=false; turnval = 0; break; case KeyEvent.VK_LEFT: if(movingForward) { turnval = (turnval==0) ? 100 : turnval-turnval/2; if(turnval<10) { action="spinleft"; turnval=0; } else action = "turn"+turnval; } else action = "spinleft"; //action = (movingForward) ? "turn100" : "spinleft"; break; case KeyEvent.VK_RIGHT: if(movingForward) { turnval = (turnval==0) ? -100 : turnval-turnval/2; if(turnval>-10) { action="spinright"; turnval=0; } else action = "turn"+turnval; } else action = "spinright"; //action = (movingForward) ? "turn-100" : "spinright"; break; case KeyEvent.VK_SPACE: action="stop"; movingForward=false; turnval = 0; break; case KeyEvent.VK_L: action="blink-leds"; break; case KeyEvent.VK_R: action="reset"; break; case KeyEvent.VK_T: action="test"; break; case KeyEvent.VK_V: vacuuming = !vacuuming; action = (vacuuming) ? "vacuum-on":"vacuum-off"; break; case KeyEvent.VK_1: action="50"; break; case KeyEvent.VK_2: action="100"; break; case KeyEvent.VK_3: action="150"; break; case KeyEvent.VK_4: action="250"; break; case KeyEvent.VK_5: action="400"; break; case KeyEvent.VK_6: action="500"; break; } if(action!=null) getCurrentTab().actionPerformed(new ActionEvent(this,0,action)); //System.out.println("process '"+e.getKeyCode()+"' "+e); return true; } }); } /** Implement Actionlistener */ public void actionPerformed(ActionEvent event) { String action = event.getActionCommand(); //System.out.println("action:"+action+", event: "+event); if("stop".equals(action)) { playButton.setSelected(false); recordButton.setSelected(false); for(int i=0; i