1 /* 2 * Copyright (c) 2005, 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 26 /* 27 * <p>These classes are designed to be used while the 28 * corresponding <code>LookAndFeel</code> class has been installed 29 * (<code>UIManager.setLookAndFeel(new <i>XXX</i>LookAndFeel())</code>). 30 * Using them while a different <code>LookAndFeel</code> is installed 31 * may produce unexpected results, including exceptions. 32 * Additionally, changing the <code>LookAndFeel</code> 33 * maintained by the <code>UIManager</code> without updating the 34 * corresponding <code>ComponentUI</code> of any 35 * <code>JComponent</code>s may also produce unexpected results, 36 * such as the wrong colors showing up, and is generally not 37 * encouraged. 38 * 39 */ 40 41 package com.sun.java.swing.plaf.windows; 42 43 import java.awt.*; 44 import java.util.*; 45 46 import javax.swing.*; 47 48 import sun.awt.windows.ThemeReader; 49 50 /** 51 * Implements Windows Parts and their States and Properties for the Windows Look and Feel. 52 * 53 * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp 54 * See tmschema.h (or vssym32.h & vsstyle.h for MS Vista) 55 * 56 * @author Leif Samuelsson 57 */ 58 class TMSchema { 59 60 /** 61 * An enumeration of the various Windows controls (also known as 62 * components, or top-level parts) 63 */ 64 public static enum Control { 65 BUTTON, 66 COMBOBOX, 67 EDIT, 68 HEADER, 69 LISTBOX, 70 LISTVIEW, 71 MENU, 72 PROGRESS, 73 REBAR, 74 SCROLLBAR, 75 SPIN, 76 TAB, 77 TOOLBAR, 78 TRACKBAR, 79 TREEVIEW, 80 WINDOW 81 } 82 83 84 /** 85 * An enumeration of the Windows compoent parts 86 */ 87 public static enum Part { 88 MENU (Control.MENU, 0), // Special case, not in native 89 MP_BARBACKGROUND (Control.MENU, 7), 90 MP_BARITEM (Control.MENU, 8), 91 MP_POPUPBACKGROUND (Control.MENU, 9), 92 MP_POPUPBORDERS (Control.MENU, 10), 93 MP_POPUPCHECK (Control.MENU, 11), 94 MP_POPUPCHECKBACKGROUND (Control.MENU, 12), 95 MP_POPUPGUTTER (Control.MENU, 13), 96 MP_POPUPITEM (Control.MENU, 14), 97 MP_POPUPSEPARATOR (Control.MENU, 15), 98 MP_POPUPSUBMENU (Control.MENU, 16), 99 100 BP_PUSHBUTTON (Control.BUTTON, 1), 101 BP_RADIOBUTTON(Control.BUTTON, 2), 102 BP_CHECKBOX (Control.BUTTON, 3), 103 BP_GROUPBOX (Control.BUTTON, 4), 104 105 CP_COMBOBOX (Control.COMBOBOX, 0), 106 CP_DROPDOWNBUTTON(Control.COMBOBOX, 1), 107 CP_BACKGROUND (Control.COMBOBOX, 2), 108 CP_TRANSPARENTBACKGROUND (Control.COMBOBOX, 3), 109 CP_BORDER (Control.COMBOBOX, 4), 110 CP_READONLY (Control.COMBOBOX, 5), 111 CP_DROPDOWNBUTTONRIGHT (Control.COMBOBOX, 6), 112 CP_DROPDOWNBUTTONLEFT (Control.COMBOBOX, 7), 113 CP_CUEBANNER (Control.COMBOBOX, 8), 114 115 116 EP_EDIT (Control.EDIT, 0), 117 EP_EDITTEXT(Control.EDIT, 1), 118 119 HP_HEADERITEM(Control.HEADER, 1), 120 HP_HEADERSORTARROW(Control.HEADER, 4), 121 122 LBP_LISTBOX(Control.LISTBOX, 0), 123 124 LVP_LISTVIEW(Control.LISTVIEW, 0), 125 126 PP_PROGRESS (Control.PROGRESS, 0), 127 PP_BAR (Control.PROGRESS, 1), 128 PP_BARVERT (Control.PROGRESS, 2), 129 PP_CHUNK (Control.PROGRESS, 3), 130 PP_CHUNKVERT(Control.PROGRESS, 4), 131 132 RP_GRIPPER (Control.REBAR, 1), 133 RP_GRIPPERVERT(Control.REBAR, 2), 134 135 SBP_SCROLLBAR (Control.SCROLLBAR, 0), 136 SBP_ARROWBTN (Control.SCROLLBAR, 1), 137 SBP_THUMBBTNHORZ (Control.SCROLLBAR, 2), 138 SBP_THUMBBTNVERT (Control.SCROLLBAR, 3), 139 SBP_LOWERTRACKHORZ(Control.SCROLLBAR, 4), 140 SBP_UPPERTRACKHORZ(Control.SCROLLBAR, 5), 141 SBP_LOWERTRACKVERT(Control.SCROLLBAR, 6), 142 SBP_UPPERTRACKVERT(Control.SCROLLBAR, 7), 143 SBP_GRIPPERHORZ (Control.SCROLLBAR, 8), 144 SBP_GRIPPERVERT (Control.SCROLLBAR, 9), 145 SBP_SIZEBOX (Control.SCROLLBAR, 10), 146 147 SPNP_UP (Control.SPIN, 1), 148 SPNP_DOWN(Control.SPIN, 2), 149 150 TABP_TABITEM (Control.TAB, 1), 151 TABP_TABITEMLEFTEDGE (Control.TAB, 2), 152 TABP_TABITEMRIGHTEDGE(Control.TAB, 3), 153 TABP_PANE (Control.TAB, 9), 154 155 TP_TOOLBAR (Control.TOOLBAR, 0), 156 TP_BUTTON (Control.TOOLBAR, 1), 157 TP_SEPARATOR (Control.TOOLBAR, 5), 158 TP_SEPARATORVERT (Control.TOOLBAR, 6), 159 160 TKP_TRACK (Control.TRACKBAR, 1), 161 TKP_TRACKVERT (Control.TRACKBAR, 2), 162 TKP_THUMB (Control.TRACKBAR, 3), 163 TKP_THUMBBOTTOM(Control.TRACKBAR, 4), 164 TKP_THUMBTOP (Control.TRACKBAR, 5), 165 TKP_THUMBVERT (Control.TRACKBAR, 6), 166 TKP_THUMBLEFT (Control.TRACKBAR, 7), 167 TKP_THUMBRIGHT (Control.TRACKBAR, 8), 168 TKP_TICS (Control.TRACKBAR, 9), 169 TKP_TICSVERT (Control.TRACKBAR, 10), 170 171 TVP_TREEVIEW(Control.TREEVIEW, 0), 172 TVP_GLYPH (Control.TREEVIEW, 2), 173 174 WP_WINDOW (Control.WINDOW, 0), 175 WP_CAPTION (Control.WINDOW, 1), 176 WP_MINCAPTION (Control.WINDOW, 3), 177 WP_MAXCAPTION (Control.WINDOW, 5), 178 WP_FRAMELEFT (Control.WINDOW, 7), 179 WP_FRAMERIGHT (Control.WINDOW, 8), 180 WP_FRAMEBOTTOM (Control.WINDOW, 9), 181 WP_SYSBUTTON (Control.WINDOW, 13), 182 WP_MDISYSBUTTON (Control.WINDOW, 14), 183 WP_MINBUTTON (Control.WINDOW, 15), 184 WP_MDIMINBUTTON (Control.WINDOW, 16), 185 WP_MAXBUTTON (Control.WINDOW, 17), 186 WP_CLOSEBUTTON (Control.WINDOW, 18), 187 WP_MDICLOSEBUTTON (Control.WINDOW, 20), 188 WP_RESTOREBUTTON (Control.WINDOW, 21), 189 WP_MDIRESTOREBUTTON(Control.WINDOW, 22); 190 191 private final Control control; 192 private final int value; 193 194 private Part(Control control, int value) { 195 this.control = control; 196 this.value = value; 197 } 198 199 public int getValue() { 200 return value; 201 } 202 203 public String getControlName(Component component) { 204 String str = ""; 205 if (component instanceof JComponent) { 206 JComponent c = (JComponent)component; 207 String subAppName = (String)c.getClientProperty("XPStyle.subAppName"); 208 if (subAppName != null) { 209 str = subAppName + "::"; 210 } 211 } 212 return str + control.toString(); 213 } 214 215 public String toString() { 216 return control.toString()+"."+name(); 217 } 218 } 219 220 221 /** 222 * An enumeration of the possible component states 223 */ 224 public static enum State { 225 ACTIVE, 226 ASSIST, 227 BITMAP, 228 CHECKED, 229 CHECKEDDISABLED, 230 CHECKEDHOT, 231 CHECKEDNORMAL, 232 CHECKEDPRESSED, 233 CHECKMARKNORMAL, 234 CHECKMARKDISABLED, 235 BULLETNORMAL, 236 BULLETDISABLED, 237 CLOSED, 238 DEFAULTED, 239 DISABLED, 240 DISABLEDHOT, 241 DISABLEDPUSHED, 242 DOWNDISABLED, 243 DOWNHOT, 244 DOWNNORMAL, 245 DOWNPRESSED, 246 FOCUSED, 247 HOT, 248 HOTCHECKED, 249 ICONHOT, 250 ICONNORMAL, 251 ICONPRESSED, 252 ICONSORTEDHOT, 253 ICONSORTEDNORMAL, 254 ICONSORTEDPRESSED, 255 INACTIVE, 256 INACTIVENORMAL, // See note 1 257 INACTIVEHOT, // See note 1 258 INACTIVEPUSHED, // See note 1 259 INACTIVEDISABLED, // See note 1 260 LEFTDISABLED, 261 LEFTHOT, 262 LEFTNORMAL, 263 LEFTPRESSED, 264 MIXEDDISABLED, 265 MIXEDHOT, 266 MIXEDNORMAL, 267 MIXEDPRESSED, 268 NORMAL, 269 PRESSED, 270 OPENED, 271 PUSHED, 272 READONLY, 273 RIGHTDISABLED, 274 RIGHTHOT, 275 RIGHTNORMAL, 276 RIGHTPRESSED, 277 SELECTED, 278 UNCHECKEDDISABLED, 279 UNCHECKEDHOT, 280 UNCHECKEDNORMAL, 281 UNCHECKEDPRESSED, 282 UPDISABLED, 283 UPHOT, 284 UPNORMAL, 285 UPPRESSED, 286 HOVER, 287 UPHOVER, 288 DOWNHOVER, 289 LEFTHOVER, 290 RIGHTHOVER, 291 SORTEDDOWN, 292 SORTEDHOT, 293 SORTEDNORMAL, 294 SORTEDPRESSED, 295 SORTEDUP; 296 297 298 /** 299 * A map of allowed states for each Part 300 */ 301 private static EnumMap<Part, State[]> stateMap; 302 303 private static synchronized void initStates() { 304 stateMap = new EnumMap<Part, State[]>(Part.class); 305 306 stateMap.put(Part.EP_EDITTEXT, 307 new State[] { 308 NORMAL, HOT, SELECTED, DISABLED, FOCUSED, READONLY, ASSIST 309 }); 310 311 stateMap.put(Part.BP_PUSHBUTTON, 312 new State[] { NORMAL, HOT, PRESSED, DISABLED, DEFAULTED }); 313 314 stateMap.put(Part.BP_RADIOBUTTON, 315 new State[] { 316 UNCHECKEDNORMAL, UNCHECKEDHOT, UNCHECKEDPRESSED, UNCHECKEDDISABLED, 317 CHECKEDNORMAL, CHECKEDHOT, CHECKEDPRESSED, CHECKEDDISABLED 318 }); 319 320 stateMap.put(Part.BP_CHECKBOX, 321 new State[] { 322 UNCHECKEDNORMAL, UNCHECKEDHOT, UNCHECKEDPRESSED, UNCHECKEDDISABLED, 323 CHECKEDNORMAL, CHECKEDHOT, CHECKEDPRESSED, CHECKEDDISABLED, 324 MIXEDNORMAL, MIXEDHOT, MIXEDPRESSED, MIXEDDISABLED 325 }); 326 327 State[] comboBoxStates = new State[] { NORMAL, HOT, PRESSED, DISABLED }; 328 stateMap.put(Part.CP_COMBOBOX, comboBoxStates); 329 stateMap.put(Part.CP_DROPDOWNBUTTON, comboBoxStates); 330 stateMap.put(Part.CP_BACKGROUND, comboBoxStates); 331 stateMap.put(Part.CP_TRANSPARENTBACKGROUND, comboBoxStates); 332 stateMap.put(Part.CP_BORDER, comboBoxStates); 333 stateMap.put(Part.CP_READONLY, comboBoxStates); 334 stateMap.put(Part.CP_DROPDOWNBUTTONRIGHT, comboBoxStates); 335 stateMap.put(Part.CP_DROPDOWNBUTTONLEFT, comboBoxStates); 336 stateMap.put(Part.CP_CUEBANNER, comboBoxStates); 337 338 stateMap.put(Part.HP_HEADERITEM, new State[] { NORMAL, HOT, PRESSED, 339 SORTEDNORMAL, SORTEDHOT, SORTEDPRESSED, 340 ICONNORMAL, ICONHOT, ICONPRESSED, 341 ICONSORTEDNORMAL, ICONSORTEDHOT, ICONSORTEDPRESSED }); 342 343 stateMap.put(Part.HP_HEADERSORTARROW, 344 new State[] {SORTEDDOWN, SORTEDUP}); 345 346 State[] scrollBarStates = new State[] { NORMAL, HOT, PRESSED, DISABLED, HOVER }; 347 stateMap.put(Part.SBP_SCROLLBAR, scrollBarStates); 348 stateMap.put(Part.SBP_THUMBBTNVERT, scrollBarStates); 349 stateMap.put(Part.SBP_THUMBBTNHORZ, scrollBarStates); 350 stateMap.put(Part.SBP_GRIPPERVERT, scrollBarStates); 351 stateMap.put(Part.SBP_GRIPPERHORZ, scrollBarStates); 352 353 stateMap.put(Part.SBP_ARROWBTN, 354 new State[] { 355 UPNORMAL, UPHOT, UPPRESSED, UPDISABLED, 356 DOWNNORMAL, DOWNHOT, DOWNPRESSED, DOWNDISABLED, 357 LEFTNORMAL, LEFTHOT, LEFTPRESSED, LEFTDISABLED, 358 RIGHTNORMAL, RIGHTHOT, RIGHTPRESSED, RIGHTDISABLED, 359 UPHOVER, DOWNHOVER, LEFTHOVER, RIGHTHOVER 360 }); 361 362 363 State[] spinnerStates = new State[] { NORMAL, HOT, PRESSED, DISABLED }; 364 stateMap.put(Part.SPNP_UP, spinnerStates); 365 stateMap.put(Part.SPNP_DOWN, spinnerStates); 366 367 stateMap.put(Part.TVP_GLYPH, new State[] { CLOSED, OPENED }); 368 369 State[] frameButtonStates = new State[] { 370 NORMAL, HOT, PUSHED, DISABLED, // See note 1 371 INACTIVENORMAL, INACTIVEHOT, INACTIVEPUSHED, INACTIVEDISABLED, 372 }; 373 // Note 1: The INACTIVE frame button states apply when the frame 374 // is inactive. They are not defined in tmschema.h 375 376 // Fix for 6316538: Vista has five frame button states 377 if (ThemeReader.getInt(Control.WINDOW.toString(), 378 Part.WP_CLOSEBUTTON.getValue(), 1, 379 Prop.IMAGECOUNT.getValue()) == 10) { 380 frameButtonStates = new State[] { 381 NORMAL, HOT, PUSHED, DISABLED, null, 382 INACTIVENORMAL, INACTIVEHOT, INACTIVEPUSHED, INACTIVEDISABLED, null 383 }; 384 } 385 386 stateMap.put(Part.WP_MINBUTTON, frameButtonStates); 387 stateMap.put(Part.WP_MAXBUTTON, frameButtonStates); 388 stateMap.put(Part.WP_RESTOREBUTTON, frameButtonStates); 389 stateMap.put(Part.WP_CLOSEBUTTON, frameButtonStates); 390 391 // States for Slider (trackbar) 392 stateMap.put(Part.TKP_TRACK, new State[] { NORMAL }); 393 stateMap.put(Part.TKP_TRACKVERT, new State[] { NORMAL }); 394 395 State[] sliderThumbStates = 396 new State[] { NORMAL, HOT, PRESSED, FOCUSED, DISABLED }; 397 stateMap.put(Part.TKP_THUMB, sliderThumbStates); 398 stateMap.put(Part.TKP_THUMBBOTTOM, sliderThumbStates); 399 stateMap.put(Part.TKP_THUMBTOP, sliderThumbStates); 400 stateMap.put(Part.TKP_THUMBVERT, sliderThumbStates); 401 stateMap.put(Part.TKP_THUMBRIGHT, sliderThumbStates); 402 403 // States for Tabs 404 State[] tabStates = new State[] { NORMAL, HOT, SELECTED, DISABLED, FOCUSED }; 405 stateMap.put(Part.TABP_TABITEM, tabStates); 406 stateMap.put(Part.TABP_TABITEMLEFTEDGE, tabStates); 407 stateMap.put(Part.TABP_TABITEMRIGHTEDGE, tabStates); 408 409 410 stateMap.put(Part.TP_BUTTON, 411 new State[] { 412 NORMAL, HOT, PRESSED, DISABLED, CHECKED, HOTCHECKED 413 }); 414 415 State[] frameStates = new State[] { ACTIVE, INACTIVE }; 416 stateMap.put(Part.WP_WINDOW, frameStates); 417 stateMap.put(Part.WP_FRAMELEFT, frameStates); 418 stateMap.put(Part.WP_FRAMERIGHT, frameStates); 419 stateMap.put(Part.WP_FRAMEBOTTOM, frameStates); 420 421 State[] captionStates = new State[] { ACTIVE, INACTIVE, DISABLED }; 422 stateMap.put(Part.WP_CAPTION, captionStates); 423 stateMap.put(Part.WP_MINCAPTION, captionStates); 424 stateMap.put(Part.WP_MAXCAPTION, captionStates); 425 426 stateMap.put(Part.MP_BARBACKGROUND, 427 new State[] { ACTIVE, INACTIVE }); 428 stateMap.put(Part.MP_BARITEM, 429 new State[] { NORMAL, HOT, PUSHED, 430 DISABLED, DISABLEDHOT, DISABLEDPUSHED }); 431 stateMap.put(Part.MP_POPUPCHECK, 432 new State[] { CHECKMARKNORMAL, CHECKMARKDISABLED, 433 BULLETNORMAL, BULLETDISABLED }); 434 stateMap.put(Part.MP_POPUPCHECKBACKGROUND, 435 new State[] { DISABLEDPUSHED, NORMAL, BITMAP }); 436 stateMap.put(Part.MP_POPUPITEM, 437 new State[] { NORMAL, HOT, DISABLED, DISABLEDHOT }); 438 stateMap.put(Part.MP_POPUPSUBMENU, 439 new State[] { NORMAL, DISABLED }); 440 441 } 442 443 444 public static synchronized int getValue(Part part, State state) { 445 if (stateMap == null) { 446 initStates(); 447 } 448 449 Enum[] states = stateMap.get(part); 450 if (states != null) { 451 for (int i = 0; i < states.length; i++) { 452 if (state == states[i]) { 453 return i + 1; 454 } 455 } 456 } 457 458 if (state == null || state == State.NORMAL) { 459 return 1; 460 } 461 462 return 0; 463 } 464 465 } 466 467 468 /** 469 * An enumeration of the possible component attributes and the 470 * corresponding value type 471 */ 472 public static enum Prop { 473 COLOR(Color.class, 204), 474 SIZE(Dimension.class, 207), 475 476 FLATMENUS(Boolean.class, 1001), 477 478 BORDERONLY(Boolean.class, 2203), // only draw the border area of the image 479 480 IMAGECOUNT(Integer.class, 2401), // the number of state images in an imagefile 481 BORDERSIZE(Integer.class, 2403), // the size of the border line for bgtype=BorderFill 482 483 PROGRESSCHUNKSIZE(Integer.class, 2411), // size of progress control chunks 484 PROGRESSSPACESIZE(Integer.class, 2412), // size of progress control spaces 485 486 TEXTSHADOWOFFSET(Point.class, 3402), // where char shadows are drawn, relative to orig. chars 487 488 NORMALSIZE(Dimension.class, 3409), // size of dest rect that exactly source 489 490 491 SIZINGMARGINS ( Insets.class, 3601), // margins used for 9-grid sizing 492 CONTENTMARGINS(Insets.class, 3602), // margins that define where content can be placed 493 CAPTIONMARGINS(Insets.class, 3603), // margins that define where caption text can be placed 494 495 BORDERCOLOR(Color.class, 3801), // color of borders for BorderFill 496 FILLCOLOR ( Color.class, 3802), // color of bg fill 497 TEXTCOLOR ( Color.class, 3803), // color text is drawn in 498 499 TEXTSHADOWCOLOR(Color.class, 3818), // color of text shadow 500 501 BGTYPE(Integer.class, 4001), // basic drawing type for each part 502 503 TEXTSHADOWTYPE(Integer.class, 4010), // type of shadow to draw with text 504 505 TRANSITIONDURATIONS(Integer.class, 6000); 506 507 private final Class type; 508 private final int value; 509 510 private Prop(Class type, int value) { 511 this.type = type; 512 this.value = value; 513 } 514 515 public int getValue() { 516 return value; 517 } 518 519 public String toString() { 520 return name()+"["+type.getName()+"] = "+value; 521 } 522 } 523 524 525 /** 526 * An enumeration of attribute values for some Props 527 */ 528 public static enum TypeEnum { 529 BT_IMAGEFILE (Prop.BGTYPE, "imagefile", 0), 530 BT_BORDERFILL(Prop.BGTYPE, "borderfill", 1), 531 532 TST_NONE(Prop.TEXTSHADOWTYPE, "none", 0), 533 TST_SINGLE(Prop.TEXTSHADOWTYPE, "single", 1), 534 TST_CONTINUOUS(Prop.TEXTSHADOWTYPE, "continuous", 2); 535 536 537 private TypeEnum(Prop prop, String enumName, int value) { 538 this.prop = prop; 539 this.enumName = enumName; 540 this.value = value; 541 } 542 543 private final Prop prop; 544 private final String enumName; 545 private final int value; 546 547 public String toString() { 548 return prop+"="+enumName+"="+value; 549 } 550 551 String getName() { 552 return enumName; 553 } 554 555 556 static TypeEnum getTypeEnum(Prop prop, int enumval) { 557 for (TypeEnum e : TypeEnum.values()) { 558 if (e.prop == prop && e.value == enumval) { 559 return e; 560 } 561 } 562 return null; 563 } 564 } 565 }