diff --git a/src/main/java/de/neemann/digital/draw/elements/VisualElement.java b/src/main/java/de/neemann/digital/draw/elements/VisualElement.java index c641a44d0..2978a575e 100644 --- a/src/main/java/de/neemann/digital/draw/elements/VisualElement.java +++ b/src/main/java/de/neemann/digital/draw/elements/VisualElement.java @@ -149,30 +149,35 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { * @return the shape */ public Shape getShape() { - if (shape == null) + if (shape == null) { shape = shapeFactory.getShape(elementName, elementAttributes); + minMax = null; + } return shape; } @Override public void drawTo(Graphic graphic, boolean highLight) { + drawShape(graphic, highLight); + + // draw circle around element + if (highLight) { + GraphicMinMax mm = getMinMax(); + Vector delta = mm.getMax().sub(mm.getMin()); + int rad = (int) Math.sqrt(delta.x * delta.x + delta.y * delta.y) / 2; + delta = new Vector(rad, rad); + Vector pos = mm.getMax().add(mm.getMin()).div(2); + graphic.drawCircle(pos.sub(delta), pos.add(delta), Style.HIGHLIGHT); + } + } + + private void drawShape(Graphic graphic, boolean highLight) { Graphic gr = new GraphicTransform(graphic, createTransform()); Shape shape = getShape(); - shape.drawTo(gr, highLight); for (Pin p : shape.getPins()) gr.drawCircle(p.getPos().add(-PIN, -PIN), p.getPos().add(PIN, PIN), p.getDirection() == Pin.Direction.input ? Style.WIRE : Style.WIRE_OUT); - - if (highLight && minMax == null && !(graphic instanceof GraphicMinMax)) getMinMax(); - - if (highLight && minMax != null) { - Vector delta = minMax.getMax().sub(minMax.getMin()); - int rad = (int) Math.sqrt(delta.x * delta.x + delta.y * delta.y) / 2; - delta = new Vector(rad, rad); - Vector pos = minMax.getMax().add(minMax.getMin()).div(2); - graphic.drawCircle(pos.sub(delta), pos.add(delta), Style.HIGHLIGHT); - } } private Transform createTransform() { @@ -188,7 +193,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { public GraphicMinMax getMinMax() { if (minMax == null) { GraphicMinMax mm = new GraphicMinMax(); - drawTo(mm, false); + drawShape(mm, false); minMax = mm; } return minMax; @@ -204,16 +209,20 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { * Create an icon from this element. * Is used to create the icons in the element menu * - * @param maxHeight the maximum hight - * @return the icon ore null if the maximum height is exceeded. + * @param maxHeight the maximum height + * @return the icon or null if the maximum height is exceeded. */ public ImageIcon createIcon(int maxHeight) { GraphicMinMax mm = getMinMax(); - if (mm.getMax().y - mm.getMin().y > maxHeight * 2) - return null; + double scale = 0.5; + if (mm.getMax().y - mm.getMin().y > maxHeight / scale) + scale = (double) (maxHeight - 1) / (mm.getMax().y - mm.getMin().y + 4); - BufferedImage bi = new BufferedImage((mm.getMax().x - mm.getMin().x + 4) / 2 + 1, (mm.getMax().y - mm.getMin().y + 4) / 2 + 1, BufferedImage.TYPE_INT_ARGB); + int width = (int) Math.round((mm.getMax().x - mm.getMin().x + 4) * scale + 1); + int height = (int) Math.round((mm.getMax().y - mm.getMin().y + 4) * scale + 1); + + BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D gr = bi.createGraphics(); gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); @@ -222,7 +231,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { gr.setColor(new Color(255, 255, 255, 0)); gr.fillRect(0, 0, bi.getWidth(), bi.getHeight()); - gr.scale(0.5, 0.5); + gr.scale(scale, scale); gr.translate(2 - mm.getMin().x, 2 - mm.getMin().y); GraphicSwing grs = new GraphicSwing(gr); drawTo(grs, false); @@ -272,7 +281,6 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { @Override public void attributeChanged(AttributeKey key) { shape = null; - minMax = null; rotate = elementAttributes.get(AttributeKey.Rotate).getRotation(); } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java index 474ab19fd..2b4b8f55e 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java @@ -72,14 +72,22 @@ public final class ShapeFactory { return outInfos; } - public Shape getShape(String partName, ElementAttributes elementAttributes) { - Creator cr = map.get(partName); + /** + * Returns a shape matching the given name. + * If no shape is found, a special "missing shape" shape is returned. + * + * @param elementName the elemnets name + * @param elementAttributes the elements attributes + * @return the shape + */ + public Shape getShape(String elementName, ElementAttributes elementAttributes) { + Creator cr = map.get(elementName); try { if (cr == null) { if (library == null) - throw new NodeException(Lang.get("err_noShapeFoundFor_N", partName)); + throw new NodeException(Lang.get("err_noShapeFoundFor_N", elementName)); else { - ElementTypeDescription pt = library.getElementType(partName); + ElementTypeDescription pt = library.getElementType(elementName); if (pt instanceof LibrarySelector.ElementTypeDescriptionCustom) { LibrarySelector.ElementTypeDescriptionCustom customDescr = (LibrarySelector.ElementTypeDescriptionCustom) pt; return new GenericShape( @@ -100,7 +108,7 @@ public final class ShapeFactory { } else return cr.create(elementAttributes); } catch (Exception e) { - return new MissingShape(partName, e); + return new MissingShape(elementName, e); } }