blob: 850aa154b83d58876eb1e099dd9d910272fa2ccb [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package com.sun.java.swing.plaf.gtk;
26
27import java.util.*;
28import javax.swing.plaf.synth.*;
29import java.awt.*;
30import java.awt.image.BufferedImage;
31import java.lang.reflect.*;
32import javax.swing.*;
33import javax.swing.plaf.*;
34import sun.swing.plaf.synth.*;
35import com.sun.java.swing.plaf.gtk.GTKConstants.ArrowType;
36import com.sun.java.swing.plaf.gtk.GTKConstants.ExpanderStyle;
37import com.sun.java.swing.plaf.gtk.GTKConstants.Orientation;
38import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType;
39
40/**
41 */
42class 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 JToolBar toolbar = (JToolBar)context.getComponent();
283 Orientation orientation =
284 (toolbar.getOrientation() == JToolBar.HORIZONTAL ?
285 Orientation.HORIZONTAL : Orientation.VERTICAL);
286
287 if (style == null) {
288 style = SynthLookAndFeel.getStyleFactory().getStyle(
289 context.getComponent(), GTKRegion.HANDLE_BOX);
290 }
291 context = new SynthContext(toolbar, GTKRegion.HANDLE_BOX,
292 style, SynthConstants.ENABLED);
293
294 GTKPainter.INSTANCE.paintIcon(context, g,
295 getMethod(), x, y, w, h, orientation);
296 }
297
298 public int getIconWidth(SynthContext context) {
299 if (context == null) {
300 return 10;
301 }
302 if (((JToolBar)context.getComponent()).getOrientation() ==
303 JToolBar.HORIZONTAL) {
304 return 10;
305 } else {
306 return context.getComponent().getWidth();
307 }
308 }
309
310 public int getIconHeight(SynthContext context) {
311 if (context == null) {
312 return 10;
313 }
314 if (((JToolBar)context.getComponent()).getOrientation() ==
315 JToolBar.HORIZONTAL) {
316 return context.getComponent().getHeight();
317 } else {
318 return 10;
319 }
320 }
321 }
322
323 private static class MenuArrowIcon extends DelegatingIcon {
324 private static final Class[] PARAM_TYPES = new Class[] {
325 SynthContext.class, Graphics.class, int.class,
326 int.class, int.class, int.class, int.class, ArrowType.class,
327 };
328
329 public MenuArrowIcon() {
330 super(MENU_ARROW_ICON);
331 }
332
333 protected Class[] getMethodParamTypes() {
334 return PARAM_TYPES;
335 }
336
337 public void paintIcon(SynthContext context, Graphics g, int x, int y,
338 int w, int h) {
339 ArrowType arrowDir = ArrowType.RIGHT;
340 if (!context.getComponent().getComponentOrientation().isLeftToRight()) {
341 arrowDir = ArrowType.LEFT;
342 }
343 GTKPainter.INSTANCE.paintIcon(context, g,
344 getMethod(), x, y, w, h, arrowDir);
345 }
346 }
347}