1 /* 2 * Copyright (c) 2011, 2014, 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.security.PrivilegedAction; 31 32 import javax.swing.*; 33 import javax.swing.plaf.*; 34 35 import sun.lwawt.macosx.LWCToolkit; 36 import apple.laf.JRSUIConstants.AlignmentHorizontal; 37 import apple.laf.JRSUIConstants.AlignmentVertical; 38 import apple.laf.JRSUIConstants.Direction; 39 import apple.laf.JRSUIConstants.State; 40 import apple.laf.JRSUIConstants.Widget; 41 import apple.laf.*; 42 43 import com.apple.eio.FileManager; 44 import com.apple.laf.AquaIcon.InvertableIcon; 45 import com.apple.laf.AquaIcon.JRSUIControlSpec; 46 import com.apple.laf.AquaIcon.SystemIcon; 47 import com.apple.laf.AquaUtils.RecyclableObject; 48 import com.apple.laf.AquaUtils.RecyclableSingleton; 49 import sun.awt.image.MultiResolutionCachedImage; 50 import sun.lwawt.macosx.CImage; 51 52 public class AquaImageFactory { getConfirmImageIcon()53 public static IconUIResource getConfirmImageIcon() { 54 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 55 56 return new IconUIResource(new AquaIcon.CachingScalingIcon(kAlertIconSize, kAlertIconSize) { 57 Image createImage() { 58 return getGenericJavaIcon(); 59 } 60 }); 61 } 62 63 public static IconUIResource getCautionImageIcon() { 64 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 65 return getAppIconCompositedOn(AquaIcon.SystemIcon.getCautionIcon()); 66 } 67 68 public static IconUIResource getStopImageIcon() { 69 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 70 return getAppIconCompositedOn(AquaIcon.SystemIcon.getStopIcon()); 71 } 72 73 public static IconUIResource getLockImageIcon() { 74 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 75 if (JRSUIUtils.Images.shouldUseLegacySecurityUIPath()) { 76 final Image lockIcon = CImage.createImageFromFile("/System/Library/CoreServices/SecurityAgent.app/Contents/Resources/Security.icns", kAlertIconSize, kAlertIconSize); 77 return getAppIconCompositedOn(lockIcon); 78 } 79 80 final Image lockIcon = Toolkit.getDefaultToolkit().getImage("NSImage://NSSecurity"); 81 return getAppIconCompositedOn(lockIcon); 82 } 83 84 static Image getGenericJavaIcon() { 85 return java.security.AccessController.doPrivileged(new PrivilegedAction<Image>() { 86 public Image run() { 87 return com.apple.eawt.Application.getApplication().getDockIconImage(); 88 } 89 }); 90 } 91 92 static String getPathToThisApplication() { 93 return java.security.AccessController.doPrivileged(new PrivilegedAction<String>() { 94 public String run() { 95 return FileManager.getPathToApplicationBundle(); 96 } 97 }); 98 } 99 100 static IconUIResource getAppIconCompositedOn(final SystemIcon systemIcon) { 101 systemIcon.setSize(kAlertIconSize, kAlertIconSize); 102 return getAppIconCompositedOn(systemIcon.createImage()); 103 } 104 105 private static final int kAlertIconSize = 64; 106 static IconUIResource getAppIconCompositedOn(final Image background) { 107 108 if (background instanceof MultiResolutionCachedImage) { 109 int width = background.getWidth(null); 110 Image mrIconImage = ((MultiResolutionCachedImage) background).map( 111 rv -> getAppIconImageCompositedOn(rv, rv.getWidth(null) / width)); 112 return new IconUIResource(new ImageIcon(mrIconImage)); 113 } 114 115 BufferedImage iconImage = getAppIconImageCompositedOn(background, 1); 116 return new IconUIResource(new ImageIcon(iconImage)); 117 } 118 119 static BufferedImage getAppIconImageCompositedOn(final Image background, int scaleFactor) { 120 121 final int scaledAlertIconSize = kAlertIconSize * scaleFactor; 122 final int kAlertSubIconSize = (int) (scaledAlertIconSize * 0.5); 123 final int kAlertSubIconInset = scaledAlertIconSize - kAlertSubIconSize; 124 final Icon smallAppIconScaled = new AquaIcon.CachingScalingIcon( 125 kAlertSubIconSize, kAlertSubIconSize) { 126 Image createImage() { 127 return getGenericJavaIcon(); 128 } 129 }; 130 131 final BufferedImage image = new BufferedImage(scaledAlertIconSize, 132 scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB_PRE); 133 final Graphics g = image.getGraphics(); 134 g.drawImage(background, 0, 0, 135 scaledAlertIconSize, scaledAlertIconSize, null); 136 if (g instanceof Graphics2D) { 137 // improves icon rendering quality in Quartz 138 ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_RENDERING, 139 RenderingHints.VALUE_RENDER_QUALITY); 140 } 141 142 smallAppIconScaled.paintIcon(null, g, 143 kAlertSubIconInset, kAlertSubIconInset); 144 g.dispose(); 145 146 return image; 147 } 148 149 public static IconUIResource getTreeFolderIcon() { 150 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 151 return AquaIcon.SystemIcon.getFolderIconUIResource(); 152 } 153 154 public static IconUIResource getTreeOpenFolderIcon() { 155 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 156 return AquaIcon.SystemIcon.getOpenFolderIconUIResource(); 157 } 158 159 public static IconUIResource getTreeDocumentIcon() { 160 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 161 return AquaIcon.SystemIcon.getDocumentIconUIResource(); 162 } 163 164 public static UIResource getTreeExpandedIcon() { 165 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 166 return AquaIcon.getIconFor(new JRSUIControlSpec() { 167 public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { 168 painter.state.set(Widget.DISCLOSURE_TRIANGLE); 169 painter.state.set(State.ACTIVE); 170 painter.state.set(Direction.DOWN); 171 painter.state.set(AlignmentHorizontal.CENTER); 172 painter.state.set(AlignmentVertical.CENTER); 173 } 174 }, 20, 20); 175 } 176 177 public static UIResource getTreeCollapsedIcon() { 178 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 179 return AquaIcon.getIconFor(new JRSUIControlSpec() { 180 public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { 181 painter.state.set(Widget.DISCLOSURE_TRIANGLE); 182 painter.state.set(State.ACTIVE); 183 painter.state.set(Direction.RIGHT); 184 painter.state.set(AlignmentHorizontal.CENTER); 185 painter.state.set(AlignmentVertical.CENTER); 186 } 187 }, 20, 20); 188 } 189 190 public static UIResource getTreeRightToLeftCollapsedIcon() { 191 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 192 return AquaIcon.getIconFor(new JRSUIControlSpec() { 193 public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { 194 painter.state.set(Widget.DISCLOSURE_TRIANGLE); 195 painter.state.set(State.ACTIVE); 196 painter.state.set(Direction.LEFT); 197 painter.state.set(AlignmentHorizontal.CENTER); 198 painter.state.set(AlignmentVertical.CENTER); 199 } 200 }, 20, 20); 201 } 202 203 static class NamedImageSingleton extends RecyclableSingleton<Image> { 204 final String namedImage; 205 206 NamedImageSingleton(final String namedImage) { 207 this.namedImage = namedImage; 208 } 209 210 @Override 211 protected Image getInstance() { 212 return getNSIcon(namedImage); 213 } 214 } 215 216 static class IconUIResourceSingleton extends RecyclableSingleton<IconUIResource> { 217 final NamedImageSingleton holder; 218 219 public IconUIResourceSingleton(final NamedImageSingleton holder) { 220 this.holder = holder; 221 } 222 223 @Override 224 protected IconUIResource getInstance() { 225 return new IconUIResource(new ImageIcon(holder.get())); 226 } 227 } 228 229 @SuppressWarnings("serial") // Superclass is not serializable across versions 230 static class InvertableImageIcon extends ImageIcon implements InvertableIcon, UIResource { 231 Icon invertedImage; 232 public InvertableImageIcon(final Image image) { 233 super(image); 234 } 235 236 @Override 237 public Icon getInvertedIcon() { 238 if (invertedImage != null) return invertedImage; 239 return invertedImage = new IconUIResource(new ImageIcon(AquaUtils.generateLightenedImage(getImage(), 100))); 240 } 241 } 242 243 private static final NamedImageSingleton northArrow = new NamedImageSingleton("NSMenuScrollUp"); 244 private static final IconUIResourceSingleton northArrowIcon = new IconUIResourceSingleton(northArrow); 245 private static final NamedImageSingleton southArrow = new NamedImageSingleton("NSMenuScrollDown"); 246 private static final IconUIResourceSingleton southArrowIcon = new IconUIResourceSingleton(southArrow); 247 private static final NamedImageSingleton westArrow = new NamedImageSingleton("NSMenuSubmenuLeft"); 248 private static final IconUIResourceSingleton westArrowIcon = new IconUIResourceSingleton(westArrow); 249 private static final NamedImageSingleton eastArrow = new NamedImageSingleton("NSMenuSubmenu"); 250 private static final IconUIResourceSingleton eastArrowIcon = new IconUIResourceSingleton(eastArrow); 251 252 static Image getArrowImageForDirection(final int direction) { 253 switch(direction) { 254 case SwingConstants.NORTH: return northArrow.get(); 255 case SwingConstants.SOUTH: return southArrow.get(); 256 case SwingConstants.EAST: return eastArrow.get(); 257 case SwingConstants.WEST: return westArrow.get(); 258 } 259 return null; 260 } 261 262 static Icon getArrowIconForDirection(int direction) { 263 switch(direction) { 264 case SwingConstants.NORTH: return northArrowIcon.get(); 265 case SwingConstants.SOUTH: return southArrowIcon.get(); 266 case SwingConstants.EAST: return eastArrowIcon.get(); 267 case SwingConstants.WEST: return westArrowIcon.get(); 268 } 269 return null; 270 } 271 272 public static Icon getMenuArrowIcon() { 273 return new InvertableImageIcon(AquaUtils.generateLightenedImage(eastArrow.get(), 25)); 274 } 275 276 public static Icon getMenuItemCheckIcon() { 277 return new InvertableImageIcon(AquaUtils.generateLightenedImage( 278 getNSIcon("NSMenuItemSelection"), 25)); 279 } 280 281 public static Icon getMenuItemDashIcon() { 282 return new InvertableImageIcon(AquaUtils.generateLightenedImage( 283 getNSIcon("NSMenuMixedState"), 25)); 284 } 285 286 private static Image getNSIcon(String imageName) { 287 Image icon = Toolkit.getDefaultToolkit() 288 .getImage("NSImage://" + imageName); 289 return icon; 290 } 291 292 public static class NineSliceMetrics { 293 public final int wCut, eCut, nCut, sCut; 294 public final int minW, minH; 295 public final boolean showMiddle, stretchH, stretchV; 296 297 public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut) { 298 this(minWidth, minHeight, westCut, eastCut, northCut, southCut, true); 299 } 300 301 public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean showMiddle) { 302 this(minWidth, minHeight, westCut, eastCut, northCut, southCut, showMiddle, true, true); 303 } 304 305 public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean showMiddle, final boolean stretchHorizontally, final boolean stretchVertically) { 306 this.wCut = westCut; this.eCut = eastCut; this.nCut = northCut; this.sCut = southCut; 307 this.minW = minWidth; this.minH = minHeight; 308 this.showMiddle = showMiddle; this.stretchH = stretchHorizontally; this.stretchV = stretchVertically; 309 } 310 } 311 312 /* 313 * A "paintable" which holds nine images, which represent a sliced up initial 314 * image that can be streched from its middles. 315 */ 316 public static class SlicedImageControl { 317 final BufferedImage NW, N, NE; 318 final BufferedImage W, C, E; 319 final BufferedImage SW, S, SE; 320 321 final NineSliceMetrics metrics; 322 323 final int totalWidth, totalHeight; 324 final int centerColWidth, centerRowHeight; 325 326 public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut) { 327 this(img, westCut, eastCut, northCut, southCut, true); 328 } 329 330 public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle) { 331 this(img, westCut, eastCut, northCut, southCut, useMiddle, true, true); 332 } 333 334 public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle, final boolean stretchHorizontally, final boolean stretchVertically) { 335 this(img, new NineSliceMetrics(img.getWidth(null), img.getHeight(null), westCut, eastCut, northCut, southCut, useMiddle, stretchHorizontally, stretchVertically)); 336 } 337 338 public SlicedImageControl(final Image img, final NineSliceMetrics metrics) { 339 this.metrics = metrics; 340 341 if (img.getWidth(null) != metrics.minW || img.getHeight(null) != metrics.minH) { 342 throw new IllegalArgumentException("SlicedImageControl: template image and NineSliceMetrics don't agree on minimum dimensions"); 343 } 344 345 totalWidth = metrics.minW; 346 totalHeight = metrics.minH; 347 centerColWidth = totalWidth - metrics.wCut - metrics.eCut; 348 centerRowHeight = totalHeight - metrics.nCut - metrics.sCut; 349 350 NW = createSlice(img, 0, 0, metrics.wCut, metrics.nCut); 351 N = createSlice(img, metrics.wCut, 0, centerColWidth, metrics.nCut); 352 NE = createSlice(img, totalWidth - metrics.eCut, 0, metrics.eCut, metrics.nCut); 353 W = createSlice(img, 0, metrics.nCut, metrics.wCut, centerRowHeight); 354 C = metrics.showMiddle ? createSlice(img, metrics.wCut, metrics.nCut, centerColWidth, centerRowHeight) : null; 355 E = createSlice(img, totalWidth - metrics.eCut, metrics.nCut, metrics.eCut, centerRowHeight); 356 SW = createSlice(img, 0, totalHeight - metrics.sCut, metrics.wCut, metrics.sCut); 357 S = createSlice(img, metrics.wCut, totalHeight - metrics.sCut, centerColWidth, metrics.sCut); 358 SE = createSlice(img, totalWidth - metrics.eCut, totalHeight - metrics.sCut, metrics.eCut, metrics.sCut); 359 } 360 361 static BufferedImage createSlice(final Image img, final int x, final int y, final int w, final int h) { 362 if (w == 0 || h == 0) return null; 363 364 final BufferedImage slice = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); 365 final Graphics2D g2d = slice.createGraphics(); 366 g2d.drawImage(img, 0, 0, w, h, x, y, x + w, y + h, null); 367 g2d.dispose(); 368 369 return slice; 370 } 371 372 public void paint(final Graphics g, final int x, final int y, final int w, final int h) { 373 g.translate(x, y); 374 375 if (w < totalWidth || h < totalHeight) { 376 paintCompressed(g, w, h); 377 } else { 378 paintStretchedMiddles(g, w, h); 379 } 380 381 g.translate(-x, -y); 382 } 383 384 void paintStretchedMiddles(final Graphics g, final int w, final int h) { 385 int baseX = metrics.stretchH ? 0 : ((w / 2) - (totalWidth / 2)); 386 int baseY = metrics.stretchV ? 0 : ((h / 2) - (totalHeight / 2)); 387 int adjustedWidth = metrics.stretchH ? w : totalWidth; 388 int adjustedHeight = metrics.stretchV ? h : totalHeight; 389 390 if (NW != null) g.drawImage(NW, baseX, baseY, null); 391 if (N != null) g.drawImage(N, baseX + metrics.wCut, baseY, adjustedWidth - metrics.eCut - metrics.wCut, metrics.nCut, null); 392 if (NE != null) g.drawImage(NE, baseX + adjustedWidth - metrics.eCut, baseY, null); 393 if (W != null) g.drawImage(W, baseX, baseY + metrics.nCut, metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut, null); 394 if (C != null) g.drawImage(C, baseX + metrics.wCut, baseY + metrics.nCut, adjustedWidth - metrics.eCut - metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut, null); 395 if (E != null) g.drawImage(E, baseX + adjustedWidth - metrics.eCut, baseY + metrics.nCut, metrics.eCut, adjustedHeight - metrics.nCut - metrics.sCut, null); 396 if (SW != null) g.drawImage(SW, baseX, baseY + adjustedHeight - metrics.sCut, null); 397 if (S != null) g.drawImage(S, baseX + metrics.wCut, baseY + adjustedHeight - metrics.sCut, adjustedWidth - metrics.eCut - metrics.wCut, metrics.sCut, null); 398 if (SE != null) g.drawImage(SE, baseX + adjustedWidth - metrics.eCut, baseY + adjustedHeight - metrics.sCut, null); 399 400 /* 401 if (NW != null) {g.setColor(Color.GREEN); g.fillRect(baseX, baseY, NW.getWidth(), NW.getHeight());} 402 if (N != null) {g.setColor(Color.RED); g.fillRect(baseX + metrics.wCut, baseY, adjustedWidth - metrics.eCut - metrics.wCut, metrics.nCut);} 403 if (NE != null) {g.setColor(Color.BLUE); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY, NE.getWidth(), NE.getHeight());} 404 if (W != null) {g.setColor(Color.PINK); g.fillRect(baseX, baseY + metrics.nCut, metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut);} 405 if (C != null) {g.setColor(Color.ORANGE); g.fillRect(baseX + metrics.wCut, baseY + metrics.nCut, adjustedWidth - metrics.eCut - metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut);} 406 if (E != null) {g.setColor(Color.CYAN); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY + metrics.nCut, metrics.eCut, adjustedHeight - metrics.nCut - metrics.sCut);} 407 if (SW != null) {g.setColor(Color.MAGENTA); g.fillRect(baseX, baseY + adjustedHeight - metrics.sCut, SW.getWidth(), SW.getHeight());} 408 if (S != null) {g.setColor(Color.DARK_GRAY); g.fillRect(baseX + metrics.wCut, baseY + adjustedHeight - metrics.sCut, adjustedWidth - metrics.eCut - metrics.wCut, metrics.sCut);} 409 if (SE != null) {g.setColor(Color.YELLOW); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY + adjustedHeight - metrics.sCut, SE.getWidth(), SE.getHeight());} 410 */ 411 } 412 413 void paintCompressed(final Graphics g, final int w, final int h) { 414 final double heightRatio = h > totalHeight ? 1.0 : (double)h / (double)totalHeight; 415 final double widthRatio = w > totalWidth ? 1.0 : (double)w / (double)totalWidth; 416 417 final int northHeight = (int)(metrics.nCut * heightRatio); 418 final int southHeight = (int)(metrics.sCut * heightRatio); 419 final int centerHeight = h - northHeight - southHeight; 420 421 final int westWidth = (int)(metrics.wCut * widthRatio); 422 final int eastWidth = (int)(metrics.eCut * widthRatio); 423 final int centerWidth = w - westWidth - eastWidth; 424 425 if (NW != null) g.drawImage(NW, 0, 0, westWidth, northHeight, null); 426 if (N != null) g.drawImage(N, westWidth, 0, centerWidth, northHeight, null); 427 if (NE != null) g.drawImage(NE, w - eastWidth, 0, eastWidth, northHeight, null); 428 if (W != null) g.drawImage(W, 0, northHeight, westWidth, centerHeight, null); 429 if (C != null) g.drawImage(C, westWidth, northHeight, centerWidth, centerHeight, null); 430 if (E != null) g.drawImage(E, w - eastWidth, northHeight, eastWidth, centerHeight, null); 431 if (SW != null) g.drawImage(SW, 0, h - southHeight, westWidth, southHeight, null); 432 if (S != null) g.drawImage(S, westWidth, h - southHeight, centerWidth, southHeight, null); 433 if (SE != null) g.drawImage(SE, w - eastWidth, h - southHeight, eastWidth, southHeight, null); 434 } 435 } 436 437 public abstract static class RecyclableSlicedImageControl extends RecyclableObject<SlicedImageControl> { 438 final NineSliceMetrics metrics; 439 440 public RecyclableSlicedImageControl(final NineSliceMetrics metrics) { 441 this.metrics = metrics; 442 } 443 444 @Override 445 protected SlicedImageControl create() { 446 return new SlicedImageControl(createTemplateImage(metrics.minW, metrics.minH), metrics); 447 } 448 449 protected abstract Image createTemplateImage(final int width, final int height); 450 } 451 452 // when we use SystemColors, we need to proxy the color with something that implements UIResource, 453 // so that it will be uninstalled when the look and feel is changed. 454 @SuppressWarnings("serial") // JDK implementation class 455 private static class SystemColorProxy extends Color implements UIResource { 456 final Color color; 457 public SystemColorProxy(final Color color) { 458 super(color.getRGB()); 459 this.color = color; 460 } 461 462 public int getRGB() { 463 return color.getRGB(); 464 } 465 } 466 467 public static Color getWindowBackgroundColorUIResource() { 468 //return AquaNativeResources.getWindowBackgroundColorUIResource(); 469 return new SystemColorProxy(SystemColor.window); 470 } 471 472 public static Color getTextSelectionBackgroundColorUIResource() { 473 return new SystemColorProxy(SystemColor.textHighlight); 474 } 475 476 public static Color getTextSelectionForegroundColorUIResource() { 477 return new SystemColorProxy(SystemColor.textHighlightText); 478 } 479 480 public static Color getSelectionBackgroundColorUIResource() { 481 return new SystemColorProxy(SystemColor.controlHighlight); 482 } 483 484 public static Color getSelectionForegroundColorUIResource() { 485 return new SystemColorProxy(SystemColor.controlLtHighlight); 486 } 487 488 public static Color getFocusRingColorUIResource() { 489 return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.KEYBOARD_FOCUS_COLOR)); 490 } 491 492 public static Color getSelectionInactiveBackgroundColorUIResource() { 493 return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_BACKGROUND_COLOR)); 494 } 495 496 public static Color getSelectionInactiveForegroundColorUIResource() { 497 return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_FOREGROUND_COLOR)); 498 } 499 } 500