From 51a12d61e1bb6c2844d36fc1ecac52af8119ceaf Mon Sep 17 00:00:00 2001 From: Tim Savage Date: Sun, 10 Feb 2019 01:53:11 +1100 Subject: [PATCH] Allow the origin of co-ordinates on boards to be specified (#428) * Added support to specific co-ordinate origin. Added the Coordinate origin property to the AbstractBoard class, this allows the user to specify the corner (TopLeft, TopRight, BottomLeft, BottomRight) cordinates should increment from. Updated rendering to reflect this change. * Use the coordinate origin setter method To safely handle the case when a project produced with an earlier verison of the application is loaded and the coordinate origin attribute is set to NULL. --- .../components/boards/AbstractBoard.java | 375 ++++++++++-------- 1 file changed, 215 insertions(+), 160 deletions(-) diff --git a/diylc/diylc-library/src/org/diylc/components/boards/AbstractBoard.java b/diylc/diylc-library/src/org/diylc/components/boards/AbstractBoard.java index 7888b22e..56906bfc 100644 --- a/diylc/diylc-library/src/org/diylc/components/boards/AbstractBoard.java +++ b/diylc/diylc-library/src/org/diylc/components/boards/AbstractBoard.java @@ -19,8 +19,8 @@ along with DIYLC. If not, see . */ -package org.diylc.components.boards; - +package org.diylc.components.boards; + import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; @@ -38,132 +38,167 @@ import org.diylc.core.VisibilityPolicy; import org.diylc.core.annotations.EditableProperty; import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; - -public abstract class AbstractBoard extends AbstractTransparentComponent { - - private static final long serialVersionUID = 1L; - - public static Color BOARD_COLOR = Color.decode("#F8EBB3"); - public static Color BORDER_COLOR = BOARD_COLOR.darker(); - public static Color COORDINATE_COLOR = Color.gray.brighter(); - public static float COORDINATE_FONT_SIZE = 9f; - public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in); - public static Size DEFAULT_HEIGHT = new Size(1.2d, SizeUnit.in); - - protected String value = ""; - protected Point[] controlPoints = new Point[] {new Point(0, 0), - new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels())}; - protected Point firstPoint = new Point(); - protected Point secondPoint = new Point(); - - protected Color boardColor = BOARD_COLOR; - protected Color borderColor = BORDER_COLOR; - protected Color coordinateColor = COORDINATE_COLOR; + +public abstract class AbstractBoard extends AbstractTransparentComponent { + + private static final long serialVersionUID = 1L; + + public static Color BOARD_COLOR = Color.decode("#F8EBB3"); + public static Color BORDER_COLOR = BOARD_COLOR.darker(); + public static Color COORDINATE_COLOR = Color.gray.brighter(); + public static float COORDINATE_FONT_SIZE = 9f; + public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in); + public static Size DEFAULT_HEIGHT = new Size(1.2d, SizeUnit.in); + + protected String value = ""; + protected Point[] controlPoints = new Point[] {new Point(0, 0), + new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels())}; + protected Point firstPoint = new Point(); + protected Point secondPoint = new Point(); + + protected Color boardColor = BOARD_COLOR; + protected Color borderColor = BORDER_COLOR; + protected Color coordinateColor = COORDINATE_COLOR; protected Boolean drawCoordinates = null; protected CoordinateType xType = CoordinateType.Numbers; + protected CoordinateOrigin coordinateOrigin = CoordinateOrigin.Top_Left; protected CoordinateDisplay coordinateDisplay = CoordinateDisplay.One_Side; - protected CoordinateType yType = CoordinateType.Letters; - - @Override - public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, - IDrawingObserver drawingObserver) { - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); - + protected CoordinateType yType = CoordinateType.Letters; + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + Composite oldComposite = g2d.getComposite(); // render as transparent when dragging - int alpha = componentState == ComponentState.DRAGGING ? 0 : this.alpha; - if (alpha < MAX_ALPHA) { - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); - } - g2d.setColor(boardColor); - g2d.fillRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); - g2d.setComposite(oldComposite); - - // Do not track any changes that follow because the whole board has been - // tracked so far. - drawingObserver.stopTracking(); - g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR - : borderColor); - g2d.drawRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); - } - - protected void drawCoordinates(Graphics2D g2d, int spacing, Project project) { - g2d.setColor(coordinateColor); - g2d.setFont(project.getFont().deriveFont(COORDINATE_FONT_SIZE)); + int alpha = componentState == ComponentState.DRAGGING ? 0 : this.alpha; + if (alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); + } + g2d.setColor(boardColor); + g2d.fillRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); + g2d.setComposite(oldComposite); + + // Do not track any changes that follow because the whole board has been + // tracked so far. + drawingObserver.stopTracking(); + g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : borderColor); + g2d.drawRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); + } + + protected void drawCoordinates(Graphics2D g2d, int spacing, Project project) { + g2d.setColor(coordinateColor); + g2d.setFont(project.getFont().deriveFont(COORDINATE_FONT_SIZE)); + + // The half space is used to do rounding when calculating the range. + int halfSpace = spacing / 2; + CoordinateOrigin origin = getCoordinateOrigin(); + + if (getCoordinateDisplay() != CoordinateDisplay.None) { + int range; + int yOffset; + CoordinateType yType = getyType(); + Point drawPoint = new Point(firstPoint); + + if (origin == CoordinateOrigin.Top_Left || origin == CoordinateOrigin.Top_Right) { + range = (int) ((secondPoint.y - firstPoint.y + halfSpace) / spacing); + yOffset = spacing; + } else { + range = (int) ((secondPoint.y - firstPoint.y + halfSpace) / spacing); + yOffset = -spacing; + drawPoint.y = secondPoint.y; + } + + for (int c = 1; c < range; c++) { + int xOffset = (yType == CoordinateType.Numbers && c >= 10) || (yType == CoordinateType.Letters && c >= 27) ? 0 : 2; + String label = yType == CoordinateType.Letters ? getCoordinateLabel(c) : Integer.toString(c); + + drawPoint.y += yOffset; + drawCenteredText(g2d, label, + firstPoint.x + xOffset, drawPoint.y, + HorizontalAlignment.LEFT, VerticalAlignment.CENTER); + if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) { + drawCenteredText(g2d, label, + secondPoint.x - xOffset, drawPoint.y, + HorizontalAlignment.RIGHT, VerticalAlignment.CENTER); + } + } + } if (getCoordinateDisplay() != CoordinateDisplay.None) { - Point p = new Point(firstPoint); - int t = 1; - while (p.y < secondPoint.y - spacing) { - p.y += spacing; - int offset = (getyType() == CoordinateType.Numbers && t >= 10) || (getyType() == CoordinateType.Letters && t >= 27) ? 0 : 2; - drawCenteredText(g2d, getyType() == CoordinateType.Letters ? getCoordinateLabel(t) : Integer.toString(t), p.x + offset, p.y, HorizontalAlignment.LEFT, - VerticalAlignment.CENTER); - if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) { - drawCenteredText(g2d, getyType() == CoordinateType.Letters ? getCoordinateLabel(t) : Integer.toString(t), secondPoint.x - offset, p.y, HorizontalAlignment.RIGHT, - VerticalAlignment.CENTER); - } - t++; + int range; + int xOffset; + CoordinateType xType = getxType(); + Point drawPoint = new Point(firstPoint); + + if (origin == CoordinateOrigin.Top_Left || origin == CoordinateOrigin.Bottom_Left) { + range = (int) ((secondPoint.x - firstPoint.x + halfSpace) / spacing); + xOffset = spacing; + } else { + range = (int) ((secondPoint.x - firstPoint.x + halfSpace) / spacing); + xOffset = -spacing; + drawPoint.x = secondPoint.x; } - } + + for (int c = 1; c < range; c++) { + String label = xType == CoordinateType.Letters ? getCoordinateLabel(c) : Integer.toString(c); + + drawPoint.x += xOffset; + drawCenteredText(g2d, label, + drawPoint.x, firstPoint.y - 2, + HorizontalAlignment.CENTER, VerticalAlignment.TOP); + if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) { + drawCenteredText(g2d, label, + drawPoint.x, (int) (secondPoint.y - COORDINATE_FONT_SIZE), + HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM); + } + } + } + } - if (getCoordinateDisplay() != CoordinateDisplay.None) { - Point p = new Point(firstPoint); - int t = 1; - while (p.x < secondPoint.x - spacing) { - p.x += spacing; - drawCenteredText(g2d, getxType() == CoordinateType.Letters ? getCoordinateLabel(t) : Integer.toString(t), p.x, p.y - 2, HorizontalAlignment.CENTER, - VerticalAlignment.TOP); - if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) { - drawCenteredText(g2d, getxType() == CoordinateType.Letters ? getCoordinateLabel(t) : Integer.toString(t), p.x, (int) (secondPoint.y - COORDINATE_FONT_SIZE), HorizontalAlignment.CENTER, - VerticalAlignment.BOTTOM); - } - t++; + private String getCoordinateLabel(int coordinate) { + String result = ""; + while (coordinate > 0) { + int digit = coordinate % 26; + coordinate /= 26; + if (digit == 0) { + result = 'Z' + result; + coordinate--; + } else { + result = (char) ((int) 'A' + digit - 1) + result; } - } - } - - private String getCoordinateLabel(int coordinate) { - String result = ""; - while (coordinate > 0) { - int digit = coordinate % 26; - coordinate /= 26; - if (digit == 0) { - result = 'Z' + result; - coordinate--; - } else { - result = (char) ((int) 'A' + digit - 1) + result; - } - } - return result; - } - - @EditableProperty(name = "Color") - public Color getBoardColor() { - return boardColor; - } - - public void setBoardColor(Color boardColor) { - this.boardColor = boardColor; - } - - @EditableProperty(name = "Coordinate Color") - public Color getCoordinateColor() { - // Null protection for older files - return coordinateColor == null ? COORDINATE_COLOR : coordinateColor; - } - - public void setCoordinateColor(Color coordinateColor) { - this.coordinateColor = coordinateColor; - } - - @EditableProperty(name = "Border") - public Color getBorderColor() { - return borderColor; - } - - public void setBorderColor(Color borderColor) { - this.borderColor = borderColor; + } + return result; + } + + @EditableProperty(name = "Color") + public Color getBoardColor() { + return boardColor; + } + + public void setBoardColor(Color boardColor) { + this.boardColor = boardColor; + } + + @EditableProperty(name = "Coordinate Color") + public Color getCoordinateColor() { + // Null protection for older files + return coordinateColor == null ? COORDINATE_COLOR : coordinateColor; + } + + public void setCoordinateColor(Color coordinateColor) { + this.coordinateColor = coordinateColor; + } + + @EditableProperty(name = "Border") + public Color getBorderColor() { + return borderColor; + } + + public void setBorderColor(Color borderColor) { + this.borderColor = borderColor; } @EditableProperty(name = "X") @@ -188,6 +223,17 @@ public abstract class AbstractBoard extends AbstractTransparentComponent this.coordinateDisplay = coordinateDisplay; } + @EditableProperty(name = "Coordinate Origin") + public CoordinateOrigin getCoordinateOrigin() { + if (coordinateOrigin == null) + coordinateOrigin = CoordinateOrigin.Top_Left; + return coordinateOrigin; + } + + public void setCoordinateOrigin(CoordinateOrigin coordinateOrigin) { + this.coordinateOrigin = coordinateOrigin; + } + @EditableProperty(name = "Y") public CoordinateType getyType() { if (yType == null) @@ -197,46 +243,46 @@ public abstract class AbstractBoard extends AbstractTransparentComponent public void setyType(CoordinateType yType) { this.yType = yType; - } - - @Override - public int getControlPointCount() { - return controlPoints.length; - } - - @Override - public Point getControlPoint(int index) { - return controlPoints[index]; - } - - @Override - public boolean isControlPointSticky(int index) { - return false; - } - - @Override - public VisibilityPolicy getControlPointVisibilityPolicy(int index) { - return VisibilityPolicy.WHEN_SELECTED; - } - - @Override - public void setControlPoint(Point point, int index) { - controlPoints[index].setLocation(point); - firstPoint.setLocation(Math.min(controlPoints[0].x, controlPoints[1].x), - Math.min(controlPoints[0].y, controlPoints[1].y)); - secondPoint.setLocation(Math.max(controlPoints[0].x, controlPoints[1].x), - Math.max(controlPoints[0].y, controlPoints[1].y)); - } - - @EditableProperty - @Override - public String getValue() { - return value; - } - - @Override - public void setValue(String value) { - this.value = value; + } + + @Override + public int getControlPointCount() { + return controlPoints.length; + } + + @Override + public Point getControlPoint(int index) { + return controlPoints[index]; + } + + @Override + public boolean isControlPointSticky(int index) { + return false; + } + + @Override + public VisibilityPolicy getControlPointVisibilityPolicy(int index) { + return VisibilityPolicy.WHEN_SELECTED; + } + + @Override + public void setControlPoint(Point point, int index) { + controlPoints[index].setLocation(point); + firstPoint.setLocation(Math.min(controlPoints[0].x, controlPoints[1].x), + Math.min(controlPoints[0].y, controlPoints[1].y)); + secondPoint.setLocation(Math.max(controlPoints[0].x, controlPoints[1].x), + Math.max(controlPoints[0].y, controlPoints[1].y)); + } + + @EditableProperty + @Override + public String getValue() { + return value; + } + + @Override + public void setValue(String value) { + this.value = value; } public static enum CoordinateType { @@ -250,5 +296,14 @@ public abstract class AbstractBoard extends AbstractTransparentComponent public String toString() { return super.toString().replace('_', ' '); }; - } -} + } + + public static enum CoordinateOrigin { + Top_Left, Top_Right, Bottom_Right, Bottom_Left; + + @Override + public String toString() { + return super.toString().replace('_', ' '); + }; + } +}