/* * GraphicsUtil.java * Eisenkraut * * Copyright (c) 2004-2016 Hanns Holger Rutz. All rights reserved. * * This software is published under the GNU General Public License v3+ * * * For further information, please contact Hanns Holger Rutz at * contact@sciss.de */ package de.sciss.eisenkraut.gui; import de.sciss.eisenkraut.Main; import de.sciss.gui.TiledImage; import javax.swing.*; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Line2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; /** * This is a helper class containing utility static functions * and public objects for common graphics operations * * TODO: the tool buttons on non-macos look-and-feel are far to wide */ public class GraphicsUtil { /** * Tool icon ID: transport play */ public static final int ICON_PLAY = 0; /** * Tool icon ID: transport stop */ public static final int ICON_STOP = 1; /** * Tool icon ID: transport loop */ public static final int ICON_LOOP = 2; /** * Tool icon ID: transport rewind */ public static final int ICON_REWIND = 3; /** * Tool icon ID: transport fast forward */ public static final int ICON_FASTFORWARD= 4; /** * Tool icon ID: open file chooser */ public static final int ICON_CHOOSEPATH = 5; /** * Tool icon ID: pointer tool */ public static final int ICON_POINTER = 6; /** * Tool icon ID: line tool */ public static final int ICON_LINE = 7; /** * Tool icon ID: bezier tool */ public static final int ICON_CURVE = 8; /** * Tool icon ID: freehand tool */ public static final int ICON_PENCIL = 9; /** * Tool icon ID: arc tool */ public static final int ICON_ARC = 10; /** * Tool icon ID: tuning fork tool */ public static final int ICON_FORK = 11; /** * Tool icon ID: tuning magnifying glass */ public static final int ICON_ZOOM = 12; /** * Tool icon ID: catch (follow) timeline postion */ public static final int ICON_CATCH = 13; /** * Tool icon ID: realtime plug-in (supercollider) */ public static final int ICON_REALTIME = 15; /** * Tool icon ID: solo button for session objects */ public static final int ICON_SOLO = 16; /** * Tool icon ID: mute button for session objects */ public static final int ICON_MUTE = 18; /** * Tool icon ID: trajectory blending */ public static final int ICON_BLENDING = 19; /** * Tool icon ID: preroll blending (not used) */ public static final int ICON_PREEXTRA = 20; /** * Tool icon ID: postroll blending (not used) */ public static final int ICON_POSTEXTRA = 21; /** * Tool icon ID: insert mode */ public static final int ICON_INSERTMODE = 22; /** * Tool icon ID: replace mode */ public static final int ICON_OVERWRITEMODE = 23; /** * Tool icon ID: mix mode */ public static final int ICON_MIXMODE = 24; /** * Blue translucent colour * for consistent style in selected objects */ public static Color colrSelection() { return isDarkSkin() ? colrSelectionDark : colrSelectionLight; } public static Color colrYellow() { return isDarkSkin() ? colrYellowDark : colrYellowLight; } public static Color colrRed() { return isDarkSkin() ? colrRedDark : colrRedLight; } public static Color colrBlue() { return isDarkSkin() ? colrBlueDark : colrBlueLight; } public static Color setAlpha(Color in, int alpha) { return new Color(in.getRed(), in.getGreen(), in.getBlue(), alpha); } /** <tt>true</tt> for bug: https://stackoverflow.com/questions/19480076 */ public static final boolean animationNeedsSync = Main.isLinux && System.getProperty("java.version").startsWith("1.8."); public static void sync() { if (animationNeedsSync) Toolkit.getDefaultToolkit().sync(); } public static Color colrInactiveSelection() { return isDarkSkin() ? colrSelectionDarkI : colrSelectionLightI; } private static final Color colrSelectionDark = new Color(95, 142, 255, 0x38); // new Color(0x7F, 0x7F, 0xFF, 0x3F); private static final Color colrSelectionLight = new Color(0x00, 0x00, 0xFF, 0x2F); private static final Color colrSelectionDarkI = new Color(0xE0, 0xE0, 0xE0, 0x30); private static final Color colrSelectionLightI = new Color(0x00, 0x00, 0x00, 0x20); private static final Color colrYellowDark = new Color(0xFF, 0xFF, 0x4F); private static final Color colrYellowLight = new Color(0x80, 0x80, 0x00); private static final Color colrRedDark = new Color(0xFF, 0x60, 0x60); private static final Color colrRedLight = Color.red; private static final Color colrBlueDark = new Color(0x5E, 0x97, 0xFF); private static final Color colrBlueLight = new Color(0x3D, 0x3D, 0xB6); /** * Yellow translucent colour * for consistent style in optional adjustment objects */ public static final Color colrAdjusting = new Color(0xFF, 0xFF, 0x00, 0x2F); /** * Default font for GUI elements. * * TODO: this is rather small and could be * user adjustable in a future version. */ public static final Font smallGUIFont = new Font( "Helvetica", Font.PLAIN, 10 ); /** * MacOS X Aqua style bar gradient with a size of 15 pixels * * TODO: this should look different on Windows and Linux * depending on their VM's chrome. * * @see de.sciss.eisenkraut.timeline.TimelineAxis */ public static Paint pntBarGradient() { return isDarkSkin() ? pntBarGradientDark : pntBarGradientLight; } public static boolean isDarkSkin() { return UIManager.getBoolean("dark-skin"); } /** * Collection of toolbar icons. The corresponding IDs are those * named ICON_... (e.g. <code>ICON_PLAY</code> for the transport * play icon). * * @see #createToolIcons( int ) */ protected static final TiledImage imgToolIcons = new TiledImage( GraphicsUtil.class.getResource( "toolicons.png" ), 16, 16 ); private static final int[] pntBarGradPixLight = { 0xFFB8B8B8, 0xFFC0C0C0, 0xFFC8C8C8, 0xFFD3D3D3, 0xFFDBDBDB, 0xFFE4E4E4, 0xFFEBEBEB, 0xFFF1F1F1, 0xFFF6F6F6, 0xFFFAFAFA, 0xFFFBFBFB, 0xFFFCFCFC, 0xFFF9F9F9, 0xFFF4F4F4, 0xFFEFEFEF}; private static final int[] pntBarGradPixDark = { 0xFF080808, 0xFF101010, 0xFF141414, 0xFF1B1B1B, 0xFF1D1D1D, 0xFF222222, 0xFF252525, 0xFF282828, 0xFF2B2B2B, 0xFF2D2D2D, 0xFF2D2D2D, 0xFF2E2E2E, 0xFF2C2C2C, 0xFF2A2A2A, 0xFF272727}; private static final Paint pntBarGradientDark; private static final Paint pntBarGradientLight; static { final BufferedImage imgDark = new BufferedImage(1, 15, BufferedImage.TYPE_INT_ARGB); imgDark.setRGB(0, 0, 1, 15, pntBarGradPixDark, 0, 1); pntBarGradientDark = new TexturePaint(imgDark, new Rectangle(0, 0, 1, 15)); final BufferedImage imgLight = new BufferedImage(1, 15, BufferedImage.TYPE_INT_ARGB); imgLight.setRGB(0, 0, 1, 15, pntBarGradPixLight, 0, 1); pntBarGradientLight = new TexturePaint(imgLight, new Rectangle(0, 0, 1, 15)); } private GraphicsUtil() { /* empty */ } /** * Creates an array of icons which display * a particular icon in different shades * which correspond to a gadget's states. * <ul> * <li>index 0 - gadget normal</li> * <li>index 1 - gadget selected</li> * <li>index 2 - gadget disabled</li> * <li>index 3 - gadget pressed down</li> * </ul> * Usually you'll pass the result directly to * the <code>setToolIcons</code> method. * * @param id ID corresponding to the index in * the tool icon tiled image, e.g. * <code>ICON_PLAY</code> or <code>ICON_LINE</code>. * @return four <code>Icon</code> objects for * different gadget states. * * @see #setToolIcons( AbstractButton, Icon[] ) */ public static Icon[] createToolIcons(int id) { final Shape shp; Color gradient = null; Color fg = null; final boolean isDark = isDarkSkin(); switch(id) { case ICON_PLAY: shp = shapePlay(); break; case ICON_STOP: shp = shapeStop(); break; case ICON_FASTFORWARD: shp = shapeFFwd(); break; case ICON_REWIND: shp = shapeRwd(); break; case ICON_LOOP: shp = shapeLoop(); break; case ICON_ZOOM: shp = shapeZoom(); break; case ICON_POINTER: shp = shapePointer(); break; case ICON_CATCH: shp = shapeLocation2(); break; case ICON_INSERTMODE: shp = shapeInsert(); gradient = colrYellow(); fg = gradient; break; case ICON_OVERWRITEMODE: shp = shapeOverwrite(); gradient = colrRed(); fg = gradient; break; case ICON_MIXMODE: shp = shapeMix(); gradient = colrBlue(); fg = gradient; break; case ICON_SOLO: shp = shapeSolo(); fg = colrYellow(); break; case ICON_MUTE: shp = shapeMute(); fg = colrRed(); break; default: final Icon[] icons = new Icon[4]; for (int i = 0; i < 4; i++) { icons[i] = imgToolIcons.createIcon(id, i); } return icons; } final Icon[] icons = new Icon[4]; icons[0] = new ShapeIcon(shp, isDark ? new Color( 200, 200, 200) : new Color( 32, 32, 32)); final ShapeIcon iconSel = new ShapeIcon(shp, fg == null ? (isDark ? new Color(0x5E, 0x97, 0xFF) : new Color(0x3D, 0x3D, 0xB6)) : fg); icons[1] = iconSel; icons[2] = new ShapeIcon(shp, isDark ? new Color( 180, 180, 180, 0x7F) : new Color(40, 40, 40, 0x7F)); icons[3] = icons[2]; // new ShapeIcon(shp, isDark ? new Color( 147, 175, 227) : new Color(26, 26, 77)); if (gradient != null) { // final Color transparent = new Color(gradient.getRGB() & 0x00FFFFFF, true); final Color transparent = isDark ? colrShadowDefaultDark : colrShadowDefaultLight; final Paint pnt = new GradientPaint(0f, 0f, gradient, 0f, /* 11f */ 15f, transparent); // iconSel.setShadow(Color.black); icons[1] = new PaintIcon(icons[1], pnt); } return icons; } private static class PaintIcon implements Icon { private final Icon peer; private final Paint paint; PaintIcon(Icon peer, Paint paint) { this.peer = peer; this.paint = paint; } public void paintIcon(Component c, Graphics g, int x, int y) { final Graphics2D g2 = (Graphics2D) g; g2.setPaint(paint); g2.fillRect(x, y, getIconWidth(), getIconHeight()); peer.paintIcon(c, g, x, y); } public int getIconWidth() { return peer.getIconWidth(); } public int getIconHeight() { return peer.getIconHeight(); } } private static Color colrShadowDefaultLight = new Color(0xFF, 0xFF, 0xFF, 0x7F); private static Color colrShadowDefaultDark = new Color(0x00, 0x00, 0x00, 0x7F); private static class ShapeIcon implements Icon { private final Shape shape; private final Paint paint; private final int width; private final int height; private Color colrShadow; ShapeIcon(Shape shape, Paint paint) { this(shape, paint, 14, 16); } ShapeIcon(Shape shape, Paint paint, int width, int height) { this.shape = shape; this.paint = paint; this.width = width; this.height = height; colrShadow = isDarkSkin() ? colrShadowDefaultDark : colrShadowDefaultLight; } public void setShadow(Color shadow) { this.colrShadow = shadow; } public void paintIcon(Component c, Graphics g, int x, int y) { final Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE ); g2.translate(x, y); g2.setPaint(colrShadow); g2.draw(shape); g2.setPaint(paint); g2.fill(shape); g2.translate(-x, -y); } public int getIconWidth() { return width; } public int getIconHeight() { return height; } } private static Shape shapeSolo() { return shapeSolo(-1f, 0f, 0.5f); } private static Shape shapeSolo(float xOff, float yOff, float scale) { final Path2D p = new Path2D.Float(); p.moveTo(21.02539f, 19.7031f); p.curveTo(21.124151f, 21.7796f, 19.508724f, 23.559101f, 17.555538f, 24.0495f); p.curveTo(15.218763f, 24.7005f, 12.6468525f, 24.677f, 10.346678f, 23.8897f); p.curveTo(8.781085f, 23.3209f, 7.5374036f, 21.9438f, 7.2089853f, 20.3008f); p.curveTo(7.9316416f, 20.1563f, 8.654298f, 20.0117f, 9.376954f, 19.8672f); p.curveTo(9.711152f, 21.6459f, 11.499057f, 22.6103f, 13.176753f, 22.6973f); p.curveTo(14.951484f, 22.8091f, 17.180979f, 22.839f, 18.384457f, 21.2908f); p.curveTo(19.223303f, 20.1046f, 18.819178f, 18.2158f, 17.404297f, 17.6758f); p.curveTo(14.717688f, 16.4685f, 11.3840275f, 16.739601f, 9.075926f, 14.7029f); p.curveTo(7.2116766f, 12.8987f, 7.7841997f, 9.310801f, 10.216306f, 8.283899f); p.curveTo(12.451131f, 7.2899995f, 15.055282f, 7.320299f, 17.400627f, 7.882499f); p.curveTo(19.051216f, 8.268099f, 20.249271f, 9.692399f, 20.638672f, 11.300799f); p.curveTo(19.904297f, 11.429699f, 19.169922f, 11.558599f, 18.435547f, 11.687499f); p.curveTo(18.095972f, 9.969099f, 16.292114f, 9.184699f, 14.698726f, 9.201699f); p.curveTo(13.171225f, 9.168699f, 11.167638f, 9.2427f, 10.361328f, 10.785099f); p.curveTo(9.680741f, 12.151099f, 10.651849f, 13.671598f, 12.035823f, 14.030999f); p.curveTo(14.608384f, 14.982699f, 17.647264f, 14.917699f, 19.843254f, 16.736f); p.curveTo(20.666546f, 17.4812f, 21.046705f, 18.6106f, 21.02539f, 19.7031f); p.lineTo(21.02539f, 19.7031f); p.moveTo(10.1875f, 1.0128f); p.curveTo(5.8650985f, 0.9218f, 1.82291f, 4.3041f, 1.1432713f, 8.5721f); p.curveTo(0.8768325f, 10.716f, 1.0492703f, 12.8868f, 1.0f, 15.0436f); p.curveTo(1.025343f, 17.607f, 0.9455098f, 20.174f, 1.047356f, 22.7349f); p.curveTo(1.4026052f, 27.0404f, 5.160718f, 30.736599f, 9.479701f, 30.9859f); p.curveTo(12.413785f, 31.0379f, 15.351056f, 31.012901f, 18.285915f, 31.0009f); p.curveTo(22.611284f, 30.8634f, 26.461956f, 27.2619f, 26.926308f, 22.9662f); p.curveTo(27.078321f, 20.3577f, 26.964987f, 17.7381f, 27.000008f, 15.124701f); p.curveTo(26.958828f, 13.016801f, 27.098648f, 10.899301f, 26.894316f, 8.799601f); p.curveTo(26.322966f, 4.5182004f, 22.370419f, 1.0369005f, 18.049965f, 1.0159006f); p.curveTo(15.429189f, 1.0059006f, 12.808315f, 1.0159006f, 10.187508f, 1.0159006f); p.lineTo(10.1875f, 1.0128f); p.moveTo(10.1875f, 3.0128f); p.curveTo(12.975908f, 3.0348f, 15.767242f, 2.9678f, 18.553688f, 3.0498f); p.curveTo(21.993467f, 3.3112f, 24.903746f, 6.3801003f, 24.990755f, 9.8274f); p.curveTo(24.998755f, 14.0019f, 25.021074f, 18.1784f, 24.979284f, 22.3524f); p.curveTo(24.802372f, 25.8659f, 21.708311f, 28.9126f, 18.185738f, 29.0038f); p.curveTo(15.273218f, 29.0029f, 12.357073f, 29.0528f, 9.446313f, 28.9758f); p.curveTo(5.931402f, 28.7044f, 3.001677f, 25.4988f, 3.0023239f, 21.9813f); p.curveTo(3.010334f, 17.8685f, 2.9744568f, 13.7544f, 3.020722f, 9.6424f); p.curveTo(3.1950474f, 6.1982f, 6.1853743f, 3.2078f, 9.629604f, 3.0335f); p.curveTo(9.815227f, 3.0195f, 10.001367f, 3.0125f, 10.187504f, 3.0125f); p.lineTo(10.1875f, 3.0128f); return scaleAndShift(p, scale, xOff, yOff); } private static Shape shapeMute() { return shapeMute(-1f, 0f, 0.5f); } private static Shape shapeMute(float xOff, float yOff, float scale) { final Path2D p = new Path2D.Float(); p.moveTo(20.134766f, 24.2617f); p.curveTo(20.162645f, 19.6085f, 20.067446f, 14.953099f, 20.208006f, 10.3018f); p.curveTo(20.329603f, 8.9957f, 19.856266f, 11.2871f, 19.652098f, 11.709499f); p.curveTo(18.243673f, 15.7111f, 16.66415f, 19.652f, 15.183624f, 23.6281f); p.curveTo(15.127804f, 24.2578f, 14.702459f, 24.352299f, 14.149389f, 24.2617f); p.curveTo(13.575208f, 24.3741f, 13.190391f, 24.2107f, 13.116675f, 23.5947f); p.curveTo(11.662157f, 19.7638f, 10.143147f, 15.956f, 8.732429f, 12.1094f); p.curveTo(8.501633f, 11.52f, 8.133532f, 9.9785f, 8.008979f, 9.8944f); p.curveTo(8.154377f, 14.681799f, 8.061826f, 19.472599f, 8.087898f, 24.2617f); p.curveTo(7.4238358f, 24.2617f, 6.7597733f, 24.2617f, 6.0957108f, 24.2617f); p.curveTo(6.0957108f, 18.7578f, 6.0957108f, 13.2539f, 6.0957108f, 7.75f); p.curveTo(7.0761795f, 7.75f, 8.056648f, 7.75f, 9.037117f, 7.75f); p.curveTo(10.559278f, 11.7728f, 12.15921f, 15.768f, 13.630867f, 19.808601f); p.curveTo(13.949362f, 20.522102f, 14.127401f, 22.701202f, 14.3984375f, 20.9248f); p.curveTo(15.465224f, 17.657701f, 16.781324f, 14.476801f, 17.961388f, 11.2489f); p.curveTo(18.400692f, 10.082601f, 18.839998f, 8.9163f, 19.279305f, 7.7500005f); p.curveTo(20.236336f, 7.7500005f, 21.193367f, 7.7500005f, 22.150398f, 7.7500005f); p.curveTo(22.150398f, 13.253901f, 22.150398f, 18.757801f, 22.150398f, 24.2617f); p.curveTo(21.478523f, 24.2617f, 20.806648f, 24.2617f, 20.134766f, 24.2617f); p.lineTo(20.134766f, 24.2617f); p.moveTo(10.1875f, 1.0128f); p.curveTo(5.8650985f, 0.9218f, 1.82291f, 4.3041f, 1.1432713f, 8.5721f); p.curveTo(0.8768325f, 10.716f, 1.0492703f, 12.8868f, 1.0f, 15.0436f); p.curveTo(1.025343f, 17.607f, 0.9455098f, 20.174f, 1.047356f, 22.7349f); p.curveTo(1.4026052f, 27.0404f, 5.160718f, 30.736599f, 9.479701f, 30.9859f); p.curveTo(12.413785f, 31.0379f, 15.351056f, 31.012901f, 18.285915f, 31.0009f); p.curveTo(22.611284f, 30.8634f, 26.461956f, 27.2619f, 26.926308f, 22.9662f); p.curveTo(27.078321f, 20.3577f, 26.964987f, 17.7381f, 27.000008f, 15.124701f); p.curveTo(26.958828f, 13.016801f, 27.098648f, 10.899301f, 26.894316f, 8.799601f); p.curveTo(26.322966f, 4.5182004f, 22.370419f, 1.0369005f, 18.049965f, 1.0159006f); p.curveTo(15.429189f, 1.0059006f, 12.808315f, 1.0159006f, 10.187508f, 1.0159006f); p.lineTo(10.1875f, 1.0128f); p.moveTo(10.1875f, 3.0128f); p.curveTo(12.975908f, 3.0348f, 15.767242f, 2.9678f, 18.553688f, 3.0498f); p.curveTo(21.993467f, 3.3112f, 24.903746f, 6.3801003f, 24.990755f, 9.8274f); p.curveTo(24.998755f, 14.0019f, 25.021074f, 18.1784f, 24.979284f, 22.3524f); p.curveTo(24.802372f, 25.8659f, 21.708311f, 28.9126f, 18.185738f, 29.0038f); p.curveTo(15.273218f, 29.0029f, 12.357073f, 29.0528f, 9.446313f, 28.9758f); p.curveTo(5.931402f, 28.7044f, 3.001677f, 25.4988f, 3.0023239f, 21.9813f); p.curveTo(3.010334f, 17.8685f, 2.9744568f, 13.7544f, 3.020722f, 9.6424f); p.curveTo(3.1950474f, 6.1982f, 6.1853743f, 3.2078f, 9.629604f, 3.0335f); p.curveTo(9.815227f, 3.0195f, 10.001367f, 3.0125f, 10.187504f, 3.0125f); p.lineTo(10.1875f, 3.0128f); return scaleAndShift(p, scale, xOff, yOff); } private static Shape shapeInsert() { return shapeInsert(-1f, 0f, 0.5f); } private static Shape shapeInsert(float xOff, float yOff, float scale) { final Path2D p = new Path2D.Float(); p.moveTo(30.601023f, 17.183632f); p.curveTo(30.2153f, 15.91982f, 29.276339f, 14.946398f, 28.019863f, 14.425948f); p.curveTo(25.931894f, 13.561084f, 23.942749f, 14.339098f, 23.284533f, 15.928166f); p.curveTo(23.009f, 16.593359f, 22.907965f, 17.568958f, 23.577961f, 18.669096f); p.curveTo(24.320553f, 19.907545f, 25.82281f, 20.984406f, 26.461647f, 21.898455f); p.curveTo(27.027885f, 22.674194f, 26.978569f, 23.368145f, 26.764267f, 23.885519f); p.curveTo(26.35097f, 24.883308f, 25.049433f, 25.621418f, 23.38645f, 24.932589f); p.curveTo(22.129974f, 24.412138f, 21.410885f, 23.378256f, 21.161392f, 22.517239f); p.curveTo(21.136572f, 22.420368f, 21.151892f, 22.383413f, 21.182491f, 22.309502f); p.curveTo(21.197802f, 22.272552f, 21.243721f, 22.161682f, 21.185091f, 22.094112f); p.lineTo(19.857967f, 23.103045f); p.curveTo(20.357725f, 24.457386f, 21.444506f, 25.492039f, 22.867281f, 26.081371f); p.curveTo(25.675875f, 27.24473f, 27.491295f, 25.78862f, 28.08828f, 24.347368f); p.curveTo(28.34085f, 23.737608f, 28.485182f, 22.866535f, 28.047739f, 21.88437f); p.curveTo(27.440287f, 20.528715f, 25.952024f, 19.522596f, 25.151371f, 18.476576f); p.curveTo(24.4278f, 17.50578f, 24.507732f, 16.737919f, 24.699074f, 16.275978f); p.curveTo(25.06645f, 15.389054f, 26.15314f, 14.908318f, 27.465048f, 15.451728f); p.curveTo(28.536749f, 15.895641f, 29.169245f, 16.720474f, 29.34483f, 17.550877f); p.curveTo(29.36965f, 17.647747f, 29.335829f, 17.67705f, 29.30525f, 17.750961f); p.curveTo(29.25933f, 17.861826f, 29.29945f, 17.921741f, 29.33641f, 17.93705f); p.lineTo(30.60099f, 17.183632f); p.moveTo(10.07259f, 20.543509f); p.lineTo(11.310588f, 21.056305f); p.lineTo(15.060886f, 12.002285f); p.lineTo(16.365795f, 23.171888f); p.lineTo(17.40054f, 23.600492f); p.lineTo(21.977432f, 12.550894f); p.curveTo(22.031012f, 12.421551f, 22.064793f, 12.392249f, 22.158495f, 12.322822f); p.curveTo(22.192286f, 12.293522f, 22.267504f, 12.216439f, 22.287294f, 12.116398f); p.lineTo(20.919985f, 11.550026f); p.lineTo(17.38399f, 20.086674f); p.lineTo(16.097334f, 9.552419f); p.lineTo(14.840857f, 9.031969f); p.lineTo(10.072622f, 20.543509f); p.moveTo(6.30421f, 5.495974f); p.lineTo(5.852644f, 6.586152f); p.lineTo(7.9775667f, 7.466324f); p.lineTo(4.097157f, 16.834461f); p.lineTo(1.8428907f, 15.900715f); p.lineTo(1.3989779f, 16.972416f); p.lineTo(7.348762f, 19.436895f); p.lineTo(7.7850213f, 18.383675f); p.lineTo(5.3829346f, 17.388697f); p.lineTo(9.270998f, 8.002081f); p.lineTo(11.543742f, 8.943482f); p.lineTo(11.995308f, 7.853304f); p.lineTo(6.30421f, 5.495974f); return scaleAndShift(p, scale, xOff, yOff); } private static Shape shapeOverwrite() { return shapeOverwrite(-1f, 0f, 0.5f); } private static Shape shapeOverwrite(float xOff, float yOff, float scale) { final Path2D p = new Path2D.Float(); p.moveTo(23.98087f, 11.956031f); p.lineTo(19.212635f, 23.467567f); p.lineTo(20.506065f, 24.003325f); p.lineTo(22.610825f, 18.921988f); p.lineTo(24.846613f, 19.848082f); p.lineTo(25.291761f, 25.985624f); p.lineTo(26.751492f, 26.590263f); p.lineTo(26.210785f, 20.369843f); p.curveTo(27.757332f, 20.555838f, 29.261578f, 19.64192f, 29.896832f, 18.10828f); p.curveTo(30.371359f, 16.96267f, 30.25012f, 15.635228f, 29.400377f, 14.655465f); p.curveTo(28.832825f, 13.98742f, 28.119852f, 13.670449f, 27.36227f, 13.356649f); p.lineTo(23.98087f, 11.956028f); p.moveTo(24.76916f, 13.711305f); p.lineTo(26.857126f, 14.57617f); p.curveTo(27.337543f, 14.775165f, 27.79183f, 14.984985f, 28.180403f, 15.405711f); p.curveTo(28.747955f, 16.073755f, 28.811361f, 16.965933f, 28.505215f, 17.705036f); p.curveTo(28.199068f, 18.44414f, 27.564808f, 18.98239f, 26.761848f, 19.039455f); p.curveTo(26.226543f, 19.077496f, 25.775427f, 18.912287f, 25.313486f, 18.720947f); p.lineTo(23.077698f, 17.794853f); p.lineTo(24.76916f, 13.711306f); p.moveTo(14.169269f, 7.8919325f); p.lineTo(13.280014f, 21.118437f); p.lineTo(13.871297f, 21.363356f); p.lineTo(22.539618f, 11.359044f); p.lineTo(21.264664f, 10.830941f); p.lineTo(14.80844f, 18.526003f); p.lineTo(15.518133f, 8.45065f); p.lineTo(14.169269f, 7.8919325f); p.moveTo(10.775881f, 13.26212f); p.curveTo(11.219794f, 12.19042f, 11.735216f, 10.737031f, 11.619773f, 9.238808f); p.curveTo(11.474486f, 7.4468f, 10.445762f, 6.2197185f, 9.189286f, 5.6992693f); p.curveTo(7.4708705f, 4.987478f, 4.499242f, 5.3152337f, 2.624093f, 9.842244f); p.curveTo(0.74894804f, 14.369244f, 2.543221f, 16.77935f, 4.3170695f, 17.514103f); p.curveTo(5.555068f, 18.0269f, 7.1762943f, 17.875814f, 8.56913f, 16.655975f); p.curveTo(9.691687f, 15.670548f, 10.354929f, 14.278388f, 10.775881f, 13.26212f); p.moveTo(8.636365f, 6.8773518f); p.curveTo(9.449379f, 7.214113f, 10.248174f, 8.107828f, 10.225306f, 9.678649f); p.curveTo(10.215305f, 10.800211f, 9.811557f, 11.931828f, 9.413566f, 12.892662f); p.curveTo(9.099766f, 13.650243f, 8.572976f, 14.817501f, 7.6869144f, 15.597818f); p.curveTo(6.6841903f, 16.502995f, 5.613578f, 16.57908f, 4.837519f, 16.257627f); p.curveTo(3.5440876f, 15.72187f, 2.4525034f, 13.862611f, 3.9679298f, 10.204048f); p.curveTo(5.391512f, 6.7672167f, 7.435322f, 6.379863f, 8.636365f, 6.8773518f); return scaleAndShift(p, scale, xOff, yOff); } private static Shape shapeMix() { return shapeMix(-1f, 0f, 0.5f); } private static Shape shapeMix(float xOff, float yOff, float scale) { final Path2D p = new Path2D.Float(); p.moveTo(30.102737f, 15.023929f); p.lineTo(25.93134f, 18.40497f); p.lineTo(25.31704f, 13.041628f); p.lineTo(23.931221f, 12.467603f); p.lineTo(24.656479f, 19.392254f); p.lineTo(19.089077f, 23.948526f); p.lineTo(20.51185f, 24.537859f); p.lineTo(24.852173f, 21.01031f); p.lineTo(25.537756f, 26.619656f); p.lineTo(26.979008f, 27.216642f); p.lineTo(26.168472f, 19.975246f); p.lineTo(31.39617f, 15.559685f); p.lineTo(30.10274f, 15.023928f); p.moveTo(15.50544f, 8.977531f); p.lineTo(15.053874f, 10.067709f); p.lineTo(17.178797f, 10.947881f); p.lineTo(13.298387f, 20.31602f); p.lineTo(11.044121f, 19.382273f); p.lineTo(10.600207f, 20.453972f); p.lineTo(16.549992f, 22.918453f); p.lineTo(16.98625f, 21.86523f); p.lineTo(14.584164f, 20.870255f); p.lineTo(18.472227f, 11.483639f); p.lineTo(20.74497f, 12.425039f); p.lineTo(21.196537f, 11.334862f); p.lineTo(15.505439f, 8.977531f); p.moveTo(5.3797207f, 4.7833204f); p.lineTo(0.6038316f, 16.313337f); p.lineTo(1.8233526f, 16.81848f); p.lineTo(5.397616f, 8.189445f); p.lineTo(5.835336f, 13.717772f); p.lineTo(6.3157535f, 13.916767f); p.lineTo(10.731299f, 10.312137f); p.lineTo(7.126421f, 19.015081f); p.lineTo(8.3459425f, 19.520224f); p.lineTo(13.121831f, 7.9902077f); p.lineTo(12.160997f, 7.592217f); p.lineTo(6.925646f, 12.026256f); p.lineTo(6.3959885f, 5.2042723f); p.lineTo(5.3797207f, 4.7833204f); return scaleAndShift(p, scale, xOff, yOff); } private static Shape shapeLocation2() { return shapeLocation2(-1f, -1f, 0.5f); } private static Shape shapeLocation2(float xOff, float yOff, float scale) { final Path2D gp = new Path2D.Float(); gp.moveTo(15.833999633789062D, 29.083999633789062D); gp.lineTo(15.833999633789062D, 16.166000366210938D); gp.lineTo(2.9170000553131104D, 16.166000366210938D); gp.lineTo(29.08300018310547D, 2.9170000553131104D); // gp.moveTo(16.0D, 3.5D); // gp.curveTo(11.857999801635742D, 3.5D, 8.5D, 6.857999801635742D, 8.5D, 11.0D); // gp.curveTo(8.5D, 15.142999649047852D, 16.0D, 29.121000289916992D, 16.0D, 29.121000289916992D); // gp.curveTo(16.0D, 29.121000289916992D, 23.5D, 15.142999649047852D, 23.5D, 11.0D); // gp.curveTo(23.5D, 6.857999801635742D, 20.14299964904785D, 3.5D, 16.0D, 3.5D); // gp.moveTo(16.0D, 14.583999633789062D); // gp.curveTo(14.020999908447266D, 14.583999633789062D, 12.416000366210938D, 12.979999542236328D, 12.416000366210938D, 11.0D); // gp.curveTo(12.416000366210938D, 9.020000457763672D, 14.020999908447266D, 7.415999889373779D, 16.0D, 7.415999889373779D); // gp.curveTo(17.979000091552734D, 7.415999889373779D, 19.583999633789062D, 9.020999908447266D, 19.583999633789062D, 11.0D); // gp.curveTo(19.583999633789062D, 12.979000091552734D, 17.979000091552734D, 14.583999633789062D, 16.0D, 14.583999633789062D); return scaleAndShift(gp, scale, xOff, yOff); } private static Shape shapePointer() { return shapePointer(-1f, -1f, 0.5f); } private static Shape shapePointer(float xOff, float yOff, float scale) { final Path2D p = new Path2D.Float(); p.moveTo(15.0f, 24.9999f); p.lineTo(21.0f, 24.9999f); p.lineTo(21.0f, 27.9999f); p.lineTo(15.0f, 27.9999f); p.lineTo(15.0f, 24.9999f); p.moveTo(7.0f, 24.9999f); p.lineTo(13.0f, 24.9999f); p.lineTo(13.0f, 27.9999f); p.lineTo(7.0f, 27.9999f); p.lineTo(7.0f, 24.9999f); p.moveTo(15.0f, 2.9999008f); p.lineTo(21.0f, 2.9999008f); p.lineTo(21.0f, 5.999901f); p.lineTo(15.0f, 5.999901f); p.lineTo(15.0f, 2.9999008f); p.moveTo(15.347826f, 6.0f); p.lineTo(15.347826f, 25.0f); p.lineTo(12.347826f, 25.0f); p.lineTo(12.347826f, 6.0f); p.lineTo(15.347826f, 6.0f); p.moveTo(7.0f, 2.9999f); p.lineTo(13.0f, 2.9999f); p.lineTo(13.0f, 5.9999f); p.lineTo(7.0f, 5.9999f); p.lineTo(7.0f, 2.9999f); return scaleAndShift(p, scale, xOff, yOff); } private static Shape shapeZoom() { return shapeZoom(-1f, -1f, 0.5f); } private static Shape shapeZoom(float xOff, float yOff, float scale) { final Path2D p = new Path2D.Float(); p.moveTo(22.645999908447266D, 19.30699920654297D); p.curveTo(23.605998992919922D, 17.7239990234375D, 24.16900062561035D, 15.871999740600586D, 24.170000076293945D, 13.88599967956543D); p.curveTo(24.16900062561035D, 8.093000411987305D, 19.47800064086914D, 3.4010000228881836D, 13.687999725341797D, 3.3989999294281006D); p.curveTo(7.896999835968018D, 3.4010000228881836D, 3.2039999961853027D, 8.093000411987305D, 3.2039999961853027D, 13.885000228881836D); p.curveTo(3.2039999961853027D, 19.673999786376953D, 7.896999835968018D, 24.36600112915039D, 13.687999725341797D, 24.36600112915039D); p.curveTo(15.674999237060547D, 24.36600112915039D, 17.527000427246094D, 23.803001403808594D, 19.110000610351562D, 22.843000411987305D); p.lineTo(26.238000869750977D, 29.970001220703125D); p.lineTo(29.773000717163086D, 26.433000564575195D); p.lineTo(22.645999908447266D, 19.30699920654297D); p.moveTo(13.687999725341797D, 20.368999481201172D); p.curveTo(10.105999946594238D, 20.361000061035156D, 7.2099995613098145D, 17.46500015258789D, 7.2039995193481445D, 13.88499927520752D); p.curveTo(7.2099995613098145D, 10.302999496459961D, 10.106999397277832D, 7.406999111175537D, 13.687999725341797D, 7.398999214172363D); p.curveTo(17.267000198364258D, 7.406999111175537D, 20.166000366210938D, 10.302999496459961D, 20.172000885009766D, 13.88499927520752D); p.curveTo(20.165000915527344D, 17.46500015258789D, 17.267000198364258D, 20.361000061035156D, 13.687999725341797D, 20.368999481201172D); p.moveTo(15.687000274658203D, 9.050999641418457D); p.lineTo(11.687000274658203D, 9.050999641418457D); p.lineTo(11.687000274658203D, 11.883999824523926D); p.lineTo(8.854000091552734D, 11.883999824523926D); p.lineTo(8.854000091552734D, 15.885000228881836D); p.lineTo(11.687000274658203D, 15.885000228881836D); p.lineTo(11.687000274658203D, 18.718000411987305D); p.lineTo(15.687000274658203D, 18.718000411987305D); p.lineTo(15.687000274658203D, 15.884000778198242D); p.lineTo(18.519001007080078D, 15.884000778198242D); p.lineTo(18.519001007080078D, 11.885000228881836D); p.lineTo(15.68600082397461D, 11.885000228881836D); p.lineTo(15.68600082397461D, 9.050999641418457D); return scaleAndShift(p, scale, xOff, yOff); } private static Shape scaleAndShift(Shape in, float scale, float xOff, float yOff) { if (scale == 1f && xOff == 0f && yOff == 0f) { return in; } else { final AffineTransform at = AffineTransform.getScaleInstance(scale, scale); at.translate(xOff, yOff); return at.createTransformedShape(in); } } private static Shape shapeStop() { return shapeStop(1f, 2f, 0.75f); } private static Shape shapeStop(float xOff, float yOff, float scale) { return new Rectangle2D.Float(xOff, yOff, scale * 16f, scale * 16f); } private static Shape shapePlay() { return shapePlay(2f, 0f, 0.75f); } private static Shape shapePlay(float xOff, float yOff, float scale) { final Path2D p = new Path2D.Float(); p.moveTo(xOff, yOff); p.lineTo(xOff + scale * 15f, yOff + scale * 10f); p.lineTo(xOff, yOff + scale * 20f); p.closePath(); return p; } private static Shape shapeFFwd() { return shapeFFwd(0f, 3f, 0.75f); } private static Shape shapeFFwd(float xOff, float yOff, float scale) { final Shape play = shapePlay(xOff, yOff, scale * 0.7f); final Shape p2 = AffineTransform.getTranslateInstance(scale * 10.667f, 0).createTransformedShape(play); final Area res = new Area(play); res.add(new Area(p2)); return res; } private static Shape shapeRwd() { return shapeRwd(-1f, 3f, 0.75f); } private static Shape shapeRwd(float xOff, float yOff, float scale) { final Shape s1 = shapeFFwd(0f, yOff, scale); final AffineTransform at = AffineTransform.getScaleInstance(-1.0, 1.0); at.translate(-s1.getBounds2D().getWidth() - xOff, 0); return at.createTransformedShape(s1); } private static Shape shapeLoop() { return shapeLoop(-1f, 4f, 0.75f, true); } private static Shape shapeLoop(float xOff, float yOff, float scale, boolean doRotate) { final Area res = new Area(new RoundRectangle2D.Float(0f, scale * 4f, scale * 22f, scale * 14f, scale * 10f, scale * 10f)); res.subtract(new Area(new RoundRectangle2D.Float(0f + scale * 3f, scale * 7f, scale * 16f, scale * 8f, scale * 8f, scale * 8f))); final Path2D gp = new Path2D.Float(); gp.moveTo(0f, scale * 18f); gp.lineTo(scale * 11f, scale * 9f); gp.lineTo(scale * 11f, 0f); gp.lineTo(scale * 22f, 0f); gp.lineTo(scale * 22f, scale * 18f); gp.closePath(); res.subtract(new Area(gp)); // final Shape play = shapePlay(9f, 0.5f, scale * 0.5f); final Shape play = shapePlay(8f, 0.5f, scale * 0.5f); res.add(new Area(play)); final Shape rot = AffineTransform.getRotateInstance(Math.PI, scale * 11f, scale * 12f).createTransformedShape(res); res.add(new Area(rot)); final AffineTransform at = AffineTransform.getScaleInstance(1f, 0.8f); if (doRotate) { at.rotate(Math.PI * -0.2, scale * 11f, scale * 12f); at.preConcatenate(AffineTransform.getTranslateInstance(xOff, yOff - 3f)); } else { at.translate(xOff, yOff); } return at.createTransformedShape(res); } /** * Change the <code>Icon</code>s of an * <code>AbstractButton</code> (<code>JButton</code> * or <code>JToggleButton</code>). * * @param b the button whose icons are to be set * @param icons four <code>Icon</code> objects for * different gadget states, such as * created by the <code>createToolIcons</code> method. * * @see #createToolIcons( int ) */ public static void setToolIcons( AbstractButton b, Icon[] icons ) { b.setIcon( icons[0] ); b.setSelectedIcon( icons[1] ); b.setPressedIcon( icons[3] ); b.setDisabledIcon( icons[2] ); // Insets defInsets = b.getInsets(); } /** * Calculates the length of line. * * @param ln the <code>Line2D</code> shape whose * length is to be calculated * @return the length as given by the distance * of the start point to the end point* */ public static double getLineLength(Line2D ln) { return (Point2D.distance(ln.getX1(), ln.getY1(), ln.getX2(), ln.getY2())); } /** * Calculates the one point on a line which is * nearest to a given point, such that a line * between the given and the returned point will * be orthogonal to the line. * * @param pt point lying somewhere next to or on the line. * @param ln line onto which the pt should be projected * @return the given point projected onto the line */ public static Point2D projectPointOntoLine( Point2D pt, Line2D ln ) { double dx = ln.getX2() - ln.getX1(); double dy = ln.getY2() - ln.getY1(); double lineLenSq = dx*dx + dy*dy; double d1; if( lineLenSq == 0.0 ) { return( new Point2D.Double( ln.getX1(), ln.getY1() )); } else { d1 = ( (pt.getX() - ln.getX1()) * dx + (pt.getY() - ln.getY1()) * dy ) / lineLenSq; return( new Point2D.Double( ln.getX1() + d1 * dx, ln.getY1() + d1 * dy )); } } }