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 
  26 package com.sun.java.swing.plaf.motif;
  27 
  28 import javax.swing.*;
  29 
  30 import javax.swing.plaf.UIResource;
  31 
  32 import java.awt.Color;
  33 import java.awt.Component;
  34 import java.awt.Dimension;
  35 import java.awt.Graphics;
  36 import java.awt.Polygon;
  37 
  38 import 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
  54 public 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         final static 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                     g.drawLine(csize-2,1,csize-2,2);
 253                     g.drawLine(csize-3,2,csize-3,3);
 254                     g.drawLine(csize-4,3,csize-4,4);
 255                     g.drawLine(csize-5,4,csize-5,6);
 256                     g.drawLine(csize-6,5,csize-6,8);
 257                     g.drawLine(csize-7,6,csize-7,10);
 258                     g.drawLine(csize-8,7,csize-8,10);
 259                     g.drawLine(csize-9,6,csize-9,9);
 260                     g.drawLine(csize-10,5,csize-10,8);
 261                     g.drawLine(csize-11,5,csize-11,7);
 262                     g.drawLine(csize-12,6,csize-12,6);
 263                 }
 264                 g.translate(-x, -y);
 265                 g.setColor(oldColor);
 266             }
 267     } // end class CheckBoxIcon
 268 
 269     @SuppressWarnings("serial") // Same-version serialization only
 270     private static class RadioButtonIcon implements Icon, UIResource, Serializable {
 271         private Color dot = UIManager.getColor("activeCaptionBorder");
 272         private Color highlight = UIManager.getColor("controlHighlight");
 273         private Color shadow = UIManager.getColor("controlShadow");
 274 
 275         public void paintIcon(Component c, Graphics g, int x, int y) {
 276             // fill interior
 277             AbstractButton b = (AbstractButton) c;
 278             ButtonModel model = b.getModel();
 279 
 280             int w = getIconWidth();
 281             int h = getIconHeight();
 282 
 283             boolean isPressed = model.isPressed();
 284             boolean isArmed = model.isArmed();
 285             boolean isEnabled = model.isEnabled();
 286             boolean isSelected = model.isSelected();
 287 
 288             boolean checkIn = ((isPressed &&
 289                                 !isArmed   &&
 290                                 isSelected) ||
 291                                (isPressed &&
 292                                 isArmed   &&
 293                                 !isSelected)
 294                                ||
 295                                (!isPressed  &&
 296                                 isArmed    &&
 297                                 isSelected  ||
 298                                 (!isPressed &&
 299                                  !isArmed  &&
 300                                  isSelected)));
 301 
 302             if (checkIn){
 303                 g.setColor(shadow);
 304                 g.drawLine(x+5,y+0,x+8,y+0);
 305                 g.drawLine(x+3,y+1,x+4,y+1);
 306                 g.drawLine(x+9,y+1,x+9,y+1);
 307                 g.drawLine(x+2,y+2,x+2,y+2);
 308                 g.drawLine(x+1,y+3,x+1,y+3);
 309                 g.drawLine(x,y+4,x,y+9);
 310                 g.drawLine(x+1,y+10,x+1,y+10);
 311                 g.drawLine(x+2,y+11,x+2,y+11);
 312                 g.setColor(highlight);
 313                 g.drawLine(x+3,y+12,x+4,y+12);
 314                 g.drawLine(x+5,y+13,x+8,y+13);
 315                 g.drawLine(x+9,y+12,x+10,y+12);
 316                 g.drawLine(x+11,y+11,x+11,y+11);
 317                 g.drawLine(x+12,y+10,x+12,y+10);
 318                 g.drawLine(x+13,y+9,x+13,y+4);
 319                 g.drawLine(x+12,y+3,x+12,y+3);
 320                 g.drawLine(x+11,y+2,x+11,y+2);
 321                 g.drawLine(x+10,y+1,x+10,y+1);
 322                 g.setColor(dot);
 323                 g.fillRect(x+4,y+5,6,4);
 324                 g.drawLine(x+5,y+4,x+8,y+4);
 325                 g.drawLine(x+5,y+9,x+8,y+9);
 326             }
 327             else {
 328                 g.setColor(highlight);
 329                 g.drawLine(x+5,y+0,x+8,y+0);
 330                 g.drawLine(x+3,y+1,x+4,y+1);
 331                 g.drawLine(x+9,y+1,x+9,y+1);
 332                 g.drawLine(x+2,y+2,x+2,y+2);
 333                 g.drawLine(x+1,y+3,x+1,y+3);
 334                 g.drawLine(x,y+4,x,y+9);
 335                 g.drawLine(x+1,y+10,x+1,y+10);
 336                 g.drawLine(x+2,y+11,x+2,y+11);
 337 
 338                 g.setColor(shadow);
 339                 g.drawLine(x+3,y+12,x+4,y+12);
 340                 g.drawLine(x+5,y+13,x+8,y+13);
 341                 g.drawLine(x+9,y+12,x+10,y+12);
 342                 g.drawLine(x+11,y+11,x+11,y+11);
 343                 g.drawLine(x+12,y+10,x+12,y+10);
 344                 g.drawLine(x+13,y+9,x+13,y+4);
 345                 g.drawLine(x+12,y+3,x+12,y+3);
 346                 g.drawLine(x+11,y+2,x+11,y+2);
 347                 g.drawLine(x+10,y+1,x+10,y+1);
 348 
 349             }
 350         }
 351 
 352         public int getIconWidth() {
 353             return 14;
 354         }
 355 
 356         public int getIconHeight() {
 357             return 14;
 358         }
 359     } // end class RadioButtonIcon
 360 
 361     @SuppressWarnings("serial") // Same-version serialization only
 362     private static class MenuItemCheckIcon implements Icon, UIResource, Serializable
 363     {
 364         public void paintIcon(Component c,Graphics g, int x, int y)
 365             {
 366             }
 367         public int getIconWidth() { return 0; }
 368         public int getIconHeight() { return 0; }
 369     }  // end class MenuItemCheckIcon
 370 
 371 
 372     @SuppressWarnings("serial") // Same-version serialization only
 373     private static class MenuItemArrowIcon implements Icon, UIResource, Serializable
 374     {
 375         public void paintIcon(Component c,Graphics g, int x, int y)
 376             {
 377             }
 378         public int getIconWidth() { return 0; }
 379         public int getIconHeight() { return 0; }
 380     }  // end class MenuItemArrowIcon
 381 
 382     @SuppressWarnings("serial") // Same-version serialization only
 383     private static class MenuArrowIcon implements Icon, UIResource, Serializable
 384     {
 385         private Color focus = UIManager.getColor("windowBorder");
 386         private Color shadow = UIManager.getColor("controlShadow");
 387         private Color highlight = UIManager.getColor("controlHighlight");
 388 
 389         public void paintIcon(Component c, Graphics g, int x, int y) {
 390             AbstractButton b = (AbstractButton) c;
 391             ButtonModel model = b.getModel();
 392 
 393             // These variables are kind of pointless as the following code
 394             // assumes the icon will be 10 x 10 regardless of their value.
 395             int w = getIconWidth();
 396             int h = getIconHeight();
 397 
 398             Color oldColor = g.getColor();
 399 
 400             if (model.isSelected()){
 401                 if( MotifGraphicsUtils.isLeftToRight(c) ){
 402                     g.setColor(shadow);
 403                     g.fillRect(x+1,y+1,2,h);
 404                     g.drawLine(x+4,y+2,x+4,y+2);
 405                     g.drawLine(x+6,y+3,x+6,y+3);
 406                     g.drawLine(x+8,y+4,x+8,y+5);
 407                     g.setColor(focus);
 408                     g.fillRect(x+2,y+2,2,h-2);
 409                     g.fillRect(x+4,y+3,2,h-4);
 410                     g.fillRect(x+6,y+4,2,h-6);
 411                     g.setColor(highlight);
 412                     g.drawLine(x+2,y+h,x+2,y+h);
 413                     g.drawLine(x+4,y+h-1,x+4,y+h-1);
 414                     g.drawLine(x+6,y+h-2,x+6,y+h-2);
 415                     g.drawLine(x+8,y+h-4,x+8,y+h-3);
 416                 } else {
 417                     g.setColor(highlight);
 418                     g.fillRect(x+7,y+1,2,10);
 419                     g.drawLine(x+5,y+9,x+5,y+9);
 420                     g.drawLine(x+3,y+8,x+3,y+8);
 421                     g.drawLine(x+1,y+6,x+1,y+7);
 422                     g.setColor(focus);
 423                     g.fillRect(x+6,y+2,2,8);
 424                     g.fillRect(x+4,y+3,2,6);
 425                     g.fillRect(x+2,y+4,2,4);
 426                     g.setColor(shadow);
 427                     g.drawLine(x+1,y+4,x+1,y+5);
 428                     g.drawLine(x+3,y+3,x+3,y+3);
 429                     g.drawLine(x+5,y+2,x+5,y+2);
 430                     g.drawLine(x+7,y+1,x+7,y+1);
 431                 }
 432             } else {
 433                 if( MotifGraphicsUtils.isLeftToRight(c) ){
 434                     g.setColor(highlight);
 435                     g.drawLine(x+1,y+1,x+1,y+h);
 436                     g.drawLine(x+2,y+1,x+2,y+h-2);
 437                     g.fillRect(x+3,y+2,2,2);
 438                     g.fillRect(x+5,y+3,2,2);
 439                     g.fillRect(x+7,y+4,2,2);
 440                     g.setColor(shadow);
 441                     g.drawLine(x+2,y+h-1,x+2,y+h);
 442                     g.fillRect(x+3,y+h-2,2,2);
 443                     g.fillRect(x+5,y+h-3,2,2);
 444                     g.fillRect(x+7,y+h-4,2,2);
 445                     g.setColor(oldColor);
 446                 } else {
 447                     g.setColor(highlight);
 448                     g.fillRect(x+1,y+4,2,2);
 449                     g.fillRect(x+3,y+3,2,2);
 450                     g.fillRect(x+5,y+2,2,2);
 451                     g.drawLine(x+7,y+1,x+7,y+2);
 452                     g.setColor(shadow);
 453                     g.fillRect(x+1,y+h-4,2,2);
 454                     g.fillRect(x+3,y+h-3,2,2);
 455                     g.fillRect(x+5,y+h-2,2,2);
 456                     g.drawLine(x+7,y+3,x+7,y+h);
 457                     g.drawLine(x+8,y+1,x+8,y+h);
 458                     g.setColor(oldColor);
 459                 }
 460             }
 461 
 462         }
 463         public int getIconWidth() { return 10; }
 464         public int getIconHeight() { return 10; }
 465     } // End class MenuArrowIcon
 466 }