1 /* 2 * Copyright (c) 2002, 2006, 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 package com.sun.java.swing.plaf.gtk; 26 27 import java.util.*; 28 import javax.swing.plaf.synth.*; 29 import java.awt.*; 30 import java.awt.image.BufferedImage; 31 import java.lang.reflect.*; 32 import javax.swing.*; 33 import javax.swing.plaf.*; 34 import sun.swing.plaf.synth.*; 35 import com.sun.java.swing.plaf.gtk.GTKConstants.ArrowType; 36 import com.sun.java.swing.plaf.gtk.GTKConstants.ExpanderStyle; 37 import com.sun.java.swing.plaf.gtk.GTKConstants.Orientation; 38 import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType; 39 40 /** 41 */ 42 class GTKIconFactory { 43 static final int CHECK_ICON_EXTRA_INSET = 1; 44 static final int DEFAULT_ICON_SPACING = 2; 45 static final int DEFAULT_ICON_SIZE = 13; 46 static final int DEFAULT_TOGGLE_MENU_ITEM_SIZE = 12; // For pre-gtk2.4 47 48 private static final String RADIO_BUTTON_ICON = "paintRadioButtonIcon"; 49 private static final String CHECK_BOX_ICON = "paintCheckBoxIcon"; 50 private static final String MENU_ARROW_ICON = "paintMenuArrowIcon"; 51 private static final String CHECK_BOX_MENU_ITEM_CHECK_ICON = 52 "paintCheckBoxMenuItemCheckIcon"; 53 private static final String RADIO_BUTTON_MENU_ITEM_CHECK_ICON = 54 "paintRadioButtonMenuItemCheckIcon"; 55 private static final String TREE_EXPANDED_ICON = "paintTreeExpandedIcon"; 56 private static final String TREE_COLLAPSED_ICON = "paintTreeCollapsedIcon"; 57 private static final String ASCENDING_SORT_ICON = "paintAscendingSortIcon"; 58 private static final String DESCENDING_SORT_ICON = "paintDescendingSortIcon"; 59 private static final String TOOL_BAR_HANDLE_ICON = "paintToolBarHandleIcon"; 60 61 private static Map<String, DelegatingIcon> iconsPool = 62 Collections.synchronizedMap(new HashMap<String, DelegatingIcon>()); 63 64 private static DelegatingIcon getIcon(String methodName) { 65 DelegatingIcon result = iconsPool.get(methodName); 66 if (result == null) { 67 if (methodName == TREE_COLLAPSED_ICON || 68 methodName == TREE_EXPANDED_ICON) 69 { 70 result = new SynthExpanderIcon(methodName); 71 72 } else if (methodName == TOOL_BAR_HANDLE_ICON) { 73 result = new ToolBarHandleIcon(); 74 75 } else if (methodName == MENU_ARROW_ICON) { 76 result = new MenuArrowIcon(); 77 78 } else { 79 result = new DelegatingIcon(methodName); 80 } 81 iconsPool.put(methodName, result); 82 } 83 return result; 84 } 85 86 // 87 // Sort arrow 88 // 89 public static Icon getAscendingSortIcon() { 90 return getIcon(ASCENDING_SORT_ICON); 91 } 92 93 public static Icon getDescendingSortIcon() { 94 return getIcon(DESCENDING_SORT_ICON); 95 } 96 97 // 98 // Tree methods 99 // 100 public static SynthIcon getTreeExpandedIcon() { 101 return getIcon(TREE_EXPANDED_ICON); 102 } 103 104 public static SynthIcon getTreeCollapsedIcon() { 105 return getIcon(TREE_COLLAPSED_ICON); 106 } 107 108 // 109 // Radio button 110 // 111 public static SynthIcon getRadioButtonIcon() { 112 return getIcon(RADIO_BUTTON_ICON); 113 } 114 115 // 116 // CheckBox 117 // 118 public static SynthIcon getCheckBoxIcon() { 119 return getIcon(CHECK_BOX_ICON); 120 } 121 122 // 123 // Menus 124 // 125 public static SynthIcon getMenuArrowIcon() { 126 return getIcon(MENU_ARROW_ICON); 127 } 128 129 public static SynthIcon getCheckBoxMenuItemCheckIcon() { 130 return getIcon(CHECK_BOX_MENU_ITEM_CHECK_ICON); 131 } 132 133 public static SynthIcon getRadioButtonMenuItemCheckIcon() { 134 return getIcon(RADIO_BUTTON_MENU_ITEM_CHECK_ICON); 135 } 136 137 // 138 // ToolBar Handle 139 // 140 public static SynthIcon getToolBarHandleIcon() { 141 return getIcon(TOOL_BAR_HANDLE_ICON); 142 } 143 144 static void resetIcons() { 145 synchronized (iconsPool) { 146 for (DelegatingIcon di: iconsPool.values()) { 147 di.resetIconDimensions(); 148 } 149 } 150 } 151 152 private static class DelegatingIcon extends SynthIcon implements 153 UIResource { 154 private static final Class<?>[] PARAM_TYPES = new Class<?>[] { 155 SynthContext.class, Graphics.class, int.class, 156 int.class, int.class, int.class, int.class 157 }; 158 159 private Object method; 160 int iconDimension = -1; 161 162 DelegatingIcon(String methodName ){ 163 this.method = methodName; 164 } 165 166 public void paintIcon(SynthContext context, Graphics g, 167 int x, int y, int w, int h) { 168 if (context != null) { 169 GTKPainter.INSTANCE.paintIcon(context, g, 170 getMethod(), x, y, w, h); 171 } 172 } 173 174 public int getIconWidth(SynthContext context) { 175 return getIconDimension(context); 176 } 177 178 public int getIconHeight(SynthContext context) { 179 return getIconDimension(context); 180 } 181 182 void resetIconDimensions() { 183 iconDimension = -1; 184 } 185 186 protected Method getMethod() { 187 if (method instanceof String) { 188 method = resolveMethod((String)method); 189 } 190 return (Method)method; 191 } 192 193 protected Class<?>[] getMethodParamTypes() { 194 return PARAM_TYPES; 195 } 196 197 private Method resolveMethod(String name) { 198 try { 199 return GTKPainter.class.getMethod(name, getMethodParamTypes()); 200 } catch (NoSuchMethodException e) { 201 assert false; 202 } 203 return null; 204 } 205 206 int getIconDimension(SynthContext context) { 207 if (iconDimension >= 0) { 208 return iconDimension; 209 } 210 211 if (context == null) { 212 return DEFAULT_ICON_SIZE; 213 } 214 215 Region region = context.getRegion(); 216 GTKStyle style = (GTKStyle) context.getStyle(); 217 iconDimension = style.getClassSpecificIntValue(context, 218 "indicator-size", 219 (region == Region.CHECK_BOX_MENU_ITEM || 220 region == Region.RADIO_BUTTON_MENU_ITEM) ? 221 DEFAULT_TOGGLE_MENU_ITEM_SIZE : DEFAULT_ICON_SIZE); 222 223 if (region == Region.CHECK_BOX || region == Region.RADIO_BUTTON) { 224 iconDimension += 2 * style.getClassSpecificIntValue(context, 225 "indicator-spacing", DEFAULT_ICON_SPACING); 226 } else if (region == Region.CHECK_BOX_MENU_ITEM || 227 region == Region.RADIO_BUTTON_MENU_ITEM) { 228 iconDimension += 2 * CHECK_ICON_EXTRA_INSET; 229 } 230 return iconDimension; 231 } 232 } 233 234 private static class SynthExpanderIcon extends DelegatingIcon { 235 SynthExpanderIcon(String method) { 236 super(method); 237 } 238 239 public void paintIcon(SynthContext context, Graphics g, int x, int y, 240 int w, int h) { 241 if (context != null) { 242 super.paintIcon(context, g, x, y, w, h); 243 updateSizeIfNecessary(context); 244 } 245 } 246 247 int getIconDimension(SynthContext context) { 248 updateSizeIfNecessary(context); 249 return (iconDimension == -1) ? DEFAULT_ICON_SIZE : 250 iconDimension; 251 } 252 253 private void updateSizeIfNecessary(SynthContext context) { 254 if (iconDimension == -1 && context != null) { 255 iconDimension = context.getStyle().getInt(context, 256 "Tree.expanderSize", 10); 257 } 258 } 259 } 260 261 // GTK has a separate widget for the handle box, to mirror this 262 // we create a unique icon per ToolBar and lookup the style for the 263 // HandleBox. 264 private static class ToolBarHandleIcon extends DelegatingIcon { 265 private static final Class<?>[] PARAM_TYPES = new Class<?>[] { 266 SynthContext.class, Graphics.class, int.class, 267 int.class, int.class, int.class, int.class, Orientation.class, 268 }; 269 270 private SynthStyle style; 271 272 public ToolBarHandleIcon() { 273 super(TOOL_BAR_HANDLE_ICON); 274 } 275 276 protected Class<?>[] getMethodParamTypes() { 277 return PARAM_TYPES; 278 } 279 280 public void paintIcon(SynthContext context, Graphics g, int x, int y, 281 int w, int h) { 282 if (context != null) { 283 JToolBar toolbar = (JToolBar)context.getComponent(); 284 Orientation orientation = 285 (toolbar.getOrientation() == JToolBar.HORIZONTAL ? 286 Orientation.HORIZONTAL : Orientation.VERTICAL); 287 288 if (style == null) { 289 style = SynthLookAndFeel.getStyleFactory().getStyle( 290 context.getComponent(), GTKRegion.HANDLE_BOX); 291 } 292 context = new SynthContext(toolbar, GTKRegion.HANDLE_BOX, 293 style, SynthConstants.ENABLED); 294 295 GTKPainter.INSTANCE.paintIcon(context, g, 296 getMethod(), x, y, w, h, orientation); 297 } 298 } 299 300 public int getIconWidth(SynthContext context) { 301 if (context == null) { 302 return 10; 303 } 304 if (((JToolBar)context.getComponent()).getOrientation() == 305 JToolBar.HORIZONTAL) { 306 return 10; 307 } else { 308 return context.getComponent().getWidth(); 309 } 310 } 311 312 public int getIconHeight(SynthContext context) { 313 if (context == null) { 314 return 10; 315 } 316 if (((JToolBar)context.getComponent()).getOrientation() == 317 JToolBar.HORIZONTAL) { 318 return context.getComponent().getHeight(); 319 } else { 320 return 10; 321 } 322 } 323 } 324 325 private static class MenuArrowIcon extends DelegatingIcon { 326 private static final Class<?>[] PARAM_TYPES = new Class<?>[] { 327 SynthContext.class, Graphics.class, int.class, 328 int.class, int.class, int.class, int.class, ArrowType.class, 329 }; 330 331 public MenuArrowIcon() { 332 super(MENU_ARROW_ICON); 333 } 334 335 protected Class<?>[] getMethodParamTypes() { 336 return PARAM_TYPES; 337 } 338 339 public void paintIcon(SynthContext context, Graphics g, int x, int y, 340 int w, int h) { 341 if (context != null) { 342 ArrowType arrowDir = ArrowType.RIGHT; 343 if (!context.getComponent().getComponentOrientation().isLeftToRight()) { 344 arrowDir = ArrowType.LEFT; 345 } 346 GTKPainter.INSTANCE.paintIcon(context, g, 347 getMethod(), x, y, w, h, arrowDir); 348 } 349 } 350 } 351 }