001package jmri.jmrit.display.layoutEditor; 002 003import java.awt.*; 004import java.awt.geom.Line2D; 005import java.awt.geom.Point2D; 006import java.awt.geom.Rectangle2D; 007 008import javax.annotation.Nonnull; 009import javax.swing.*; 010 011import jmri.util.*; 012 013/* 014* This is an intermediate component used to put the Layout Editor 015* into the component layers hierarchy so that objects can be drawn 016* in front of or behind layout editor objects. 017* 018* @author George Warner Copyright (c) 2017-2018 019 */ 020class LayoutEditorComponent extends JComponent { 021 022 private final LayoutEditor layoutEditor; 023 024 // Antialiasing rendering 025 protected static final RenderingHints antialiasing = new RenderingHints( 026 RenderingHints.KEY_ANTIALIASING, 027 RenderingHints.VALUE_ANTIALIAS_ON); 028 029 protected LayoutEditorComponent(@Nonnull final LayoutEditor LayoutEditor) { 030 super(); 031 this.layoutEditor = LayoutEditor; 032 } 033 034 /* 035 * {@inheritDoc} 036 */ 037 @Override 038 public void paint(Graphics g) { 039 if (g instanceof Graphics2D) { 040 // layoutEditor.draw((Graphics2D) g); 041 042 Graphics2D g2 = (Graphics2D) g; 043 044 if (clipBounds != null) { 045 if (!clipBounds.isEmpty()) { 046 if ((clipBounds.getWidth() > 0) && (clipBounds.getHeight() > 0)) { 047 // clipBounds is the visible part of the panel, 048 // used here to cull drawing, while the incoming clip in g2 049 // is the area Swing actually asked for in original graphics units 050 // (not scaled units). 051 052 log.debug("LEComponent.paint(): original g2 clip: {} requested clip: {}", 053 g2.getClipBounds(), clipBounds); 054 055 g2.setClip(clipBounds); 056 } 057 } 058 } 059 // Optional antialising, to eliminate (reduce) staircase on diagonal lines 060 if (layoutEditor.getAntialiasingOn()) { 061 g2.setRenderingHints(antialiasing); 062 } 063 064 // drawPositionableLabelBorder(g2); 065 // things that only get drawn in edit mode 066 if (layoutEditor.isEditable()) { 067 if (layoutEditor.getDrawGrid()) { 068 drawPanelGrid(g2); 069 } 070 drawLayoutTracksHidden(g2); 071 } 072 073 drawShapes(g2, true); 074 drawTrackSegmentsDashed(g2); 075 drawLayoutTracksBallast(g2); 076 drawLayoutTracksTies(g2); 077 drawLayoutTracksRails(g2); 078 drawLayoutTracksBlockLines(g2); 079 080 drawPositionablePoints(g2, false); 081 drawPositionablePoints(g2, true); 082 083 drawShapes(g2, false); 084 085 drawDecorations(g2); 086 087 // things that only get drawn in edit mode 088 if (layoutEditor.isEditable()) { 089 drawLayoutTrackEditControls(g2); 090 drawShapeEditControls(g2); 091 092 drawMemoryRects(g2); 093 drawGlobalVariableRects(g2); 094 drawBlockContentsRects(g2); 095 096 if (layoutEditor.allControlling()) { 097 drawTurnoutControls(g2); 098 } 099 drawSelectionRect(g2); 100 highLightSelection(g2); 101 102 drawTrackSegmentInProgress(g2); 103 drawShapeInProgress(g2); 104 105 if (layoutEditor.isDrawLayoutTracksLabel()) { 106 drawLayoutTracksLabel(g2); 107 } 108 } else if (layoutEditor.getTurnoutCircles()) { 109 if (layoutEditor.allControlling()) { 110 drawTurnoutControls(g2); 111 } 112 } 113 } else { 114 log.error("LayoutEditor drawing requires Graphics2D"); 115 } 116 } 117 118 private void drawPanelGrid(Graphics2D g2) { 119 int wideMod = layoutEditor.gContext.getGridSize() * layoutEditor.gContext.getGridSize2nd(); 120 int wideMin = layoutEditor.gContext.getGridSize() / 2; 121 122 // granulize puts these on getGridSize() increments 123 int minX = 0; 124 int minY = 0; 125 int maxX = (int) MathUtil.granulize(layoutEditor.gContext.getLayoutWidth(), layoutEditor.gContext.getGridSize()); 126 int maxY = (int) MathUtil.granulize(layoutEditor.gContext.getLayoutHeight(), layoutEditor.gContext.getGridSize()); 127 128 log.debug("drawPanelGrid: minX: {}, minY: {}, maxX: {}, maxY: {}", minX, minY, maxX, maxY); 129 130 Point2D startPt, stopPt; 131 BasicStroke narrow = new BasicStroke(1.0F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 132 BasicStroke wide = new BasicStroke(2.0F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 133 134 g2.setColor(Color.gray); 135 g2.setStroke(narrow); 136 137 // draw horizontal lines 138 for (int y = minY; y <= maxY; y += layoutEditor.gContext.getGridSize()) { 139 startPt = new Point2D.Double(minX, y); 140 stopPt = new Point2D.Double(maxX, y); 141 142 if ((y % wideMod) < wideMin) { 143 g2.setStroke(wide); 144 g2.draw(new Line2D.Double(startPt, stopPt)); 145 g2.setStroke(narrow); 146 } else { 147 g2.draw(new Line2D.Double(startPt, stopPt)); 148 } 149 } 150 151 // draw vertical lines 152 for (int x = minX; x <= maxX; x += layoutEditor.gContext.getGridSize()) { 153 startPt = new Point2D.Double(x, minY); 154 stopPt = new Point2D.Double(x, maxY); 155 156 if ((x % wideMod) < wideMin) { 157 g2.setStroke(wide); 158 g2.draw(new Line2D.Double(startPt, stopPt)); 159 g2.setStroke(narrow); 160 } else { 161 g2.draw(new Line2D.Double(startPt, stopPt)); 162 } 163 } 164 } 165 166 // 167 // draw hidden layout tracks 168 // 169 private void drawLayoutTracksHidden(Graphics2D g2) { 170 LayoutTrackDrawingOptions ltdo = layoutEditor.getLayoutTrackDrawingOptions(); 171 Stroke stroke = new BasicStroke(1.F); 172 Stroke dashedStroke = new BasicStroke(1.F, 173 BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.F, 174 new float[]{6.F, 4.F}, 0); 175 176 // setup for drawing hidden sideline rails 177 g2.setColor(ltdo.getSideRailColor()); 178 g2.setStroke(stroke); 179 boolean main = false, block = false, hidden = true, dashed = false; 180 draw1(g2, main, block, hidden, dashed); 181 g2.setStroke(dashedStroke); 182 draw1(g2, main, block, hidden, dashed = true); 183 184 // setup for drawing mainline rails 185 main = true; 186 g2.setColor(ltdo.getMainRailColor()); 187 g2.setStroke(stroke); 188 draw1(g2, main, block, hidden, dashed = false); 189 g2.setStroke(dashedStroke); 190 dashed = true; 191 draw1(g2, main, block, hidden, dashed); 192 } 193 194 // 195 // draw dashed track segments 196 // 197 private void drawTrackSegmentsDashed(Graphics2D g2) { 198 LayoutTrackDrawingOptions ltdo = layoutEditor.getLayoutTrackDrawingOptions(); 199 boolean main = false, block = false, hidden = false, dashed = true; 200 201 if (ltdo.getSideRailCount() > 0) { 202 // setup for drawing dashed sideline rails 203 int railWidth = ltdo.getSideRailWidth(); 204 float[] dashArray = new float[]{6.F + railWidth, 4.F + railWidth}; 205 g2.setStroke(new BasicStroke( 206 railWidth, 207 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 208 10.F, dashArray, 0)); 209 g2.setColor(ltdo.getSideRailColor()); 210 if ((ltdo.getSideRailCount() & 1) == 1) { 211 draw1(g2, main, block, hidden, dashed); 212 } 213 if (ltdo.getSideRailCount() >= 2) { 214 float railDisplacement = railWidth + (ltdo.getSideRailGap() / 2.F); 215 draw2(g2, main, railDisplacement, dashed); 216 } 217 } 218 219 if (ltdo.getMainRailCount() > 0) { 220 // setup for drawing dashed mainline rails 221 main = true; 222 int railWidth = ltdo.getMainRailWidth(); 223 float[] dashArray = new float[]{6.F + railWidth, 4.F + railWidth}; 224 g2.setStroke(new BasicStroke( 225 railWidth, 226 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 227 10.F, dashArray, 0)); 228 g2.setColor(ltdo.getMainRailColor()); 229 if ((ltdo.getMainRailCount() & 1) == 1) { 230 draw1(g2, main, block, hidden, dashed); 231 } 232 if (ltdo.getMainRailCount() >= 2) { 233 float railDisplacement = railWidth + (ltdo.getSideRailGap() / 2.F); 234 draw2(g2, main, railDisplacement, dashed); 235 } 236 } 237 } // drawTrackSegmentsDashed 238 239 // 240 // draw layout track ballast 241 // 242 private void drawLayoutTracksBallast(Graphics2D g2) { 243 LayoutTrackDrawingOptions ltdo = layoutEditor.getLayoutTrackDrawingOptions(); 244 boolean main = false, block = false, hidden = false, dashed = false; 245 246 // setup for drawing sideline ballast 247 int ballastWidth = ltdo.getSideBallastWidth(); 248 if (ballastWidth > 0) { 249 g2.setStroke(new BasicStroke(ballastWidth, 250 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 251 g2.setColor(ltdo.getSideBallastColor()); 252 draw1(g2, main, block, hidden, dashed); 253 } 254 255 // setup for drawing mainline ballast 256 ballastWidth = ltdo.getMainBallastWidth(); 257 if (ballastWidth > 0) { 258 g2.setStroke(new BasicStroke(ballastWidth, 259 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 260 g2.setColor(ltdo.getMainBallastColor()); 261 main = true; 262 draw1(g2, main, block, hidden, dashed); 263 } 264 } 265 266 // 267 // draw layout track ties 268 // 269 private void drawLayoutTracksTies(Graphics2D g2) { 270 LayoutTrackDrawingOptions ltdo = layoutEditor.getLayoutTrackDrawingOptions(); 271 272 // setup for drawing sideline ties 273 int tieLength = ltdo.getSideTieLength(); 274 int tieWidth = ltdo.getSideTieWidth(); 275 int tieGap = ltdo.getSideTieGap(); 276 if ((tieLength > 0) && (tieWidth > 0) && (tieGap > 0)) { 277 g2.setStroke(new BasicStroke(tieLength, 278 BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.F, 279 new float[]{tieWidth, tieGap}, 0)); 280 g2.setColor(ltdo.getSideTieColor()); 281 draw1(g2, false); // main = false 282 } 283 284 // setup for drawing mainline ties 285 tieLength = ltdo.getMainTieLength(); 286 tieWidth = ltdo.getMainTieWidth(); 287 tieGap = ltdo.getMainTieGap(); 288 if ((tieLength > 0) && (tieWidth > 0) && (tieGap > 0)) { 289 g2.setStroke(new BasicStroke(tieLength, 290 BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.F, 291 new float[]{tieWidth, tieGap}, 0)); 292 g2.setColor(ltdo.getMainTieColor()); 293 draw1(g2, true); // main = true 294 } 295 } 296 297 // 298 // draw layout track rails 299 // 300 private void drawLayoutTracksRails(Graphics2D g2) { 301 LayoutTrackDrawingOptions ltdo = layoutEditor.getLayoutTrackDrawingOptions(); 302 int railWidth = ltdo.getSideRailWidth(); 303 Color railColor = ltdo.getSideRailColor(); 304 305 boolean main = false, block = false, hidden = false, dashed = false; 306 307 if (ltdo.getSideRailCount() > 1) { 308 // setup for drawing sideline rails 309 float railDisplacement = railWidth + (ltdo.getSideRailGap() / 2.F); 310 g2.setStroke(new BasicStroke(railWidth, 311 BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 312 g2.setColor(railColor); 313 draw2(g2, main, railDisplacement); 314 } 315 316 if ((ltdo.getSideRailCount() & 1) == 1) { 317 // setup for drawing sideline rails 318 g2.setStroke(new BasicStroke( 319 railWidth, 320 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 321 g2.setColor(railColor); 322 draw1(g2, main, block, hidden, dashed); 323 } 324 325 main = true; 326 327 railWidth = ltdo.getMainRailWidth(); 328 railColor = ltdo.getMainRailColor(); 329 if (ltdo.getMainRailCount() > 1) { 330 // setup for drawing mainline rails 331 float railDisplacement = railWidth + (ltdo.getMainRailGap() / 2.F); 332 g2.setStroke(new BasicStroke(railWidth, 333 BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 334 g2.setColor(railColor); 335 draw2(g2, main, railDisplacement); 336 } 337 if ((ltdo.getMainRailCount() & 1) == 1) { 338 // setup for drawing mainline rails 339 g2.setStroke(new BasicStroke( 340 railWidth, 341 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 342 g2.setColor(railColor); 343 dashed = false; 344 draw1(g2, main, block, hidden, dashed); 345 } 346 } // drawLayoutTracksRails 347 348 // 349 // draw layout track block lines 350 // 351 private void drawLayoutTracksBlockLines(Graphics2D g2) { 352 LayoutTrackDrawingOptions ltdo = layoutEditor.getLayoutTrackDrawingOptions(); 353 354 // setup for drawing sideline block lines 355 int blockLineWidth = ltdo.getSideBlockLineWidth(); 356 float[] dashArray = new float[]{6.F + blockLineWidth, 4.F + blockLineWidth}; 357 358 Stroke blockLineStroke; 359 int dashPercentageX10 = ltdo.getSideBlockLineDashPercentageX10(); 360 if (dashPercentageX10 > 0) { 361 float[] blockLineDashArray = new float[]{ 362 dashPercentageX10 + blockLineWidth, 363 10.F - dashPercentageX10 + blockLineWidth}; 364 blockLineStroke = new BasicStroke( 365 blockLineWidth, 366 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 367 10.F, blockLineDashArray, 0); 368 g2.setStroke(blockLineStroke); 369 } else { 370 blockLineStroke = new BasicStroke( 371 blockLineWidth, 372 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 373 g2.setStroke(new BasicStroke( 374 blockLineWidth, 375 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 376 10.F, dashArray, 0)); 377 } 378 379 // note: color is set in layout track's draw1 when isBlock is true 380 boolean main = false, block = true, hidden = false, dashed = true; 381 draw1(g2, main, block, hidden, dashed); 382 g2.setStroke(blockLineStroke); 383 draw1(g2, main, block, hidden, dashed = false); 384 385 // setup for drawing mainline block lines 386 blockLineWidth = ltdo.getMainBlockLineWidth(); 387 dashArray = new float[]{6.F + blockLineWidth, 4.F + blockLineWidth}; 388 389 dashPercentageX10 = ltdo.getMainBlockLineDashPercentageX10(); 390 if (dashPercentageX10 > 0) { 391 float[] blockLineDashArray = new float[]{ 392 dashPercentageX10 + blockLineWidth, 393 10 - dashPercentageX10 + blockLineWidth}; 394 blockLineStroke = new BasicStroke( 395 blockLineWidth, 396 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 397 10.F, blockLineDashArray, 0); 398 g2.setStroke(blockLineStroke); 399 } else { 400 blockLineStroke = new BasicStroke( 401 blockLineWidth, 402 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 403 g2.setStroke(new BasicStroke( 404 blockLineWidth, 405 BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 406 10.F, dashArray, 0)); 407 } 408 // note: color is set in layout track's draw1 when isBlock is true 409 draw1(g2, main = true, block, hidden, dashed = true); 410 g2.setStroke(blockLineStroke); 411 dashed = false; 412 draw1(g2, main, block, hidden, dashed); 413 } 414 415 // isDashed defaults to false 416 private void draw1(Graphics2D g2, 417 boolean isMain, 418 boolean isBlock, 419 boolean isHidden) { 420 draw1(g2, isMain, isBlock, isHidden, false); 421 } 422 423 // isHidden defaults to false 424 private void draw1(Graphics2D g2, 425 boolean isMain, 426 boolean isBlock) { 427 draw1(g2, isMain, isBlock, false); 428 } 429 430 // isBlock defaults to false 431 private void draw1(Graphics2D g2, boolean isMain) { 432 draw1(g2, isMain, false); 433 } 434 435 // draw single line (ballast, ties & block lines) 436 private void draw1(Graphics2D g2, 437 boolean isMain, 438 boolean isBlock, 439 boolean isHidden, 440 boolean isDashed) { 441 for (LayoutTrackView layoutTrackView : layoutEditor.getLayoutTrackViews()) { 442 if (!(layoutTrackView instanceof PositionablePointView)) { 443 if (isHidden == layoutTrackView.isHidden()) { 444 if ((layoutTrackView instanceof TrackSegmentView)) { 445 if (((TrackSegmentView) layoutTrackView).isDashed() == isDashed) { 446 layoutTrackView.draw1(g2, isMain, isBlock); 447 } 448 } else if (!isDashed) { 449 layoutTrackView.draw1(g2, isMain, isBlock); 450 } 451 } 452 } 453 } 454 } 455 456 // draw positionable points 457 private void drawPositionablePoints(Graphics2D g2, boolean isMain) { 458 for (PositionablePointView positionablePointView : layoutEditor.getPositionablePointViews()) { 459 positionablePointView.draw1(g2, isMain, false); 460 } 461 } 462 463 // isDashed defaults to false 464 private void draw2(Graphics2D g2, boolean isMain, float railDisplacement) { 465 draw2(g2, isMain, railDisplacement, false); 466 } 467 468 // draw parallel lines (rails) 469 private void draw2(Graphics2D g2, boolean isMain, 470 float railDisplacement, boolean isDashed) { 471 for (LayoutTrackView layoutTrackView : layoutEditor.getLayoutTrackViews()) { 472 if ((layoutTrackView instanceof TrackSegmentView)) { 473 if (((TrackSegmentView) layoutTrackView).isDashed() == isDashed) { 474 layoutTrackView.draw2(g2, isMain, railDisplacement); 475 } 476 } else if (!isDashed) { 477 layoutTrackView.draw2(g2, isMain, railDisplacement); 478 } 479 } 480 } 481 482 // draw decorations 483 private void drawDecorations(Graphics2D g2) { 484 layoutEditor.getLayoutTrackViews().forEach((tr) -> tr.drawDecorations(g2)); 485 } 486 487 // draw shapes 488 private void drawShapes(Graphics2D g2, boolean isBackground) { 489 layoutEditor.getLayoutShapes().forEach((s) -> { 490 if (isBackground == (s.getLevel() < 3)) { 491 s.draw(g2); 492 } 493 }); 494 } 495 496 // draw track segment (in progress) 497 private void drawTrackSegmentInProgress(Graphics2D g2) { 498 // check for segment in progress 499 if (layoutEditor.isEditable() && (layoutEditor.beginTrack != null) && layoutEditor.getLayoutEditorToolBarPanel().trackButton.isSelected()) { 500 g2.setColor(layoutEditor.defaultTrackColor); 501 g2.setStroke(new BasicStroke(layoutEditor.gContext.getSidelineTrackWidth(), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 502 g2.draw(new Line2D.Double(layoutEditor.beginLocation, layoutEditor.currentLocation)); 503 504 // highlight unconnected endpoints of all tracks 505 Color highlightColor = ColorUtil.setAlpha(Color.red, 0.25); 506 Color connectColor = ColorUtil.setAlpha(Color.green, 0.5); 507 g2.setColor(highlightColor); 508 g2.setStroke(new BasicStroke(1.0F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 509 for (LayoutTrack lt : layoutEditor.getLayoutTracks()) { 510 if (lt != layoutEditor.beginTrack) { 511 LayoutTrackView ltv = layoutEditor.getLayoutTrackView(lt); 512 if (lt == layoutEditor.foundTrack) { 513 ltv.highlightUnconnected(g2); 514 g2.setColor(connectColor); 515 ltv.highlightUnconnected(g2, layoutEditor.foundHitPointType); 516 g2.setColor(highlightColor); 517 } else { 518 ltv.highlightUnconnected(g2); 519 } 520 } 521 } 522 } 523 } 524 525 // draw shape (in progress) 526 private void drawShapeInProgress(Graphics2D g2) { 527 // check for segment in progress 528 if (layoutEditor.getLayoutEditorToolBarPanel().shapeButton.isSelected()) { 529 // log.warn("drawShapeInProgress: selectedObject: " + selectedObject); 530 if ((layoutEditor.selectedObject != null)) { 531 g2.setColor(Color.DARK_GRAY); 532 g2.setStroke(new BasicStroke(3.0F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 533 g2.draw(new Line2D.Double(layoutEditor.beginLocation, layoutEditor.currentLocation)); 534 } 535 } 536 } 537 538 // draw layout track edit controls 539 private void drawLayoutTrackEditControls(Graphics2D g2) { 540 g2.setStroke(new BasicStroke(1.0F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 541 542 layoutEditor.getLayoutTrackViews().forEach((tr) -> tr.drawEditControls(g2)); 543 } 544 545 private void drawShapeEditControls(Graphics2D g2) { 546 g2.setStroke(new BasicStroke(1.0F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 547 layoutEditor.getLayoutShapes().forEach((s) -> s.drawEditControls(g2)); 548 } 549 550 // draw layout turnout controls 551 private void drawTurnoutControls(Graphics2D g2) { 552 g2.setStroke(new BasicStroke(1.0F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 553 g2.setColor(layoutEditor.turnoutCircleColor); 554 g2.setBackground(layoutEditor.turnoutCircleThrownColor); 555 556 // loop over all turnouts 557 boolean editable = layoutEditor.isEditable(); 558 layoutEditor.getLayoutTrackViews().forEach((tr) -> { 559 if (tr instanceof LayoutTurnoutView) { //<== this includes LayoutSlips 560 LayoutTurnoutView lt = (LayoutTurnoutView) tr; 561 if (editable || !(lt.isHidden() || lt.isDisabled())) { 562 lt.drawTurnoutControls(g2); 563 } 564 } else if (tr instanceof LayoutTurntableView) { 565 LayoutTurntableView lt = (LayoutTurntableView) tr; 566 if (editable || !lt.isHidden()) { 567 lt.drawTurnoutControls(g2); 568 } 569 }else if (tr instanceof LayoutTraverserView) { 570 LayoutTraverserView lt = (LayoutTraverserView) tr; 571 if (editable || !lt.isHidden()) { 572 lt.drawTurnoutControls(g2); 573 } 574 } 575 }); 576 577 } 578 579 private void drawSelectionRect(Graphics2D g2) { 580 if (layoutEditor.selectionActive && (layoutEditor.selectionWidth != 0.0) && (layoutEditor.selectionHeight != 0.0)) { 581 // The Editor super class draws a dashed red selection rectangle... 582 // We're going to also draw a non-dashed yellow selection rectangle... 583 // This could be code stripped if the super-class implementation is "good enough" 584 Stroke stroke = g2.getStroke(); 585 Color color = g2.getColor(); 586 587 g2.setColor(new Color(204, 207, 88)); 588 g2.setStroke(new BasicStroke(3.0F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 589 590 g2.draw(layoutEditor.getSelectionRect()); // this sets _selectRect also 591 592 g2.setColor(color); 593 g2.setStroke(stroke); 594 } else { 595 layoutEditor.setSelectRect(null); // and clear it to turn it off 596 } 597 } 598 599 private void drawMemoryRects(Graphics2D g2) { 600 g2.setColor(layoutEditor.defaultTrackColor); 601 g2.setStroke(new BasicStroke(1.0F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 602 603 layoutEditor.getMemoryLabelList().forEach((l) -> g2.draw(new Rectangle2D.Double(l.getX(), l.getY(), l.getSize().width, l.getSize().height))); 604 } 605 606 private void drawGlobalVariableRects(Graphics2D g2) { 607 g2.setColor(layoutEditor.defaultTrackColor); 608 g2.setStroke(new BasicStroke(1.0F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 609 610 layoutEditor.getGlobalVariableLabelList().forEach((l) -> g2.draw(new Rectangle2D.Double(l.getX(), l.getY(), l.getSize().width, l.getSize().height))); 611 } 612 613 private void drawBlockContentsRects(Graphics2D g2) { 614 g2.setColor(layoutEditor.defaultTrackColor); 615 g2.setStroke(new BasicStroke(1.0F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)); 616 617 layoutEditor.getBlockContentsLabelList().forEach((l) -> g2.draw(new Rectangle2D.Double(l.getX(), l.getY(), l.getSize().width, l.getSize().height))); 618 } 619 620 private void highLightSelection(Graphics2D g) { 621 Stroke stroke = g.getStroke(); 622 Color color = g.getColor(); 623 g.setColor(new Color(204, 207, 88)); 624 g.setStroke(new BasicStroke(2.0f)); 625 626 layoutEditor.getPositionalSelection().forEach((c) -> g.drawRect(c.getX(), c.getY(), c.maxWidth(), c.maxHeight())); 627 628 layoutEditor._layoutTrackSelection.stream().map((lt) -> { 629 LayoutTrackView ltv = layoutEditor.getLayoutTrackView(lt); 630 Rectangle2D r = ltv.getBounds(); 631 if (r.isEmpty()) { 632 r = MathUtil.inset(r, -4.0); 633 } 634 //r = MathUtil.centerRectangleOnPoint(r, ltv.getCoordsCenter()); 635 return r; 636 }).forEachOrdered(g::draw); 637 638 layoutEditor._layoutShapeSelection.stream().map((ls) -> { 639 Rectangle2D r = ls.getBounds(); 640 if (r.isEmpty()) { 641 r = MathUtil.inset(r, -4.0); 642 } 643 //r = MathUtil.centerRectangleOnPoint(r, ls.getCoordsCenter()); 644 return r; 645 }).forEachOrdered(g::draw); 646 647 g.setColor(color); 648 g.setStroke(stroke); 649 } 650 651 private void drawLayoutTracksLabel(Graphics2D g) { 652 g.setFont(new Font(Font.MONOSPACED, Font.BOLD, 12)); 653 g.setColor(Color.red); 654 for (LayoutTrackView layoutTrackView : layoutEditor.getLayoutTrackViews()) { 655 layoutTrackView.drawLayoutTrackText(g); 656 } 657 } 658 659 /* 660 * {@inheritDoc} 661 */ 662 @Override 663 public Rectangle getBounds() { 664 JComponent targetPanel = layoutEditor.getTargetPanel(); 665 Rectangle2D targetBounds = targetPanel.getBounds(); 666 Container parent = getParent(); 667 if (parent != null) { // if there is a parent... 668 Rectangle2D parentBounds = parent.getBounds(); 669 670 // convert our origin to parent coordinates 671 Point2D origin = new Point2D.Double( 672 targetBounds.getX() - parentBounds.getX(), 673 targetBounds.getY() - parentBounds.getY()); 674 675 return new Rectangle((int) origin.getX(), (int) origin.getY(), 676 (int) targetBounds.getWidth(), (int) targetBounds.getHeight()); 677 } else { 678 return MathUtil.rectangle2DToRectangle(targetBounds); 679 } 680 } 681 682 /* 683 * {@inheritDoc} 684 */ 685 @Override 686 public Rectangle getBounds(Rectangle rv) { 687 rv.setBounds(getBounds()); 688 return rv; 689 } 690 691 /* 692 * {@inheritDoc} 693 */ 694 @Override 695 public int getX() { 696 Rectangle bounds = getBounds(); 697 return (int) bounds.getX(); 698 } 699 700 /* 701 * {@inheritDoc} 702 */ 703 @Override 704 public int getY() { 705 Rectangle bounds = getBounds(); 706 return (int) bounds.getY(); 707 } 708 709 /* 710 * {@inheritDoc} 711 */ 712 @Override 713 public int getWidth() { 714 Rectangle bounds = getBounds(); 715 return (int) bounds.getWidth(); 716 } 717 718 /* 719 * {@inheritDoc} 720 */ 721 @Override 722 public int getHeight() { 723 Rectangle bounds = getBounds(); 724 return (int) bounds.getHeight(); 725 } 726 727 private Rectangle2D clipBounds = null; 728 729 public void setClip(Rectangle2D clipBounds) { 730 this.clipBounds = clipBounds; 731 } 732 733 // initialize logging 734 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutEditorComponent.class); 735}