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 26package com.apple.laf; 27 28import java.awt.*; 29import java.awt.image.BufferedImage; 30import java.io.File; 31 32import javax.swing.*; 33import javax.swing.plaf.*; 34 35import apple.laf.JRSUIConstants.Size; 36import apple.laf.*; 37 38import com.apple.laf.AquaUtilControlSize.*; 39import com.apple.laf.AquaUtils.RecyclableSingleton; 40import sun.lwawt.macosx.CImage; 41 42public class AquaIcon { 43 interface InvertableIcon extends Icon { 44 public Icon getInvertedIcon(); 45 } 46 47 static UIResource getIconFor(final JRSUIControlSpec spec, final int width, final int height) { 48 return new ScalingJRSUIIcon(width, height) { 49 @Override 50 public void initIconPainter(final AquaPainter<JRSUIState> painter) { 51 spec.initIconPainter(painter); 52 } 53 }; 54 } 55 56 // converts an object that is an icon into an image so we can hand it off to AppKit 57 public static Image getImageForIcon(final Icon i) { 58 if (i instanceof ImageIcon) return ((ImageIcon)i).getImage(); 59 60 final int w = i.getIconWidth(); 61 final int h = i.getIconHeight(); 62 63 if (w <= 0 || h <= 0) return null; 64 65 // 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. 66 final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); 67 final Graphics g = image.getGraphics(); 68 i.paintIcon(null, g, 0, 0); 69 g.dispose(); 70 return image; 71 } 72 73 public interface JRSUIControlSpec { 74 public void initIconPainter(final AquaPainter<? extends JRSUIState> painter); 75 } 76 77 abstract static class JRSUIIcon implements Icon, UIResource { 78 protected final AquaPainter<JRSUIState> painter = AquaPainter.create(JRSUIState.getInstance()); 79 80 public void paintIcon(final Component c, final Graphics g, final int x, final int y) { 81 painter.paint(g, c, x, y, getIconWidth(), getIconHeight()); 82 } 83 } 84 85 abstract static class DynamicallySizingJRSUIIcon extends JRSUIIcon { 86 protected final SizeDescriptor sizeDescriptor; 87 protected SizeVariant sizeVariant; 88 89 public DynamicallySizingJRSUIIcon(final SizeDescriptor sizeDescriptor) { 90 this.sizeDescriptor = sizeDescriptor; 91 this.sizeVariant = sizeDescriptor.regular; 92 initJRSUIState(); 93 } 94 95 public abstract void initJRSUIState(); 96 97 public int getIconHeight() { 98 return sizeVariant == null ? 0 : sizeVariant.h; 99 } 100 101 public int getIconWidth() { 102 return sizeVariant == null ? 0 : sizeVariant.w; 103 } 104 105 public void paintIcon(final Component c, final Graphics g, final int x, final int y) { 106 final Size size = c instanceof JComponent ? AquaUtilControlSize.getUserSizeFrom((JComponent)c) : Size.REGULAR; 107 sizeVariant = sizeDescriptor.get(size); 108 painter.state.set(size); 109 super.paintIcon(c, g, x, y); 110 } 111 } 112 113 abstract static class CachingScalingIcon implements Icon, UIResource { 114 int width; 115 int height; 116 Image image; 117 118 public CachingScalingIcon(final int width, final int height) { 119 this.width = width; 120 this.height = height; 121 } 122 123 void setSize(final int width, final int height) { 124 this.width = width; 125 this.height = height; 126 this.image = null; 127 } 128 129 Image getImage() { 130 if (image != null) return image; 131 132 if (!GraphicsEnvironment.isHeadless()) { 133 image = createImage(); 134 } 135 136 return image; 137 } 138 139 abstract Image createImage(); 140 141 public boolean hasIconRef() { 142 return getImage() != null; 143 } 144 145 public void paintIcon(final Component c, Graphics g, final int x, final int y) { 146 g = g.create(); 147 148 if (g instanceof Graphics2D) { 149 // improves icon rendering quality in Quartz 150 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 151 } 152 153 final Image myImage = getImage(); 154 if (myImage != null) { 155 g.drawImage(myImage, x, y, getIconWidth(), getIconHeight(), null); 156 } 157 158 g.dispose(); 159 } 160 161 public int getIconWidth() { 162 return width; 163 } 164 165 public int getIconHeight() { 166 return height; 167 } 168 169 } 170 171 abstract static class ScalingJRSUIIcon implements Icon, UIResource { 172 final int width; 173 final int height; 174 175 public ScalingJRSUIIcon(final int width, final int height) { 176 this.width = width; 177 this.height = height; 178 } 179 180 @Override 181 public void paintIcon(final Component c, Graphics g, 182 final int x, final int y) { 183 if (GraphicsEnvironment.isHeadless()) { 184 return; 185 } 186 187 g = g.create(); 188 189 if (g instanceof Graphics2D) { 190 // improves icon rendering quality in Quartz 191 ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_RENDERING, 192 RenderingHints.VALUE_RENDER_QUALITY); 193 } 194 195 final AquaPainter<JRSUIState> painter = 196 AquaPainter.create(JRSUIState.getInstance()); 197 initIconPainter(painter); 198 199 g.clipRect(x, y, width, height); 200 painter.paint(g, c, x, y, width, height); 201 g.dispose(); 202 } 203 204 public abstract void initIconPainter(final AquaPainter<JRSUIState> painter); 205 206 @Override 207 public int getIconWidth() { 208 return width; 209 } 210 211 @Override 212 public int getIconHeight() { 213 return height; 214 } 215 } 216 217 static class FileIcon extends CachingScalingIcon { 218 final File file; 219 220 public FileIcon(final File file, final int width, final int height) { 221 super(width, height); 222 this.file = file; 223 } 224 225 public FileIcon(final File file) { 226 this(file, 16, 16); 227 } 228 229 Image createImage() { 230 return CImage.createImageOfFile(file.getAbsolutePath(), getIconWidth(), getIconHeight()); 231 } 232 } 233 234 static class SystemIconSingleton extends RecyclableSingleton<SystemIcon> { 235 final String selector; 236 237 public SystemIconSingleton(String selector) { 238 this.selector = selector; 239 } 240 241 @Override 242 protected SystemIcon getInstance() { 243 return new SystemIcon(selector); 244 } 245 } 246 247 static class SystemIconUIResourceSingleton extends RecyclableSingleton<IconUIResource> { 248 final String selector; 249 250 public SystemIconUIResourceSingleton(String selector) { 251 this.selector = selector; 252 } 253 254 @Override 255 protected IconUIResource getInstance() { 256 return new IconUIResource(new SystemIcon(selector)); 257 } 258 } 259 260 static class SystemIcon extends CachingScalingIcon { 261 private static final SystemIconUIResourceSingleton folderIcon = new SystemIconUIResourceSingleton("fldr"); 262 static IconUIResource getFolderIconUIResource() { return folderIcon.get(); } 263 264 private static final SystemIconUIResourceSingleton openFolderIcon = new SystemIconUIResourceSingleton("ofld"); 265 static IconUIResource getOpenFolderIconUIResource() { return openFolderIcon.get(); } 266 267 private static final SystemIconUIResourceSingleton desktopIcon = new SystemIconUIResourceSingleton("desk"); 268 static IconUIResource getDesktopIconUIResource() { return desktopIcon.get(); } 269 270 private static final SystemIconUIResourceSingleton computerIcon = new SystemIconUIResourceSingleton("FNDR"); 271 static IconUIResource getComputerIconUIResource() { return computerIcon.get(); } 272 273 private static final SystemIconUIResourceSingleton documentIcon = new SystemIconUIResourceSingleton("docu"); 274 static IconUIResource getDocumentIconUIResource() { return documentIcon.get(); } 275 276 private static final SystemIconUIResourceSingleton hardDriveIcon = new SystemIconUIResourceSingleton("hdsk"); 277 static IconUIResource getHardDriveIconUIResource() { return hardDriveIcon.get(); } 278 279 private static final SystemIconUIResourceSingleton floppyIcon = new SystemIconUIResourceSingleton("flpy"); 280 static IconUIResource getFloppyIconUIResource() { return floppyIcon.get(); } 281 282 //private static final SystemIconUIResourceSingleton noteIcon = new SystemIconUIResourceSingleton("note"); 283 //static IconUIResource getNoteIconUIResource() { return noteIcon.get(); } 284 285 private static final SystemIconSingleton caut = new SystemIconSingleton("caut"); 286 static SystemIcon getCautionIcon() { return caut.get(); } 287 288 private static final SystemIconSingleton stop = new SystemIconSingleton("stop"); 289 static SystemIcon getStopIcon() { return stop.get(); } 290 291 final String selector; 292 293 public SystemIcon(final String iconSelector, final int width, final int height) { 294 super(width, height); 295 selector = iconSelector; 296 } 297 298 public SystemIcon(final String iconSelector) { 299 this(iconSelector, 16, 16); 300 } 301 302 Image createImage() { 303 return CImage.createSystemImageFromSelector( 304 selector, getIconWidth(), getIconHeight()); 305 } 306 } 307} 308