Changeset 1602 in josm for trunk


Ignore:
Timestamp:
2009-05-19T18:53:16+02:00 (16 years ago)
Author:
stoecker
Message:

better keyboard support for slippy map chooser - patch by jpstotz

Location:
trunk/src/org/openstreetmap/josm/gui/download
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/download/OsmMapControl.java

    r1390 r1602  
    44
    55import java.awt.Point;
     6import java.awt.event.ActionEvent;
     7import java.awt.event.InputEvent;
    68import java.awt.event.KeyEvent;
    79import java.awt.event.MouseAdapter;
     
    911import java.awt.event.MouseListener;
    1012import java.awt.event.MouseMotionListener;
    11 
     13import java.util.Timer;
     14import java.util.TimerTask;
     15
     16import javax.swing.AbstractAction;
     17import javax.swing.ActionMap;
     18import javax.swing.InputMap;
    1219import javax.swing.JComponent;
    1320import javax.swing.JPanel;
     
    2431public class OsmMapControl extends MouseAdapter implements MouseMotionListener, MouseListener {
    2532
     33    /** A Timer for smoothly moving the map area */
     34    private static final Timer timer = new Timer(true);
     35
     36    /** Does the moving */
     37    private MoveTask moveTask = new MoveTask();
     38
     39    /** How often to do the moving (milliseconds) */
     40    private static long timerInterval = 20;
     41
     42    /** The maximum speed (pixels per timer interval) */
     43    private static final double MAX_SPEED = 20;
     44
     45    /** The speed increase per timer interval when a cursor button is clicked */
     46    private static final double ACCELERATION = 0.10;
     47
    2648    // start and end point of selection rectangle
    2749    private Point iStartSelectionPoint;
     
    4365
    4466        String[] n = { ",", ".", "up", "right", "down", "left" };
    45         int[] k =
    46                 { KeyEvent.VK_COMMA, KeyEvent.VK_PERIOD, KeyEvent.VK_UP, KeyEvent.VK_RIGHT,
    47                         KeyEvent.VK_DOWN, KeyEvent.VK_LEFT };
     67        int[] k = { KeyEvent.VK_COMMA, KeyEvent.VK_PERIOD, KeyEvent.VK_UP, KeyEvent.VK_RIGHT, KeyEvent.VK_DOWN,
     68                KeyEvent.VK_LEFT };
    4869
    4970        if (contentPane != null) {
    5071            for (int i = 0; i < n.length; ++i) {
    5172                contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    52                         KeyStroke.getKeyStroke(k[i], KeyEvent.CTRL_DOWN_MASK),
    53                         "MapMover.Zoomer." + n[i]);
     73                        KeyStroke.getKeyStroke(k[i], KeyEvent.CTRL_DOWN_MASK), "MapMover.Zoomer." + n[i]);
    5474            }
    5575        }
    5676        iSizeButton = sizeButton;
    5777        iSourceButton = sourceButton;
     78
     79        InputMap inputMap = navComp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
     80        ActionMap actionMap = navComp.getActionMap();
     81
     82        // map moving
     83        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "MOVE_RIGHT");
     84        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "MOVE_LEFT");
     85        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "MOVE_UP");
     86        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "MOVE_DOWN");
     87        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "STOP_MOVE_HORIZONTALLY");
     88        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "STOP_MOVE_HORIZONTALLY");
     89        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "STOP_MOVE_VERTICALLY");
     90        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "STOP_MOVE_VERTICALLY");
     91
     92        // zooming. To avoid confusion about which modifier key to use,
     93        // we just add all keys left of the space bar
     94        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.CTRL_DOWN_MASK, false), "ZOOM_IN");
     95        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.META_DOWN_MASK, false), "ZOOM_IN");
     96        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.ALT_DOWN_MASK, false), "ZOOM_IN");
     97        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.CTRL_DOWN_MASK, false), "ZOOM_OUT");
     98        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.META_DOWN_MASK, false), "ZOOM_OUT");
     99        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK, false), "ZOOM_OUT");
     100
     101        // action mapping
     102        actionMap.put("MOVE_RIGHT", new MoveXAction(1));
     103        actionMap.put("MOVE_LEFT", new MoveXAction(-1));
     104        actionMap.put("MOVE_UP", new MoveYAction(-1));
     105        actionMap.put("MOVE_DOWN", new MoveYAction(1));
     106        actionMap.put("STOP_MOVE_HORIZONTALLY", new MoveXAction(0));
     107        actionMap.put("STOP_MOVE_VERTICALLY", new MoveYAction(0));
     108        actionMap.put("ZOOM_IN", new ZoomInAction());
     109        actionMap.put("ZOOM_OUT", new ZoomOutAction());
    58110    }
    59111
     
    70122            }
    71123        }
    72        
    73     }
    74 
    75     public void mouseDragged(MouseEvent e) {       
    76         if((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK){
    77             if (iStartSelectionPoint != null) {             
     124
     125    }
     126
     127    public void mouseDragged(MouseEvent e) {
     128        if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK) {
     129            if (iStartSelectionPoint != null) {
    78130                iEndSelectionPoint = e.getPoint();
    79131                iSlippyMapChooser.setSelection(iStartSelectionPoint, iEndSelectionPoint);
     
    89141    public void mouseReleased(MouseEvent e) {
    90142        if (e.getButton() == MouseEvent.BUTTON1) {
    91            
     143
    92144            int sourceButton = iSourceButton.hit(e.getPoint());
    93            
     145
    94146            if (iSizeButton.hit(e.getPoint())) {
    95147                iSizeButton.toggle();
    96148                iSlippyMapChooser.resizeSlippyMap();
    97             }
    98             else if(sourceButton == SourceButton.HIDE_OR_SHOW) {
     149            } else if (sourceButton == SourceButton.HIDE_OR_SHOW) {
    99150                iSourceButton.toggle();
    100151                iSlippyMapChooser.repaint();
    101                
    102             }else if(sourceButton == SourceButton.MAPNIK || sourceButton == SourceButton.OSMARENDER || sourceButton == SourceButton.CYCLEMAP) {
     152
     153            } else if (sourceButton == SourceButton.MAPNIK || sourceButton == SourceButton.OSMARENDER
     154                    || sourceButton == SourceButton.CYCLEMAP) {
    103155                iSlippyMapChooser.toggleMapSource(sourceButton);
    104             }
    105             else {
     156            } else {
    106157                if (e.getClickCount() == 1) {
    107158                    iSlippyMapChooser.setSelection(iStartSelectionPoint, e.getPoint());
     
    112163                }
    113164            }
    114            
     165
    115166        }
    116167    }
     
    119170    }
    120171
     172    private class MoveXAction extends AbstractAction {
     173
     174        int direction;
     175
     176        public MoveXAction(int direction) {
     177            this.direction = direction;
     178        }
     179
     180        public void actionPerformed(ActionEvent e) {
     181            moveTask.setDirectionX(direction);
     182        }
     183    }
     184
     185    private class MoveYAction extends AbstractAction {
     186
     187        int direction;
     188
     189        public MoveYAction(int direction) {
     190            this.direction = direction;
     191        }
     192
     193        public void actionPerformed(ActionEvent e) {
     194            moveTask.setDirectionY(direction);
     195        }
     196    }
     197
     198    /** Moves the map depending on which cursor keys are pressed (or not) */
     199    private class MoveTask extends TimerTask {
     200        /** The current x speed (pixels per timer interval) */
     201        private double speedX = 1;
     202
     203        /** The current y speed (pixels per timer interval) */
     204        private double speedY = 1;
     205
     206        /** The horizontal direction of movement, -1:left, 0:stop, 1:right */
     207        private int directionX = 0;
     208
     209        /** The vertical direction of movement, -1:up, 0:stop, 1:down */
     210        private int directionY = 0;
     211
     212        /**
     213         * Indicated if <code>moveTask</code> is currently enabled (periodically
     214         * executed via timer) or disabled
     215         */
     216        protected boolean scheduled = false;
     217
     218        protected void setDirectionX(int directionX) {
     219            this.directionX = directionX;
     220            updateScheduleStatus();
     221        }
     222
     223        protected void setDirectionY(int directionY) {
     224            this.directionY = directionY;
     225            updateScheduleStatus();
     226        }
     227
     228        private void updateScheduleStatus() {
     229            boolean newMoveTaskState = !(directionX == 0 && directionY == 0);
     230
     231            if (newMoveTaskState != scheduled) {
     232                scheduled = newMoveTaskState;
     233                if (newMoveTaskState)
     234                    timer.schedule(this, 0, timerInterval);
     235                else {
     236                    // We have to create a new instance because rescheduling a
     237                    // once canceled TimerTask is not possible
     238                    moveTask = new MoveTask();
     239                    cancel(); // Stop this TimerTask
     240                }
     241            }
     242        }
     243
     244        @Override
     245        public void run() {
     246            // update the x speed
     247            switch (directionX) {
     248            case -1:
     249                if (speedX > -1)
     250                    speedX = -1;
     251                if (speedX > -1 * MAX_SPEED)
     252                    speedX -= ACCELERATION;
     253                break;
     254            case 0:
     255                speedX = 0;
     256                break;
     257            case 1:
     258                if (speedX < 1)
     259                    speedX = 1;
     260                if (speedX < MAX_SPEED)
     261                    speedX += ACCELERATION;
     262                break;
     263            }
     264
     265            // update the y speed
     266            switch (directionY) {
     267            case -1:
     268                if (speedY > -1)
     269                    speedY = -1;
     270                if (speedY > -1 * MAX_SPEED)
     271                    speedY -= ACCELERATION;
     272                break;
     273            case 0:
     274                speedY = 0;
     275                break;
     276            case 1:
     277                if (speedY < 1)
     278                    speedY = 1;
     279                if (speedY < MAX_SPEED)
     280                    speedY += ACCELERATION;
     281                break;
     282            }
     283
     284            // move the map
     285            int moveX = (int) Math.floor(speedX);
     286            int moveY = (int) Math.floor(speedY);
     287            if (moveX != 0 || moveY != 0)
     288                iSlippyMapChooser.moveMap(moveX, moveY);
     289        }
     290    }
     291
     292    private class ZoomInAction extends AbstractAction {
     293
     294        public void actionPerformed(ActionEvent e) {
     295            iSlippyMapChooser.zoomIn();
     296        }
     297    }
     298
     299    private class ZoomOutAction extends AbstractAction {
     300
     301        public void actionPerformed(ActionEvent e) {
     302            iSlippyMapChooser.zoomOut();
     303        }
     304    }
     305
    121306}
  • trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java

    r1428 r1602  
    105105        slipyyMapTabPanel.setLayout(new BorderLayout());
    106106        slipyyMapTabPanel.add(this, BorderLayout.CENTER);
    107         slipyyMapTabPanel.add(new JLabel((tr("Zoom: Mousewheel or double click.   "
    108                 + "Move map: Hold right mousebutton and move mouse.   Select: Click."))), BorderLayout.SOUTH);
     107        String labelText = "<b>Zoom:</b> Mousewheel, double click or Ctrl + Up/Down "
     108                + "<b>Move map:</b> Hold right mousebutton and move mouse or use cursor keys. <b>Select:</b> Click.";
     109        slipyyMapTabPanel.add(new JLabel("<html>" + tr(labelText) + "</html>"), BorderLayout.SOUTH);
    109110        iGui.tabpane.add(slipyyMapTabPanel, tr("Slippy map"));
    110111        new OsmMapControl(this, slipyyMapTabPanel, iSizeButton, iSourceButton);
Note: See TracChangeset for help on using the changeset viewer.