1 /* 2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.apple.laf; 27 28 import java.awt.*; 29 import java.awt.image.BufferedImage; 30 import java.io.File; 31 32 import javax.swing.*; 33 import javax.swing.plaf.*; 34 35 import apple.laf.JRSUIConstants.Size; 36 import apple.laf.*; 37 38 import com.apple.laf.AquaUtilControlSize.*; 39 import com.apple.laf.AquaUtils.RecyclableSingleton; 40 41 public class AquaIcon { 42 interface InvertableIcon extends Icon { 43 public Icon getInvertedIcon(); 44 } 45 46 static UIResource getIconFor(final JRSUIControlSpec spec, final int width, final int height) { 47 return new ScalingJRSUIIcon(width, height) { 48 @Override 49 public void initIconPainter(final AquaPainter<JRSUIState> painter) { 50 spec.initIconPainter(painter); 51 } 52 }; 53 } 54 55 // converts an object that is an icon into an image so we can hand it off to AppKit 56 public static Image getImageForIcon(final Icon i) { 57 if (i instanceof ImageIcon) return ((ImageIcon)i).getImage(); 58 59 final int w = i.getIconWidth(); 60 final int h = i.getIconHeight(); 61 62 if (w <= 0 || h <= 0) return null; 63 64 // This could be any kind of icon, so we need to make a buffer for it, draw it and then pass the new image off to appkit. 65 final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); 66 final Graphics g = image.getGraphics(); 67 i.paintIcon(null, g, 0, 0); 68 g.dispose(); 69 return image; 70 } 71 72 public interface JRSUIControlSpec { 73 public void initIconPainter(final AquaPainter<? extends JRSUIState> painter); 74 } 75 76 abstract static class JRSUIIcon implements Icon, UIResource { 77 protected final AquaPainter<JRSUIState> painter = AquaPainter.create(JRSUIState.getInstance()); 78 79 public void paintIcon(final Component c, final Graphics g, final int x, final int y) { 80 painter.paint(g, c, x, y, getIconWidth(), getIconHeight()); 81 } 82 } 83 84 abstract static class DynamicallySizingJRSUIIcon extends JRSUIIcon { 85 protected final SizeDescriptor sizeDescriptor; 86 protected SizeVariant sizeVariant; 87 88 public DynamicallySizingJRSUIIcon(final SizeDescriptor sizeDescriptor) { 89 this.sizeDescriptor = sizeDescriptor; 90 this.sizeVariant = sizeDescriptor.regular; 91 initJRSUIState(); 92 } 93 94 public abstract void initJRSUIState(); 95 96 public int getIconHeight() { 97 return sizeVariant == null ? 0 : sizeVariant.h; 98 } 99 100 public int getIconWidth() { 101 return sizeVariant == null ? 0 : sizeVariant.w; 102 } 103 104 public void paintIcon(final Component c, final Graphics g, final int x, final int y) { 105 final Size size = c instanceof JComponent ? AquaUtilControlSize.getUserSizeFrom((JComponent)c) : Size.REGULAR; 106 sizeVariant = sizeDescriptor.get(size); 107 painter.state.set(size); 108 super.paintIcon(c, g, x, y); 109 } 110 } 111 112 abstract static class CachingScalingIcon implements Icon, UIResource { 113 int width; 114 int height; 115 Image image; 116 117 public CachingScalingIcon(final int width, final int height) { 118 this.width = width; 119 this.height = height; 120 } 121 122 void setSize(final int width, final int height) { 123 this.width = width; 124 this.height = height; 125 this.image = null; 126 } 127 128 Image getImage() { 129 if (image != null) return image; 130 131 if (!GraphicsEnvironment.isHeadless()) { 132 image = createImage(); 133 } 134 135 return image; 136 } 137 138 abstract Image createImage(); 139 140 public boolean hasIconRef() { 141 return getImage() != null; 142 } 143 144 public void paintIcon(final Component c, Graphics g, final int x, final int y) { 145 g = g.create(); 146 147 if (g instanceof Graphics2D) { 148 // improves icon rendering quality in Quartz 149 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 150 } 151 152 final Image myImage = getImage(); 153 if (myImage != null) { 154 g.drawImage(myImage, x, y, getIconWidth(), getIconHeight(), null); 155 } 156 157 g.dispose(); 158 } 159 160 public int getIconWidth() { 161 return width; 162 } 163 164 public int getIconHeight() { 165 return height; 166 } 167 168 } 169 170 abstract static class ScalingJRSUIIcon implements Icon, UIResource { 171 final int width; 172 final int height; 173 174 public ScalingJRSUIIcon(final int width, final int height) { 175 this.width = width; 176 this.height = height; 177 } 178 179 @Override 180 public void paintIcon(final Component c, Graphics g, 181 final int x, final int y) { 182 if (GraphicsEnvironment.isHeadless()) { 183 return; 184 } 185 186 g = g.create(); 187 188 if (g instanceof Graphics2D) { 189 // improves icon rendering quality in Quartz 190 ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_RENDERING, 191 RenderingHints.VALUE_RENDER_QUALITY); 192 } 193 194 final AquaPainter<JRSUIState> painter = 195 AquaPainter.create(JRSUIState.getInstance()); 196 initIconPainter(painter); 197 198 g.clipRect(x, y, width, height); 199 painter.paint(g, c, x, y, width, height); 200 g.dispose(); 201 } 202 203 public abstract void initIconPainter(final AquaPainter<JRSUIState> painter); 204 205 @Override 206 public int getIconWidth() { 207 return width; 208 } 209 210 @Override 211 public int getIconHeight() { 212 return height; 213 } 214 } 215 216 static class FileIcon extends CachingScalingIcon { 217 final File file; 218 219 public FileIcon(final File file, final int width, final int height) { 220 super(width, height); 221 this.file = file; 222 } 223 224 public FileIcon(final File file) { 225 this(file, 16, 16); 226 } 227 228 Image createImage() { 229 return AquaUtils.getCImageCreator().createImageOfFile(file.getAbsolutePath(), getIconWidth(), getIconHeight()); 230 } 231 } 232 233 static class SystemIconSingleton extends RecyclableSingleton<SystemIcon> { 234 final String selector; 235 236 public SystemIconSingleton(String selector) { 237 this.selector = selector; 238 } 239 240 @Override 241 protected SystemIcon getInstance() { 242 return new SystemIcon(selector); 243 } 244 } 245 246 static class SystemIconUIResourceSingleton extends RecyclableSingleton<IconUIResource> { 247 final String selector; 248 249 public SystemIconUIResourceSingleton(String selector) { 250 this.selector = selector; 251 } 252 253 @Override 254 protected IconUIResource getInstance() { 255 return new IconUIResource(new SystemIcon(selector)); 256 } 257 } 258 259 static class SystemIcon extends CachingScalingIcon { 260 private static final SystemIconUIResourceSingleton folderIcon = new SystemIconUIResourceSingleton("fldr"); 261 static IconUIResource getFolderIconUIResource() { return folderIcon.get(); } 262 263 private static final SystemIconUIResourceSingleton openFolderIcon = new SystemIconUIResourceSingleton("ofld"); 264 static IconUIResource getOpenFolderIconUIResource() { return openFolderIcon.get(); } 265 266 private static final SystemIconUIResourceSingleton desktopIcon = new SystemIconUIResourceSingleton("desk"); 267 static IconUIResource getDesktopIconUIResource() { return desktopIcon.get(); } 268 269 private static final SystemIconUIResourceSingleton computerIcon = new SystemIconUIResourceSingleton("FNDR"); 270 static IconUIResource getComputerIconUIResource() { return computerIcon.get(); } 271 272 private static final SystemIconUIResourceSingleton documentIcon = new SystemIconUIResourceSingleton("docu"); 273 static IconUIResource getDocumentIconUIResource() { return documentIcon.get(); } 274 275 private static final SystemIconUIResourceSingleton hardDriveIcon = new SystemIconUIResourceSingleton("hdsk"); 276 static IconUIResource getHardDriveIconUIResource() { return hardDriveIcon.get(); } 277 278 private static final SystemIconUIResourceSingleton floppyIcon = new SystemIconUIResourceSingleton("flpy"); 279 static IconUIResource getFloppyIconUIResource() { return floppyIcon.get(); } 280 281 //private static final SystemIconUIResourceSingleton noteIcon = new SystemIconUIResourceSingleton("note"); 282 //static IconUIResource getNoteIconUIResource() { return noteIcon.get(); } 283 284 private static final SystemIconSingleton caut = new SystemIconSingleton("caut"); 285 static SystemIcon getCautionIcon() { return caut.get(); } 286 287 private static final SystemIconSingleton stop = new SystemIconSingleton("stop"); 288 static SystemIcon getStopIcon() { return stop.get(); } 289 290 final String selector; 291 292 public SystemIcon(final String iconSelector, final int width, final int height) { 293 super(width, height); 294 selector = iconSelector; 295 } 296 297 public SystemIcon(final String iconSelector) { 298 this(iconSelector, 16, 16); 299 } 300 301 Image createImage() { 302 return AquaUtils.getCImageCreator().createSystemImageFromSelector( 303 selector, getIconWidth(), getIconHeight()); 304 } 305 } 306 }