Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2004 IBM Corporation and others. |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Common Public License v1.0 |
5 |
* which accompanies this distribution, and is available at |
6 |
* http://www.eclipse.org/legal/cpl-v10.html |
7 |
* |
8 |
* Contributors: |
9 |
* IBM Corporation - initial API and implementation |
10 |
******************************************************************************/ |
11 |
package org.eclipse.jface.dialogs; |
12 |
|
13 |
import org.eclipse.jface.action.Action; |
14 |
import org.eclipse.jface.action.GroupMarker; |
15 |
import org.eclipse.jface.action.IAction; |
16 |
import org.eclipse.jface.action.IMenuManager; |
17 |
import org.eclipse.jface.action.MenuManager; |
18 |
import org.eclipse.jface.resource.ImageDescriptor; |
19 |
import org.eclipse.jface.util.Geometry; |
20 |
import org.eclipse.swt.SWT; |
21 |
import org.eclipse.swt.events.SelectionAdapter; |
22 |
import org.eclipse.swt.events.SelectionEvent; |
23 |
import org.eclipse.swt.events.ShellAdapter; |
24 |
import org.eclipse.swt.events.ShellEvent; |
25 |
import org.eclipse.swt.graphics.Color; |
26 |
import org.eclipse.swt.graphics.Image; |
27 |
import org.eclipse.swt.graphics.Point; |
28 |
import org.eclipse.swt.graphics.Rectangle; |
29 |
import org.eclipse.swt.layout.GridData; |
30 |
import org.eclipse.swt.layout.GridLayout; |
31 |
import org.eclipse.swt.widgets.Composite; |
32 |
import org.eclipse.swt.widgets.Display; |
33 |
import org.eclipse.swt.widgets.Event; |
34 |
import org.eclipse.swt.widgets.Label; |
35 |
import org.eclipse.swt.widgets.Listener; |
36 |
import org.eclipse.swt.widgets.Menu; |
37 |
import org.eclipse.swt.widgets.Monitor; |
38 |
import org.eclipse.swt.widgets.Shell; |
39 |
import org.eclipse.swt.widgets.ToolBar; |
40 |
import org.eclipse.swt.widgets.ToolItem; |
41 |
import org.eclipse.swt.widgets.Tracker; |
42 |
|
43 |
/** |
44 |
* The <code>PopupDialog</code> is a generic and customizable dialog comprised |
45 |
* of three components: a header, the dialog's content and a footer. The |
46 |
* following properties can be set for this dialog: |
47 |
* |
48 |
* <ul> |
49 |
* |
50 |
* <li>Background and Border color: default color is the widget color.</li> |
51 |
* <li>Shell style: default style for the shell is SWT.NO_TRIM.</li> |
52 |
* <li>Footer component: If the <code>hasFooter</code> flag is set, the pop |
53 |
* up dialog will contain a footer component. To fill the footer's content, |
54 |
* override <code>createFooterContent(Composite)</code>.</li> |
55 |
* <li>Header component: If the <code>hasHeader</code> flag is set, the pop |
56 |
* up dialog will contain a header component. To fill the header's content, |
57 |
* override <code>createHeaderContent(Composite)</code>.</li> |
58 |
* <li>Move property: Specify if the pop up dialog should be moveable. If the |
59 |
* <code>isMoveable</code> property is set, a pull down menu with a move |
60 |
* action will be added to the dialog. You can also set the standard move |
61 |
* capability by setting the appropriate shell style.</li> |
62 |
* <li>Resize property: Specify if the pop up dialog should be resizable. If |
63 |
* the <code>isResizable</code> property is set, a pull down menu with a |
64 |
* resize action will be added to the dialog. You can also set the standard |
65 |
* resize capability by setting the appropriate shell style (i.e: SWT.RESIZE). |
66 |
* </li> |
67 |
* <li>Allow the user to remember the bounds: Setting this property will add an |
68 |
* action item to the pull down menu that will allow the user to select whether |
69 |
* he/she wants to remember the dialog's bounds if they have changed.</li> |
70 |
* <li>Remember the bounds of the dialog: Set whether the dialog should |
71 |
* remember its bounds after it is closed. The location of the dialog is |
72 |
* remembered relative to its parent, or relative to the display if no parent is |
73 |
* set.</li> |
74 |
* <li>Remember the properties of the dialog: Set whether the dialog should |
75 |
* remember its properties (color, style, parent) on close.</li> |
76 |
* <li>Dialog location: If the pop up dialog's parent component is set, |
77 |
* pre-defined locations (relative to the parent) can be set: TOP, BOTTOM, |
78 |
* RIGHT, LEFT, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT. If no location |
79 |
* is set, the dialog will be positioned at the center of its parent, or at the |
80 |
* center of the display if no parent is set.</li> |
81 |
* <li>Dialog size: If the pop up dialog's size is not set, the default size |
82 |
* will be computed using <code>SWT.DEFAULT</code>.</li> |
83 |
* <li>Dialog content: To specify the dialog's content, override |
84 |
* <code>createDialogContent(Composite)</code>.</li> |
85 |
* <li>closeCondition: The dialog's close condition can be set to |
86 |
* <code>closeDialogOnDeactivation</code>. If no close condition set, the |
87 |
* default is for the pop up dialog to close when its <code>close()</code> |
88 |
* method is called.</li> |
89 |
* </ul> |
90 |
* |
91 |
* The default behavior for the pop up dialog is to contain no header and no |
92 |
* footer, with widget colors for border and background, SWT.NO_TRIM as the |
93 |
* shell style and no resize or moving capabilities. |
94 |
* |
95 |
*/ |
96 |
public class PopupDialog { |
97 |
/** |
98 |
* Move action for the dialog. |
99 |
*/ |
100 |
private class MoveAction extends Action { |
101 |
|
102 |
MoveAction() { |
103 |
super("Move", IAction.AS_PUSH_BUTTON); //$NON-NLS-1$ |
104 |
} |
105 |
|
106 |
/* |
107 |
* (non-Javadoc) |
108 |
* |
109 |
* @see org.eclipse.jface.action.IAction#run() |
110 |
*/ |
111 |
public void run() { |
112 |
performTrackerAction(SWT.NONE); |
113 |
} |
114 |
|
115 |
} |
116 |
|
117 |
/** |
118 |
* |
119 |
* Remember bounds action for the dialog. |
120 |
*/ |
121 |
private class RememberBoundsAction extends Action { |
122 |
|
123 |
RememberBoundsAction() { |
124 |
super("Remember bounds", IAction.AS_CHECK_BOX); //$NON-NLS-1$ |
125 |
setChecked(rememberDialogBounds); |
126 |
} |
127 |
|
128 |
/* |
129 |
* (non-Javadoc) |
130 |
* |
131 |
* @see org.eclipse.jface.action.IAction#run() |
132 |
*/ |
133 |
public void run() { |
134 |
rememberDialogBounds = isChecked(); |
135 |
} |
136 |
} |
137 |
|
138 |
/** |
139 |
* |
140 |
* Resize action for the dialog. |
141 |
*/ |
142 |
private class ResizeAction extends Action { |
143 |
|
144 |
ResizeAction() { |
145 |
super("Resize", IAction.AS_PUSH_BUTTON); //$NON-NLS-1$ |
146 |
} |
147 |
|
148 |
/* |
149 |
* @see org.eclipse.jface.action.Action#run() |
150 |
*/ |
151 |
public void run() { |
152 |
performTrackerAction(SWT.RESIZE); |
153 |
} |
154 |
} |
155 |
|
156 |
/** |
157 |
* At the top (middle) of the parent shell. |
158 |
*/ |
159 |
final public static int TOP = 0; |
160 |
|
161 |
/** |
162 |
* At the bottom (middle) of the parent shell. |
163 |
*/ |
164 |
final public static int BOTTOM = 1; |
165 |
|
166 |
/** |
167 |
* At the right (middle) of the parent shell. |
168 |
*/ |
169 |
final public static int RIGHT = 2; |
170 |
|
171 |
/** |
172 |
* At the left (middle) of the parent shell. |
173 |
*/ |
174 |
final public static int LEFT = 3; |
175 |
|
176 |
/** |
177 |
* At the top left of the parent shell. |
178 |
*/ |
179 |
final public static int TOP_LEFT = 4; |
180 |
|
181 |
/** |
182 |
* At the top right of the parent shell. |
183 |
*/ |
184 |
final public static int TOP_RIGHT = 5; |
185 |
|
186 |
/** |
187 |
* At the bottom left of the parent shell. |
188 |
*/ |
189 |
final public static int BOTTOM_LEFT = 6; |
190 |
|
191 |
/** |
192 |
* At the bottom right of the parent shell. |
193 |
*/ |
194 |
final public static int BOTTOM_RIGHT = 7; |
195 |
|
196 |
// Margin height and width for locations |
197 |
private final int marginWidth = 5; |
198 |
|
199 |
private final int marginHeight = 5; |
200 |
|
201 |
/** |
202 |
* Close the dialong when it is de-activated. |
203 |
*/ |
204 |
public final static int closeDialogOnDeactivate = 0; |
205 |
|
206 |
/** |
207 |
* By default, the dialog has no closing condition. |
208 |
*/ |
209 |
private int closeCondition = -1; |
210 |
|
211 |
// Flag to remember the dialog properties (color, size, shell style) |
212 |
private boolean rememberDialogProperties = false; |
213 |
|
214 |
// Flag to remember the bounds of the dialog (size and location) |
215 |
private boolean rememberDialogBounds = false; |
216 |
|
217 |
// Background and border colors |
218 |
private Color backGroundColor = null; |
219 |
|
220 |
private Color borderColor = null; |
221 |
|
222 |
// Bounds of the dialog (location relative to the parent, or display if |
223 |
// parent is null) |
224 |
protected Point deltaLocation = null; |
225 |
|
226 |
// Current size for the dialog. |
227 |
protected Point currentSize = null; |
228 |
|
229 |
// The dialog's toolbar for the move and resize capabilities |
230 |
private ToolBar fToolBar = null; |
231 |
|
232 |
// The dialog's menu manager |
233 |
private MenuManager fViewMenuManager = null; |
234 |
|
235 |
// The menu's image |
236 |
private Image menuImage = null; |
237 |
|
238 |
// The dialog's shell |
239 |
private Shell dialogShell = null; |
240 |
|
241 |
// The dialog's parent shell |
242 |
private Shell parentShell = null; |
243 |
|
244 |
// The shell's style |
245 |
private int shellStyle = SWT.NO_TRIM; |
246 |
|
247 |
// Specify whether the dialog should be moveable |
248 |
private boolean isMoveable = false; |
249 |
|
250 |
// Specify whether the dialog should be resizable |
251 |
private boolean isResizable = false; |
252 |
|
253 |
// Specify whether the dialog should have a footer component |
254 |
private boolean hasFooter = false; |
255 |
|
256 |
// Specify whether the dialog should have a header component |
257 |
private boolean hasHeader = false; |
258 |
|
259 |
// Specify whether the dialog should allow the user to opt |
260 |
// to remember the dialog's bounds |
261 |
private boolean showRememberBounds = false; |
262 |
|
263 |
/** |
264 |
* Constructs a new instance of <code>PopupInformationDialog</code>. When |
265 |
* the dialog is first constructed, it contains no widgets. |
266 |
* |
267 |
* @param parent |
268 |
* The parent shell (could be null). |
269 |
*/ |
270 |
public PopupDialog(Shell parent) { |
271 |
parentShell = parent; |
272 |
} |
273 |
|
274 |
/** |
275 |
* Constructs a new instance of <code>PopupInformationDialog</code>. When |
276 |
* the dialog is first constructed, it contains no widgets. |
277 |
* |
278 |
* @param parent |
279 |
* The parent shell. Or null to create a top level shell. |
280 |
* @param shellStyle |
281 |
* The shell style. |
282 |
*/ |
283 |
public PopupDialog(Shell parent, int shellStyle) { |
284 |
this.shellStyle = shellStyle; |
285 |
parentShell = parent; |
286 |
} |
287 |
|
288 |
/** |
289 |
* Constructs a new instance of <code>PopupInformationDialog</code>. When |
290 |
* the dialog is first constructed, it contains no widgets. |
291 |
* |
292 |
* @param parent |
293 |
* The parent shell. |
294 |
* @param shellStyle |
295 |
* The shell style. |
296 |
* @param backGroundColor |
297 |
* The background color. |
298 |
* @param borderColor |
299 |
* The border color. |
300 |
*/ |
301 |
public PopupDialog(Shell parent, int shellStyle, Color backGroundColor, |
302 |
Color borderColor) { |
303 |
this.shellStyle = shellStyle; |
304 |
parentShell = parent; |
305 |
this.backGroundColor = backGroundColor; |
306 |
this.borderColor = borderColor; |
307 |
} |
308 |
|
309 |
/** |
310 |
* Constructs a new instance of <code>PopupInformationDialog</code>. When |
311 |
* the dialog is first constructed, it contains no widgets. |
312 |
* |
313 |
* @param parent |
314 |
* The parent shell. |
315 |
* @param shellStyle |
316 |
* The shell style. |
317 |
* @param isMoveable |
318 |
* The move property of the dialog. |
319 |
* @param isResizable |
320 |
* The resizable property of the dialog. |
321 |
* @param hasFooter |
322 |
* Specify footer component for the dialog. |
323 |
* @param hasHeader |
324 |
* Specify header component for the dialog. |
325 |
* @param showRememberBounds |
326 |
* Show the remember bounds menu item. |
327 |
* @param backGroundColor |
328 |
* Specify the background color for the dialog. |
329 |
* @param borderColor |
330 |
* Specify the border color for the dialog. |
331 |
*/ |
332 |
public PopupDialog(Shell parent, int shellStyle, boolean isMoveable, |
333 |
boolean isResizable, boolean hasFooter, boolean hasHeader, |
334 |
boolean showRememberBounds, Color backGroundColor, Color borderColor) { |
335 |
this.shellStyle = shellStyle; |
336 |
this.parentShell = parent; |
337 |
this.isMoveable = isMoveable; |
338 |
this.isResizable = isResizable; |
339 |
this.hasFooter = hasFooter; |
340 |
this.hasHeader = hasHeader; |
341 |
this.backGroundColor = backGroundColor; |
342 |
this.borderColor = borderColor; |
343 |
this.showRememberBounds = showRememberBounds; |
344 |
} |
345 |
|
346 |
/** |
347 |
* Close the dialog. |
348 |
* |
349 |
*/ |
350 |
public void close() { |
351 |
close(rememberDialogProperties); |
352 |
} |
353 |
|
354 |
/** |
355 |
* Close the dialog and specify if the current dialog properties should be |
356 |
* remembered. |
357 |
* |
358 |
* @param rememberDialogProperties |
359 |
* Remember the dialog properties (colors, move/resize |
360 |
* properties, shell style). |
361 |
*/ |
362 |
public void close(final boolean rememberDialogProperties) { |
363 |
this.rememberDialogProperties = rememberDialogProperties; |
364 |
|
365 |
// Persist the bounds |
366 |
if (rememberDialogBounds) { |
367 |
currentSize = dialogShell.getSize(); |
368 |
deltaLocation = getDeltaLocation(dialogShell.getLocation()); |
369 |
} else { |
370 |
deltaLocation = null; |
371 |
currentSize = null; |
372 |
} |
373 |
|
374 |
// Reset style, colors... |
375 |
if (!rememberDialogProperties) { |
376 |
resetDialogSettings(); |
377 |
} |
378 |
|
379 |
// Clean up variables |
380 |
menuImage.dispose(); |
381 |
menuImage = null; |
382 |
fToolBar = null; |
383 |
fViewMenuManager = null; |
384 |
|
385 |
// dispose |
386 |
dialogShell.dispose(); |
387 |
dialogShell = null; |
388 |
} |
389 |
|
390 |
/** |
391 |
* Uses the Window's default location computation. Overrite to perform |
392 |
* specific location calculations. |
393 |
*/ |
394 |
protected Point computeLocation(Point size) { |
395 |
|
396 |
// If the location has not been set, compute default |
397 |
if (deltaLocation == null) { |
398 |
return getDefaultLocation(size); |
399 |
} |
400 |
|
401 |
Display display = dialogShell.getDisplay(); |
402 |
// getParentShell() could be null |
403 |
return display.map(parentShell, null, deltaLocation); |
404 |
|
405 |
} |
406 |
|
407 |
/** |
408 |
* Compute the size of the dialog. |
409 |
* |
410 |
* @return the size of the dialog. |
411 |
*/ |
412 |
protected Point computeSize() { |
413 |
if (currentSize == null) { |
414 |
return dialogShell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); |
415 |
} |
416 |
return currentSize; |
417 |
|
418 |
} |
419 |
|
420 |
/** |
421 |
* Create the dialog's content. |
422 |
* |
423 |
*/ |
424 |
protected void createContents() { |
425 |
menuImage = ImageDescriptor.createFromFile(PopupDialog.class, |
426 |
"images/view_menu.gif").createImage();//$NON-NLS-1$ |
427 |
|
428 |
// Create a border around the outside of the shell. |
429 |
dialogShell.setBackground(borderColor); |
430 |
final GridLayout shellLayout = new GridLayout(1, false); |
431 |
shellLayout.marginHeight = 1; |
432 |
shellLayout.marginWidth = 1; |
433 |
dialogShell.setLayout(shellLayout); |
434 |
|
435 |
// To handle closing of shell for example |
436 |
setCloseCondition(); |
437 |
|
438 |
// Create the top-level composite for the dialog |
439 |
final Composite contents = new Composite(dialogShell, SWT.NONE); |
440 |
contents.setBackground(backGroundColor); |
441 |
|
442 |
GridLayout layout = new GridLayout(); |
443 |
layout.marginHeight = 1; |
444 |
layout.marginWidth = 1; |
445 |
contents.setLayout(layout); |
446 |
contents.setLayoutData(new GridData(GridData.FILL_BOTH)); |
447 |
|
448 |
// Create the header area |
449 |
createHeaderArea(contents); |
450 |
|
451 |
// Create the dialog content of the pop up |
452 |
createDialogArea(contents); |
453 |
|
454 |
if (hasFooter) { |
455 |
// Create the footer content of the pop up |
456 |
createFooterArea(contents); |
457 |
} |
458 |
|
459 |
} |
460 |
|
461 |
/** |
462 |
* Create the dialog area. |
463 |
* |
464 |
* @param parent |
465 |
* The parent composite. |
466 |
*/ |
467 |
protected void createDialogArea(Composite parent) { |
468 |
// Create a composite for the dialog area. |
469 |
final Composite composite = new Composite(parent, SWT.NONE); |
470 |
final GridLayout compositeLayout = new GridLayout(); |
471 |
compositeLayout.marginHeight = 0; |
472 |
compositeLayout.marginWidth = 0; |
473 |
composite.setLayout(compositeLayout); |
474 |
composite.setLayoutData(new GridData(GridData.FILL_BOTH)); |
475 |
composite.setBackground(parent.getBackground()); |
476 |
// Fill in top part |
477 |
createDialogContent(parent); |
478 |
} |
479 |
|
480 |
/** |
481 |
* Create the dialog's content. This method should be overriden to fill the |
482 |
* dialog's content. The default implementation does not create anything. |
483 |
* |
484 |
* @param parent |
485 |
* The parent composite. |
486 |
* |
487 |
*/ |
488 |
protected void createDialogContent(Composite parent) { |
489 |
// default implementation does nothing |
490 |
} |
491 |
|
492 |
/** |
493 |
* Create the dialog's menu for the resize, move and remember bounds |
494 |
* actions. |
495 |
* |
496 |
* @param parent |
497 |
* The parent composite. |
498 |
*/ |
499 |
private void createDialogMenu(Composite parent) { |
500 |
|
501 |
fToolBar = new ToolBar(parent, SWT.FLAT); |
502 |
ToolItem viewMenuButton = new ToolItem(fToolBar, SWT.PUSH, 0); |
503 |
|
504 |
fToolBar.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END |
505 |
| GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL)); |
506 |
fToolBar.setBackground(parent.getBackground()); |
507 |
|
508 |
viewMenuButton.setImage(menuImage); |
509 |
viewMenuButton.setToolTipText("Menu"); //$NON-NLS-1$ |
510 |
viewMenuButton.addSelectionListener(new SelectionAdapter() { |
511 |
public void widgetSelected(SelectionEvent e) { |
512 |
showDialogMenu(); |
513 |
} |
514 |
}); |
515 |
} |
516 |
|
517 |
/** |
518 |
* Creates the footer area for the dialog. |
519 |
*/ |
520 |
protected void createFooterArea(Composite parent) { |
521 |
final Composite composite = new Composite(parent, SWT.NONE); |
522 |
composite.setLayout(new GridLayout()); |
523 |
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
524 |
composite.setBackground(parent.getBackground()); |
525 |
createSeparator(parent); |
526 |
|
527 |
// Fill in bottom part |
528 |
createFooterContent(parent); |
529 |
} |
530 |
|
531 |
/** |
532 |
* Creates the footer content of the pop up dialog if the |
533 |
* <code>hasFooter</code> flag is set to true. Default implementation does |
534 |
* nothing. Override this method to specify the content of the footer |
535 |
* component. |
536 |
* |
537 |
* @param parent |
538 |
* The parent composite. |
539 |
*/ |
540 |
protected void createFooterContent(Composite parent) { |
541 |
// default implementation does nothing |
542 |
|
543 |
} |
544 |
|
545 |
/** |
546 |
* Create the header aread for the dialog. |
547 |
* |
548 |
* @param parent |
549 |
* The parent composite. |
550 |
*/ |
551 |
protected void createHeaderArea(final Composite parent) { |
552 |
boolean hasMenu = isResizable || isMoveable; |
553 |
if (!hasHeader && !(hasMenu)) { |
554 |
// If the dialog does not have a header and the menu, don't create |
555 |
// anything |
556 |
return; |
557 |
} |
558 |
|
559 |
int numColumns = 1; |
560 |
if (hasHeader) { |
561 |
numColumns = 2; |
562 |
} |
563 |
|
564 |
Composite headerComposite = new Composite(parent, SWT.NONE); |
565 |
headerComposite.setBackground(parent.getBackground()); |
566 |
GridLayout layout = new GridLayout(numColumns, false); |
567 |
layout.marginHeight = 0; |
568 |
layout.marginWidth = 0; |
569 |
headerComposite.setLayout(layout); |
570 |
headerComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
571 |
|
572 |
if (hasHeader) { |
573 |
// Should be overwritten - does nothing |
574 |
createHeaderContent(headerComposite); |
575 |
} |
576 |
if (hasMenu) { |
577 |
createDialogMenu(headerComposite); |
578 |
} |
579 |
|
580 |
createSeparator(parent); |
581 |
} |
582 |
|
583 |
/** |
584 |
* Creates the header content of the pop up dialog if the |
585 |
* <code>hasHeader</code> flag is set to true. Default implementation does |
586 |
* nothing. Override this method to specify the content of the header |
587 |
* component. |
588 |
* |
589 |
* @param parent |
590 |
* The parent composite. |
591 |
*/ |
592 |
protected void createHeaderContent(Composite parent) { |
593 |
// default implementation does nothing |
594 |
} |
595 |
|
596 |
/** |
597 |
* Create the separator. |
598 |
* |
599 |
* @param parent |
600 |
* The parent composite. |
601 |
*/ |
602 |
private void createSeparator(Composite parent) { |
603 |
Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL |
604 |
| SWT.LINE_DOT); |
605 |
separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
606 |
} |
607 |
|
608 |
/** |
609 |
* Create the shell for the dialog. |
610 |
* |
611 |
*/ |
612 |
protected void createShell() { |
613 |
// Create the shell |
614 |
dialogShell = new Shell(parentShell, shellStyle); |
615 |
|
616 |
// To handle "ESC" case |
617 |
dialogShell.addShellListener(new ShellAdapter() { |
618 |
public void shellClosed(ShellEvent event) { |
619 |
event.doit = false; // don't close now |
620 |
close(); |
621 |
} |
622 |
}); |
623 |
|
624 |
GridLayout layout = new GridLayout(); |
625 |
layout.marginHeight = 0; |
626 |
layout.marginWidth = 0; |
627 |
dialogShell.setLayout(layout); |
628 |
|
629 |
} |
630 |
|
631 |
/** |
632 |
* Fill the dialog's menu. |
633 |
* |
634 |
* @param dialogMenu |
635 |
* The dialog's menu. |
636 |
*/ |
637 |
protected void fillDialogMenu(IMenuManager dialogMenu) { |
638 |
dialogMenu.add(new GroupMarker("SystemMenuStart")); //$NON-NLS-1$ |
639 |
if (isMoveable) { |
640 |
dialogMenu.add(new MoveAction()); |
641 |
} |
642 |
if (isResizable) { |
643 |
dialogMenu.add(new ResizeAction()); |
644 |
} |
645 |
|
646 |
if (showRememberBounds) { |
647 |
dialogMenu.add(new RememberBoundsAction()); |
648 |
} |
649 |
} |
650 |
|
651 |
/** |
652 |
* Get the bottom Y coordinate. |
653 |
* |
654 |
* @param parentLocation |
655 |
* The parent location. |
656 |
* @param parentSize |
657 |
* The parent's size. |
658 |
* @return the bottom Y coordinate. |
659 |
*/ |
660 |
private int getBottomYCoordinate(Point parentLocation, Point parentSize) { |
661 |
return parentLocation.y + parentSize.y + marginHeight; |
662 |
} |
663 |
|
664 |
/** |
665 |
* Return the computed location. |
666 |
* |
667 |
* @param locationType |
668 |
* The location type. |
669 |
* @param newSize |
670 |
* The dialog's size. |
671 |
* @return the new dialog's location. |
672 |
*/ |
673 |
private Point getComputedLocation(int locationType, Point newSize) { |
674 |
Point parentLocation = parentShell.getLocation(); |
675 |
Point parentSize = parentShell.getSize(); |
676 |
Point newLocation = null; |
677 |
switch (locationType) { |
678 |
// TOP |
679 |
case 0: |
680 |
newLocation = new Point(getMiddleXCoordinate(parentLocation, |
681 |
parentSize, newSize), getTopYCoordinate(newSize, |
682 |
parentLocation)); |
683 |
|
684 |
break; |
685 |
// BOTTOM |
686 |
case 1: |
687 |
newLocation = new Point(getMiddleXCoordinate(parentLocation, |
688 |
parentSize, newSize), getBottomYCoordinate(parentLocation, |
689 |
parentSize)); |
690 |
break; |
691 |
// RIGHT |
692 |
case 2: |
693 |
newLocation = new Point(getRightXCoordinate(parentLocation, |
694 |
parentSize), getMiddleYCoordinate(newSize, parentLocation, |
695 |
parentSize)); |
696 |
break; |
697 |
// LEFT |
698 |
case 3: |
699 |
newLocation = new Point( |
700 |
getLeftXCoordinate(newSize, parentLocation), |
701 |
getMiddleYCoordinate(newSize, parentLocation, parentSize)); |
702 |
break; |
703 |
// TOP_LEFT |
704 |
case 4: |
705 |
newLocation = new Point( |
706 |
getLeftXCoordinate(newSize, parentLocation), |
707 |
getTopYCoordinate(newSize, parentLocation)); |
708 |
break; |
709 |
// TOP_RIGHT |
710 |
case 5: |
711 |
newLocation = new Point(getRightXCoordinate(parentLocation, |
712 |
parentSize), getTopYCoordinate(newSize, parentLocation)); |
713 |
break; |
714 |
// BOTTOM_LEFT |
715 |
case 6: |
716 |
newLocation = new Point( |
717 |
getLeftXCoordinate(newSize, parentLocation), |
718 |
getBottomYCoordinate(parentLocation, parentSize)); |
719 |
break; |
720 |
// BOTTOM_RIGHT |
721 |
case 7: |
722 |
newLocation = new Point(getRightXCoordinate(parentLocation, |
723 |
parentSize), getBottomYCoordinate(parentLocation, |
724 |
parentSize)); |
725 |
break; |
726 |
|
727 |
} |
728 |
return newLocation; |
729 |
} |
730 |
|
731 |
/** |
732 |
* Default location compuation. The default location positions the dialog at |
733 |
* the center of its parent, or at the center of the display if the parent |
734 |
* has not been set. |
735 |
* |
736 |
* @param initialSize |
737 |
* The dialog's size. |
738 |
* @return default location. |
739 |
*/ |
740 |
protected Point getDefaultLocation(Point initialSize) { |
741 |
Monitor monitor = dialogShell.getDisplay().getPrimaryMonitor(); |
742 |
if (parentShell != null) { |
743 |
monitor = parentShell.getMonitor(); |
744 |
} |
745 |
|
746 |
Rectangle monitorBounds = monitor.getClientArea(); |
747 |
Point centerPoint; |
748 |
if (parentShell != null) { |
749 |
centerPoint = Geometry.centerPoint(parentShell.getBounds()); |
750 |
} else { |
751 |
centerPoint = Geometry.centerPoint(monitorBounds); |
752 |
} |
753 |
|
754 |
return new Point(centerPoint.x - (initialSize.x / 2), Math.max( |
755 |
monitorBounds.y, Math.min(centerPoint.y |
756 |
- (initialSize.y * 2 / 3), monitorBounds.y |
757 |
+ monitorBounds.height - initialSize.y))); |
758 |
} |
759 |
|
760 |
/** |
761 |
* Return the location relative to the parent (or the display if parent is |
762 |
* null). |
763 |
* |
764 |
* @param childLocation |
765 |
* The child's location. |
766 |
* @return the location relative to the parent's location. |
767 |
*/ |
768 |
private Point getDeltaLocation(Point childLocation) { |
769 |
Display display = null; |
770 |
if (dialogShell != null) { |
771 |
display = dialogShell.getDisplay(); |
772 |
} else { |
773 |
display = Display.getDefault(); |
774 |
} |
775 |
// parentShell could be null |
776 |
return display.map(null, parentShell, childLocation); |
777 |
} |
778 |
|
779 |
/** |
780 |
* Get the left X coordinate. |
781 |
* |
782 |
* @param newSize |
783 |
* The new size. |
784 |
* @param parentLocation |
785 |
* The parent location. |
786 |
* @return the left X coordinate. |
787 |
*/ |
788 |
private int getLeftXCoordinate(Point newSize, Point parentLocation) { |
789 |
return (parentLocation.x - newSize.x) - marginWidth; |
790 |
} |
791 |
|
792 |
/** |
793 |
* Get the middle X coordinate. |
794 |
* |
795 |
* @param parentLocation |
796 |
* The parent location. |
797 |
* @param parentSize |
798 |
* The parent size. |
799 |
* @param childSize |
800 |
* The child size. |
801 |
* @return the middle X coordinate. |
802 |
*/ |
803 |
private int getMiddleXCoordinate(Point parentLocation, Point parentSize, |
804 |
Point childSize) { |
805 |
return parentLocation.x + parentSize.x / 2 - childSize.x / 2; |
806 |
} |
807 |
|
808 |
/** |
809 |
* Get the middle Y coordinate. |
810 |
* |
811 |
* @param newSize |
812 |
* The new size. |
813 |
* @param parentLocation |
814 |
* The parent location. |
815 |
* @param parentSize |
816 |
* The parent's size. |
817 |
* @return the middle Y coordinate. |
818 |
*/ |
819 |
private int getMiddleYCoordinate(Point newSize, Point parentLocation, |
820 |
Point parentSize) { |
821 |
return parentLocation.y + parentSize.y / 2 - newSize.y / 2; |
822 |
} |
823 |
|
824 |
/** |
825 |
* Get the right X coordinate. |
826 |
* |
827 |
* @param parentLocation |
828 |
* The parent location. |
829 |
* @param parentSize |
830 |
* The parent's size. |
831 |
* @return the right X coordinate. |
832 |
*/ |
833 |
private int getRightXCoordinate(Point parentLocation, Point parentSize) { |
834 |
return parentLocation.x + parentSize.x + marginWidth; |
835 |
} |
836 |
|
837 |
/** |
838 |
* Get the top Y coordinate. |
839 |
* |
840 |
* @param size |
841 |
* The dialog's size. |
842 |
* @param parentLocation |
843 |
* The parent location. |
844 |
* @return the top Y coordinate. |
845 |
*/ |
846 |
private int getTopYCoordinate(Point size, Point parentLocation) { |
847 |
return parentLocation.y - size.y - marginHeight; |
848 |
} |
849 |
|
850 |
/** |
851 |
* Initialize the shell's bounds. |
852 |
* |
853 |
*/ |
854 |
protected void initializeBounds() { |
855 |
Point size = computeSize(); |
856 |
Point location = computeLocation(size); |
857 |
dialogShell.setBounds(new Rectangle(location.x, location.y, size.x, |
858 |
size.y)); |
859 |
} |
860 |
|
861 |
/** |
862 |
* Checks whether the dialog is open. |
863 |
* |
864 |
* @return returns true if the dialog is open, false otherwise. |
865 |
*/ |
866 |
public boolean isOpen() { |
867 |
return dialogShell != null; |
868 |
} |
869 |
|
870 |
/** |
871 |
* Open the pop up dialog. |
872 |
* |
873 |
*/ |
874 |
public void open() { |
875 |
// If the dialog is already open, dispose the shell and recreate it |
876 |
if (dialogShell != null) { |
877 |
close(); |
878 |
} |
879 |
|
880 |
// create shell |
881 |
createShell(); |
882 |
createContents(); |
883 |
initializeBounds(); |
884 |
|
885 |
// open the window |
886 |
dialogShell.open(); |
887 |
} |
888 |
|
889 |
/** |
890 |
* Perform the requested tracker action (resize or move). |
891 |
* |
892 |
* @param style |
893 |
* The track style (resize or move). |
894 |
*/ |
895 |
private void performTrackerAction(int style) { |
896 |
Tracker tracker = new Tracker(dialogShell.getDisplay(), style); |
897 |
tracker.setStippled(true); |
898 |
Rectangle[] r = new Rectangle[] { dialogShell.getBounds() }; |
899 |
tracker.setRectangles(r); |
900 |
|
901 |
if (tracker.open()) { |
902 |
dialogShell.setBounds(tracker.getRectangles()[0]); |
903 |
|
904 |
} |
905 |
} |
906 |
|
907 |
/** |
908 |
* Clear the shell settings. |
909 |
* |
910 |
*/ |
911 |
protected void resetDialogSettings() { |
912 |
// Reset values |
913 |
backGroundColor = null; |
914 |
borderColor = null; |
915 |
closeCondition = -1; |
916 |
rememberDialogProperties = false; |
917 |
shellStyle = SWT.NO_TRIM; |
918 |
isMoveable = true; |
919 |
isResizable = true; |
920 |
hasFooter = true; |
921 |
hasHeader = true; |
922 |
parentShell = null; |
923 |
showRememberBounds = false; |
924 |
} |
925 |
|
926 |
/** |
927 |
* Set the background color of the dialog. |
928 |
* |
929 |
* @param color |
930 |
* The color. |
931 |
*/ |
932 |
public void setBackGroundColor(Color color) { |
933 |
backGroundColor = color; |
934 |
} |
935 |
|
936 |
/** |
937 |
* Set the border color of the dialog. |
938 |
* |
939 |
* @param color |
940 |
* The color. |
941 |
*/ |
942 |
public void setBorderColor(Color color) { |
943 |
borderColor = color; |
944 |
} |
945 |
|
946 |
/** |
947 |
* Set the closing condition for the dialog. |
948 |
* |
949 |
*/ |
950 |
protected void setCloseCondition() { |
951 |
switch (closeCondition) { |
952 |
case closeDialogOnDeactivate: |
953 |
dialogShell.addListener(SWT.Deactivate, new Listener() { |
954 |
public void handleEvent(Event event) { |
955 |
dialogShell.removeListener(SWT.Deactivate, this); |
956 |
close(); |
957 |
} |
958 |
}); |
959 |
break; |
960 |
default: |
961 |
} |
962 |
|
963 |
} |
964 |
|
965 |
/** |
966 |
* Set the dialog's closing condition. |
967 |
* |
968 |
* @param closingStyle |
969 |
* The closing style. |
970 |
*/ |
971 |
public void setCloseCondition(int closingStyle) { |
972 |
this.closeCondition = closingStyle; |
973 |
} |
974 |
|
975 |
/** |
976 |
* Specify if the pop up dialog has a footer component. |
977 |
* |
978 |
* @param hasFooter |
979 |
* Footer component flag. |
980 |
*/ |
981 |
public void setHasFooter(boolean hasFooter) { |
982 |
this.hasFooter = hasFooter; |
983 |
} |
984 |
|
985 |
/** |
986 |
* Specifiy if the pop up dialog has a header component. |
987 |
* |
988 |
* @param hasHeader |
989 |
* Header component flag. |
990 |
*/ |
991 |
public void setHasHeader(boolean hasHeader) { |
992 |
this.hasHeader = hasHeader; |
993 |
} |
994 |
|
995 |
/** |
996 |
* Specify if the dialog is moveable. If the flag is set to true, a pull |
997 |
* down menu is added to the top right corner of the dialog to provide that |
998 |
* functionality. To allow the move functionality without having the pull |
999 |
* down menu, just specify the appropriate shell style. |
1000 |
* |
1001 |
* @param isMoveable |
1002 |
* Moveable flag. |
1003 |
*/ |
1004 |
public void setIsMoveable(boolean isMoveable) { |
1005 |
this.isMoveable = isMoveable; |
1006 |
} |
1007 |
|
1008 |
/** |
1009 |
* Specify if the dialog is resizable. If the flag is set to true, a pull |
1010 |
* down menu is added to the top right corner of the dialog to provide that |
1011 |
* functionality. To allow the resize functionality without having the pull |
1012 |
* down menu, just specify the appropriate shell style (i.e.: |
1013 |
* <code>setShellStyle(SWT.RESIZE)</code>). |
1014 |
* |
1015 |
* @param isResizable |
1016 |
* Resizable flag. |
1017 |
*/ |
1018 |
public void setIsResizable(boolean isResizable) { |
1019 |
this.isResizable = isResizable; |
1020 |
|
1021 |
} |
1022 |
|
1023 |
/** |
1024 |
* Set the diaog's location. |
1025 |
* |
1026 |
* @param x |
1027 |
* The width. |
1028 |
* @param y |
1029 |
* The height. |
1030 |
*/ |
1031 |
public void setLocation(int x, int y) { |
1032 |
// Store the location relative to its parent |
1033 |
deltaLocation = getDeltaLocation(new Point(x, y)); |
1034 |
} |
1035 |
|
1036 |
/** |
1037 |
* Set the location of the dialog. The location type is relative to the |
1038 |
* parent, hence, the parent shell cannot be null. |
1039 |
* |
1040 |
* @param locationType |
1041 |
* The location type. |
1042 |
* @param newSize |
1043 |
* The size of the dialog. |
1044 |
*/ |
1045 |
public void setLocation(int locationType, Point newSize) { |
1046 |
Point newLocation = getComputedLocation(locationType, newSize); |
1047 |
if (newLocation != null) { |
1048 |
deltaLocation = getDeltaLocation(newLocation); |
1049 |
this.currentSize = newSize; |
1050 |
} |
1051 |
|
1052 |
} |
1053 |
|
1054 |
/** |
1055 |
* Set the location. |
1056 |
* |
1057 |
* @param childLocation |
1058 |
* The child location. |
1059 |
*/ |
1060 |
public void setLocation(Point childLocation) { |
1061 |
// Store the location relative to its parent |
1062 |
deltaLocation = getDeltaLocation(childLocation); |
1063 |
} |
1064 |
|
1065 |
/** |
1066 |
* Specify if the pop up dialog should remember its bounds (size and |
1067 |
* location) on close. |
1068 |
* |
1069 |
* @param rememberBounds |
1070 |
* Remember bounds flag. |
1071 |
*/ |
1072 |
public void setRememberDialogBounds(boolean rememberBounds) { |
1073 |
this.rememberDialogBounds = rememberBounds; |
1074 |
} |
1075 |
|
1076 |
/** |
1077 |
* Specify if the pop up diaog should remember its properties (colors, shell |
1078 |
* style, closing style...) on close. |
1079 |
* |
1080 |
* @param rememberProperties |
1081 |
* Remember properties flag. |
1082 |
*/ |
1083 |
public void setRememberDialogProperties(boolean rememberProperties) { |
1084 |
this.rememberDialogProperties = rememberProperties; |
1085 |
} |
1086 |
|
1087 |
/** |
1088 |
* Set the shell's style. |
1089 |
* |
1090 |
* @param newShellStyle |
1091 |
* The shell style. |
1092 |
*/ |
1093 |
public void setShellStyle(int newShellStyle) { |
1094 |
this.shellStyle = newShellStyle; |
1095 |
} |
1096 |
|
1097 |
/** |
1098 |
* Set whether the dialog should allow the user to chose to save or discard |
1099 |
* the pop up's bounds through a menu item. |
1100 |
* |
1101 |
* @param showRememberBounds |
1102 |
* Flag to show the remember bounds menu item. |
1103 |
*/ |
1104 |
public void setShowRememberBounds(boolean showRememberBounds) { |
1105 |
this.showRememberBounds = showRememberBounds; |
1106 |
} |
1107 |
|
1108 |
/** |
1109 |
* Set the dialog's size. |
1110 |
* |
1111 |
* @param x |
1112 |
* The width. |
1113 |
* @param y |
1114 |
* The height. |
1115 |
*/ |
1116 |
public void setSize(int x, int y) { |
1117 |
if (currentSize == null) { |
1118 |
currentSize = new Point(x, y); |
1119 |
} else { |
1120 |
currentSize.x = x; |
1121 |
currentSize.y = y; |
1122 |
} |
1123 |
} |
1124 |
|
1125 |
/** |
1126 |
* Set the size of the dialog. |
1127 |
* |
1128 |
* @param point |
1129 |
* The dialog's size. |
1130 |
*/ |
1131 |
public void setSize(Point point) { |
1132 |
currentSize = point; |
1133 |
|
1134 |
} |
1135 |
|
1136 |
/** |
1137 |
* Show the dialog's menu. |
1138 |
* |
1139 |
*/ |
1140 |
private void showDialogMenu() { |
1141 |
fViewMenuManager = new MenuManager(); |
1142 |
fillDialogMenu(fViewMenuManager); |
1143 |
Menu aMenu = fViewMenuManager.createContextMenu(dialogShell); |
1144 |
Rectangle bounds = fToolBar.getBounds(); |
1145 |
Point topLeft = new Point(bounds.x, bounds.y + bounds.height); |
1146 |
topLeft = dialogShell.toDisplay(topLeft); |
1147 |
aMenu.setLocation(topLeft.x, topLeft.y); |
1148 |
aMenu.setVisible(true); |
1149 |
} |
1150 |
|
1151 |
} |