1/*
2 * Copyright (c) 1997, 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
26package com.sun.java.swing.plaf.motif;
27
28import javax.swing.*;
29
30import javax.swing.plaf.UIResource;
31
32import java.awt.Color;
33import java.awt.Component;
34import java.awt.Dimension;
35import java.awt.Graphics;
36import java.awt.Polygon;
37
38import java.io.Serializable;
39
40/**
41 * Icon factory for the CDE/Motif Look and Feel
42 * <p>
43 * <strong>Warning:</strong>
44 * Serialized objects of this class will not be compatible with
45 * future Swing releases.  The current serialization support is appropriate
46 * for short term storage or RMI between applications running the same
47 * version of Swing.  A future release of Swing will provide support for
48 * long term persistence.
49 *
50 * 1.20 04/27/99
51 * @author Georges Saab
52 */
53@SuppressWarnings("serial") // Same-version serialization only
54public class MotifIconFactory implements Serializable
55{
56    private static Icon checkBoxIcon;
57    private static Icon radioButtonIcon;
58    private static Icon menuItemCheckIcon;
59    private static Icon menuItemArrowIcon;
60    private static Icon menuArrowIcon;
61
62    public static Icon getMenuItemCheckIcon() {
63        return null;
64    }
65
66    public static Icon getMenuItemArrowIcon() {
67        if (menuItemArrowIcon == null) {
68            menuItemArrowIcon = new MenuItemArrowIcon();
69        }
70        return menuItemArrowIcon;
71    }
72
73    public static Icon getMenuArrowIcon() {
74        if (menuArrowIcon == null) {
75            menuArrowIcon = new MenuArrowIcon();
76        }
77        return menuArrowIcon;
78    }
79
80    public static Icon getCheckBoxIcon() {
81        if (checkBoxIcon == null) {
82            checkBoxIcon = new CheckBoxIcon();
83        }
84        return checkBoxIcon;
85    }
86
87    public static Icon getRadioButtonIcon() {
88        if (radioButtonIcon == null) {
89            radioButtonIcon = new RadioButtonIcon();
90        }
91        return radioButtonIcon;
92    }
93
94    @SuppressWarnings("serial") // Same-version serialization only
95    private static class CheckBoxIcon implements Icon, UIResource, Serializable  {
96        static final int csize = 13;
97
98        private Color control = UIManager.getColor("control");
99        private Color foreground = UIManager.getColor("CheckBox.foreground");
100        private Color shadow = UIManager.getColor("controlShadow");
101        private Color highlight = UIManager.getColor("controlHighlight");
102        private Color lightShadow = UIManager.getColor("controlLightShadow");
103
104        public void paintIcon(Component c, Graphics g, int x, int y) {
105            AbstractButton b = (AbstractButton) c;
106            ButtonModel model = b.getModel();
107
108            boolean flat = false;
109
110            if(b instanceof JCheckBox) {
111                flat = ((JCheckBox)b).isBorderPaintedFlat();
112            }
113
114            boolean isPressed = model.isPressed();
115            boolean isArmed = model.isArmed();
116            boolean isEnabled = model.isEnabled();
117            boolean isSelected = model.isSelected();
118
119            // There are 4 "looks" to the Motif CheckBox:
120            //  drawCheckBezelOut  -  default unchecked state
121            //  drawBezel          -  when we uncheck in toggled state
122            //  drawCheckBezel     -  when we check in toggle state
123            //  drawCheckBezelIn   -  selected, mouseReleased
124            boolean checkToggleIn = ((isPressed &&
125                                      !isArmed   &&
126                                      isSelected) ||
127                                     (isPressed &&
128                                      isArmed   &&
129                                      !isSelected));
130            boolean uncheckToggleOut = ((isPressed &&
131                                         !isArmed &&
132                                         !isSelected) ||
133                                        (isPressed &&
134                                         isArmed &&
135                                         isSelected));
136
137            boolean checkIn = (!isPressed  &&
138                               isArmed    &&
139                               isSelected  ||
140                               (!isPressed &&
141                                !isArmed  &&
142                                isSelected));
143
144
145            if(flat) {
146                g.setColor(shadow);
147                g.drawRect(x+2,y,csize-1,csize-1);
148                if(uncheckToggleOut || checkToggleIn) {
149                    g.setColor(control);
150                    g.fillRect(x+3,y+1,csize-2,csize-2);
151                }
152            }
153
154            if (checkToggleIn) {
155                // toggled from unchecked to checked
156                drawCheckBezel(g,x,y,csize,true,false,false,flat);
157            } else if (uncheckToggleOut) {
158                // MotifBorderFactory.drawBezel(g,x,y,csize,csize,false,false);
159                drawCheckBezel(g,x,y,csize,true,true,false,flat);
160            } else if (checkIn) {
161                // show checked, unpressed state
162                drawCheckBezel(g,x,y,csize,false,false,true,flat);
163            } else if(!flat) {
164                //  show unchecked state
165                drawCheckBezelOut(g,x,y,csize);
166            }
167        }
168
169        public int getIconWidth() {
170            return csize;
171        }
172
173        public int getIconHeight() {
174            return csize;
175        }
176
177        public void drawCheckBezelOut(Graphics g, int x, int y, int csize){
178            Color controlShadow = UIManager.getColor("controlShadow");
179
180            int w = csize;
181            int h = csize;
182            Color oldColor = g.getColor();
183
184            g.translate(x,y);
185            g.setColor(highlight);    // inner 3D border
186            g.drawLine(0, 0, 0, h-1);
187            g.drawLine(1, 0, w-1, 0);
188
189            g.setColor(shadow);         // black drop shadow  __|
190            g.drawLine(1, h-1, w-1, h-1);
191            g.drawLine(w-1, h-1, w-1, 1);
192            g.translate(-x,-y);
193            g.setColor(oldColor);
194        }
195
196        public void drawCheckBezel(Graphics g, int x, int y, int csize,
197                                   boolean shade, boolean out, boolean check, boolean flat)
198            {
199
200
201                Color oldColor = g.getColor();
202                g.translate(x, y);
203
204
205                //bottom
206                if(!flat) {
207                    if (out) {
208                        g.setColor(control);
209                        g.fillRect(1,1,csize-2,csize-2);
210                        g.setColor(shadow);
211                    } else {
212                        g.setColor(lightShadow);
213                        g.fillRect(0,0,csize,csize);
214                        g.setColor(highlight);
215                    }
216
217                    g.drawLine(1,csize-1,csize-2,csize-1);
218                    if (shade) {
219                        g.drawLine(2,csize-2,csize-3,csize-2);
220                        g.drawLine(csize-2,2,csize-2 ,csize-1);
221                        if (out) {
222                            g.setColor(highlight);
223                        } else {
224                            g.setColor(shadow);
225                        }
226                        g.drawLine(1,2,1,csize-2);
227                        g.drawLine(1,1,csize-3,1);
228                        if (out) {
229                            g.setColor(shadow);
230                        } else {
231                            g.setColor(highlight);
232                        }
233                    }
234                    //right
235                    g.drawLine(csize-1,1,csize-1,csize-1);
236
237                    //left
238                    if (out) {
239                        g.setColor(highlight);
240                    } else {
241                        g.setColor(shadow);
242                    }
243                    g.drawLine(0,1,0,csize-1);
244
245                    //top
246                    g.drawLine(0,0,csize-1,0);
247                }
248
249                if (check) {
250                    // draw check
251                    g.setColor(foreground);
252                    int[] xa = {csize - 12, csize - 8, csize - 7, csize - 4,
253                                csize - 2, csize - 2, csize - 8, csize - 10,
254                                csize - 11};
255                    int[] ya = new int[]{6, 10, 10, 4, 2, 1, 7, 5, 5};
256                    g.fillPolygon(xa, ya, 9);
257                }
258                g.translate(-x, -y);
259                g.setColor(oldColor);
260            }
261    } // end class CheckBoxIcon
262
263    @SuppressWarnings("serial") // Same-version serialization only
264    private static class RadioButtonIcon implements Icon, UIResource, Serializable {
265        private Color dot = UIManager.getColor("activeCaptionBorder");
266        private Color highlight = UIManager.getColor("controlHighlight");
267        private Color shadow = UIManager.getColor("controlShadow");
268
269        public void paintIcon(Component c, Graphics g, int x, int y) {
270            // fill interior
271            AbstractButton b = (AbstractButton) c;
272            ButtonModel model = b.getModel();
273
274            int w = getIconWidth();
275            int h = getIconHeight();
276
277            boolean isPressed = model.isPressed();
278            boolean isArmed = model.isArmed();
279            boolean isEnabled = model.isEnabled();
280            boolean isSelected = model.isSelected();
281
282            boolean checkIn = ((isPressed &&
283                                !isArmed   &&
284                                isSelected) ||
285                               (isPressed &&
286                                isArmed   &&
287                                !isSelected)
288                               ||
289                               (!isPressed  &&
290                                isArmed    &&
291                                isSelected  ||
292                                (!isPressed &&
293                                 !isArmed  &&
294                                 isSelected)));
295
296            if (checkIn){
297                g.setColor(shadow);
298                g.drawArc(x, y, w - 1, h - 1, 45, 180);
299                g.setColor(highlight);
300                g.drawArc(x, y, w - 1, h - 1, 45, -180);
301                g.setColor(dot);
302                g.fillOval(x + 3, y + 3, 7, 7);
303            }
304            else {
305                g.setColor(highlight);
306                g.drawArc(x, y, w - 1, h - 1, 45, 180);
307
308                g.setColor(shadow);
309                g.drawArc(x, y, w - 1, h - 1, 45, -180);
310
311            }
312        }
313
314        public int getIconWidth() {
315            return 14;
316        }
317
318        public int getIconHeight() {
319            return 14;
320        }
321    } // end class RadioButtonIcon
322
323    @SuppressWarnings("serial") // Same-version serialization only
324    private static class MenuItemCheckIcon implements Icon, UIResource, Serializable
325    {
326        public void paintIcon(Component c,Graphics g, int x, int y)
327            {
328            }
329        public int getIconWidth() { return 0; }
330        public int getIconHeight() { return 0; }
331    }  // end class MenuItemCheckIcon
332
333
334    @SuppressWarnings("serial") // Same-version serialization only
335    private static class MenuItemArrowIcon implements Icon, UIResource, Serializable
336    {
337        public void paintIcon(Component c,Graphics g, int x, int y)
338            {
339            }
340        public int getIconWidth() { return 0; }
341        public int getIconHeight() { return 0; }
342    }  // end class MenuItemArrowIcon
343
344    @SuppressWarnings("serial") // Same-version serialization only
345    private static class MenuArrowIcon implements Icon, UIResource, Serializable
346    {
347        private Color focus = UIManager.getColor("windowBorder");
348        private Color shadow = UIManager.getColor("controlShadow");
349        private Color highlight = UIManager.getColor("controlHighlight");
350
351        public void paintIcon(Component c, Graphics g, int x, int y) {
352            AbstractButton b = (AbstractButton) c;
353            ButtonModel model = b.getModel();
354
355            // These variables are kind of pointless as the following code
356            // assumes the icon will be 10 x 10 regardless of their value.
357            int w = getIconWidth();
358            int h = getIconHeight();
359
360            Color oldColor = g.getColor();
361
362            if (model.isSelected()){
363                if( MotifGraphicsUtils.isLeftToRight(c) ){
364                    g.setColor(shadow);
365                    g.fillRect(x+1,y+1,2,h);
366                    g.drawLine(x+4,y+2,x+4,y+2);
367                    g.drawLine(x+6,y+3,x+6,y+3);
368                    g.drawLine(x+8,y+4,x+8,y+5);
369                    g.setColor(focus);
370                    g.fillRect(x+2,y+2,2,h-2);
371                    g.fillRect(x+4,y+3,2,h-4);
372                    g.fillRect(x+6,y+4,2,h-6);
373                    g.setColor(highlight);
374                    g.drawLine(x+2,y+h,x+2,y+h);
375                    g.drawLine(x+4,y+h-1,x+4,y+h-1);
376                    g.drawLine(x+6,y+h-2,x+6,y+h-2);
377                    g.drawLine(x+8,y+h-4,x+8,y+h-3);
378                } else {
379                    g.setColor(highlight);
380                    g.fillRect(x+7,y+1,2,10);
381                    g.drawLine(x+5,y+9,x+5,y+9);
382                    g.drawLine(x+3,y+8,x+3,y+8);
383                    g.drawLine(x+1,y+6,x+1,y+7);
384                    g.setColor(focus);
385                    g.fillRect(x+6,y+2,2,8);
386                    g.fillRect(x+4,y+3,2,6);
387                    g.fillRect(x+2,y+4,2,4);
388                    g.setColor(shadow);
389                    g.drawLine(x+1,y+4,x+1,y+5);
390                    g.drawLine(x+3,y+3,x+3,y+3);
391                    g.drawLine(x+5,y+2,x+5,y+2);
392                    g.drawLine(x+7,y+1,x+7,y+1);
393                }
394            } else {
395                if( MotifGraphicsUtils.isLeftToRight(c) ){
396                    g.setColor(highlight);
397                    g.drawLine(x+1,y+1,x+1,y+h);
398                    g.drawLine(x+2,y+1,x+2,y+h-2);
399                    g.fillRect(x+3,y+2,2,2);
400                    g.fillRect(x+5,y+3,2,2);
401                    g.fillRect(x+7,y+4,2,2);
402                    g.setColor(shadow);
403                    g.drawLine(x+2,y+h-1,x+2,y+h);
404                    g.fillRect(x+3,y+h-2,2,2);
405                    g.fillRect(x+5,y+h-3,2,2);
406                    g.fillRect(x+7,y+h-4,2,2);
407                    g.setColor(oldColor);
408                } else {
409                    g.setColor(highlight);
410                    g.fillRect(x+1,y+4,2,2);
411                    g.fillRect(x+3,y+3,2,2);
412                    g.fillRect(x+5,y+2,2,2);
413                    g.drawLine(x+7,y+1,x+7,y+2);
414                    g.setColor(shadow);
415                    g.fillRect(x+1,y+h-4,2,2);
416                    g.fillRect(x+3,y+h-3,2,2);
417                    g.fillRect(x+5,y+h-2,2,2);
418                    g.drawLine(x+7,y+3,x+7,y+h);
419                    g.drawLine(x+8,y+1,x+8,y+h);
420                    g.setColor(oldColor);
421                }
422            }
423
424        }
425        public int getIconWidth() { return 10; }
426        public int getIconHeight() { return 10; }
427    } // End class MenuArrowIcon
428}
429