1 16 17 package com.google.gwt.user.client.ui; 18 19 import com.google.gwt.user.client.DOM; 20 import com.google.gwt.user.client.Element; 21 import com.google.gwt.user.client.Event; 22 23 99 public abstract class CustomButton extends ButtonBase implements 100 SourcesKeyboardEvents { 101 105 public abstract class Face implements HasHTML, HasText { 106 private static final String STYLENAME_HTML_FACE = "html-face"; 107 private final Face delegateTo; 108 private Element face; 109 110 116 private Face(Face delegateTo) { 117 this.delegateTo = delegateTo; 118 } 119 120 126 public String getHTML() { 127 return DOM.getInnerHTML(getFace()); 128 } 129 130 136 public String getText() { 137 return DOM.getInnerText(getFace()); 138 } 139 140 146 public void setHTML(String html) { 147 face = DOM.createDiv(); 148 UIObject.setStyleName(face, STYLENAME_HTML_FACE, true); 149 DOM.setInnerHTML(face, html); 150 updateButtonFace(); 151 } 152 153 158 public final void setImage(Image image) { 159 face = image.getElement(); 160 updateButtonFace(); 161 } 162 163 168 public final void setText(String text) { 169 face = DOM.createDiv(); 170 UIObject.setStyleName(face, STYLENAME_HTML_FACE, true); 171 DOM.setInnerText(face, text); 172 updateButtonFace(); 173 } 174 175 public final String toString() { 176 return this.getName(); 177 } 178 179 183 abstract int getFaceID(); 184 185 193 abstract String getName(); 194 195 198 private Element getFace() { 199 if (face == null) { 200 if (delegateTo == null) { 201 face = DOM.createDiv(); 203 return face; 204 } else { 205 return delegateTo.getFace(); 206 } 207 } else { 208 return face; 209 } 210 } 211 212 private void updateButtonFace() { 213 if (curFace != null && curFace.getFace() == this.getFace()) { 214 setCurrentFaceElement(face); 215 } 216 } 217 } 218 219 private static final String STYLENAME_DEFAULT = "gwt-CustomButton"; 220 221 224 private static final int DOWN_ATTRIBUTE = 1; 225 226 229 private static final int HOVERING_ATTRIBUTE = 2; 230 231 234 private static final int DISABLED_ATTRIBUTE = 4; 235 236 239 private static final int UP = 0; 240 241 244 private static final int DOWN = DOWN_ATTRIBUTE; 245 246 249 private static final int UP_HOVERING = HOVERING_ATTRIBUTE; 250 251 254 private static final int DOWN_HOVERING = DOWN_ATTRIBUTE | HOVERING_ATTRIBUTE; 255 256 259 private static final int UP_DISABLED = DISABLED_ATTRIBUTE; 260 261 264 private static final int DOWN_DISABLED = DOWN | DISABLED_ATTRIBUTE; 265 266 269 private Element curFaceElement; 270 271 274 private Face curFace; 275 276 279 private Face up; 280 281 284 private Face down; 285 286 289 private Face downHovering; 290 291 294 private Face upHovering; 295 296 299 private Face upDisabled; 300 301 304 private Face downDisabled; 305 306 309 private boolean isCapturing; 310 311 314 private boolean isFocusing; 315 316 321 public CustomButton(Image upImage) { 322 this(); 323 getUpFace().setImage(upImage); 324 } 325 326 332 public CustomButton(Image upImage, Image downImage) { 333 this(upImage); 334 getDownFace().setImage(downImage); 335 } 336 337 344 public CustomButton(Image upImage, Image downImage, ClickListener listener) { 345 this(upImage, listener); 346 getDownFace().setImage(downImage); 347 } 348 349 355 public CustomButton(Image upImage, ClickListener listener) { 356 this(upImage); 357 addClickListener(listener); 358 } 359 360 365 public CustomButton(String upText) { 366 this(); 367 getUpFace().setText(upText); 368 } 369 370 376 public CustomButton(String upText, ClickListener listener) { 377 this(upText); 378 addClickListener(listener); 379 } 380 381 387 public CustomButton(String upText, String downText) { 388 this(upText); 389 getDownFace().setText(downText); 390 } 391 392 399 public CustomButton(String upText, String downText, ClickListener listener) { 400 this(upText, downText); 401 addClickListener(listener); 402 } 403 404 407 protected CustomButton() { 408 super(FocusPanel.impl.createFocusable()); 411 sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS | Event.FOCUSEVENTS); 412 setUpFace(createFace(null, "up", UP)); 413 setStyleName(STYLENAME_DEFAULT); 414 } 415 416 421 public final Face getDownDisabledFace() { 422 if (downDisabled == null) { 423 setDownDisabledFace(createFace(getDownFace(), "down-disabled", 424 DOWN_DISABLED)); 425 } 426 return downDisabled; 427 } 428 429 434 public final Face getDownFace() { 435 if (down == null) { 436 setDownFace(createFace(getUpFace(), "down", DOWN)); 437 } 438 return down; 439 } 440 441 446 public final Face getDownHoveringFace() { 447 if (downHovering == null) { 448 setDownHoveringFace(createFace(getDownFace(), "down-hovering", 449 DOWN_HOVERING)); 450 } 451 return downHovering; 452 } 453 454 459 public String getHTML() { 460 return getCurrentFace().getHTML(); 461 } 462 463 public int getTabIndex() { 464 return FocusPanel.impl.getTabIndex(getElement()); 465 } 466 467 472 public String getText() { 473 return getCurrentFace().getText(); 474 } 475 476 481 public final Face getUpDisabledFace() { 482 if (upDisabled == null) { 483 setUpDisabledFace(createFace(getUpFace(), "up-disabled", UP_DISABLED)); 484 } 485 return upDisabled; 486 } 487 488 493 public final Face getUpFace() { 494 return up; 495 } 496 497 502 public final Face getUpHoveringFace() { 503 if (upHovering == null) { 504 setUpHoveringFace(createFace(getUpFace(), "up-hovering", UP_HOVERING)); 505 } 506 return upHovering; 507 } 508 509 public void onBrowserEvent(Event event) { 510 if (isEnabled() == false) { 512 return; 514 } 515 516 int type = DOM.eventGetType(event); 517 switch (type) { 518 case Event.ONMOUSEDOWN: 519 setFocus(true); 520 onClickStart(); 521 DOM.setCapture(getElement()); 522 isCapturing = true; 523 DOM.eventPreventDefault(event); 525 break; 526 case Event.ONMOUSEUP: 527 if (isCapturing) { 528 isCapturing = false; 529 DOM.releaseCapture(getElement()); 530 if (isHovering()) { 531 onClick(); 532 } 533 } 534 break; 535 case Event.ONMOUSEMOVE: 536 if (isCapturing) { 537 DOM.eventPreventDefault(event); 539 } 540 break; 541 case Event.ONMOUSEOUT: 542 if (DOM.isOrHasChild(getElement(), DOM.eventGetTarget(event))) { 543 if (isCapturing) { 544 onClickCancel(); 545 } 546 setHovering(false); 547 } 548 break; 549 case Event.ONMOUSEOVER: 550 if (DOM.isOrHasChild(getElement(), DOM.eventGetTarget(event))) { 551 setHovering(true); 552 if (isCapturing) { 553 onClickStart(); 554 } 555 } 556 break; 557 case Event.ONCLICK: 558 return; 560 case Event.ONBLUR: 561 if (isFocusing) { 562 isFocusing = false; 563 onClickCancel(); 564 } 565 break; 566 case Event.ONLOSECAPTURE: 567 if (isCapturing) { 568 isCapturing = false; 569 onClickCancel(); 570 } 571 break; 572 } 573 574 super.onBrowserEvent(event); 575 576 char keyCode = (char) DOM.eventGetKeyCode(event); 578 switch (type) { 579 case Event.ONKEYDOWN: 580 if (keyCode == ' ') { 581 isFocusing = true; 582 onClickStart(); 583 } 584 break; 585 case Event.ONKEYUP: 586 if (isFocusing && keyCode == ' ') { 587 isFocusing = false; 588 onClick(); 589 } 590 break; 591 case Event.ONKEYPRESS: 592 if (keyCode == '\n' || keyCode == '\r') { 593 onClickStart(); 594 onClick(); 595 } 596 break; 597 } 598 } 599 600 public void setAccessKey(char key) { 601 FocusPanel.impl.setAccessKey(getElement(), key); 602 } 603 604 610 public final void setEnabled(boolean enabled) { 611 if (isEnabled() != enabled) { 612 toggleDisabled(); 613 super.setEnabled(enabled); 614 if (!enabled) { 615 cleanupCaptureState(); 616 } 617 } 618 } 619 620 public void setFocus(boolean focused) { 621 if (focused) { 622 FocusPanel.impl.focus(getElement()); 623 } else { 624 FocusPanel.impl.blur(getElement()); 625 } 626 } 627 628 633 public void setHTML(String html) { 634 getCurrentFace().setHTML(html); 635 } 636 637 public void setTabIndex(int index) { 638 FocusPanel.impl.setTabIndex(getElement(), index); 639 } 640 641 646 public void setText(String text) { 647 getCurrentFace().setText(text); 648 } 649 650 655 protected boolean isDown() { 656 return (DOWN_ATTRIBUTE & getCurrentFace().getFaceID()) > 0; 657 } 658 659 663 protected void onAttach() { 664 finishSetup(); 665 super.onAttach(); 666 } 667 668 674 protected void onClick() { 675 fireClickListeners(); 676 } 677 678 684 protected void onClickCancel() { 685 } 686 687 696 protected void onClickStart() { 697 } 698 699 protected void onDetach() { 700 super.onDetach(); 701 cleanupCaptureState(); 702 } 703 704 710 protected void setDown(boolean down) { 711 if (down != isDown()) { 712 toggleDown(); 713 } 714 } 715 716 719 void finishSetup() { 720 if (curFace == null) { 721 setCurrentFace(getUpFace()); 722 } 723 } 724 725 730 731 Face getCurrentFace() { 732 736 finishSetup(); 737 return curFace; 738 } 739 740 745 final boolean isHovering() { 746 return (HOVERING_ATTRIBUTE & getCurrentFace().getFaceID()) > 0; 747 } 748 749 void setCurrentFace(Face newFace) { 750 753 if (curFace != newFace) { 754 if (curFace != null) { 755 super.removeStyleName(getCSSStyleName()); 756 } 757 curFace = newFace; 758 setCurrentFaceElement(newFace.getFace()); 759 super.addStyleName(getCSSStyleName()); 760 } 761 } 762 763 768 final void setHovering(boolean hovering) { 769 if (hovering != isHovering()) { 770 toggleHover(); 771 } 772 } 773 774 777 void toggleDown() { 778 int newFaceID = getCurrentFace().getFaceID() ^ DOWN_ATTRIBUTE; 779 setCurrentFace(newFaceID); 780 } 781 782 786 private void cleanupCaptureState() { 787 if (isCapturing || isFocusing) { 788 DOM.releaseCapture(getElement()); 789 isCapturing = false; 790 isFocusing = false; 791 onClickCancel(); 792 } 793 } 794 795 private Face createFace(Face delegateTo, final String name, final int faceID) { 796 return new Face(delegateTo) { 797 798 public String getName() { 799 return name; 800 } 801 802 int getFaceID() { 803 return faceID; 804 } 805 }; 806 } 807 808 813 private String getCSSStyleName() { 814 return getStyleName() + "-" + curFace.getName(); 815 } 816 817 private Face getFaceFromID(int id) { 818 switch (id) { 819 case DOWN: 820 return getDownFace(); 821 case UP: 822 return getUpFace(); 823 case DOWN_HOVERING: 824 return getDownHoveringFace(); 825 case UP_HOVERING: 826 return getUpHoveringFace(); 827 case UP_DISABLED: 828 return getUpDisabledFace(); 829 case DOWN_DISABLED: 830 return getDownDisabledFace(); 831 default: 832 throw new IllegalStateException (id + " is not a known face id."); 833 } 834 } 835 836 841 private void setCurrentFace(int faceID) { 842 Face newFace = getFaceFromID(faceID); 843 setCurrentFace(newFace); 844 } 845 846 private void setCurrentFaceElement(Element newFaceElement) { 847 if (curFaceElement != newFaceElement) { 848 if (curFaceElement != null) { 849 DOM.removeChild(getElement(), curFaceElement); 850 } 851 curFaceElement = newFaceElement; 852 DOM.appendChild(getElement(), curFaceElement); 853 } 854 } 855 856 861 private void setDownDisabledFace(Face downDisabled) { 862 this.downDisabled = downDisabled; 863 } 864 865 870 private void setDownFace(Face down) { 871 this.down = down; 872 } 873 874 879 private void setDownHoveringFace(Face downHovering) { 880 this.downHovering = downHovering; 881 } 882 883 888 private void setUpDisabledFace(Face upDisabled) { 889 this.upDisabled = upDisabled; 890 } 891 892 897 private void setUpFace(Face up) { 898 this.up = up; 899 } 900 901 906 private void setUpHoveringFace(Face upHovering) { 907 this.upHovering = upHovering; 908 } 909 910 913 private void toggleDisabled() { 914 int newFaceID = getCurrentFace().getFaceID() ^ DISABLED_ATTRIBUTE; 916 917 newFaceID &= ~HOVERING_ATTRIBUTE; 919 920 setCurrentFace(newFaceID); 922 } 923 924 927 private void toggleHover() { 928 int newFaceID = getCurrentFace().getFaceID() ^ HOVERING_ATTRIBUTE; 930 931 newFaceID &= ~DISABLED_ATTRIBUTE; 933 setCurrentFace(newFaceID); 934 } 935 } 936 | Popular Tags |