001package jmri.jmrit.display.controlPanelEditor.shape; 002 003import java.awt.Graphics; 004import java.awt.Point; 005import java.awt.Rectangle; 006import java.awt.event.ActionEvent; 007 008import javax.swing.JMenu; 009import javax.swing.JMenuItem; 010 011import jmri.jmrit.display.Editor; 012import jmri.jmrit.display.Positionable; 013import jmri.util.swing.JmriJOptionPane; 014import jmri.util.swing.JmriMouseEvent; 015 016/** 017 * @author Pete Cressman Copyright (c) 2012 018 */ 019public class ShapeDrawer { 020 021 private final Editor _editor; 022 private DrawFrame _drawFrame; 023 private PositionableShape _currentSelection; 024 025 public ShapeDrawer(Editor ed) { 026 _editor = ed; 027 } 028 029 public JMenu makeMenu() { 030 JMenu drawMenu = new JMenu(Bundle.getMessage("drawShapes")); 031 032 JMenuItem shapeItem = new JMenuItem(Bundle.getMessage("drawSth", Bundle.getMessage("Rectangle"))); 033 drawMenu.add(shapeItem); 034 shapeItem.addActionListener((ActionEvent event) -> newRectangle()); 035 shapeItem = new JMenuItem(Bundle.getMessage("drawSth", Bundle.getMessage("roundRect"))); 036 drawMenu.add(shapeItem); 037 shapeItem.addActionListener((ActionEvent event) -> newRoundRectangle()); 038 039 shapeItem = new JMenuItem(Bundle.getMessage("drawSth", Bundle.getMessage("Polygon"))); 040 drawMenu.add(shapeItem); 041 shapeItem.addActionListener((ActionEvent event) -> newPolygon()); 042 043 shapeItem = new JMenuItem(Bundle.getMessage("drawSth", Bundle.getMessage("Circle"))); 044 drawMenu.add(shapeItem); 045 shapeItem.addActionListener((ActionEvent event) -> newCircle()); 046 shapeItem = new JMenuItem(Bundle.getMessage("drawSth", Bundle.getMessage("Ellipse"))); 047 drawMenu.add(shapeItem); 048 shapeItem.addActionListener((ActionEvent event) -> newEllipse()); 049 050 return drawMenu; 051 } 052 053 private void newRectangle() { 054 if (makeNewShape()) { 055 _drawFrame = new DrawRectangle("newShape", "Rectangle", null, _editor, true); 056 } 057 } 058 059 private void newRoundRectangle() { 060 if (makeNewShape()) { 061 _drawFrame = new DrawRoundRect("newShape", "roundRect", null, _editor, true); 062 } 063 } 064 065 private void newPolygon() { 066 if (makeNewShape()) { 067 _drawFrame = new DrawPolygon("newShape", "Polygon", null, _editor, true); 068 } 069 } 070 071 private void newCircle() { 072 if (makeNewShape()) { 073 _drawFrame = new DrawCircle("newShape", "Circle", null, _editor, true); 074 } 075 } 076 077 private void newEllipse() { 078 if (makeNewShape()) { 079 _drawFrame = new DrawEllipse("newShape", "Ellipse", null, _editor, true); 080 } 081 } 082 083 protected boolean makeNewShape() { 084 if (_drawFrame != null) { 085 int ans = JmriJOptionPane.showConfirmDialog(_drawFrame, 086 Bundle.getMessage("cancelFrame", _drawFrame.getTitle()), 087 Bundle.getMessage("QuestionTitle"), 088 JmriJOptionPane.YES_NO_OPTION, JmriJOptionPane.QUESTION_MESSAGE); 089 if (ans == JmriJOptionPane.YES_OPTION) { 090 _drawFrame.closingEvent(true); 091 return true; 092 } else { 093 _drawFrame.toFront(); 094 _drawFrame.setVisible(true); 095 return false; 096 } 097 } else { 098 return true; 099 } 100 } 101 102 protected boolean setDrawFrame(DrawFrame f) { 103 if (f == null) { 104 _drawFrame = null; 105 if (_currentSelection != null) { 106 _currentSelection.removeHandles(); 107 _currentSelection = null; 108 } 109 return true; 110 } 111 if (makeNewShape()) { 112 _drawFrame = f; 113 _currentSelection = _drawFrame._shape; 114 _currentSelection.drawHandles(); 115 _editor.deselectSelectionGroup(); 116 return true; 117 } 118 return false; 119 } 120 121 public void paint(Graphics g) { 122 if (_drawFrame instanceof DrawPolygon) { 123 ((DrawPolygon) _drawFrame).drawShape(g); 124 } 125 } 126 127 ///////////////////////////// Mouse ///////////////////////////// 128 /** 129 * @param event the event to process 130 * @param pos the item to check 131 * @return true if creating or editing; false otherwise 132 */ 133 public boolean doMousePressed(JmriMouseEvent event, Positionable pos) { 134 log.debug("Mouse Pressed _drawFrame= {}, _currentSelection= {}", 135 (_drawFrame==null ? "null" : _drawFrame.getTitle()), 136 (_currentSelection == null ? "null" :_currentSelection.getClass().getName())); 137 if (_drawFrame != null) { 138 if (_drawFrame instanceof DrawPolygon && _drawFrame._shape != null) { 139 ((DrawPolygon) _drawFrame).anchorPoint(event.getX(), event.getY()); 140 } 141 return true; 142 } 143 if (pos instanceof PositionableShape && _editor.isEditable()) { 144 if (_currentSelection != null) { 145 _currentSelection.removeHandles(); 146 } 147 _currentSelection = (PositionableShape) pos; 148 _currentSelection.drawHandles(); 149 return true; 150 } 151 if (_currentSelection != null) { 152 _currentSelection.removeHandles(); 153 _currentSelection = null; 154 } 155 return false; 156 } 157 158 /* 159 * For all PositionableShapes except PositionablePolygon, this terminates the first 160 * phase of creating the PositionableShape. The initial DrawFrame is discarded and 161 * the shape is created, entered into the Editor'c content and the editing version 162 * of the DrawFrame is made. 163 * For a PositionablePolygon, the releases add a vertex to the shape. The actual 164 * creation of the PositionablePolygon, and the above actions are done at doMouseClicked 165 * 166 */ 167 public boolean doMouseReleased(Positionable selection, JmriMouseEvent event, Editor ed) { 168 log.debug("Mouse Released _drawFrame= {}", (_drawFrame==null ? "null" : _drawFrame.getTitle())); 169 if (_drawFrame != null && _drawFrame._shape == null && _drawFrame._create) { 170 if (_drawFrame instanceof DrawPolygon) { 171 ((DrawPolygon)_drawFrame).makeVertex(event, ed); 172 } else { 173 Rectangle r = ed.getSelectRect(); 174 PositionableShape shape; 175 if (r != null) { 176 shape = _drawFrame.makeFigure(r, ed); 177 } else { 178 return false; 179 } 180 shape.setWidth(r.width); 181 shape.setHeight(r.height); 182 shape.setLocation(r.x, r.y); 183 shape.updateSize(); 184 _drawFrame.closingEvent(false); // close opening create prompt frame 185 _drawFrame = shape.makeEditFrame(true); // make finishing create frame; 186 try { 187 ed.putItem(shape); 188 } catch (Positionable.DuplicateIdException e) { 189 // This should never happen 190 log.error("Editor.putItem() with null id has thrown DuplicateIdException", e); 191 } 192 return true; 193 } 194 } 195 return false; 196 } 197 198 public boolean doMouseClicked(JmriMouseEvent event, Editor ed) { 199 log.debug("Mouse Clicked _drawFrame= {}", (_drawFrame==null ? "null" : _drawFrame.getTitle())); 200 if (_drawFrame != null && _drawFrame._create) { 201 PositionableShape shape; 202 if (_drawFrame instanceof DrawPolygon && event.getClickCount() > 1) { 203 shape = _drawFrame.makeFigure(null, ed); 204 if (shape != null) { 205 Point pt = ((DrawPolygon)_drawFrame).getStartPoint(); 206 shape.setLocation(pt.x, pt.y); 207 shape.updateSize(); 208 _drawFrame.closingEvent(false); // close opening create prompt frame 209 _drawFrame = shape.makeEditFrame(true); // make finishing create frame; 210 try { 211 ed.putItem(shape); 212 } catch (Positionable.DuplicateIdException e) { 213 // This should never happen 214 log.error("Editor.putItem() with null id has thrown DuplicateIdException", e); 215 } 216 return true; 217 } 218 } 219 } 220 return false; 221 } 222 223 public boolean doMouseDragged(JmriMouseEvent event) { 224 log.debug("Mouse Dragged _drawFrame= {}, _currentSelection= {}", 225 (_drawFrame==null ? "null" : _drawFrame.getTitle()), 226 (_currentSelection == null ? "null" :_currentSelection.getClass().getName())); 227 if (_currentSelection == null && _drawFrame instanceof DrawPolygon) { 228 ((DrawPolygon) _drawFrame).moveTo(event.getX(), event.getY()); 229 return true; // no select rect 230 } else if (_currentSelection != null) { 231 return _currentSelection.doHandleMove(event); 232 } 233 return false; 234 } 235 236 /* 237 * Make rubber band line 238 */ 239 public boolean doMouseMoved(JmriMouseEvent event) { 240 if (_drawFrame instanceof DrawPolygon) { 241 ((DrawPolygon) _drawFrame).moveTo(event.getX(), event.getY()); 242 return true; // no dragging when editing 243 } 244 return false; 245 } 246 247 public void add(boolean up) { 248 if (_drawFrame instanceof DrawPolygon) { 249 ((DrawPolygon) _drawFrame).addVertex(up); 250 } 251 } 252 253 public void delete() { 254 if (_drawFrame instanceof DrawPolygon) { 255 ((DrawPolygon) _drawFrame).deleteVertex(); 256 } 257 } 258 259 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ShapeDrawer.class); 260 261}