mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
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.
This commit is contained in:
@@ -19,8 +19,8 @@
|
|||||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package org.diylc.components.boards;
|
package org.diylc.components.boards;
|
||||||
|
|
||||||
import java.awt.AlphaComposite;
|
import java.awt.AlphaComposite;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Composite;
|
import java.awt.Composite;
|
||||||
@@ -38,132 +38,167 @@ import org.diylc.core.VisibilityPolicy;
|
|||||||
import org.diylc.core.annotations.EditableProperty;
|
import org.diylc.core.annotations.EditableProperty;
|
||||||
import org.diylc.core.measures.Size;
|
import org.diylc.core.measures.Size;
|
||||||
import org.diylc.core.measures.SizeUnit;
|
import org.diylc.core.measures.SizeUnit;
|
||||||
|
|
||||||
public abstract class AbstractBoard extends AbstractTransparentComponent<String> {
|
public abstract class AbstractBoard extends AbstractTransparentComponent<String> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public static Color BOARD_COLOR = Color.decode("#F8EBB3");
|
public static Color BOARD_COLOR = Color.decode("#F8EBB3");
|
||||||
public static Color BORDER_COLOR = BOARD_COLOR.darker();
|
public static Color BORDER_COLOR = BOARD_COLOR.darker();
|
||||||
public static Color COORDINATE_COLOR = Color.gray.brighter();
|
public static Color COORDINATE_COLOR = Color.gray.brighter();
|
||||||
public static float COORDINATE_FONT_SIZE = 9f;
|
public static float COORDINATE_FONT_SIZE = 9f;
|
||||||
public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in);
|
public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in);
|
||||||
public static Size DEFAULT_HEIGHT = new Size(1.2d, SizeUnit.in);
|
public static Size DEFAULT_HEIGHT = new Size(1.2d, SizeUnit.in);
|
||||||
|
|
||||||
protected String value = "";
|
protected String value = "";
|
||||||
protected Point[] controlPoints = new Point[] {new Point(0, 0),
|
protected Point[] controlPoints = new Point[] {new Point(0, 0),
|
||||||
new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels())};
|
new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels())};
|
||||||
protected Point firstPoint = new Point();
|
protected Point firstPoint = new Point();
|
||||||
protected Point secondPoint = new Point();
|
protected Point secondPoint = new Point();
|
||||||
|
|
||||||
protected Color boardColor = BOARD_COLOR;
|
protected Color boardColor = BOARD_COLOR;
|
||||||
protected Color borderColor = BORDER_COLOR;
|
protected Color borderColor = BORDER_COLOR;
|
||||||
protected Color coordinateColor = COORDINATE_COLOR;
|
protected Color coordinateColor = COORDINATE_COLOR;
|
||||||
protected Boolean drawCoordinates = null;
|
protected Boolean drawCoordinates = null;
|
||||||
protected CoordinateType xType = CoordinateType.Numbers;
|
protected CoordinateType xType = CoordinateType.Numbers;
|
||||||
|
protected CoordinateOrigin coordinateOrigin = CoordinateOrigin.Top_Left;
|
||||||
protected CoordinateDisplay coordinateDisplay = CoordinateDisplay.One_Side;
|
protected CoordinateDisplay coordinateDisplay = CoordinateDisplay.One_Side;
|
||||||
protected CoordinateType yType = CoordinateType.Letters;
|
protected CoordinateType yType = CoordinateType.Letters;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||||
IDrawingObserver drawingObserver) {
|
IDrawingObserver drawingObserver) {
|
||||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||||
|
|
||||||
Composite oldComposite = g2d.getComposite();
|
Composite oldComposite = g2d.getComposite();
|
||||||
// render as transparent when dragging
|
// render as transparent when dragging
|
||||||
int alpha = componentState == ComponentState.DRAGGING ? 0 : this.alpha;
|
int alpha = componentState == ComponentState.DRAGGING ? 0 : this.alpha;
|
||||||
if (alpha < MAX_ALPHA) {
|
if (alpha < MAX_ALPHA) {
|
||||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
|
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
|
||||||
}
|
}
|
||||||
g2d.setColor(boardColor);
|
g2d.setColor(boardColor);
|
||||||
g2d.fillRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
|
g2d.fillRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
|
||||||
g2d.setComposite(oldComposite);
|
g2d.setComposite(oldComposite);
|
||||||
|
|
||||||
// Do not track any changes that follow because the whole board has been
|
// Do not track any changes that follow because the whole board has been
|
||||||
// tracked so far.
|
// tracked so far.
|
||||||
drawingObserver.stopTracking();
|
drawingObserver.stopTracking();
|
||||||
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||||
: borderColor);
|
: borderColor);
|
||||||
g2d.drawRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
|
g2d.drawRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void drawCoordinates(Graphics2D g2d, int spacing, Project project) {
|
protected void drawCoordinates(Graphics2D g2d, int spacing, Project project) {
|
||||||
g2d.setColor(coordinateColor);
|
g2d.setColor(coordinateColor);
|
||||||
g2d.setFont(project.getFont().deriveFont(COORDINATE_FONT_SIZE));
|
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) {
|
if (getCoordinateDisplay() != CoordinateDisplay.None) {
|
||||||
Point p = new Point(firstPoint);
|
int range;
|
||||||
int t = 1;
|
int xOffset;
|
||||||
while (p.y < secondPoint.y - spacing) {
|
CoordinateType xType = getxType();
|
||||||
p.y += spacing;
|
Point drawPoint = new Point(firstPoint);
|
||||||
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,
|
if (origin == CoordinateOrigin.Top_Left || origin == CoordinateOrigin.Bottom_Left) {
|
||||||
VerticalAlignment.CENTER);
|
range = (int) ((secondPoint.x - firstPoint.x + halfSpace) / spacing);
|
||||||
if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) {
|
xOffset = spacing;
|
||||||
drawCenteredText(g2d, getyType() == CoordinateType.Letters ? getCoordinateLabel(t) : Integer.toString(t), secondPoint.x - offset, p.y, HorizontalAlignment.RIGHT,
|
} else {
|
||||||
VerticalAlignment.CENTER);
|
range = (int) ((secondPoint.x - firstPoint.x + halfSpace) / spacing);
|
||||||
}
|
xOffset = -spacing;
|
||||||
t++;
|
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) {
|
private String getCoordinateLabel(int coordinate) {
|
||||||
Point p = new Point(firstPoint);
|
String result = "";
|
||||||
int t = 1;
|
while (coordinate > 0) {
|
||||||
while (p.x < secondPoint.x - spacing) {
|
int digit = coordinate % 26;
|
||||||
p.x += spacing;
|
coordinate /= 26;
|
||||||
drawCenteredText(g2d, getxType() == CoordinateType.Letters ? getCoordinateLabel(t) : Integer.toString(t), p.x, p.y - 2, HorizontalAlignment.CENTER,
|
if (digit == 0) {
|
||||||
VerticalAlignment.TOP);
|
result = 'Z' + result;
|
||||||
if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) {
|
coordinate--;
|
||||||
drawCenteredText(g2d, getxType() == CoordinateType.Letters ? getCoordinateLabel(t) : Integer.toString(t), p.x, (int) (secondPoint.y - COORDINATE_FONT_SIZE), HorizontalAlignment.CENTER,
|
} else {
|
||||||
VerticalAlignment.BOTTOM);
|
result = (char) ((int) 'A' + digit - 1) + result;
|
||||||
}
|
|
||||||
t++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
private String getCoordinateLabel(int coordinate) {
|
|
||||||
String result = "";
|
@EditableProperty(name = "Color")
|
||||||
while (coordinate > 0) {
|
public Color getBoardColor() {
|
||||||
int digit = coordinate % 26;
|
return boardColor;
|
||||||
coordinate /= 26;
|
}
|
||||||
if (digit == 0) {
|
|
||||||
result = 'Z' + result;
|
public void setBoardColor(Color boardColor) {
|
||||||
coordinate--;
|
this.boardColor = boardColor;
|
||||||
} else {
|
}
|
||||||
result = (char) ((int) 'A' + digit - 1) + result;
|
|
||||||
}
|
@EditableProperty(name = "Coordinate Color")
|
||||||
}
|
public Color getCoordinateColor() {
|
||||||
return result;
|
// Null protection for older files
|
||||||
}
|
return coordinateColor == null ? COORDINATE_COLOR : coordinateColor;
|
||||||
|
}
|
||||||
@EditableProperty(name = "Color")
|
|
||||||
public Color getBoardColor() {
|
public void setCoordinateColor(Color coordinateColor) {
|
||||||
return boardColor;
|
this.coordinateColor = coordinateColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBoardColor(Color boardColor) {
|
@EditableProperty(name = "Border")
|
||||||
this.boardColor = boardColor;
|
public Color getBorderColor() {
|
||||||
}
|
return borderColor;
|
||||||
|
}
|
||||||
@EditableProperty(name = "Coordinate Color")
|
|
||||||
public Color getCoordinateColor() {
|
public void setBorderColor(Color borderColor) {
|
||||||
// Null protection for older files
|
this.borderColor = borderColor;
|
||||||
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")
|
@EditableProperty(name = "X")
|
||||||
@@ -188,6 +223,17 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
|
|||||||
this.coordinateDisplay = coordinateDisplay;
|
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")
|
@EditableProperty(name = "Y")
|
||||||
public CoordinateType getyType() {
|
public CoordinateType getyType() {
|
||||||
if (yType == null)
|
if (yType == null)
|
||||||
@@ -197,46 +243,46 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
|
|||||||
|
|
||||||
public void setyType(CoordinateType yType) {
|
public void setyType(CoordinateType yType) {
|
||||||
this.yType = yType;
|
this.yType = yType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getControlPointCount() {
|
public int getControlPointCount() {
|
||||||
return controlPoints.length;
|
return controlPoints.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Point getControlPoint(int index) {
|
public Point getControlPoint(int index) {
|
||||||
return controlPoints[index];
|
return controlPoints[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isControlPointSticky(int index) {
|
public boolean isControlPointSticky(int index) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||||
return VisibilityPolicy.WHEN_SELECTED;
|
return VisibilityPolicy.WHEN_SELECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setControlPoint(Point point, int index) {
|
public void setControlPoint(Point point, int index) {
|
||||||
controlPoints[index].setLocation(point);
|
controlPoints[index].setLocation(point);
|
||||||
firstPoint.setLocation(Math.min(controlPoints[0].x, controlPoints[1].x),
|
firstPoint.setLocation(Math.min(controlPoints[0].x, controlPoints[1].x),
|
||||||
Math.min(controlPoints[0].y, controlPoints[1].y));
|
Math.min(controlPoints[0].y, controlPoints[1].y));
|
||||||
secondPoint.setLocation(Math.max(controlPoints[0].x, controlPoints[1].x),
|
secondPoint.setLocation(Math.max(controlPoints[0].x, controlPoints[1].x),
|
||||||
Math.max(controlPoints[0].y, controlPoints[1].y));
|
Math.max(controlPoints[0].y, controlPoints[1].y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EditableProperty
|
@EditableProperty
|
||||||
@Override
|
@Override
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setValue(String value) {
|
public void setValue(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum CoordinateType {
|
public static enum CoordinateType {
|
||||||
@@ -250,5 +296,14 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString().replace('_', ' ');
|
return super.toString().replace('_', ' ');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static enum CoordinateOrigin {
|
||||||
|
Top_Left, Top_Right, Bottom_Right, Bottom_Left;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString().replace('_', ' ');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user