diff --git a/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java b/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java index 76c4da5d..26f6653a 100644 --- a/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java +++ b/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java @@ -21,25 +21,18 @@ */ package org.diylc.components; -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.geom.Rectangle2D; -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Arrays; +import java.awt.Color; +import java.awt.Font; +import java.awt.Point; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; -import org.diylc.common.HorizontalAlignment; -import org.diylc.common.VerticalAlignment; -import org.diylc.core.IDIYComponent; -import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.IDIYComponent; +import org.diylc.core.annotations.EditableProperty; /** * Abstract implementation of {@link IDIYComponent} that contains component name and toString. @@ -147,54 +140,6 @@ public abstract class AbstractComponent implements IDIYComponent { return !clip.intersects(rect); } - protected void drawCenteredText(Graphics2D g2d, String text, int x, int y, HorizontalAlignment horizontalAlignment, - VerticalAlignment verticalAlignment) { - String[] parts = text.split("\n"); - if (parts.length > 1) { - FontMetrics fontMetrics = g2d.getFontMetrics(); - Rectangle stringBounds = fontMetrics.getStringBounds(parts[0], g2d).getBounds(); - for (int i = 0; i < parts.length; i++) - drawCenteredText(g2d, parts[i], x, (int)(y - stringBounds.height * (parts.length - 1) / 2d + i * stringBounds.height), horizontalAlignment, verticalAlignment); - return; - } - - FontMetrics fontMetrics = g2d.getFontMetrics(); - Rectangle stringBounds = fontMetrics.getStringBounds(text, g2d).getBounds(); - - Font font = g2d.getFont(); - FontRenderContext renderContext = g2d.getFontRenderContext(); - GlyphVector glyphVector = font.createGlyphVector(renderContext, text); - Rectangle visualBounds = glyphVector.getVisualBounds().getBounds(); - - int textX = 0; - switch (horizontalAlignment) { - case CENTER: - textX = x - stringBounds.width / 2; - break; - case LEFT: - textX = x; - break; - case RIGHT: - textX = x - stringBounds.width; - break; - } - - int textY = 0; - switch (verticalAlignment) { - case TOP: - textY = y + stringBounds.height; - break; - case CENTER: - textY = y - visualBounds.height / 2 - visualBounds.y; - break; - case BOTTOM: - textY = y - visualBounds.y; - break; - } - - g2d.drawString(text, textX, textY); - } - @SuppressWarnings("unchecked") public IDIYComponent clone() throws CloneNotSupportedException { try { diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index 70a6bcb0..01e2ed7f 100644 Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ diff --git a/diylc/diylc-library/src/org/diylc/awt/StringUtils.java b/diylc/diylc-library/src/org/diylc/awt/StringUtils.java new file mode 100644 index 00000000..996266ae --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/awt/StringUtils.java @@ -0,0 +1,245 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2018 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.awt; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.diylc.common.HorizontalAlignment; +import org.diylc.common.VerticalAlignment; + +/** + * Globally available utility classes, mostly for string manipulation. + * + * @author Jim Menard, jimm@io.com + */ +public class StringUtils { + + public static void drawWrappedText(String text, Graphics2D g2d, int x, int y, int maxWidth, HorizontalAlignment horizontalAlignment) { + FontMetrics textMetrics = g2d.getFontMetrics(); + List lines = wrap(text, textMetrics, maxWidth); + int lineHeight = textMetrics.getHeight(); + + if (horizontalAlignment == HorizontalAlignment.CENTER) + x += maxWidth / 2; + else if (horizontalAlignment == HorizontalAlignment.RIGHT) + x += maxWidth; + + for (String line : lines) { + drawCenteredText(g2d, line, x, y, horizontalAlignment, VerticalAlignment.BOTTOM); + y += lineHeight; + } + } + + /** + * Returns an array of strings, one for each line in the string after it has been wrapped to fit + * lines of maxWidth. Lines end with any of cr, lf, or cr lf. A line ending at the end + * of the string will not output a further, empty string. + *

+ * This code assumes str is not null. + * + * @param str the string to split + * @param fm needed for string width calculations + * @param maxWidth the max line width, in points + * @return a non-empty list of strings + */ + public static List wrap(String str, FontMetrics fm, int maxWidth) { + List lines = splitIntoLines(str); + if (lines.size() == 0) + return lines; + + ArrayList strings = new ArrayList(); + for (Iterator iter = lines.iterator(); iter.hasNext();) + wrapLineInto((String) iter.next(), strings, fm, maxWidth); + return strings; + } + + /** + * Given a line of text and font metrics information, wrap the line and add the new line(s) to + * list. + * + * @param line a line of text + * @param list an output list of strings + * @param fm font metrics + * @param maxWidth maximum width of the line(s) + */ + public static void wrapLineInto(String line, List list, FontMetrics fm, int maxWidth) { + int len = line.length(); + int width; + while (len > 0 && (width = fm.stringWidth(line)) > maxWidth) { + // Guess where to split the line. Look for the next space before + // or after the guess. + int guess = len * maxWidth / width; + String before = line.substring(0, guess).trim(); + + width = fm.stringWidth(before); + int pos; + if (width > maxWidth) // Too long + pos = findBreakBefore(line, guess); + else { // Too short or possibly just right + pos = findBreakAfter(line, guess); + if (pos != -1) { // Make sure this doesn't make us too long + before = line.substring(0, pos).trim(); + if (fm.stringWidth(before) > maxWidth) + pos = findBreakBefore(line, guess); + } + } + if (pos == -1) + pos = guess; // Split in the middle of the word + + list.add(line.substring(0, pos).trim()); + line = line.substring(pos).trim(); + len = line.length(); + } + if (len > 0) + list.add(line); + } + + /** + * Returns the index of the first whitespace character or '-' in line that is at or + * before start. Returns -1 if no such character is found. + * + * @param line a string + * @param start where to star looking + */ + public static int findBreakBefore(String line, int start) { + for (int i = start; i >= 0; --i) { + char c = line.charAt(i); + if (Character.isWhitespace(c) || c == '-') + return i; + } + return -1; + } + + /** + * Returns the index of the first whitespace character or '-' in line that is at or + * after start. Returns -1 if no such character is found. + * + * @param line a string + * @param start where to star looking + */ + public static int findBreakAfter(String line, int start) { + int len = line.length(); + for (int i = start; i < len; ++i) { + char c = line.charAt(i); + if (Character.isWhitespace(c) || c == '-') + return i; + } + return -1; + } + + /** + * Returns an array of strings, one for each line in the string. Lines end with any of cr, lf, or + * cr lf. A line ending at the end of the string will not output a further, empty string. + *

+ * This code assumes str is not null. + * + * @param str the string to split + * @return a non-empty list of strings + */ + public static List splitIntoLines(String str) { + List strings = new ArrayList(); + + int len = str.length(); + if (len == 0) { + strings.add(""); + return strings; + } + + int lineStart = 0; + + for (int i = 0; i < len; ++i) { + char c = str.charAt(i); + if (c == '\r') { + int newlineLength = 1; + if ((i + 1) < len && str.charAt(i + 1) == '\n') + newlineLength = 2; + strings.add(str.substring(lineStart, i)); + lineStart = i + newlineLength; + if (newlineLength == 2) // skip \n next time through loop + ++i; + } else if (c == '\n') { + strings.add(str.substring(lineStart, i)); + lineStart = i + 1; + } + } + if (lineStart < len) + strings.add(str.substring(lineStart)); + + return strings; + } + + public static void drawCenteredText(Graphics2D g2d, String text, int x, int y, HorizontalAlignment horizontalAlignment, + VerticalAlignment verticalAlignment) { + String[] parts = text.split("\n"); + if (parts.length > 1) { + FontMetrics fontMetrics = g2d.getFontMetrics(); + Rectangle stringBounds = fontMetrics.getStringBounds(parts[0], g2d).getBounds(); + for (int i = 0; i < parts.length; i++) + drawCenteredText(g2d, parts[i], x, (int)(y - stringBounds.height * (parts.length - 1) / 2d + i * stringBounds.height), horizontalAlignment, verticalAlignment); + return; + } + + FontMetrics fontMetrics = g2d.getFontMetrics(); + Rectangle stringBounds = fontMetrics.getStringBounds(text, g2d).getBounds(); + + Font font = g2d.getFont(); + FontRenderContext renderContext = g2d.getFontRenderContext(); + GlyphVector glyphVector = font.createGlyphVector(renderContext, text); + Rectangle visualBounds = glyphVector.getVisualBounds().getBounds(); + + int textX = 0; + switch (horizontalAlignment) { + case CENTER: + textX = x - stringBounds.width / 2; + break; + case LEFT: + textX = x; + break; + case RIGHT: + textX = x - stringBounds.width; + break; + } + + int textY = 0; + switch (verticalAlignment) { + case TOP: + textY = y + stringBounds.height; + break; + case CENTER: + textY = y - visualBounds.height / 2 - visualBounds.y; + break; + case BOTTOM: + textY = y - visualBounds.y; + break; + } + + g2d.drawString(text, textX, textY); + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/Abstract3LegSymbol.java b/diylc/diylc-library/src/org/diylc/components/Abstract3LegSymbol.java index 6ce1f886..ca916839 100644 --- a/diylc/diylc-library/src/org/diylc/components/Abstract3LegSymbol.java +++ b/diylc/diylc-library/src/org/diylc/components/Abstract3LegSymbol.java @@ -21,33 +21,33 @@ */ package org.diylc.components; -import java.awt.Color; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; -import org.diylc.appframework.miscutils.ConfigurationManager; -import org.diylc.common.Display; -import org.diylc.common.HorizontalAlignment; -import org.diylc.common.IPlugInPort; -import org.diylc.common.ObjectCache; -import org.diylc.common.Orientation; -import org.diylc.common.VerticalAlignment; -import org.diylc.components.AbstractComponent; -import org.diylc.components.semiconductors.SymbolFlipping; -import org.diylc.core.ComponentState; -import org.diylc.core.IDrawingObserver; -import org.diylc.core.Project; -import org.diylc.core.Theme; -import org.diylc.core.VisibilityPolicy; -import org.diylc.core.annotations.EditableProperty; -import org.diylc.core.measures.Size; -import org.diylc.core.measures.SizeUnit; -import org.diylc.utils.Constants; +import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; +import org.diylc.common.Display; +import org.diylc.common.HorizontalAlignment; +import org.diylc.common.IPlugInPort; +import org.diylc.common.ObjectCache; +import org.diylc.common.Orientation; +import org.diylc.common.VerticalAlignment; +import org.diylc.components.semiconductors.SymbolFlipping; +import org.diylc.core.ComponentState; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.Theme; +import org.diylc.core.VisibilityPolicy; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; +import org.diylc.utils.Constants; public abstract class Abstract3LegSymbol extends AbstractComponent { @@ -160,10 +160,10 @@ public abstract class Abstract3LegSymbol extends AbstractComponent { Rectangle shapeRect = body[0].getBounds().union(body[1].getBounds()).union(body[2].getBounds()); if (getMoveLabel()) { - drawCenteredText(g2d, label, controlPoints[3].x, controlPoints[3].y, flip == SymbolFlipping.X ? HorizontalAlignment.RIGHT + StringUtils.drawCenteredText(g2d, label, controlPoints[3].x, controlPoints[3].y, flip == SymbolFlipping.X ? HorizontalAlignment.RIGHT : HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } else { - drawCenteredText(g2d, label, getLabelX(shapeRect, textRect, fontMetrics, outlineMode), + StringUtils.drawCenteredText(g2d, label, getLabelX(shapeRect, textRect, fontMetrics, outlineMode), getLabelY(shapeRect, textRect, fontMetrics, outlineMode), flip == SymbolFlipping.X ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, VerticalAlignment.CENTER); } diff --git a/diylc/diylc-library/src/org/diylc/components/AbstractLeadedComponent.java b/diylc/diylc-library/src/org/diylc/components/AbstractLeadedComponent.java index 5612c480..66e4956f 100644 --- a/diylc/diylc-library/src/org/diylc/components/AbstractLeadedComponent.java +++ b/diylc/diylc-library/src/org/diylc/components/AbstractLeadedComponent.java @@ -36,6 +36,7 @@ import java.awt.geom.Rectangle2D; import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.awt.ShadedPaint; +import org.diylc.awt.StringUtils; import org.diylc.common.Display; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; @@ -331,7 +332,7 @@ public abstract class AbstractLeadedComponent extends AbstractTransparentComp if (getLabelOriantation() != LabelOriantation.Horizontal) { g2d.rotate(theta); } - drawCenteredText(g2d, label, offset, 0, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, label, offset, 0, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); g2d.setTransform(oldTransform); } else { if (isStanding() || getLabelOriantation() == LabelOriantation.Horizontal) { 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 56906bfc..d3a9ad05 100644 --- a/diylc/diylc-library/src/org/diylc/components/boards/AbstractBoard.java +++ b/diylc/diylc-library/src/org/diylc/components/boards/AbstractBoard.java @@ -27,6 +27,7 @@ import java.awt.Composite; import java.awt.Graphics2D; import java.awt.Point; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.ObjectCache; import org.diylc.common.VerticalAlignment; @@ -116,11 +117,11 @@ public abstract class AbstractBoard extends AbstractTransparentComponent String label = yType == CoordinateType.Letters ? getCoordinateLabel(c) : Integer.toString(c); drawPoint.y += yOffset; - drawCenteredText(g2d, label, + StringUtils.drawCenteredText(g2d, label, firstPoint.x + xOffset, drawPoint.y, HorizontalAlignment.LEFT, VerticalAlignment.CENTER); if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) { - drawCenteredText(g2d, label, + StringUtils.drawCenteredText(g2d, label, secondPoint.x - xOffset, drawPoint.y, HorizontalAlignment.RIGHT, VerticalAlignment.CENTER); } @@ -146,11 +147,11 @@ public abstract class AbstractBoard extends AbstractTransparentComponent String label = xType == CoordinateType.Letters ? getCoordinateLabel(c) : Integer.toString(c); drawPoint.x += xOffset; - drawCenteredText(g2d, label, + StringUtils.drawCenteredText(g2d, label, drawPoint.x, firstPoint.y - 2, HorizontalAlignment.CENTER, VerticalAlignment.TOP); if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) { - drawCenteredText(g2d, label, + StringUtils.drawCenteredText(g2d, label, drawPoint.x, (int) (secondPoint.y - COORDINATE_FONT_SIZE), HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM); } diff --git a/diylc/diylc-library/src/org/diylc/components/boards/Breadboard.java b/diylc/diylc-library/src/org/diylc/components/boards/Breadboard.java index 9eb80f17..7abf0856 100644 --- a/diylc/diylc-library/src/org/diylc/components/boards/Breadboard.java +++ b/diylc/diylc-library/src/org/diylc/components/boards/Breadboard.java @@ -28,6 +28,7 @@ import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.AffineTransform; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.ObjectCache; import org.diylc.common.Orientation; @@ -146,7 +147,7 @@ public class Breadboard extends AbstractComponent { } else { coordinateX = (int) (point.x + offset + 10.5 * spacing); } - drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing), + StringUtils.drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing), section == 0 ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, VerticalAlignment.CENTER); for (int x = 0; x < 5; x++) { int holeX = (int) (point.x + offset + (x + 6) * spacing); @@ -159,9 +160,9 @@ public class Breadboard extends AbstractComponent { // Draw horizontal labels if (y == 0) { g2d.setColor(COORDINATE_COLOR); - drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y), + StringUtils.drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y), HorizontalAlignment.CENTER, VerticalAlignment.TOP); - drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y + StringUtils.drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y + spacing * 30 + COORDINATE_FONT_SIZE / 2), HorizontalAlignment.CENTER, VerticalAlignment.TOP); } } @@ -218,7 +219,7 @@ public class Breadboard extends AbstractComponent { } else { coordinateX = (int) (point.x + offset + 10.5 * spacing); } - drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing), + StringUtils.drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing), section == 0 ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, VerticalAlignment.CENTER); // for (int x = 0; x < 5; x++) { int holeX1 = (int) (point.x + offset + 6 * spacing); diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/CliffJack1_4.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/CliffJack1_4.java index ba7988ab..3bf012ed 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/CliffJack1_4.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/CliffJack1_4.java @@ -34,6 +34,7 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.RoundRectangle2D; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; import org.diylc.common.ObjectCache; @@ -246,7 +247,7 @@ public class CliffJack1_4 extends AbstractMultiPartComponent { g2d.setFont(project.getFont()); int centerX = (controlPoints[0].x + controlPoints[3].x) / 2; int centerY = (controlPoints[0].y + controlPoints[3].y) / 2; - drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); drawSelectionOutline(g2d, componentState, outlineMode, project, drawingObserver); } diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/ClosedJack1_4.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/ClosedJack1_4.java index 975d1724..403f841b 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/ClosedJack1_4.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/ClosedJack1_4.java @@ -34,6 +34,7 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; import org.diylc.common.ObjectCache; @@ -269,7 +270,7 @@ public class ClosedJack1_4 extends AbstractMultiPartComponent { Rectangle bounds = body[0].getBounds(); int centerX = bounds.x + bounds.width / 2; int centerY = bounds.y + bounds.height / 2; - drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); drawSelectionOutline(g2d, componentState, outlineMode, project, drawingObserver); } diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/OpenJack1_4.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/OpenJack1_4.java index 017141cd..9a057692 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/OpenJack1_4.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/OpenJack1_4.java @@ -33,6 +33,7 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.RoundRectangle2D; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; import org.diylc.common.ObjectCache; @@ -170,12 +171,12 @@ public class OpenJack1_4 extends AbstractMultiPartComponent { rotation.transform(ringOrSwitchLabel, ringOrSwitchLabel); rotation.transform(sleeveLabel, sleeveLabel); } - drawCenteredText(g2d, "T", tipLabel.x, tipLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, "S", sleeveLabel.x, sleeveLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "T", tipLabel.x, tipLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "S", sleeveLabel.x, sleeveLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); if (getType() == OpenJackType.STEREO) - drawCenteredText(g2d, "R", ringOrSwitchLabel.x, ringOrSwitchLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "R", ringOrSwitchLabel.x, ringOrSwitchLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); if (getType() == OpenJackType.SWITCHED) - drawCenteredText(g2d, "Sw", ringOrSwitchLabel.x, ringOrSwitchLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "Sw", ringOrSwitchLabel.x, ringOrSwitchLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } drawSelectionOutline(g2d, componentState, outlineMode, project, drawingObserver); diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/PlasticDCJack.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/PlasticDCJack.java index 59ed0b09..95e0575d 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/PlasticDCJack.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/PlasticDCJack.java @@ -32,6 +32,7 @@ import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; import org.diylc.common.ObjectCache; @@ -182,9 +183,9 @@ public class PlasticDCJack extends AbstractMultiPartComponent { int spacing = (int) SPACING.convertToPixels(); g2d.setColor(MARKING_COLOR); g2d.setFont(project.getFont().deriveFont(12f)); - drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "+" : "-", controlPoints[0].x, + StringUtils.drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "+" : "-", controlPoints[0].x, controlPoints[0].y - spacing * 7 / 16, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "_" : "+", controlPoints[2].x, + StringUtils.drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "_" : "+", controlPoints[2].x, controlPoints[2].y - spacing * 3 / 4, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } diff --git a/diylc/diylc-library/src/org/diylc/components/guitar/AbstractGuitarPickup.java b/diylc/diylc-library/src/org/diylc/components/guitar/AbstractGuitarPickup.java index 24a1d334..6788a781 100644 --- a/diylc/diylc-library/src/org/diylc/components/guitar/AbstractGuitarPickup.java +++ b/diylc/diylc-library/src/org/diylc/components/guitar/AbstractGuitarPickup.java @@ -26,6 +26,7 @@ import java.awt.Shape; import java.awt.geom.AffineTransform; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; import org.diylc.common.Orientation; @@ -90,8 +91,8 @@ public abstract class AbstractGuitarPickup extends AbstractTransparentComponent< break; } - drawCenteredText(g2d, "N", (points[0].x + points[1].x) / 2 + dx, (points[0].y + points[1].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, "S", (points[2].x + points[3].x) / 2 + dx, (points[2].y + points[3].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "N", (points[0].x + points[1].x) / 2 + dx, (points[0].y + points[1].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "S", (points[2].x + points[3].x) / 2 + dx, (points[2].y + points[3].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } protected void drawMainLabel(Graphics2D g2d, Project project, boolean outlineMode, ComponentState componentState) { @@ -120,7 +121,7 @@ public abstract class AbstractGuitarPickup extends AbstractTransparentComponent< } g2d.translate(0, getMainLabelYOffset()); - drawCenteredText(g2d, getName(), 0, 0, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, getName(), 0, 0, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); g2d.setTransform(originalTx); } diff --git a/diylc/diylc-library/src/org/diylc/components/guitar/AbstractSingleOrHumbuckerPickup.java b/diylc/diylc-library/src/org/diylc/components/guitar/AbstractSingleOrHumbuckerPickup.java index 1bbeedec..15f7957a 100644 --- a/diylc/diylc-library/src/org/diylc/components/guitar/AbstractSingleOrHumbuckerPickup.java +++ b/diylc/diylc-library/src/org/diylc/components/guitar/AbstractSingleOrHumbuckerPickup.java @@ -21,6 +21,7 @@ import java.awt.Color; import java.awt.Graphics2D; import java.awt.Point; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.OrientationHV; import org.diylc.common.VerticalAlignment; @@ -60,11 +61,11 @@ public abstract class AbstractSingleOrHumbuckerPickup extends AbstractGuitarPick } if (getPolarity() == Polarity.North || getPolarity() == Polarity.South) { - drawCenteredText(g2d, getPolarity().name().substring(0, 1), (points[1].x + points[2].x) / 2 + dx, (points[1].y + points[2].y) / 2 + dy, HorizontalAlignment.CENTER, + StringUtils.drawCenteredText(g2d, getPolarity().name().substring(0, 1), (points[1].x + points[2].x) / 2 + dx, (points[1].y + points[2].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } else { - drawCenteredText(g2d, "N", (points[0].x + points[1].x) / 2 + dx, (points[0].y + points[1].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, "S", (points[2].x + points[3].x) / 2 + dx, (points[2].y + points[3].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "N", (points[0].x + points[1].x) / 2 + dx, (points[0].y + points[1].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "S", (points[2].x + points[3].x) / 2 + dx, (points[2].y + points[3].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } } diff --git a/diylc/diylc-library/src/org/diylc/components/misc/Label.java b/diylc/diylc-library/src/org/diylc/components/misc/Label.java index 513168d0..d3f48210 100644 --- a/diylc/diylc-library/src/org/diylc/components/misc/Label.java +++ b/diylc/diylc-library/src/org/diylc/components/misc/Label.java @@ -244,7 +244,7 @@ public class Label extends AbstractComponent { this.color = color; } - @EditableProperty(name = "Vertical alignment") + @EditableProperty(name = "Vertical Alignment") public VerticalAlignment getVerticalAlignment() { if (verticalAlignment == null) { verticalAlignment = VerticalAlignment.CENTER; @@ -256,7 +256,7 @@ public class Label extends AbstractComponent { this.verticalAlignment = verticalAlignment; } - @EditableProperty(name = "Horizontal alignment") + @EditableProperty(name = "Horizontal Alignment") public HorizontalAlignment getHorizontalAlignment() { if (horizontalAlignment == null) { horizontalAlignment = HorizontalAlignment.CENTER; diff --git a/diylc/diylc-library/src/org/diylc/components/misc/WrapLabel.java b/diylc/diylc-library/src/org/diylc/components/misc/WrapLabel.java new file mode 100644 index 00000000..a4c51923 --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/components/misc/WrapLabel.java @@ -0,0 +1,227 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2018 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.components.misc; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.geom.Rectangle2D; + +import org.diylc.awt.StringUtils; +import org.diylc.common.HorizontalAlignment; +import org.diylc.components.AbstractComponent; +import org.diylc.components.transform.TextTransformer; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.VisibilityPolicy; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.annotations.MultiLineText; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; + +@ComponentDescriptor(name = "Auto-Wrap Label", author = "Branislav Stojkovic", category = "Misc", +description = "User defined label with auto-wrapped text", instanceNamePrefix = "L", zOrder = IDIYComponent.TEXT, flexibleZOrder = true, +bomPolicy = BomPolicy.NEVER_SHOW, transformer = TextTransformer.class) +public class WrapLabel extends AbstractComponent { + + private static final long serialVersionUID = 1L; + + public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in); + public static Size DEFAULT_HEIGHT = new Size(0.5d, SizeUnit.in); + + 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(); + + private Font font = LABEL_FONT; + private Color color = LABEL_COLOR; + private HorizontalAlignment horizontalAlignment = HorizontalAlignment.LEFT; + + private String value = "The quick brown fox jumped over a lazy dog"; + + public WrapLabel() { + } + + @MultiLineText + @EditableProperty + @Override + public String getValue() { + return value; + } + + @Override + public void setValue(String value) { + this.value = value; + } + + @Override + public int getControlPointCount() { + return 2; + } + + @Override + public Point getControlPoint(int index) { + return controlPoints[index]; + } + + @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)); + } + + @Override + public boolean isControlPointSticky(int index) { + return false; + } + + @Override + public VisibilityPolicy getControlPointVisibilityPolicy(int index) { + return VisibilityPolicy.WHEN_SELECTED; + } + + @EditableProperty + public Font getFont() { + return font; + } + + public void setFont(Font font) { + this.font = font; + } + +//Bold and italic fields are named to be alphabetically after Font. This is + // important! + + @EditableProperty(name = "Font Bold") + public boolean getBold() { + return font.isBold(); + } + + public void setBold(boolean bold) { + if (bold) { + if (font.isItalic()) { + font = font.deriveFont(Font.BOLD + Font.ITALIC); + } else { + font = font.deriveFont(Font.BOLD); + } + } else { + if (font.isItalic()) { + font = font.deriveFont(Font.ITALIC); + } else { + font = font.deriveFont(Font.PLAIN); + } + } + } + + @EditableProperty(name = "Font Italic") + public boolean getItalic() { + return font.isItalic(); + } + + public void setItalic(boolean italic) { + if (italic) { + if (font.isBold()) { + font = font.deriveFont(Font.BOLD + Font.ITALIC); + } else { + font = font.deriveFont(Font.ITALIC); + } + } else { + if (font.isBold()) { + font = font.deriveFont(Font.BOLD); + } else { + font = font.deriveFont(Font.PLAIN); + } + } + } + + @EditableProperty(name = "Font Size") + public int getFontSize() { + return font.getSize(); + } + + public void setFontSize(int size) { + font = font.deriveFont((float) size); + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setColor(componentState == ComponentState.SELECTED ? LABEL_COLOR_SELECTED : color); + g2d.setFont(font); + + int x = firstPoint.x; + int y = firstPoint.y; + int maxWidth = secondPoint.x - firstPoint.x; + + StringUtils.drawWrappedText(value, g2d, x, y, maxWidth, horizontalAlignment); + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + g2d.setColor(LABEL_COLOR); + g2d.setFont(LABEL_FONT.deriveFont(10f * width / 32).deriveFont(Font.PLAIN)); + + FontMetrics fontMetrics = g2d.getFontMetrics(); + Rectangle2D rect = fontMetrics.getStringBounds("Wrap", g2d); + + int textHeight = (int) (rect.getHeight()); + int textWidth = (int) (rect.getWidth()); + + int x = (width - textWidth) / 2 + 1; + int y = (int) (4f * width / 32) + fontMetrics.getAscent(); + + g2d.drawString("Wrap", x, y); + y += g2d.getFont().getSize(); + g2d.drawString("Text", x, y); + } + + @EditableProperty + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + @EditableProperty(name = "Horizontal Alignment") + public HorizontalAlignment getHorizontalAlignment() { + if (horizontalAlignment == null) { + horizontalAlignment = HorizontalAlignment.CENTER; + } + return horizontalAlignment; + } + + public void setHorizontalAlignment(HorizontalAlignment alignment) { + this.horizontalAlignment = alignment; + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/passive/AudioTransformer.java b/diylc/diylc-library/src/org/diylc/components/passive/AudioTransformer.java index 5ca68478..77dce4fd 100644 --- a/diylc/diylc-library/src/org/diylc/components/passive/AudioTransformer.java +++ b/diylc/diylc-library/src/org/diylc/components/passive/AudioTransformer.java @@ -34,6 +34,7 @@ import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.Display; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; @@ -315,11 +316,11 @@ public class AudioTransformer extends AbstractMultiPartComponent { AffineTransform tx = getTx(); if (tx != null) tx.transform(wPoint, wPoint); - drawCenteredText(g2d, "P", wPoint.x, wPoint.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "P", wPoint.x, wPoint.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); wPoint = new Point((int) (controlPoints[0].x + windingSpacing.convertToPixels() - project.getFontSize()), (int) (controlPoints[0].y + leadSpacing.convertToPixels())); if (tx != null) tx.transform(wPoint, wPoint); - drawCenteredText(g2d, "S", wPoint.x, wPoint.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "S", wPoint.x, wPoint.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); // Draw label. Color finalLabelColor; diff --git a/diylc/diylc-library/src/org/diylc/components/passive/MultiSectionCapacitor.java b/diylc/diylc-library/src/org/diylc/components/passive/MultiSectionCapacitor.java index a8160d48..eb13cee2 100644 --- a/diylc/diylc-library/src/org/diylc/components/passive/MultiSectionCapacitor.java +++ b/diylc/diylc-library/src/org/diylc/components/passive/MultiSectionCapacitor.java @@ -33,6 +33,7 @@ import java.text.DecimalFormat; import java.text.Format; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.Display; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; @@ -414,7 +415,7 @@ public class MultiSectionCapacitor extends AbstractTransparentComponent { break; } - drawCenteredText(g2d, pointLabels[i], point.x + dx, point.y + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, pointLabels[i], point.x + dx, point.y + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } } @@ -581,10 +582,10 @@ public class BridgeRectifier extends AbstractTransparentComponent { g2d.fillOval(width * 2 / 8, height * 6 / 8 - pinSize, pinSize, pinSize); g2d.setColor(LABEL_COLOR); g2d.setFont(LABEL_FONT.deriveFont(8f * width / 32)); - drawCenteredText(g2d, "+", width * 2 / 8 + 1, height * 2 / 8 + 4 * width / 32, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, "-", width * 2 / 8 + 1, height * 6 / 8 - 5 * width / 32, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, "~", width * 6 / 8 - 2 * width / 32, height * 2 / 8 + 5 * width / 32, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, "~", width * 6 / 8 - 2 * width / 32, height * 6 / 8 - 5 * width / 32, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "+", width * 2 / 8 + 1, height * 2 / 8 + 4 * width / 32, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "-", width * 2 / 8 + 1, height * 6 / 8 - 5 * width / 32, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "~", width * 6 / 8 - 2 * width / 32, height * 2 / 8 + 5 * width / 32, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "~", width * 6 / 8 - 2 * width / 32, height * 6 / 8 - 5 * width / 32, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } @EditableProperty(name = "Body") diff --git a/diylc/diylc-library/src/org/diylc/components/semiconductors/ICSymbol.java b/diylc/diylc-library/src/org/diylc/components/semiconductors/ICSymbol.java index 5f3acb7b..ea703b19 100644 --- a/diylc/diylc-library/src/org/diylc/components/semiconductors/ICSymbol.java +++ b/diylc/diylc-library/src/org/diylc/components/semiconductors/ICSymbol.java @@ -21,36 +21,37 @@ */ package org.diylc.components.semiconductors; -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Polygon; -import java.awt.Shape; -import java.awt.geom.Area; -import java.awt.geom.GeneralPath; -import java.awt.geom.Rectangle2D; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Polygon; +import java.awt.Shape; +import java.awt.geom.Area; +import java.awt.geom.GeneralPath; +import java.awt.geom.Rectangle2D; -import org.diylc.appframework.miscutils.ConfigurationManager; -import org.diylc.common.Display; -import org.diylc.common.HorizontalAlignment; -import org.diylc.common.IPlugInPort; -import org.diylc.common.ObjectCache; -import org.diylc.common.VerticalAlignment; -import org.diylc.components.AbstractTransparentComponent; -import org.diylc.core.ComponentState; -import org.diylc.core.IDIYComponent; -import org.diylc.core.IDrawingObserver; -import org.diylc.core.Project; -import org.diylc.core.Theme; -import org.diylc.core.VisibilityPolicy; -import org.diylc.core.annotations.ComponentDescriptor; -import org.diylc.core.annotations.EditableProperty; -import org.diylc.core.annotations.KeywordPolicy; -import org.diylc.core.measures.Size; -import org.diylc.core.measures.SizeUnit; -import org.diylc.utils.Constants; +import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; +import org.diylc.common.Display; +import org.diylc.common.HorizontalAlignment; +import org.diylc.common.IPlugInPort; +import org.diylc.common.ObjectCache; +import org.diylc.common.VerticalAlignment; +import org.diylc.components.AbstractTransparentComponent; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.Theme; +import org.diylc.core.VisibilityPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.annotations.KeywordPolicy; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; +import org.diylc.utils.Constants; @ComponentDescriptor(name = "IC", author = "Branislav Stojkovic", category = "Schematic Symbols", instanceNamePrefix = "IC", description = "IC symbol with 3 or 5 contacts", @@ -134,12 +135,12 @@ public class ICSymbol extends AbstractTransparentComponent { if (display == Display.BOTH) { label = getName() + " " + (getValue() == null ? "" : getValue().toString()); } - drawCenteredText(g2d, label, x, controlPoints[0].y + pinSpacing, HorizontalAlignment.CENTER, + StringUtils.drawCenteredText(g2d, label, x, controlPoints[0].y + pinSpacing, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); // Draw +/- markers - drawCenteredText(g2d, getFlip() ? "+" : "-", controlPoints[0].x + pinSpacing, controlPoints[0].y, HorizontalAlignment.CENTER, + StringUtils.drawCenteredText(g2d, getFlip() ? "+" : "-", controlPoints[0].x + pinSpacing, controlPoints[0].y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, getFlip() ? "-" : "+", controlPoints[1].x + pinSpacing, controlPoints[1].y, HorizontalAlignment.CENTER, + StringUtils.drawCenteredText(g2d, getFlip() ? "-" : "+", controlPoints[1].x + pinSpacing, controlPoints[1].y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } @@ -156,8 +157,8 @@ public class ICSymbol extends AbstractTransparentComponent { g2d.fill(area); g2d.setColor(BORDER_COLOR); g2d.setFont(LABEL_FONT.deriveFont(8f)); - drawCenteredText(g2d, "-", 3 * margin, height / 3, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - drawCenteredText(g2d, "+", 3 * margin + 1, height * 2 / 3, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "-", 3 * margin, height / 3, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "+", 3 * margin + 1, height * 2 / 3, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); // g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_ROUND, // BasicStroke.JOIN_ROUND)); g2d.draw(area); diff --git a/diylc/diylc-library/src/org/diylc/components/semiconductors/LogicGateSymbol.java b/diylc/diylc-library/src/org/diylc/components/semiconductors/LogicGateSymbol.java index 737965cf..da9213cf 100644 --- a/diylc/diylc-library/src/org/diylc/components/semiconductors/LogicGateSymbol.java +++ b/diylc/diylc-library/src/org/diylc/components/semiconductors/LogicGateSymbol.java @@ -31,6 +31,7 @@ import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.Display; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; @@ -132,7 +133,7 @@ public class LogicGateSymbol extends AbstractTransparentComponent { if (display == Display.BOTH) { label = getName() + " " + (getValue() == null ? "" : getValue().toString()); } - drawCenteredText(g2d, label, x, controlPoints[0].y + (getControlPointCount() == 2 ? 0 : pinSpacing), HorizontalAlignment.CENTER, + StringUtils.drawCenteredText(g2d, label, x, controlPoints[0].y + (getControlPointCount() == 2 ? 0 : pinSpacing), HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } diff --git a/diylc/diylc-library/src/org/diylc/components/tube/AbstractTubeSymbol.java b/diylc/diylc-library/src/org/diylc/components/tube/AbstractTubeSymbol.java index 5e62318c..992d8a2b 100644 --- a/diylc/diylc-library/src/org/diylc/components/tube/AbstractTubeSymbol.java +++ b/diylc/diylc-library/src/org/diylc/components/tube/AbstractTubeSymbol.java @@ -21,30 +21,31 @@ */ package org.diylc.components.tube; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.geom.AffineTransform; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.AffineTransform; -import org.diylc.appframework.miscutils.ConfigurationManager; -import org.diylc.common.Display; -import org.diylc.common.HorizontalAlignment; -import org.diylc.common.IPlugInPort; -import org.diylc.common.ObjectCache; -import org.diylc.common.Orientation; -import org.diylc.common.VerticalAlignment; -import org.diylc.components.AbstractComponent; -import org.diylc.components.semiconductors.SymbolFlipping; -import org.diylc.core.ComponentState; -import org.diylc.core.IDrawingObserver; -import org.diylc.core.Project; -import org.diylc.core.Theme; -import org.diylc.core.annotations.EditableProperty; -import org.diylc.core.measures.Size; -import org.diylc.core.measures.SizeUnit; -import org.diylc.utils.Constants; +import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; +import org.diylc.common.Display; +import org.diylc.common.HorizontalAlignment; +import org.diylc.common.IPlugInPort; +import org.diylc.common.ObjectCache; +import org.diylc.common.Orientation; +import org.diylc.common.VerticalAlignment; +import org.diylc.components.AbstractComponent; +import org.diylc.components.semiconductors.SymbolFlipping; +import org.diylc.core.ComponentState; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.Theme; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; +import org.diylc.utils.Constants; public abstract class AbstractTubeSymbol extends AbstractComponent { @@ -121,7 +122,7 @@ public abstract class AbstractTubeSymbol extends AbstractComponent { if (display == Display.BOTH) { label = getName() + " " + (getValue() == null ? "" : getValue().toString()); } - drawCenteredText(g2d, label, rect.x + rect.width, rect.y + rect.height, HorizontalAlignment.RIGHT, + StringUtils.drawCenteredText(g2d, label, rect.x + rect.width, rect.y + rect.height, HorizontalAlignment.RIGHT, VerticalAlignment.BOTTOM); } diff --git a/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java b/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java index c3afc560..904050b2 100644 --- a/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java +++ b/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java @@ -33,6 +33,7 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; import org.diylc.common.IPlugInPort; import org.diylc.common.ObjectCache; @@ -314,7 +315,7 @@ public class TubeSocket extends AbstractTransparentComponent { double theta = Math.atan2(controlPoints[i + 1].y - controlPoints[0].y, controlPoints[i + 1].x - controlPoints[0].x); double x = controlPoints[i + 1].x - Math.cos(theta) * electrodeLabelOffset; double y = controlPoints[i + 1].y - Math.sin(theta) * electrodeLabelOffset; - drawCenteredText(g2d, label, (int)x, (int)y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, label, (int)x, (int)y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); } } } diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 70a6bcb0..01e2ed7f 100644 Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index 63f61c40..b8da31c1 100644 Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ diff --git a/diylc/diylc-swing/update.xml b/diylc/diylc-swing/update.xml index 8adc3720..ebb27d3c 100644 --- a/diylc/diylc-swing/update.xml +++ b/diylc/diylc-swing/update.xml @@ -2638,6 +2638,10 @@ NEW_FEATURE Added mini toolbar in the top-right corner of the screen with transform actions exposed for quick access + + NEW_FEATURE + Added "Auto-Wrap Label" component + NEW_FEATURE Auto-save plugin now works by periodically creating project backups in user\.diylc\autoSave directory and maintains file history, keeping the last X versions of the file. Maximum size for all backups combined is configurable and pre-set to 64MB