1 12 package org.eclipse.jface.dialogs; 13 14 import java.util.ArrayList ; 15 import java.util.List ; 16 17 import org.eclipse.jface.action.Action; 18 import org.eclipse.jface.action.GroupMarker; 19 import org.eclipse.jface.action.IAction; 20 import org.eclipse.jface.action.IMenuManager; 21 import org.eclipse.jface.action.MenuManager; 22 import org.eclipse.jface.action.Separator; 23 import org.eclipse.jface.layout.GridDataFactory; 24 import org.eclipse.jface.layout.GridLayoutFactory; 25 import org.eclipse.jface.resource.ImageDescriptor; 26 import org.eclipse.jface.resource.JFaceResources; 27 import org.eclipse.jface.window.Window; 28 import org.eclipse.swt.SWT; 29 import org.eclipse.swt.events.DisposeEvent; 30 import org.eclipse.swt.events.DisposeListener; 31 import org.eclipse.swt.events.MouseAdapter; 32 import org.eclipse.swt.events.MouseEvent; 33 import org.eclipse.swt.events.SelectionAdapter; 34 import org.eclipse.swt.events.SelectionEvent; 35 import org.eclipse.swt.graphics.Color; 36 import org.eclipse.swt.graphics.Font; 37 import org.eclipse.swt.graphics.FontData; 38 import org.eclipse.swt.graphics.Image; 39 import org.eclipse.swt.graphics.Point; 40 import org.eclipse.swt.graphics.Rectangle; 41 import org.eclipse.swt.widgets.Composite; 42 import org.eclipse.swt.widgets.Control; 43 import org.eclipse.swt.widgets.Display; 44 import org.eclipse.swt.widgets.Event; 45 import org.eclipse.swt.widgets.Label; 46 import org.eclipse.swt.widgets.Listener; 47 import org.eclipse.swt.widgets.Menu; 48 import org.eclipse.swt.widgets.Shell; 49 import org.eclipse.swt.widgets.ToolBar; 50 import org.eclipse.swt.widgets.ToolItem; 51 import org.eclipse.swt.widgets.Tracker; 52 53 73 public class PopupDialog extends Window { 74 75 78 private static final GridDataFactory LAYOUTDATA_GRAB_BOTH = GridDataFactory.fillDefaults().grab(true,true); 79 80 83 private static final String DIALOG_ORIGIN_X = "DIALOG_X_ORIGIN"; 85 88 private static final String DIALOG_ORIGIN_Y = "DIALOG_Y_ORIGIN"; 90 93 private static final String DIALOG_WIDTH = "DIALOG_WIDTH"; 95 98 private static final String DIALOG_HEIGHT = "DIALOG_HEIGHT"; 100 104 private static final String DIALOG_USE_PERSISTED_BOUNDS = "DIALOG_USE_PERSISTED_BOUNDS"; 106 109 private class MoveAction extends Action { 110 111 MoveAction() { 112 super(JFaceResources.getString("PopupDialog.move"), IAction.AS_PUSH_BUTTON); 114 } 115 116 121 public void run() { 122 performTrackerAction(SWT.NONE); 123 } 124 125 } 126 127 130 private class ResizeAction extends Action { 131 132 ResizeAction() { 133 super(JFaceResources.getString("PopupDialog.resize"), IAction.AS_PUSH_BUTTON); 135 } 136 137 140 public void run() { 141 performTrackerAction(SWT.RESIZE); 142 } 143 } 144 145 149 private class PersistBoundsAction extends Action { 150 151 PersistBoundsAction() { 152 super(JFaceResources.getString("PopupDialog.persistBounds"), IAction.AS_CHECK_BOX); 154 setChecked(persistBounds); 155 } 156 157 162 public void run() { 163 persistBounds = isChecked(); 164 } 165 } 166 167 170 public final static int HOVER_SHELLSTYLE = SWT.NO_FOCUS | SWT.ON_TOP 171 | SWT.NO_TRIM; 172 173 176 public final static int INFOPOPUP_SHELLSTYLE = SWT.NO_TRIM; 177 178 181 public final static int INFOPOPUPRESIZE_SHELLSTYLE = SWT.RESIZE; 182 183 187 public final static int POPUP_MARGINWIDTH = 0; 188 189 193 public final static int POPUP_MARGINHEIGHT = 0; 194 195 199 public final static int POPUP_VERTICALSPACING = 1; 200 201 205 public final static int POPUP_HORIZONTALSPACING = 1; 206 207 210 private static final GridLayoutFactory POPUP_LAYOUT_FACTORY = GridLayoutFactory 211 .fillDefaults().margins(POPUP_MARGINWIDTH, POPUP_MARGINHEIGHT) 212 .spacing(POPUP_HORIZONTALSPACING, POPUP_VERTICALSPACING); 213 214 217 private static final int BORDER_THICKNESS = 1; 218 219 222 private ToolBar toolBar = null; 223 224 227 private MenuManager menuManager = null; 228 229 232 private Control dialogArea; 233 234 238 private Label titleLabel, infoLabel; 239 240 243 private Control titleSeparator, infoSeparator; 244 245 248 private Image menuImage, disabledMenuImage = null; 249 250 254 private Font infoFont; 255 256 260 private Font titleFont; 261 262 267 private boolean listenToDeactivate; 268 269 private boolean listenToParentDeactivate; 270 271 private Listener parentDeactivateListener; 272 273 276 private boolean takeFocusOnOpen = false; 277 278 282 private boolean showDialogMenu = false; 283 284 288 private boolean showPersistAction = false; 289 290 294 private boolean persistBounds = false; 295 296 299 private String titleText; 300 301 304 private String infoText; 305 306 340 public PopupDialog(Shell parent, int shellStyle, boolean takeFocusOnOpen, 341 boolean persistBounds, boolean showDialogMenu, 342 boolean showPersistAction, String titleText, String infoText) { 343 super(parent); 344 setShellStyle(shellStyle); 345 this.takeFocusOnOpen = takeFocusOnOpen; 346 this.showDialogMenu = showDialogMenu; 347 this.showPersistAction = showPersistAction; 348 this.titleText = titleText; 349 this.infoText = infoText; 350 351 setBlockOnOpen(false); 352 353 this.persistBounds = persistBounds; 354 initializeWidgetState(); 355 } 356 357 362 protected void configureShell(Shell shell) { 363 Display display = shell.getDisplay(); 364 shell.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); 365 366 int border = ((getShellStyle() & SWT.NO_TRIM) == 0) ? 0 367 : BORDER_THICKNESS; 368 GridLayoutFactory.fillDefaults().margins(border, border).spacing(5,5).applyTo(shell); 369 370 shell.addListener(SWT.Deactivate, new Listener() { 371 public void handleEvent(Event event) { 372 379 if (listenToDeactivate && event.widget == getShell() 380 && getShell().getShells().length == 0) { 381 close(); 382 } else { 383 388 listenToDeactivate = true; 389 } 390 } 391 }); 392 shell.addListener(SWT.Activate, new Listener() { 395 public void handleEvent(Event event) { 396 if (event.widget == getShell() 398 && getShell().getShells().length == 0) { 399 listenToDeactivate = true; 400 listenToParentDeactivate = !"carbon".equals(SWT.getPlatform()); } 406 } 407 }); 408 409 if ((getShellStyle() & SWT.ON_TOP) != 0 && shell.getParent() != null) { 410 parentDeactivateListener= new Listener() { 411 public void handleEvent(Event event) { 412 if (listenToParentDeactivate) { 413 close(); 414 } else { 415 listenToParentDeactivate = listenToDeactivate; 417 } 418 } 419 }; 420 shell.getParent().addListener(SWT.Deactivate, parentDeactivateListener); 421 } 422 423 shell.addDisposeListener(new DisposeListener() { 424 public void widgetDisposed(DisposeEvent event) { 425 handleDispose(); 426 } 427 }); 428 } 429 430 446 protected Control createContents(Composite parent) { 447 Composite composite = new Composite(parent, SWT.NONE); 448 POPUP_LAYOUT_FACTORY.applyTo(composite); 449 LAYOUTDATA_GRAB_BOTH.applyTo(composite); 450 451 if (hasTitleArea()) { 453 createTitleMenuArea(composite); 454 titleSeparator = createHorizontalSeparator(composite); 455 } 456 dialogArea = createDialogArea(composite); 458 if (dialogArea.getLayoutData() == null) { 461 LAYOUTDATA_GRAB_BOTH.applyTo(dialogArea); 462 } 463 464 if (hasInfoArea()) { 466 infoSeparator = createHorizontalSeparator(composite); 467 createInfoTextArea(composite); 468 } 469 470 applyColors(composite); 471 applyFonts(composite); 472 return composite; 473 } 474 475 500 protected Control createDialogArea(Composite parent) { 501 Composite composite = new Composite(parent, SWT.NONE); 502 POPUP_LAYOUT_FACTORY.applyTo(composite); 503 LAYOUTDATA_GRAB_BOTH.applyTo(composite); 504 return composite; 505 } 506 507 513 protected Control getFocusControl() { 514 return dialogArea; 515 } 516 517 526 protected void setTabOrder(Composite composite) { 527 } 529 530 538 protected boolean hasTitleArea() { 539 return titleText != null || showDialogMenu; 540 } 541 542 550 protected boolean hasInfoArea() { 551 return infoText != null; 552 } 553 554 571 protected Control createTitleMenuArea(Composite parent) { 572 573 Composite titleAreaComposite = new Composite(parent, SWT.NONE); 574 POPUP_LAYOUT_FACTORY.copy().numColumns(2).applyTo(titleAreaComposite); 575 GridDataFactory.fillDefaults() 576 .align(SWT.FILL, SWT.CENTER).grab(true, false) 577 .applyTo(titleAreaComposite); 578 579 createTitleControl(titleAreaComposite); 580 581 if (showDialogMenu) { 582 createDialogMenu(titleAreaComposite); 583 } 584 return titleAreaComposite; 585 } 586 587 602 protected Control createTitleControl(Composite parent) { 603 titleLabel = new Label(parent, SWT.NONE); 604 605 GridDataFactory.fillDefaults() 606 .align(SWT.FILL, SWT.CENTER) 607 .grab(true, false) 608 .span(showDialogMenu ? 1 : 2, 1) 609 .applyTo(titleLabel); 610 611 Font font = titleLabel.getFont(); 612 FontData[] fontDatas = font.getFontData(); 613 for (int i = 0; i < fontDatas.length; i++) { 614 fontDatas[i].setStyle(SWT.BOLD); 615 } 616 titleFont = new Font(titleLabel.getDisplay(), fontDatas); 617 titleLabel.setFont(titleFont); 618 619 if (titleText != null) { 620 titleLabel.setText(titleText); 621 } 622 return titleLabel; 623 } 624 625 643 protected Control createInfoTextArea(Composite parent) { 644 infoLabel = new Label(parent, SWT.RIGHT); 646 infoLabel.setText(infoText); 647 Font font = infoLabel.getFont(); 648 FontData[] fontDatas = font.getFontData(); 649 for (int i = 0; i < fontDatas.length; i++) { 650 fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10); 651 } 652 infoFont = new Font(infoLabel.getDisplay(), fontDatas); 653 infoLabel.setFont(infoFont); 654 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.BEGINNING) 655 .applyTo(infoLabel); 656 infoLabel.setForeground(parent.getDisplay().getSystemColor( 657 SWT.COLOR_WIDGET_DARK_SHADOW)); 658 return infoLabel; 659 } 660 661 668 private Control createHorizontalSeparator(Composite parent) { 669 Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL 670 | SWT.LINE_DOT); 671 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(separator); 672 return separator; 673 } 674 675 681 private void createDialogMenu(Composite parent) { 682 683 toolBar = new ToolBar(parent, SWT.FLAT); 684 ToolItem viewMenuButton = new ToolItem(toolBar, SWT.PUSH, 0); 685 686 GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(toolBar); 687 688 menuImage = ImageDescriptor.createFromFile(PopupDialog.class, 689 "images/popup_menu.gif").createImage(); disabledMenuImage = ImageDescriptor.createFromFile(PopupDialog.class, 691 "images/popup_menu_disabled.gif").createImage(); viewMenuButton.setImage(menuImage); 693 viewMenuButton.setDisabledImage(disabledMenuImage); 694 viewMenuButton.setToolTipText(JFaceResources 695 .getString("PopupDialog.menuTooltip")); viewMenuButton.addSelectionListener(new SelectionAdapter() { 697 public void widgetSelected(SelectionEvent e) { 698 showDialogMenu(); 699 } 700 }); 701 viewMenuButton.addDisposeListener(new DisposeListener() { 702 public void widgetDisposed(DisposeEvent e) { 703 menuImage.dispose(); 704 menuImage = null; 705 disabledMenuImage.dispose(); 706 disabledMenuImage = null; 707 } 708 }); 709 toolBar.addMouseListener(new MouseAdapter() { 711 public void mouseDown(MouseEvent e) { 712 showDialogMenu(); 713 } 714 }); 715 } 716 717 723 protected void fillDialogMenu(IMenuManager dialogMenu) { 724 dialogMenu.add(new GroupMarker("SystemMenuStart")); dialogMenu.add(new MoveAction()); 726 dialogMenu.add(new ResizeAction()); 727 if (showPersistAction) { 728 dialogMenu.add(new PersistBoundsAction()); 729 } 730 dialogMenu.add(new Separator("SystemMenuEnd")); } 732 733 739 private void performTrackerAction(int style) { 740 Shell shell = getShell(); 741 if (shell == null || shell.isDisposed()) { 742 return; 743 } 744 745 Tracker tracker = new Tracker(shell.getDisplay(), style); 746 tracker.setStippled(true); 747 Rectangle[] r = new Rectangle[] { shell.getBounds() }; 748 tracker.setRectangles(r); 749 750 boolean oldListenToDeactivate = listenToDeactivate; 753 listenToDeactivate = false; 754 if (tracker.open()) { 755 if (shell != null && !shell.isDisposed()) { 756 shell.setBounds(tracker.getRectangles()[0]); 757 } 758 } 759 listenToDeactivate = oldListenToDeactivate; 760 } 761 762 768 protected void showDialogMenu() { 769 if (!showDialogMenu) { 770 return; 771 } 772 773 if (menuManager == null) { 774 menuManager = new MenuManager(); 775 fillDialogMenu(menuManager); 776 } 777 listenToDeactivate = !"gtk".equals(SWT.getPlatform()); 781 Menu menu = menuManager.createContextMenu(getShell()); 782 Rectangle bounds = toolBar.getBounds(); 783 Point topLeft = new Point(bounds.x, bounds.y + bounds.height); 784 topLeft = getShell().toDisplay(topLeft); 785 menu.setLocation(topLeft.x, topLeft.y); 786 menu.setVisible(true); 787 } 788 789 798 protected void setInfoText(String text) { 799 infoText = text; 800 if (infoLabel != null) { 801 infoLabel.setText(text); 802 } 803 } 804 805 814 protected void setTitleText(String text) { 815 titleText = text; 816 if (titleLabel != null) { 817 titleLabel.setText(text); 818 } 819 } 820 821 830 protected boolean getPersistBounds() { 831 return persistBounds; 832 } 833 834 848 public int open() { 849 850 Shell shell = getShell(); 851 if (shell == null || shell.isDisposed()) { 852 shell = null; 853 create(); 855 shell = getShell(); 856 } 857 858 adjustBounds(); 862 863 constrainShellSize(); 865 866 setTabOrder((Composite) getContents()); 868 869 listenToDeactivate = false; 871 listenToParentDeactivate = false; 872 873 if (takeFocusOnOpen) { 875 shell.open(); 876 getFocusControl().setFocus(); 877 } else { 878 shell.setVisible(true); 879 } 880 881 return OK; 882 883 } 884 885 897 public boolean close() { 898 if (getShell() == null || getShell().isDisposed()) { 901 return true; 902 } 903 904 saveDialogBounds(getShell()); 905 initializeWidgetState(); 910 911 if (parentDeactivateListener != null) { 912 getShell().getParent().removeListener(SWT.Deactivate, parentDeactivateListener); 913 parentDeactivateListener = null; 914 } 915 916 return super.close(); 917 } 918 919 928 protected IDialogSettings getDialogSettings() { 929 return null; 930 } 931 932 944 protected void saveDialogBounds(Shell shell) { 945 IDialogSettings settings = getDialogSettings(); 946 if (settings != null) { 947 Point shellLocation = shell.getLocation(); 948 Point shellSize = shell.getSize(); 949 Shell parent = getParentShell(); 950 if (parent != null) { 951 Point parentLocation = parent.getLocation(); 952 shellLocation.x -= parentLocation.x; 953 shellLocation.y -= parentLocation.y; 954 } 955 if (persistBounds) { 956 String prefix = getClass().getName(); 957 settings.put(prefix + DIALOG_ORIGIN_X, shellLocation.x); 958 settings.put(prefix + DIALOG_ORIGIN_Y, shellLocation.y); 959 settings.put(prefix + DIALOG_WIDTH, shellSize.x); 960 settings.put(prefix + DIALOG_HEIGHT, shellSize.y); 961 } 962 if (showPersistAction && showDialogMenu) { 963 settings.put( 964 getClass().getName() + DIALOG_USE_PERSISTED_BOUNDS, 965 persistBounds); 966 } 967 } 968 } 969 970 975 protected Point getInitialSize() { 976 Point result = super.getInitialSize(); 977 if (persistBounds) { 978 IDialogSettings settings = getDialogSettings(); 979 if (settings != null) { 980 try { 981 int width = settings.getInt(getClass().getName() 982 + DIALOG_WIDTH); 983 int height = settings.getInt(getClass().getName() 984 + DIALOG_HEIGHT); 985 result = new Point(width, height); 986 987 } catch (NumberFormatException e) { 988 } 989 } 990 } 991 return result; 994 } 995 996 1003 protected void adjustBounds() { 1004 } 1005 1006 1011 protected Point getInitialLocation(Point initialSize) { 1012 Point result = super.getInitialLocation(initialSize); 1013 if (persistBounds) { 1014 IDialogSettings settings = getDialogSettings(); 1015 if (settings != null) { 1016 try { 1017 int x = settings.getInt(getClass().getName() 1018 + DIALOG_ORIGIN_X); 1019 int y = settings.getInt(getClass().getName() 1020 + DIALOG_ORIGIN_Y); 1021 result = new Point(x, y); 1022 Shell parent = getParentShell(); 1025 if (parent != null) { 1026 Point parentLocation = parent.getLocation(); 1027 result.x += parentLocation.x; 1028 result.y += parentLocation.y; 1029 } 1030 } catch (NumberFormatException e) { 1031 } 1032 } 1033 } 1034 return result; 1037 } 1038 1039 1045 private void applyColors(Composite composite) { 1046 applyForegroundColor(getShell().getDisplay().getSystemColor( 1047 SWT.COLOR_INFO_FOREGROUND), composite, 1048 getForegroundColorExclusions()); 1049 applyBackgroundColor(getShell().getDisplay().getSystemColor( 1050 SWT.COLOR_INFO_BACKGROUND), composite, 1051 getBackgroundColorExclusions()); 1052 } 1053 1054 1060 private void applyFonts(Composite composite) { 1061 Dialog.applyDialogFont(composite); 1062 1063 } 1064 1065 1077 private void applyForegroundColor(Color color, Control control, 1078 List exclusions) { 1079 if (!exclusions.contains(control)) { 1080 control.setForeground(color); 1081 } 1082 if (control instanceof Composite) { 1083 Control[] children = ((Composite) control).getChildren(); 1084 for (int i = 0; i < children.length; i++) { 1085 applyForegroundColor(color, children[i], exclusions); 1086 } 1087 } 1088 } 1089 1090 1102 private void applyBackgroundColor(Color color, Control control, 1103 List exclusions) { 1104 if (!exclusions.contains(control)) { 1105 control.setBackground(color); 1106 } 1107 if (control instanceof Composite) { 1108 Control[] children = ((Composite) control).getChildren(); 1109 for (int i = 0; i < children.length; i++) { 1110 applyBackgroundColor(color, children[i], exclusions); 1111 } 1112 } 1113 } 1114 1115 1128 protected void applyForegroundColor(Color color, Control control) { 1129 applyForegroundColor(color, control, getForegroundColorExclusions()); 1130 } 1131 1132 1145 protected void applyBackgroundColor(Color color, Control control) { 1146 applyBackgroundColor(color, control, getBackgroundColorExclusions()); 1147 } 1148 1149 1157 protected List getForegroundColorExclusions() { 1158 List list = new ArrayList (3); 1159 if (infoLabel != null) { 1160 list.add(infoLabel); 1161 } 1162 if (titleSeparator != null) { 1163 list.add(titleSeparator); 1164 } 1165 if (infoSeparator != null) { 1166 list.add(infoSeparator); 1167 } 1168 return list; 1169 } 1170 1171 1178 protected List getBackgroundColorExclusions() { 1179 List list = new ArrayList (2); 1180 if (titleSeparator != null) { 1181 list.add(titleSeparator); 1182 } 1183 if (infoSeparator != null) { 1184 list.add(infoSeparator); 1185 } 1186 return list; 1187 } 1188 1189 1193 private void initializeWidgetState() { 1194 menuManager = null; 1195 dialogArea = null; 1196 titleLabel = null; 1197 titleSeparator = null; 1198 infoSeparator = null; 1199 infoLabel = null; 1200 toolBar = null; 1201 1202 if (showDialogMenu && showPersistAction) { 1206 IDialogSettings settings = getDialogSettings(); 1207 if (settings != null) { 1208 persistBounds = settings.getBoolean(getClass().getName() 1209 + DIALOG_USE_PERSISTED_BOUNDS); 1210 } 1211 } 1212 1213 } 1214 1215 1219 private void handleDispose() { 1220 if (infoFont != null && !infoFont.isDisposed()) { 1221 infoFont.dispose(); 1222 } 1223 infoFont = null; 1224 if (titleFont != null && !titleFont.isDisposed()) { 1225 titleFont.dispose(); 1226 } 1227 titleFont = null; 1228 } 1229} 1230 | Popular Tags |