129
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2008 IBM Corporation and others.
|
|
3 * All rights reserved. This program and the accompanying materials
|
|
4 * are made available under the terms of the Eclipse Public License v1.0
|
|
5 * which accompanies this distribution, and is available at
|
|
6 * http://www.eclipse.org/legal/epl-v10.html
|
|
7 *
|
|
8 * Contributors:
|
|
9 * IBM Corporation - initial API and implementation
|
|
10 * Port to the D programming language:
|
|
11 * Frank Benoit <benoit@tionex.de>
|
|
12 *******************************************************************************/
|
|
13 module dwtx.jface.text.AbstractInformationControl;
|
|
14
|
|
15 import dwt.dwthelper.utils;
|
|
16
|
|
17
|
|
18
|
|
19
|
|
20 import dwt.DWT;
|
|
21 import dwt.events.DisposeListener;
|
|
22 import dwt.events.FocusEvent;
|
|
23 import dwt.events.FocusListener;
|
|
24 import dwt.events.MouseAdapter;
|
|
25 import dwt.events.MouseEvent;
|
|
26 import dwt.events.MouseMoveListener;
|
|
27 import dwt.events.PaintEvent;
|
|
28 import dwt.events.PaintListener;
|
|
29 import dwt.graphics.Color;
|
|
30 import dwt.graphics.Cursor;
|
|
31 import dwt.graphics.Font;
|
|
32 import dwt.graphics.FontData;
|
|
33 import dwt.graphics.GC;
|
|
34 import dwt.graphics.Point;
|
|
35 import dwt.graphics.Rectangle;
|
|
36 import dwt.layout.FillLayout;
|
|
37 import dwt.layout.GridData;
|
|
38 import dwt.layout.GridLayout;
|
|
39 import dwt.widgets.Canvas;
|
|
40 import dwt.widgets.Composite;
|
|
41 import dwt.widgets.Control;
|
|
42 import dwt.widgets.Display;
|
|
43 import dwt.widgets.Event;
|
|
44 import dwt.widgets.Label;
|
|
45 import dwt.widgets.Listener;
|
|
46 import dwt.widgets.Shell;
|
|
47 import dwt.widgets.Slider;
|
|
48 import dwt.widgets.ToolBar;
|
|
49 import dwtx.core.runtime.Assert;
|
|
50 import dwtx.core.runtime.ListenerList;
|
|
51 import dwtx.jface.action.ToolBarManager;
|
|
52 import dwtx.jface.resource.JFaceResources;
|
|
53 import dwtx.jface.util.Geometry;
|
|
54
|
|
55
|
|
56 /**
|
|
57 * An abstract information control that can show content inside a shell.
|
|
58 * The information control can be created in two styles:
|
|
59 * <ul>
|
|
60 * <li>non-resizable tooltip with optional status</li>
|
|
61 * <li>resizable tooltip with optional tool bar</li>
|
|
62 * </ul>
|
|
63 * Additionally it can present either a status line containing a status text or
|
|
64 * a toolbar containing toolbar buttons.
|
|
65 * <p>
|
|
66 * Subclasses must either override {@link IInformationControl#setInformation(String)}
|
|
67 * or implement {@link IInformationControlExtension2}.
|
|
68 * They should also extend {@link #computeTrim()} if they create a content area
|
|
69 * with additional trim (e.g. scrollbars) and override {@link #getInformationPresenterControlCreator()}.
|
|
70 * </p>
|
|
71 *
|
|
72 * @since 3.4
|
|
73 */
|
|
74 public abstract class AbstractInformationControl : IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension4, IInformationControlExtension5 {
|
|
75
|
|
76 /** The information control's shell. */
|
|
77 private final Shell fShell;
|
|
78 /** Composite containing the content created by subclasses. */
|
|
79 private final Composite fContentComposite;
|
|
80 /** Whether the information control is resizable. */
|
|
81 private final bool fResizable;
|
|
82
|
|
83 /** Composite containing the status line content or <code>null</code> if none. */
|
|
84 private Composite fStatusComposite;
|
|
85 /** Separator between content and status line or <code>null</code> if none. */
|
|
86 private Label fSeparator;
|
|
87 /** Label in the status line or <code>null</code> if none. */
|
|
88 private Label fStatusLabel;
|
|
89 /** The toolbar manager used by the toolbar or <code>null</code> if none. */
|
|
90 private final ToolBarManager fToolBarManager;
|
|
91 /** Status line toolbar or <code>null</code> if none. */
|
|
92 private ToolBar fToolBar;
|
|
93
|
|
94 /** Listener for shell activation and deactivation. */
|
|
95 private Listener fShellListener;
|
|
96 /** All focus listeners registered to this information control. */
|
|
97 private ListenerList fFocusListeners= new ListenerList(ListenerList.IDENTITY);
|
|
98
|
|
99 /** Size constraints, x is the maxWidth and y is the maxHeight, or <code>null</code> if not set. */
|
|
100 private Point fSizeConstraints;
|
|
101 /** The size of the resize handle if already set, -1 otherwise */
|
|
102 private int fResizeHandleSize;
|
|
103
|
|
104 /**
|
|
105 * Creates an abstract information control with the given shell as parent.
|
|
106 * The control will not be resizable and optionally show a status line with
|
|
107 * the given status field text.
|
|
108 * <p>
|
|
109 * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
|
|
110 * </p>
|
|
111 *
|
|
112 * @param parentShell the parent of this control's shell
|
|
113 * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
|
|
114 */
|
|
115 public AbstractInformationControl(Shell parentShell, String statusFieldText) {
|
|
116 this(parentShell, DWT.TOOL | DWT.ON_TOP, statusFieldText, null);
|
|
117 }
|
|
118
|
|
119 /**
|
|
120 * Creates an abstract information control with the given shell as parent.
|
|
121 * The control will be resizable and optionally show a tool bar managed by
|
|
122 * the given tool bar manager.
|
|
123 * <p>
|
|
124 * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
|
|
125 * </p>
|
|
126 *
|
|
127 * @param parentShell the parent of this control's shell
|
|
128 * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
|
|
129 */
|
|
130 public AbstractInformationControl(Shell parentShell, ToolBarManager toolBarManager) {
|
|
131 this(parentShell, DWT.TOOL | DWT.ON_TOP | DWT.RESIZE, null, toolBarManager);
|
|
132 }
|
|
133
|
|
134 /**
|
|
135 * Creates an abstract information control with the given shell as parent.
|
|
136 * <p>
|
|
137 * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
|
|
138 * </p>
|
|
139 *
|
|
140 * @param parentShell the parent of this control's shell
|
|
141 * @param isResizable <code>true</code> if the control should be resizable
|
|
142 */
|
|
143 public AbstractInformationControl(Shell parentShell, bool isResizable) {
|
|
144 this(parentShell, DWT.TOOL | DWT.ON_TOP | (isResizable ? DWT.RESIZE : 0), null, null);
|
|
145 }
|
|
146
|
|
147 /**
|
|
148 * Creates an abstract information control with the given shell as parent.
|
|
149 * The given shell style is used for the shell (NO_TRIM will be removed to make sure there's a border).
|
|
150 * <p>
|
|
151 * The control will optionally show either a status line or a tool bar.
|
|
152 * At most one of <code>toolBarManager</code> or <code>statusFieldText</code> can be non-null.
|
|
153 * </p>
|
|
154 * <p>
|
|
155 * <strong>Important:</strong>: Subclasses are required to call {@link #create()} at the end of their constructor.
|
|
156 * </p>
|
|
157 *
|
|
158 * @param parentShell the parent of this control's shell
|
|
159 * @param shellStyle style of this control's shell
|
|
160 * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
|
|
161 * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
|
|
162 *
|
|
163 * @deprecated clients should use one of the public constructors
|
|
164 */
|
|
165 AbstractInformationControl(Shell parentShell, int shellStyle, final String statusFieldText, final ToolBarManager toolBarManager) {
|
|
166 Assert.isTrue(statusFieldText is null || toolBarManager is null);
|
|
167 fResizeHandleSize= -1;
|
|
168 fToolBarManager= toolBarManager;
|
|
169
|
|
170 if ((shellStyle & DWT.NO_TRIM) !is 0)
|
|
171 shellStyle&= ~(DWT.NO_TRIM | DWT.SHELL_TRIM); // make sure we get the OS border but no other trims
|
|
172
|
|
173 fResizable= (shellStyle & DWT.RESIZE) !is 0; // on GTK, Shell removes DWT.RESIZE if DWT.ON_TOP is set
|
|
174 fShell= new Shell(parentShell, shellStyle);
|
|
175 Display display= fShell.getDisplay();
|
|
176 Color foreground= display.getSystemColor(DWT.COLOR_INFO_FOREGROUND);
|
|
177 Color background= display.getSystemColor(DWT.COLOR_INFO_BACKGROUND);
|
|
178 setColor(fShell, foreground, background);
|
|
179
|
|
180 GridLayout layout= new GridLayout(1, false);
|
|
181 layout.marginHeight= 0;
|
|
182 layout.marginWidth= 0;
|
|
183 layout.verticalSpacing= 0;
|
|
184 fShell.setLayout(layout);
|
|
185
|
|
186 fContentComposite= new Composite(fShell, DWT.NONE);
|
|
187 fContentComposite.setLayoutData(new GridData(DWT.FILL, DWT.FILL, true, true));
|
|
188 fContentComposite.setLayout(new FillLayout());
|
|
189 setColor(fContentComposite, foreground, background);
|
|
190
|
|
191 createStatusComposite(statusFieldText, toolBarManager, foreground, background);
|
|
192 }
|
|
193
|
|
194 private void createStatusComposite(final String statusFieldText, final ToolBarManager toolBarManager, Color foreground, Color background) {
|
|
195 if (toolBarManager is null && statusFieldText is null)
|
|
196 return;
|
|
197
|
|
198 fStatusComposite= new Composite(fShell, DWT.NONE);
|
|
199 GridData gridData= new GridData(DWT.FILL, DWT.BOTTOM, true, false);
|
|
200 fStatusComposite.setLayoutData(gridData);
|
|
201 GridLayout statusLayout= new GridLayout(1, false);
|
|
202 statusLayout.marginHeight= 0;
|
|
203 statusLayout.marginWidth= 0;
|
|
204 statusLayout.verticalSpacing= 1;
|
|
205 fStatusComposite.setLayout(statusLayout);
|
|
206
|
|
207 fSeparator= new Label(fStatusComposite, DWT.SEPARATOR | DWT.HORIZONTAL);
|
|
208 fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
|
209
|
|
210 if (statusFieldText !is null) {
|
|
211 createStatusLabel(statusFieldText, foreground, background);
|
|
212 } else {
|
|
213 createToolBar(toolBarManager);
|
|
214 }
|
|
215 }
|
|
216
|
|
217 private void createStatusLabel(final String statusFieldText, Color foreground, Color background) {
|
|
218 fStatusLabel= new Label(fStatusComposite, DWT.RIGHT);
|
|
219 fStatusLabel.setLayoutData(new GridData(DWT.FILL, DWT.CENTER, true, false));
|
|
220 fStatusLabel.setText(statusFieldText);
|
|
221
|
|
222 FontData[] fontDatas= JFaceResources.getDialogFont().getFontData();
|
|
223 for (int i= 0; i < fontDatas.length; i++) {
|
|
224 fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
|
|
225 }
|
|
226 fStatusLabel.setFont(new Font(fStatusLabel.getDisplay(), fontDatas));
|
|
227
|
|
228 fStatusLabel.setForeground(fStatusLabel.getDisplay().getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW));
|
|
229 fStatusLabel.setBackground(background);
|
|
230 setColor(fStatusComposite, foreground, background);
|
|
231 }
|
|
232
|
|
233 private void createToolBar(ToolBarManager toolBarManager) {
|
|
234 final Composite bars= new Composite(fStatusComposite, DWT.NONE);
|
|
235 bars.setLayoutData(new GridData(DWT.FILL, DWT.FILL, false, false));
|
|
236
|
|
237 GridLayout layout= new GridLayout(3, false);
|
|
238 layout.marginHeight= 0;
|
|
239 layout.marginWidth= 0;
|
|
240 layout.horizontalSpacing= 0;
|
|
241 layout.verticalSpacing= 0;
|
|
242 bars.setLayout(layout);
|
|
243
|
|
244 fToolBar= toolBarManager.createControl(bars);
|
|
245 GridData gd= new GridData(DWT.BEGINNING, DWT.BEGINNING, false, false);
|
|
246 fToolBar.setLayoutData(gd);
|
|
247
|
|
248 Composite spacer= new Composite(bars, DWT.NONE);
|
|
249 gd= new GridData(DWT.FILL, DWT.FILL, true, true);
|
|
250 gd.widthHint= 0;
|
|
251 gd.heightHint= 0;
|
|
252 spacer.setLayoutData(gd);
|
|
253
|
|
254 addMoveSupport(spacer);
|
|
255 addResizeSupportIfNecessary(bars);
|
|
256 }
|
|
257
|
|
258 private void addResizeSupportIfNecessary(final Composite bars) {
|
|
259 // XXX: workarounds for
|
|
260 // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=219139 : API to add resize grip / grow box in lower right corner of shell
|
|
261 // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=23980 : platform specific shell resize behavior
|
|
262 String platform= DWT.getPlatform();
|
|
263 final bool isWin= platform.equals("win32"); //$NON-NLS-1$
|
|
264 if (!isWin && !platform.equals("gtk")) //$NON-NLS-1$
|
|
265 return;
|
|
266
|
|
267 final Canvas resizer= new Canvas(bars, DWT.NONE);
|
|
268
|
|
269 int size= getResizeHandleSize(bars);
|
|
270
|
|
271 GridData data= new GridData(DWT.END, DWT.END, false, true);
|
|
272 data.widthHint= size;
|
|
273 data.heightHint= size;
|
|
274 resizer.setLayoutData(data);
|
|
275 resizer.addPaintListener(new PaintListener() {
|
|
276 public void paintControl(PaintEvent e) {
|
|
277 Point s= resizer.getSize();
|
|
278 int x= s.x - 2;
|
|
279 int y= s.y - 2;
|
|
280 int min= Math.min(x, y);
|
|
281 if (isWin) {
|
|
282 // draw dots
|
|
283 e.gc.setBackground(resizer.getDisplay().getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
|
|
284 int end= min - 1;
|
|
285 for (int i= 0; i <= 2; i++)
|
|
286 for (int j= 0; j <= 2 - i; j++)
|
|
287 e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2);
|
|
288 end--;
|
|
289 e.gc.setBackground(resizer.getDisplay().getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW));
|
|
290 for (int i= 0; i <= 2; i++)
|
|
291 for (int j= 0; j <= 2 - i; j++)
|
|
292 e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2);
|
|
293
|
|
294 } else {
|
|
295 // draw diagonal lines
|
|
296 e.gc.setForeground(resizer.getDisplay().getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW));
|
|
297 for (int i= 1; i < min; i+= 4) {
|
|
298 e.gc.drawLine(i, y, x, i);
|
|
299 }
|
|
300 e.gc.setForeground(resizer.getDisplay().getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
|
|
301 for (int i= 2; i < min; i+= 4) {
|
|
302 e.gc.drawLine(i, y, x, i);
|
|
303 }
|
|
304 }
|
|
305 }
|
|
306 });
|
|
307
|
|
308 resizer.setCursor(new Cursor(resizer.getDisplay(), DWT.CURSOR_SIZESE));
|
|
309 MouseAdapter resizeSupport= new MouseAdapter() {
|
|
310 private MouseMoveListener fResizeListener;
|
|
311
|
|
312 public void mouseDown(MouseEvent e) {
|
|
313 Point shellSize= fShell.getSize();
|
|
314 final int shellX= shellSize.x;
|
|
315 final int shellY= shellSize.y;
|
|
316 Point mouseLoc= resizer.toDisplay(e.x, e.y);
|
|
317 final int mouseX= mouseLoc.x;
|
|
318 final int mouseY= mouseLoc.y;
|
|
319 fResizeListener= new MouseMoveListener() {
|
|
320 public void mouseMove(MouseEvent e2) {
|
|
321 Point mouseLoc2= resizer.toDisplay(e2.x, e2.y);
|
|
322 int dx= mouseLoc2.x - mouseX;
|
|
323 int dy= mouseLoc2.y - mouseY;
|
|
324 setSize(shellX + dx, shellY + dy);
|
|
325 }
|
|
326 };
|
|
327 resizer.addMouseMoveListener(fResizeListener);
|
|
328 }
|
|
329
|
|
330 public void mouseUp(MouseEvent e) {
|
|
331 resizer.removeMouseMoveListener(fResizeListener);
|
|
332 fResizeListener= null;
|
|
333 }
|
|
334 };
|
|
335 resizer.addMouseListener(resizeSupport);
|
|
336 }
|
|
337
|
|
338 private int getResizeHandleSize(Composite parent) {
|
|
339 if (fResizeHandleSize is -1) {
|
|
340 Slider sliderV= new Slider(parent, DWT.VERTICAL);
|
|
341 Slider sliderH= new Slider(parent, DWT.HORIZONTAL);
|
|
342 int width= sliderV.computeSize(DWT.DEFAULT, DWT.DEFAULT).x;
|
|
343 int height= sliderH.computeSize(DWT.DEFAULT, DWT.DEFAULT).y;
|
|
344 sliderV.dispose();
|
|
345 sliderH.dispose();
|
|
346 fResizeHandleSize= Math.min(width, height);
|
|
347 }
|
|
348
|
|
349 return fResizeHandleSize;
|
|
350 }
|
|
351
|
|
352 /**
|
|
353 * Adds support to move the shell by dragging the given control.
|
|
354 *
|
|
355 * @param control the control that can be used to move the shell
|
|
356 */
|
|
357 private void addMoveSupport(final Control control) {
|
|
358 MouseAdapter moveSupport= new MouseAdapter() {
|
|
359 private MouseMoveListener fMoveListener;
|
|
360
|
|
361 public void mouseDown(MouseEvent e) {
|
|
362 Point shellLoc= fShell.getLocation();
|
|
363 final int shellX= shellLoc.x;
|
|
364 final int shellY= shellLoc.y;
|
|
365 Point mouseLoc= control.toDisplay(e.x, e.y);
|
|
366 final int mouseX= mouseLoc.x;
|
|
367 final int mouseY= mouseLoc.y;
|
|
368 fMoveListener= new MouseMoveListener() {
|
|
369 public void mouseMove(MouseEvent e2) {
|
|
370 Point mouseLoc2= control.toDisplay(e2.x, e2.y);
|
|
371 int dx= mouseLoc2.x - mouseX;
|
|
372 int dy= mouseLoc2.y - mouseY;
|
|
373 fShell.setLocation(shellX + dx, shellY + dy);
|
|
374 }
|
|
375 };
|
|
376 control.addMouseMoveListener(fMoveListener);
|
|
377 }
|
|
378
|
|
379 public void mouseUp(MouseEvent e) {
|
|
380 control.removeMouseMoveListener(fMoveListener);
|
|
381 fMoveListener= null;
|
|
382 }
|
|
383 };
|
|
384 control.addMouseListener(moveSupport);
|
|
385 }
|
|
386
|
|
387 /**
|
|
388 * Utility to set the foreground and the background color of the given
|
|
389 * control
|
|
390 *
|
|
391 * @param control the control to modify
|
|
392 * @param foreground the color to use for the foreground
|
|
393 * @param background the color to use for the background
|
|
394 */
|
|
395 private static void setColor(Control control, Color foreground, Color background) {
|
|
396 control.setForeground(foreground);
|
|
397 control.setBackground(background);
|
|
398 }
|
|
399
|
|
400 /**
|
|
401 * The shell of the popup window.
|
|
402 *
|
|
403 * @return the shell used for the popup window
|
|
404 */
|
|
405 protected final Shell getShell() {
|
|
406 return fShell;
|
|
407 }
|
|
408
|
|
409 /**
|
|
410 * The toolbar manager used to manage the toolbar, or <code>null</code> if
|
|
411 * no toolbar is shown.
|
|
412 *
|
|
413 * @return the tool bar manager or <code>null</code>
|
|
414 */
|
|
415 protected final ToolBarManager getToolBarManager() {
|
|
416 return fToolBarManager;
|
|
417 }
|
|
418
|
|
419 /**
|
|
420 * Creates the content of this information control. Subclasses must call
|
|
421 * this method at the end of their constructor(s).
|
|
422 */
|
|
423 protected final void create() {
|
|
424 createContent(fContentComposite);
|
|
425 }
|
|
426
|
|
427 /**
|
|
428 * Creates the content of the popup window.
|
|
429 * <p>
|
|
430 * Implementors will usually take over {@link Composite#getBackground()} and
|
|
431 * {@link Composite#getForeground()} from <code>parent</code>.
|
|
432 * </p>
|
|
433 * <p>
|
|
434 * Implementors are expected to consider {@link #isResizable()}: If
|
|
435 * <code>true</code>, they should show scrollbars if their content may
|
|
436 * exceed the size of the information control. If <code>false</code>,
|
|
437 * they should never show scrollbars.
|
|
438 * </p>
|
|
439 * <p>
|
|
440 * The given <code>parent</code> comes with a {@link FillLayout}.
|
|
441 * Subclasses may set a different layout.
|
|
442 * </p>
|
|
443 *
|
|
444 * @param parent the container of the content
|
|
445 */
|
|
446 protected abstract void createContent(Composite parent);
|
|
447
|
|
448 /**
|
|
449 * Sets the information to be presented by this information control.
|
|
450 * <p>
|
|
451 * The default implementation does nothing. Subclasses must either override this method
|
|
452 * or implement {@link IInformationControlExtension2}.
|
|
453 *
|
|
454 * @param information the information to be presented
|
|
455 *
|
|
456 * @see dwtx.jface.text.IInformationControl#setInformation(java.lang.String)
|
|
457 */
|
|
458 public void setInformation(String information) {
|
|
459
|
|
460 }
|
|
461
|
|
462 /**
|
|
463 * Returns whether the information control is resizable.
|
|
464 *
|
|
465 * @return <code>true</code> if the information control is resizable,
|
|
466 * <code>false</code> if it is not resizable.
|
|
467 */
|
|
468 public bool isResizable() {
|
|
469 return fResizable;
|
|
470 }
|
|
471
|
|
472 /*
|
|
473 * @see IInformationControl#setVisible(bool)
|
|
474 */
|
|
475 public void setVisible(bool visible) {
|
|
476 if (fShell.isVisible() is visible)
|
|
477 return;
|
|
478
|
|
479 fShell.setVisible(visible);
|
|
480 }
|
|
481
|
|
482 /*
|
|
483 * @see IInformationControl#dispose()
|
|
484 */
|
|
485 public void dispose() {
|
|
486 if (fShell !is null && !fShell.isDisposed())
|
|
487 fShell.dispose();
|
|
488 }
|
|
489
|
|
490 /*
|
|
491 * @see IInformationControl#setSize(int, int)
|
|
492 */
|
|
493 public void setSize(int width, int height) {
|
|
494 fShell.setSize(width, height);
|
|
495 }
|
|
496
|
|
497 /*
|
|
498 * @see IInformationControl#setLocation(Point)
|
|
499 */
|
|
500 public void setLocation(Point location) {
|
|
501 fShell.setLocation(location);
|
|
502 }
|
|
503
|
|
504 /*
|
|
505 * @see IInformationControl#setSizeConstraints(int, int)
|
|
506 */
|
|
507 public void setSizeConstraints(int maxWidth, int maxHeight) {
|
|
508 fSizeConstraints= new Point(maxWidth, maxHeight);
|
|
509 }
|
|
510
|
|
511 /**
|
|
512 * Returns the size constraints.
|
|
513 *
|
|
514 * @return the size constraints or <code>null</code> if not set
|
|
515 * @see #setSizeConstraints(int, int)
|
|
516 */
|
|
517 protected final Point getSizeConstraints() {
|
|
518 return fSizeConstraints !is null ? Geometry.copy(fSizeConstraints) : null;
|
|
519 }
|
|
520
|
|
521 /*
|
|
522 * @see IInformationControl#computeSizeHint()
|
|
523 */
|
|
524 public Point computeSizeHint() {
|
|
525 // XXX: Verify whether this is a good default implementation. If yes, document it.
|
|
526 Point constrains= getSizeConstraints();
|
|
527 if (constrains is null)
|
|
528 return fShell.computeSize(DWT.DEFAULT, DWT.DEFAULT, true);
|
|
529
|
|
530 return fShell.computeSize(constrains.x, constrains.y, true);
|
|
531 }
|
|
532
|
|
533 /**
|
|
534 * Computes the trim (status text and tool bar are considered as trim).
|
|
535 * Subclasses can extend this method to add additional trim (e.g. scroll
|
|
536 * bars for resizable information controls).
|
|
537 *
|
|
538 * @see dwtx.jface.text.IInformationControlExtension3#computeTrim()
|
|
539 */
|
|
540 public Rectangle computeTrim() {
|
|
541 Rectangle trim= fShell.computeTrim(0, 0, 0, 0);
|
|
542
|
|
543 if (fStatusComposite !is null)
|
|
544 trim.height+= fStatusComposite.computeSize(DWT.DEFAULT, DWT.DEFAULT).y;
|
|
545
|
|
546 return trim;
|
|
547 }
|
|
548
|
|
549 /*
|
|
550 * @see dwtx.jface.text.IInformationControlExtension3#getBounds()
|
|
551 */
|
|
552 public Rectangle getBounds() {
|
|
553 return fShell.getBounds();
|
|
554 }
|
|
555
|
|
556 /**
|
|
557 * {@inheritDoc}
|
|
558 * <p>
|
|
559 * The default implementation always returns <code>false</code>.
|
|
560 * </p>
|
|
561 * @see dwtx.jface.text.IInformationControlExtension3#restoresLocation()
|
|
562 */
|
|
563 public bool restoresLocation() {
|
|
564 return false;
|
|
565 }
|
|
566
|
|
567 /**
|
|
568 * {@inheritDoc}
|
|
569 * <p>
|
|
570 * The default implementation always returns <code>false</code>.
|
|
571 * </p>
|
|
572 * @see dwtx.jface.text.IInformationControlExtension3#restoresSize()
|
|
573 */
|
|
574 public bool restoresSize() {
|
|
575 return false;
|
|
576 }
|
|
577
|
|
578 /*
|
|
579 * @see IInformationControl#addDisposeListener(DisposeListener)
|
|
580 */
|
|
581 public void addDisposeListener(DisposeListener listener) {
|
|
582 fShell.addDisposeListener(listener);
|
|
583 }
|
|
584
|
|
585 /*
|
|
586 * @see IInformationControl#removeDisposeListener(DisposeListener)
|
|
587 */
|
|
588 public void removeDisposeListener(DisposeListener listener) {
|
|
589 fShell.removeDisposeListener(listener);
|
|
590 }
|
|
591
|
|
592 /*
|
|
593 * @see IInformationControl#setForegroundColor(Color)
|
|
594 */
|
|
595 public void setForegroundColor(Color foreground) {
|
|
596 fContentComposite.setForeground(foreground);
|
|
597 }
|
|
598
|
|
599 /*
|
|
600 * @see IInformationControl#setBackgroundColor(Color)
|
|
601 */
|
|
602 public void setBackgroundColor(Color background) {
|
|
603 fContentComposite.setBackground(background);
|
|
604 }
|
|
605
|
|
606 /**
|
|
607 * {@inheritDoc}
|
|
608 * This method is not intended to be overridden by subclasses.
|
|
609 */
|
|
610 public bool isFocusControl() {
|
|
611 return fShell.getDisplay().getActiveShell() is fShell;
|
|
612 }
|
|
613
|
|
614 /**
|
|
615 * This default implementation sets the focus on the popup shell.
|
|
616 * Subclasses can override or extend.
|
|
617 *
|
|
618 * @see IInformationControl#setFocus()
|
|
619 */
|
|
620 public void setFocus() {
|
|
621 bool focusTaken= fShell.setFocus();
|
|
622 if (!focusTaken)
|
|
623 fShell.forceFocus();
|
|
624 }
|
|
625
|
|
626 /**
|
|
627 * {@inheritDoc}
|
|
628 * This method is not intended to be overridden by subclasses.
|
|
629 */
|
|
630 public void addFocusListener(final FocusListener listener) {
|
|
631 if (fFocusListeners.isEmpty()) {
|
|
632 fShellListener= new Listener() {
|
|
633
|
|
634 public void handleEvent(Event event) {
|
|
635 Object[] listeners= fFocusListeners.getListeners();
|
|
636 for (int i= 0; i < listeners.length; i++) {
|
|
637 FocusListener focusListener= (FocusListener)listeners[i];
|
|
638 if (event.type is DWT.Activate) {
|
|
639 focusListener.focusGained(new FocusEvent(event));
|
|
640 } else {
|
|
641 focusListener.focusLost(new FocusEvent(event));
|
|
642 }
|
|
643 }
|
|
644 }
|
|
645 };
|
|
646 fShell.addListener(DWT.Deactivate, fShellListener);
|
|
647 fShell.addListener(DWT.Activate, fShellListener);
|
|
648 }
|
|
649 fFocusListeners.add(listener);
|
|
650 }
|
|
651
|
|
652 /**
|
|
653 * {@inheritDoc}
|
|
654 * This method is not intended to be overridden by subclasses.
|
|
655 */
|
|
656 public void removeFocusListener(FocusListener listener) {
|
|
657 fFocusListeners.remove(listener);
|
|
658 if (fFocusListeners.isEmpty()) {
|
|
659 fShell.removeListener(DWT.Activate, fShellListener);
|
|
660 fShell.removeListener(DWT.Deactivate, fShellListener);
|
|
661 fShellListener= null;
|
|
662 }
|
|
663 }
|
|
664
|
|
665 /**
|
|
666 * Sets the text of the status field.
|
|
667 * <p>
|
|
668 * The default implementation currently only updates the status field when
|
|
669 * the popup shell is not visible. The status field can currently only be
|
|
670 * shown if the information control has been created with a non-null status
|
|
671 * field text.
|
|
672 * </p>
|
|
673 *
|
|
674 * @param statusFieldText the text to be used in the optional status field
|
|
675 * or <code>null</code> if the status field should be hidden
|
|
676 *
|
|
677 * @see dwtx.jface.text.IInformationControlExtension4#setStatusText(java.lang.String)
|
|
678 */
|
|
679 public void setStatusText(String statusFieldText) {
|
|
680 if (fStatusLabel !is null && ! getShell().isVisible()) {
|
|
681 if (statusFieldText is null ) {
|
|
682 fStatusComposite.setVisible(false);
|
|
683 } else {
|
|
684 fStatusLabel.setText(statusFieldText);
|
|
685 fStatusComposite.setVisible(true);
|
|
686 }
|
|
687 }
|
|
688 }
|
|
689
|
|
690 /*
|
|
691 * @see dwtx.jface.text.IInformationControlExtension5#containsControl(dwt.widgets.Control)
|
|
692 */
|
|
693 public bool containsControl(Control control) {
|
|
694 do {
|
|
695 if (control is fShell)
|
|
696 return true;
|
|
697 if (control instanceof Shell)
|
|
698 return false;
|
|
699 control= control.getParent();
|
|
700 } while (control !is null);
|
|
701 return false;
|
|
702 }
|
|
703
|
|
704 /*
|
|
705 * @see dwtx.jface.text.IInformationControlExtension5#isVisible()
|
|
706 */
|
|
707 public bool isVisible() {
|
|
708 return fShell !is null && !fShell.isDisposed() && fShell.isVisible();
|
|
709 }
|
|
710
|
|
711 /**
|
|
712 * {@inheritDoc}
|
|
713 * This default implementation returns <code>null</code>. Subclasses may override.
|
|
714 */
|
|
715 public IInformationControlCreator getInformationPresenterControlCreator() {
|
|
716 return null;
|
|
717 }
|
|
718
|
|
719 /**
|
|
720 * Computes the size constraints based on the
|
|
721 * {@link JFaceResources#getDialogFont() dialog font}. Subclasses can
|
|
722 * override or extend.
|
|
723 *
|
|
724 * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int)
|
|
725 */
|
|
726 public Point computeSizeConstraints(int widthInChars, int heightInChars) {
|
|
727 GC gc= new GC(fContentComposite);
|
|
728 gc.setFont(JFaceResources.getDialogFont());
|
|
729 int width= gc.getFontMetrics().getAverageCharWidth();
|
|
730 int height= gc.getFontMetrics().getHeight();
|
|
731 gc.dispose();
|
|
732
|
|
733 return new Point(widthInChars * width, heightInChars * height);
|
|
734 }
|
|
735
|
|
736 }
|