Changeset 7 in josm for src/org/openstreetmap/josm/gui


Ignore:
Timestamp:
2005-10-02T20:32:00+02:00 (19 years ago)
Author:
imi
Message:

added mapmodes for adding and combining stuff. Reorganized images

Location:
src/org/openstreetmap/josm/gui
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/org/openstreetmap/josm/gui/IconToggleButton.java

    r4 r7  
    11package org.openstreetmap.josm.gui;
     2
     3import java.beans.PropertyChangeEvent;
     4import java.beans.PropertyChangeListener;
    25
    36import javax.swing.Action;
     
    1114 * @author imi
    1215 */
    13 public class IconToggleButton extends JToggleButton {
     16public class IconToggleButton extends JToggleButton implements PropertyChangeListener {
    1417
    1518        /**
     
    1922                super(action);
    2023                setText(null);
     24               
     25                // Tooltip
     26                String toolTipText = "";
    2127                Object o = action.getValue(Action.LONG_DESCRIPTION);
    2228                if (o != null)
    23                         setToolTipText(o.toString());
     29                        toolTipText += o.toString();
     30                o = action.getValue(Action.ACCELERATOR_KEY);
     31                if (o != null) {
     32                        String ksName = o.toString();
     33                        if (ksName.startsWith("pressed "))
     34                                ksName = ksName.substring("pressed ".length());
     35                        else if (ksName.startsWith("released "))
     36                                ksName = ksName.substring("released ".length());
     37                        toolTipText += " Shortcut: "+ksName;
     38                }
     39                setToolTipText(toolTipText);
     40               
     41                action.addPropertyChangeListener(this);
     42        }
     43
     44        public void propertyChange(PropertyChangeEvent evt) {
     45                if (evt.getPropertyName() == "active")
     46                        setSelected((Boolean)evt.getNewValue());
    2447        }
    2548}
  • src/org/openstreetmap/josm/gui/Main.java

    r1 r7  
    6262                setExtendedState(MAXIMIZED_BOTH); // some platform are able to maximize
    6363               
     64                // creating actions
     65                OpenGpxAction openGpxAction = new OpenGpxAction();
     66                SaveGpxAction saveGpxAction = new SaveGpxAction();
     67                ExitAction exitAction = new ExitAction();
     68                PreferencesAction preferencesAction = new PreferencesAction();
     69
    6470                // creating menu
    6571                JMenuBar mainMenu = new JMenuBar();
     
    6874                JMenu fileMenu = new JMenu("Files");
    6975                fileMenu.setMnemonic('F');
    70                 fileMenu.add(new OpenGpxAction());
    71                 fileMenu.add(new SaveGpxAction());
     76                fileMenu.add(openGpxAction);
     77                fileMenu.add(saveGpxAction);
    7278                fileMenu.addSeparator();
    73                 fileMenu.add(new ExitAction());
     79                fileMenu.add(exitAction);
    7480                mainMenu.add(fileMenu);
    7581               
    7682                JMenu editMenu = new JMenu("Edit");
    7783                editMenu.setMnemonic('E');
    78                 editMenu.add(new PreferencesAction());
     84                editMenu.add(preferencesAction);
    7985                mainMenu.add(editMenu);
    8086
     
    8288                JToolBar toolBar = new JToolBar();
    8389                toolBar.setFloatable(false);
    84                 toolBar.add(new OpenGpxAction());
    85                 toolBar.add(new SaveGpxAction());
     90                toolBar.add(openGpxAction);
     91                toolBar.add(saveGpxAction);
    8692                toolBar.addSeparator();
    87                 toolBar.add(new PreferencesAction());
     93                toolBar.add(preferencesAction);
    8894               
    8995                getContentPane().add(toolBar, BorderLayout.NORTH);
     
    133139                this.name = name;
    134140                this.mapFrame = mapFrame;
     141                panel.setVisible(false);
    135142                panel.removeAll();
    136143                panel.add(mapFrame, BorderLayout.CENTER);
    137144                panel.add(mapFrame.getToolBarActions(), BorderLayout.WEST);
     145                panel.setVisible(true);
    138146        }
    139147        /**
  • src/org/openstreetmap/josm/gui/MapFrame.java

    r4 r7  
    2525import javax.swing.event.ChangeListener;
    2626
     27import org.openstreetmap.josm.actions.mapmode.AddLineSegmentAction;
     28import org.openstreetmap.josm.actions.mapmode.AddNodeAction;
     29import org.openstreetmap.josm.actions.mapmode.AddTrackAction;
     30import org.openstreetmap.josm.actions.mapmode.CombineAction;
    2731import org.openstreetmap.josm.actions.mapmode.DebugAction;
     32import org.openstreetmap.josm.actions.mapmode.DeleteAction;
    2833import org.openstreetmap.josm.actions.mapmode.MapMode;
     34import org.openstreetmap.josm.actions.mapmode.MoveAction;
    2935import org.openstreetmap.josm.actions.mapmode.SelectionAction;
    3036import org.openstreetmap.josm.actions.mapmode.ZoomAction;
     
    3945 * @author imi
    4046 */
    41 public class MapFrame extends JComponent {
     47public class MapFrame extends JPanel {
    4248
    4349        /**
     
    123129
    124130                add(mapView = new MapView(dataSet), BorderLayout.CENTER);
    125                
     131
     132                // toolbar
    126133                toolBarActions.setFloatable(false);
    127134                toolBarActions.add(new IconToggleButton(this, new ZoomAction(this)));
    128135                toolBarActions.add(new IconToggleButton(this, new SelectionAction(this)));
     136                toolBarActions.add(new IconToggleButton(this, new MoveAction(this)));
     137                toolBarActions.add(new IconToggleButton(this, new AddNodeAction(this)));
     138                toolBarActions.add(new IconToggleButton(this, new AddLineSegmentAction(this)));
     139                toolBarActions.add(new IconToggleButton(this, new AddTrackAction(this)));
     140                toolBarActions.add(new IconToggleButton(this, new CombineAction(this)));
     141                toolBarActions.add(new IconToggleButton(this, new DeleteAction(this)));
    129142                toolBarActions.add(new IconToggleButton(this, new DebugAction(this)));
    130143
     
    159172        public void selectMapMode(MapMode mapMode) {
    160173                if (this.mapMode != null)
    161                         this.mapMode.unregisterListener(mapView);
     174                        this.mapMode.unregisterListener();
    162175                this.mapMode = mapMode;
    163                 mapMode.registerListener(mapView);
     176                mapMode.registerListener();
    164177        }
    165178
  • src/org/openstreetmap/josm/gui/MapView.java

    r6 r7  
    2424import org.openstreetmap.josm.data.osm.LineSegment;
    2525import org.openstreetmap.josm.data.osm.Node;
     26import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2627import org.openstreetmap.josm.data.osm.Track;
    2728import org.openstreetmap.josm.data.projection.Projection;
     
    8182
    8283       
    83         // Event handling functions and data
    84        
    85         /**
    86          * The event list with all state chaned listener
    87          */
    88         List<ChangeListener> listener = new LinkedList<ChangeListener>();
    89         /**
    90          * Add an event listener to the state changed event queue. If passed
    91          * <code>null</code>, nothing happens.
    92          */
    93         public final void addChangeListener(ChangeListener l) {
    94                 if (l != null)
    95                         listener.add(l);
    96         }
    97         /**
    98          * Remove an event listener from the event queue. If passed
    99          * <code>null</code>, nothing happens.
    100          */
    101         public final void removeChangeListener(ChangeListener l) {
    102                 listener.remove(l);
    103         }
    104         /**
    105          * Fires an ChangeEvent. Occours, when an non-data value changed, as example
    106          * the autoScale - state or the center. Is not fired, dataSet internal things
    107          * changes.
    108          */
    109         public final void fireStateChanged() {
    110                 ChangeEvent e = null;
    111                 for(ChangeListener l : listener) {
    112                         if (e == null)
    113                                 e = new ChangeEvent(this);
    114                         l.stateChanged(e);
    115                 }
    116         }
    117        
    118        
    119        
    120        
    121        
    122         // other functions
    123        
    12484        /**
    12585         * Construct a MapView and attach it to a frame.
     
    178138                return new Point(toScreenX(p.x), toScreenY(p.y));
    179139        }
    180        
     140
     141        /**
     142         * Return the object, that is nearest to the given screen point.
     143         *
     144         * First, a node will be searched. If a node within 10 pixel is found, the
     145         * nearest node is returned.
     146         *
     147         * If no node is found, search for pending line segments.
     148         *
     149         * If no such line segment is found, and a non-pending line segment is
     150         * within 10 pixel to p, this segment is returned, except when
     151         * <code>wholeTrack</code> is <code>true</code>, in which case the
     152         * corresponding Track is returned.
     153         *
     154         * If no line segment is found and the point is within an area, return that
     155         * area.
     156         *
     157         * If no area is found, return <code>null</code>.
     158         *
     159         * @param p                             The point on screen.
     160         * @param wholeTrack    Whether the whole track or only the line segment
     161         *                                              should be returned.
     162         * @return      The primitive, that is nearest to the point p.
     163         */
     164        public OsmPrimitive getNearest(Point p, boolean wholeTrack) {
     165                double minDistanceSq = Double.MAX_VALUE;
     166                OsmPrimitive minPrimitive = null;
     167               
     168                // nodes
     169                for (Node n : dataSet.nodes) {
     170                        Point sp = getScreenPoint(n.coor);
     171                        double dist = p.distanceSq(sp);
     172                        if (minDistanceSq > dist && dist < 100) {
     173                                minDistanceSq = p.distanceSq(sp);
     174                                minPrimitive = n;
     175                        }
     176                }
     177                if (minPrimitive != null)
     178                        return minPrimitive;
     179               
     180                // pending line segments
     181                for (LineSegment ls : dataSet.pendingLineSegments) {
     182                        Point A = getScreenPoint(ls.start.coor);
     183                        Point B = getScreenPoint(ls.end.coor);
     184                        double c = A.distanceSq(B);
     185                        double a = p.distanceSq(B);
     186                        double b = p.distanceSq(A);
     187                        double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
     188                        if (perDist < 100 && minDistanceSq > perDist && a < c+100 && b < c+100) {
     189                                minDistanceSq = perDist;
     190                                minPrimitive = ls;
     191                        }
     192                }
     193
     194                // tracks & line segments
     195                minDistanceSq = Double.MAX_VALUE;
     196                for (Track t : dataSet.tracks) {
     197                        for (LineSegment ls : t.segments) {
     198                                Point A = getScreenPoint(ls.start.coor);
     199                                Point B = getScreenPoint(ls.end.coor);
     200                                double c = A.distanceSq(B);
     201                                double a = p.distanceSq(B);
     202                                double b = p.distanceSq(A);
     203                                double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
     204                                if (perDist < 100 && minDistanceSq > perDist && a < c+100 && b < c+100) {
     205                                        minDistanceSq = perDist;
     206                                        minPrimitive = wholeTrack ? t : ls;
     207                                }
     208                        }                       
     209                }
     210                if (minPrimitive != null)
     211                        return minPrimitive;
     212               
     213                // TODO areas
     214               
     215               
     216                return null; // nothing found
     217        }
     218
    181219        /**
    182220         * Zoom to the given coordinate.
     
    220258                                center = new GeoPoint(51.526447, -0.14746371);
    221259                                getProjection().latlon2xy(center);
    222                                 scale = 10000; // nice view from 1:10000, eh?
     260                                scale = 10;
    223261                        } else {
    224262                                center = bounds.centerXY();
     
    258296                                }
    259297
     298                // draw pending line segments
     299                for (LineSegment ls : dataSet.pendingLineSegments) {
     300                        g.setColor(ls.selected ? Color.WHITE : Color.LIGHT_GRAY);
     301                        g.drawLine(toScreenX(ls.start.coor.x), toScreenY(ls.start.coor.y),
     302                                        toScreenX(ls.end.coor.x), toScreenY(ls.end.coor.y));
     303                }
     304
    260305                // draw nodes
    261306                Set<Integer> alreadyDrawn = new HashSet<Integer>();
    262307                int width = getWidth();
    263                 for (Node w : dataSet.allNodes) {
     308                for (Node w : dataSet.nodes) {
    264309                        g.setColor(w.selected ? Color.WHITE : Color.RED);
    265310                        int x = toScreenX(w.coor.x);
     
    294339        }
    295340
    296         /**
    297          * Does nothing. Just to satisfy ComponentListener.
    298          */
    299         public void componentMoved(ComponentEvent e) {}
    300         /**
    301          * Does nothing. Just to satisfy ComponentListener.
    302          */
    303         public void componentShown(ComponentEvent e) {}
    304         /**
    305          * Does nothing. Just to satisfy ComponentListener.
    306          */
    307         public void componentHidden(ComponentEvent e) {}
    308 
     341
     342        // Event handling functions and data
     343       
     344        /**
     345         * The event list with all state chaned listener
     346         */
     347        List<ChangeListener> listener = new LinkedList<ChangeListener>();
     348        /**
     349         * Add an event listener to the state changed event queue. If passed
     350         * <code>null</code>, nothing happens.
     351         */
     352        public final void addChangeListener(ChangeListener l) {
     353                if (l != null)
     354                        listener.add(l);
     355        }
     356        /**
     357         * Remove an event listener from the event queue. If passed
     358         * <code>null</code>, nothing happens.
     359         */
     360        public final void removeChangeListener(ChangeListener l) {
     361                listener.remove(l);
     362        }
     363        /**
     364         * Fires an ChangeEvent. Occours, when an non-data value changed, as example
     365         * the autoScale - state or the center. Is not fired, dataSet internal things
     366         * changes.
     367         */
     368        public final void fireStateChanged() {
     369                ChangeEvent e = null;
     370                for(ChangeListener l : listener) {
     371                        if (e == null)
     372                                e = new ChangeEvent(this);
     373                        l.stateChanged(e);
     374                }
     375        }
     376       
    309377        /**
    310378         * Notify from the projection, that something has changed.
     
    363431                return center.clone();
    364432        }
     433
     434        /**
     435         * Does nothing. Just to satisfy ComponentListener.
     436         */
     437        public void componentMoved(ComponentEvent e) {}
     438        /**
     439         * Does nothing. Just to satisfy ComponentListener.
     440         */
     441        public void componentShown(ComponentEvent e) {}
     442        /**
     443         * Does nothing. Just to satisfy ComponentListener.
     444         */
     445        public void componentHidden(ComponentEvent e) {}
    365446}
  • src/org/openstreetmap/josm/gui/SelectionManager.java

    r4 r7  
    1010import java.awt.event.MouseListener;
    1111import java.awt.event.MouseMotionListener;
     12import java.beans.PropertyChangeEvent;
     13import java.beans.PropertyChangeListener;
     14import java.util.Collection;
     15import java.util.LinkedList;
     16
     17import org.openstreetmap.josm.data.osm.LineSegment;
     18import org.openstreetmap.josm.data.osm.Node;
     19import org.openstreetmap.josm.data.osm.OsmPrimitive;
     20import org.openstreetmap.josm.data.osm.Track;
    1221
    1322/**
     
    3645 * @author imi
    3746 */
    38 public class SelectionManager implements MouseListener, MouseMotionListener {
     47public class SelectionManager implements MouseListener, MouseMotionListener, PropertyChangeListener {
    3948
    4049        /**
     
    4756                 * Called, when the left mouse button was released.
    4857                 * @param r The rectangle, that is currently the selection.
    49                  * @param modifiers The modifiers returned from the MouseEvent when
    50                  *              the left mouse button was released.
     58                 * @param alt Whether the alt key was pressed
     59                 * @param shift Whether the shift key was pressed
     60                 * @param ctrl Whether the ctrl key was pressed
    5161                 * @see InputEvent#getModifiersEx()
    5262                 */
    53                 public void selectionEnded(Rectangle r, int modifiers);
     63                public void selectionEnded(Rectangle r, boolean alt, boolean shift, boolean ctrl);
     64                /**
     65                 * Called to register the selection manager for "active" property.
     66                 * @param listener The listener to register
     67                 */
     68                public void addPropertyChangeListener(PropertyChangeListener listener);
     69                /**
     70                 * Called to remove the selection manager from the listener list
     71                 * for "active" property.
     72                 * @param listener The listener to register
     73                 */
     74                public void removePropertyChangeListener(PropertyChangeListener listener);
    5475        }
    5576        /**
     
    6788        private Point mousePos;
    6889        /**
    69          * The component, the selection rectangle is drawn onto.
    70          */
    71         private final Component drawComponent;
     90         * The MapView, the selection rectangle is drawn onto.
     91         */
     92        private final MapView mv;
    7293        /**
    7394         * Whether the selection rectangle must obtain the aspect ratio of the
     
    83104         * @param aspectRatio If true, the selection window must obtain the aspect
    84105         *              ratio of the drawComponent.
    85          * @param drawComponent The component, the rectangle is drawn onto.
    86          */
    87         public SelectionManager(SelectionEnded selectionEndedListener, boolean aspectRatio, Component drawComponent) {
     106         * @param mapView The view, the rectangle is drawn onto.
     107         */
     108        public SelectionManager(SelectionEnded selectionEndedListener, boolean aspectRatio, MapView mapView) {
    88109                this.selectionEndedListener = selectionEndedListener;
    89110                this.aspectRatio = aspectRatio;
    90                 this.drawComponent = drawComponent;
     111                this.mv = mapView;
    91112        }
    92113       
     
    98119                eventSource.addMouseListener(this);
    99120                eventSource.addMouseMotionListener(this);
     121                selectionEndedListener.addPropertyChangeListener(this);
    100122        }
    101123        /**
     
    108130                eventSource.removeMouseListener(this);
    109131                eventSource.removeMouseMotionListener(this);
     132                selectionEndedListener.removePropertyChangeListener(this);
    110133        }
    111134
     
    158181                mousePosStart = null;
    159182                mousePos = null;
     183
     184                boolean shift = (e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) != 0;
     185                boolean alt = (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0;
     186                boolean ctrl = (e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0;
    160187                if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) == 0)
    161                         selectionEndedListener.selectionEnded(r, e.getModifiersEx());
     188                        selectionEndedListener.selectionEnded(r, alt, shift, ctrl);
    162189        }
    163190
     
    168195         */
    169196        private void paintRect() {
    170                 Graphics g = drawComponent.getGraphics();
     197                Graphics g = mv.getGraphics();
    171198                g.setColor(Color.BLACK);
    172199                g.setXORMode(Color.WHITE);
     
    196223                if (aspectRatio) {
    197224                        // keep the aspect ration by shrinking the rectangle
    198                         double aspectRatio = (double)drawComponent.getWidth()/drawComponent.getHeight();
     225                        double aspectRatio = (double)mv.getWidth()/mv.getHeight();
    199226                        if ((double)w/h > aspectRatio) {
    200227                                int neww = (int)(h*aspectRatio);
     
    212239                return new Rectangle(x,y,w,h);
    213240        }
     241
     242        /**
     243         * If the action goes inactive, remove the selection rectangle from screen
     244         */
     245        public void propertyChange(PropertyChangeEvent evt) {
     246                if (evt.getPropertyName() == "active" && !(Boolean)evt.getNewValue() && mousePosStart != null) {
     247                        paintRect();
     248                        mousePosStart = null;
     249                        mousePos = null;
     250                }
     251        }
     252
     253        /**
     254         * Return a list of all objects in the rectangle, respecting the different
     255         * modifier.
     256         * @param alt Whether the alt key was pressed, which means select all objects
     257         *              that are touched, instead those which are completly covered. Also
     258         *              select whole tracks instead of line segments.
     259         */
     260        public Collection<OsmPrimitive> getObjectsInRectangle(Rectangle r, boolean alt) {
     261                Collection<OsmPrimitive> selection = new LinkedList<OsmPrimitive>();
     262
     263                // whether user only clicked, not dragged.
     264                boolean clicked = r.width <= 2 && r.height <= 2;
     265                Point center = new Point(r.x+r.width/2, r.y+r.height/2);
     266
     267                if (clicked) {
     268                        OsmPrimitive osm = mv.getNearest(center, alt);
     269                        if (osm != null)
     270                                selection.add(osm);
     271                } else {
     272                        // nodes
     273                        for (Node n : mv.dataSet.nodes) {
     274                                if (r.contains(mv.getScreenPoint(n.coor)))
     275                                        selection.add(n);
     276                        }
     277                       
     278                        // pending line segments
     279                        for (LineSegment ls : mv.dataSet.pendingLineSegments)
     280                                if (rectangleContainLineSegment(r, alt, ls))
     281                                        selection.add(ls);
     282
     283                        // tracks
     284                        for (Track t : mv.dataSet.tracks) {
     285                                boolean wholeTrackSelected = t.segments.size() > 0;
     286                                for (LineSegment ls : t.segments)
     287                                        if (rectangleContainLineSegment(r, alt, ls))
     288                                                selection.add(ls);
     289                                        else
     290                                                wholeTrackSelected = false;
     291                                if (wholeTrackSelected)
     292                                        selection.add(t);
     293                        }
     294                       
     295                        // TODO areas
     296                }
     297                return selection;
     298        }
     299
     300        /**
     301         * Decide whether the line segment is in the rectangle Return
     302         * <code>true</code>, if it is in or false if not.
     303         *
     304         * @param r                     The rectangle, in which the line segment has to be.
     305         * @param alt           Whether user pressed the Alt key
     306         * @param ls            The line segment.
     307         * @return <code>true</code>, if the LineSegment was added to the selection.
     308         */
     309        private boolean rectangleContainLineSegment(Rectangle r, boolean alt, LineSegment ls) {
     310                if (alt) {
     311                        Point p1 = mv.getScreenPoint(ls.start.coor);
     312                        Point p2 = mv.getScreenPoint(ls.end.coor);
     313                        if (r.intersectsLine(p1.x, p1.y, p2.x, p2.y))
     314                                return true;
     315                } else {
     316                        if (r.contains(mv.getScreenPoint(ls.start.coor))
     317                                        && r.contains(mv.getScreenPoint(ls.end.coor)))
     318                                return true;
     319                }
     320                return false;
     321        }
    214322       
     323       
    215324        /**
    216325         * Does nothing. Only to satisfy MouseListener
     
    229338         */
    230339        public void mouseMoved(MouseEvent e) {}
     340
    231341}
Note: See TracChangeset for help on using the changeset viewer.