1. /*
  2. * @(#)GTKIconFactory.java 1.23 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.gtk;
  8. import javax.swing.plaf.synth.*;
  9. import java.awt.*;
  10. import java.lang.reflect.*;
  11. import javax.swing.*;
  12. import javax.swing.plaf.*;
  13. import sun.swing.plaf.synth.*;
  14. /**
  15. * @version 1.23, 12/19/03
  16. */
  17. class GTKIconFactory {
  18. // Tree icons
  19. private static SynthIcon expandedIcon;
  20. private static SynthIcon collapsedIcon;
  21. private static SynthIcon radioButtonIcon;
  22. private static SynthIcon checkBoxIcon;
  23. private static SynthIcon menuArrowIcon;
  24. private static SynthIcon menuCheckIcon;
  25. private static SynthIcon menuItemArrowIcon;
  26. private static SynthIcon menuItemCheckIcon;
  27. private static SynthIcon checkBoxMenuItemArrowIcon;
  28. private static SynthIcon checkBoxMenuItemCheckIcon;
  29. private static SynthIcon radioButtonMenuItemArrowIcon;
  30. private static SynthIcon radioButtonMenuItemCheckIcon;
  31. //
  32. // Tree methods
  33. //
  34. public static SynthIcon getTreeExpandedIcon() {
  35. if (expandedIcon == null) {
  36. expandedIcon =
  37. new SynthExpanderIcon("paintTreeExpandedIcon");
  38. }
  39. return expandedIcon;
  40. }
  41. public static void paintTreeExpandedIcon(SynthContext context, Graphics g,
  42. int x, int y, int w, int h) {
  43. ((GTKStyle)context.getStyle()).getEngine(context).paintExpander(
  44. context, g, GTKLookAndFeel.synthStateToGTKState(
  45. context.getRegion(), context.getComponentState()),
  46. GTKConstants.EXPANDER_EXPANDED, "treeview", x, y, w, h);
  47. }
  48. public static SynthIcon getTreeCollapsedIcon() {
  49. if (collapsedIcon == null) {
  50. collapsedIcon =
  51. new SynthExpanderIcon("paintTreeCollapsedIcon");
  52. }
  53. return collapsedIcon;
  54. }
  55. public static void paintTreeCollapsedIcon(SynthContext context, Graphics g,
  56. int x, int y, int w, int h) {
  57. ((GTKStyle)context.getStyle()).getEngine(context).paintExpander(
  58. context, g, GTKLookAndFeel.synthStateToGTKState(
  59. context.getRegion(), context.getComponentState()),
  60. GTKConstants.EXPANDER_COLLAPSED, "treeview", x, y, w, h);
  61. }
  62. //
  63. // Radio button
  64. //
  65. public static SynthIcon getRadioButtonIcon() {
  66. if (radioButtonIcon == null) {
  67. radioButtonIcon = new DelegatingIcon("paintRadioButtonIcon",
  68. 13, 13);
  69. }
  70. return radioButtonIcon;
  71. }
  72. public static void paintRadioButtonIcon(SynthContext context, Graphics g,
  73. int x, int y, int w, int h) {
  74. GTKStyle style = (GTKStyle)context.getStyle();
  75. int state = context.getComponentState();
  76. int gtkState = GTKLookAndFeel.synthStateToGTKState(context.getRegion(),
  77. state);
  78. int shadowType = GTKConstants.SHADOW_OUT;
  79. // RadioButton painting appears to be special cased to pass
  80. // SELECTED into the engine even though text colors are PRESSED.
  81. if ((state & SynthConstants.SELECTED) != 0) {
  82. gtkState = SynthConstants.SELECTED;
  83. }
  84. if (gtkState == SynthConstants.SELECTED) {
  85. shadowType = GTKConstants.SHADOW_IN;
  86. }
  87. ((GTKStyle)context.getStyle()).getEngine(
  88. context).paintOption(context, g, gtkState, shadowType,
  89. "radiobutton", x, y, w, h);
  90. }
  91. //
  92. // CheckBox
  93. //
  94. public static SynthIcon getCheckBoxIcon() {
  95. if (checkBoxIcon == null) {
  96. checkBoxIcon = new DelegatingIcon("paintCheckBoxIcon", 13, 13);
  97. }
  98. return checkBoxIcon;
  99. }
  100. public static void paintCheckBoxIcon(SynthContext context, Graphics g,
  101. int x, int y, int w, int h) {
  102. GTKStyle style = (GTKStyle)context.getStyle();
  103. int state = context.getComponentState();
  104. int shadowType = GTKConstants.SHADOW_OUT;
  105. if (((JCheckBox)context.getComponent()).isSelected()) {
  106. shadowType = GTKConstants.SHADOW_IN;
  107. }
  108. ((GTKStyle)context.getStyle()).getEngine(
  109. context).paintCheck(context, g,
  110. GTKLookAndFeel.synthStateToGTKState(context.getRegion(),
  111. context.getComponentState()), shadowType, "checkbutton",
  112. x, y, w, h);
  113. }
  114. //
  115. // Menus
  116. //
  117. public static SynthIcon getMenuArrowIcon() {
  118. if (menuArrowIcon == null) {
  119. menuArrowIcon = new DelegatingIcon("paintMenuArrowIcon", 13, 13);
  120. }
  121. return menuArrowIcon;
  122. }
  123. public static void paintMenuArrowIcon(SynthContext context, Graphics g,
  124. int x, int y, int w, int h) {
  125. GTKStyle style = (GTKStyle)context.getStyle();
  126. int gtkState = GTKLookAndFeel.synthStateToGTKState(
  127. context.getRegion(), context.getComponentState());
  128. int shadow = GTKConstants.SHADOW_OUT;
  129. if (gtkState == SynthConstants.MOUSE_OVER) {
  130. shadow = GTKConstants.SHADOW_IN;
  131. }
  132. int arrowDir;
  133. if (context.getComponent().getComponentOrientation().isLeftToRight()) {
  134. arrowDir = GTKConstants.ARROW_RIGHT;
  135. }
  136. else {
  137. arrowDir = GTKConstants.ARROW_LEFT;
  138. }
  139. style.getEngine(context).paintArrow(context, g, gtkState,
  140. shadow, arrowDir, "menuitem", x + 3, y + 3, 7, 7);
  141. }
  142. public static SynthIcon getMenuItemArrowIcon() {
  143. if (menuItemArrowIcon == null) {
  144. menuItemArrowIcon = new DelegatingIcon("paintMenuItemArrowIcon",
  145. 13, 13);
  146. }
  147. return menuItemArrowIcon;
  148. }
  149. public static void paintMenuItemArrowIcon(SynthContext context, Graphics g,
  150. int x, int y, int w, int h) {
  151. // Don't paint anything. We are just reserving space so we align the
  152. // menu items correctly.
  153. }
  154. public static SynthIcon getCheckBoxMenuItemArrowIcon() {
  155. if (checkBoxMenuItemArrowIcon == null) {
  156. checkBoxMenuItemArrowIcon = new DelegatingIcon(
  157. "paintCheckBoxMenuItemArrowIcon", 13, 13);
  158. }
  159. return checkBoxMenuItemArrowIcon;
  160. }
  161. public static void paintCheckBoxMenuItemArrowIcon(SynthContext context,
  162. Graphics g, int x, int y, int w, int h) {
  163. // Don't paint anything. We are just reserving space so we align the
  164. // menu items correctly.
  165. }
  166. public static SynthIcon getCheckBoxMenuItemCheckIcon() {
  167. if (checkBoxMenuItemCheckIcon == null) {
  168. checkBoxMenuItemCheckIcon = new DelegatingIcon(
  169. "paintCheckBoxMenuItemCheckIcon", 13, 13);
  170. }
  171. return checkBoxMenuItemCheckIcon;
  172. }
  173. public static void paintCheckBoxMenuItemCheckIcon(
  174. SynthContext context, Graphics g, int x, int y, int w, int h) {
  175. GTKStyle style = (GTKStyle)context.getStyle();
  176. int state = context.getComponentState();
  177. int shadowType = GTKConstants.SHADOW_OUT;
  178. int gtkState = GTKLookAndFeel.synthStateToGTKState(
  179. context.getRegion(), state);
  180. if ((state & SynthConstants.MOUSE_OVER) != 0) {
  181. gtkState = SynthConstants.MOUSE_OVER;
  182. }
  183. if ((state & SynthConstants.SELECTED) != 0) {
  184. shadowType = GTKConstants.SHADOW_IN;
  185. }
  186. style.getEngine(context).paintCheck(context, g, gtkState,
  187. shadowType, "check", x, y, w, h);
  188. }
  189. public static SynthIcon getRadioButtonMenuItemArrowIcon() {
  190. if (radioButtonMenuItemArrowIcon == null) {
  191. radioButtonMenuItemArrowIcon = new DelegatingIcon(
  192. "paintRadioButtonMenuItemArrowIcon", 13, 13);
  193. }
  194. return radioButtonMenuItemArrowIcon;
  195. }
  196. public static void paintRadioButtonMenuItemArrowIcon(SynthContext context,
  197. Graphics g, int x, int y, int w, int h) {
  198. // Don't paint anything. We are just reserving space so we align the
  199. // menu items correctly.
  200. }
  201. public static SynthIcon getRadioButtonMenuItemCheckIcon() {
  202. if (radioButtonMenuItemCheckIcon == null) {
  203. radioButtonMenuItemCheckIcon = new DelegatingIcon(
  204. "paintRadioButtonMenuItemCheckIcon", 13, 13);
  205. }
  206. return radioButtonMenuItemCheckIcon;
  207. }
  208. public static void paintRadioButtonMenuItemCheckIcon(
  209. SynthContext context, Graphics g, int x, int y, int w, int h) {
  210. GTKStyle style = (GTKStyle)context.getStyle();
  211. int state = context.getComponentState();
  212. int gtkState = GTKLookAndFeel.synthStateToGTKState(
  213. context.getRegion(), state);
  214. if ((state & SynthConstants.MOUSE_OVER) != 0) {
  215. gtkState = SynthConstants.MOUSE_OVER;
  216. }
  217. int shadowType = GTKConstants.SHADOW_OUT;
  218. if ((state & SynthConstants.SELECTED) != 0) {
  219. shadowType = GTKConstants.SHADOW_IN;
  220. }
  221. ((GTKStyle)context.getStyle()).getEngine(
  222. context).paintOption(context, g, gtkState, shadowType,
  223. "option", x, y, w, h);
  224. }
  225. //
  226. // ToolBar Handle
  227. //
  228. public static SynthIcon getToolBarHandleIcon() {
  229. return new ToolBarHandleIcon();
  230. }
  231. public static void paintToolBarHandleIcon(SynthContext context,
  232. Graphics g, int x, int y, int w, int h) {
  233. int orientation =
  234. ((JToolBar)context.getComponent()).getOrientation() ==
  235. JToolBar.HORIZONTAL ?
  236. GTKConstants.HORIZONTAL : GTKConstants.VERTICAL;
  237. GTKStyle style = (GTKStyle)context.getStyle();
  238. int gtkState = GTKLookAndFeel.synthStateToGTKState(
  239. context.getRegion(), context.getComponentState());
  240. style.getEngine(context).paintHandle(context, g, gtkState,
  241. GTKConstants.SHADOW_OUT, "handlebox", x, y, w, h,
  242. orientation);
  243. }
  244. private static class DelegatingIcon extends SynthIcon implements
  245. UIResource {
  246. private static final Class[] PARAM_TYPES = new Class[] {
  247. SynthContext.class, Graphics.class, int.class, int.class,
  248. int.class, int.class };
  249. private int width;
  250. private int height;
  251. private Object method;
  252. DelegatingIcon(String methodName, int width, int height) {
  253. this.method = methodName;
  254. this.width = width;
  255. this.height = height;
  256. }
  257. public void paintIcon(SynthContext context, Graphics g, int x, int y,
  258. int w, int h) {
  259. if (context != null) {
  260. try {
  261. getMethod().invoke(GTKIconFactory.class, new Object[] {
  262. context, g, new Integer(x), new Integer(y),
  263. new Integer(w), new Integer(h) });
  264. } catch (IllegalAccessException iae) {
  265. } catch (InvocationTargetException ite) {
  266. }
  267. }
  268. }
  269. public int getIconWidth(SynthContext context) {
  270. return width;
  271. }
  272. public int getIconHeight(SynthContext context) {
  273. return height;
  274. }
  275. private Method getMethod() {
  276. if (method instanceof String) {
  277. Method[] methods = GTKIconFactory.class.getMethods();
  278. try {
  279. method = GTKIconFactory.class.getMethod((String)method,
  280. PARAM_TYPES);
  281. } catch (NoSuchMethodException nsme) {
  282. System.out.println("NSME: " + nsme);
  283. }
  284. }
  285. return (Method)method;
  286. }
  287. }
  288. private static class SynthExpanderIcon extends SynthIcon {
  289. private static final Class[] PARAM_TYPES = new Class[] {
  290. SynthContext.class, Graphics.class, int.class, int.class,
  291. int.class, int.class };
  292. private int width = -1;
  293. private int height = -1;
  294. private Object method;
  295. SynthExpanderIcon(String method) {
  296. this.method = method;
  297. }
  298. public void paintIcon(SynthContext context, Graphics g, int x, int y,
  299. int w, int h) {
  300. if (context != null) {
  301. try {
  302. getMethod().invoke(GTKIconFactory.class, new Object[] {
  303. context, g, new Integer(x), new Integer(y),
  304. new Integer(w), new Integer(h) });
  305. updateSizeIfNecessary(context);
  306. } catch (IllegalAccessException iae) {
  307. } catch (InvocationTargetException ite) {
  308. }
  309. }
  310. }
  311. public int getIconWidth(SynthContext context) {
  312. updateSizeIfNecessary(context);
  313. return width;
  314. }
  315. public int getIconHeight(SynthContext context) {
  316. updateSizeIfNecessary(context);
  317. return height;
  318. }
  319. private void updateSizeIfNecessary(SynthContext context) {
  320. if (width == -1 && context != null) {
  321. width = height = context.getStyle().getInt(context,
  322. "Tree.expanderSize", 10);
  323. }
  324. }
  325. private Method getMethod() {
  326. if (method instanceof String) {
  327. Method[] methods = GTKIconFactory.class.getMethods();
  328. try {
  329. method = GTKIconFactory.class.getMethod((String)method,
  330. PARAM_TYPES);
  331. } catch (NoSuchMethodException nsme) {
  332. System.out.println("NSME: " + nsme);
  333. }
  334. }
  335. return (Method)method;
  336. }
  337. }
  338. // GTK has a separate widget for the handle box, to mirror this
  339. // we create a unique icon per ToolBar and lookup the style for the
  340. // HandleBox.
  341. private static class ToolBarHandleIcon extends SynthIcon {
  342. private SynthStyle style;
  343. public void paintIcon(SynthContext context, Graphics g, int x, int y,
  344. int w, int h) {
  345. if (context != null) {
  346. context = getContext(context);
  347. paintToolBarHandleIcon(context, g, x, y, w, h);
  348. }
  349. }
  350. public int getIconWidth(SynthContext context) {
  351. if (((JToolBar)context.getComponent()).getOrientation() ==
  352. JToolBar.HORIZONTAL) {
  353. return 10;
  354. } else {
  355. return context.getComponent().getWidth();
  356. }
  357. }
  358. public int getIconHeight(SynthContext context) {
  359. if (((JToolBar)context.getComponent()).getOrientation() ==
  360. JToolBar.HORIZONTAL) {
  361. return context.getComponent().getHeight();
  362. } else {
  363. return 10;
  364. }
  365. }
  366. private SynthContext getContext(SynthContext context) {
  367. if (style == null) {
  368. style = SynthLookAndFeel.getStyleFactory().getStyle(
  369. context.getComponent(), GTKRegion.HANDLE_BOX);
  370. }
  371. return new SynthContext(context.getComponent(),
  372. GTKRegion.HANDLE_BOX,
  373. style, SynthConstants.ENABLED);
  374. }
  375. }
  376. }