75
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2000, 2007 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.ui.internal.forms.widgets.FormHeading;
|
|
14
|
|
15 import dwtx.ui.internal.forms.widgets.TitleRegion;
|
|
16
|
|
17 import dwt.DWT;
|
|
18 import dwt.custom.CLabel;
|
|
19 import dwt.dnd.DragSourceListener;
|
|
20 import dwt.dnd.DropTargetListener;
|
|
21 import dwt.dnd.Transfer;
|
|
22 import dwt.events.DisposeEvent;
|
|
23 import dwt.events.DisposeListener;
|
|
24 import dwt.events.MouseEvent;
|
|
25 import dwt.events.MouseMoveListener;
|
|
26 import dwt.events.MouseTrackListener;
|
|
27 import dwt.graphics.Color;
|
|
28 import dwt.graphics.Font;
|
|
29 import dwt.graphics.FontMetrics;
|
|
30 import dwt.graphics.GC;
|
|
31 import dwt.graphics.Image;
|
|
32 import dwt.graphics.Point;
|
|
33 import dwt.graphics.Rectangle;
|
|
34 import dwt.widgets.Canvas;
|
|
35 import dwt.widgets.Composite;
|
|
36 import dwt.widgets.Control;
|
|
37 import dwt.widgets.Event;
|
|
38 import dwt.widgets.Layout;
|
|
39 import dwt.widgets.Listener;
|
|
40 import dwt.widgets.ToolBar;
|
|
41 import dwtx.core.runtime.Assert;
|
|
42 import dwtx.core.runtime.ListenerList;
|
|
43 import dwtx.jface.action.IMenuManager;
|
|
44 import dwtx.jface.action.IToolBarManager;
|
|
45 import dwtx.jface.action.ToolBarManager;
|
|
46 import dwtx.jface.dialogs.Dialog;
|
|
47 import dwtx.jface.dialogs.IMessageProvider;
|
|
48 import dwtx.jface.resource.JFaceResources;
|
|
49 import dwtx.ui.forms.IFormColors;
|
|
50 import dwtx.ui.forms.IMessage;
|
|
51 import dwtx.ui.forms.events.IHyperlinkListener;
|
|
52 import dwtx.ui.forms.widgets.Hyperlink;
|
|
53 import dwtx.ui.forms.widgets.ILayoutExtension;
|
|
54 import dwtx.ui.forms.widgets.SizeCache;
|
|
55 import dwtx.ui.internal.forms.IMessageToolTipManager;
|
|
56 import dwtx.ui.internal.forms.MessageManager;
|
|
57
|
|
58 import dwt.dwthelper.utils;
|
|
59 import tango.util.collection.HashMap;
|
|
60
|
|
61 /**
|
|
62 * Form header moved out of the form class.
|
|
63 */
|
|
64 public class FormHeading : Canvas {
|
|
65 private static const int TITLE_HMARGIN = 1;
|
|
66 private static const int SPACING = 5;
|
|
67 private static const int VSPACING = 5;
|
|
68 private static const int HMARGIN = 6;
|
|
69 private static const int VMARGIN = 1;
|
|
70 private static const int CLIENT_MARGIN = 1;
|
|
71
|
|
72 private static const int SEPARATOR = 1 << 1;
|
|
73 private static const int BOTTOM_TOOLBAR = 1 << 2;
|
|
74 private static const int BACKGROUND_IMAGE_TILED = 1 << 3;
|
|
75 private static const int SEPARATOR_HEIGHT = 2;
|
|
76 private static const int MESSAGE_AREA_LIMIT = 50;
|
|
77 static IMessage[] NULL_MESSAGE_ARRAY;
|
|
78
|
|
79 public static const String COLOR_BASE_BG = "baseBg"; //$NON-NLS-1$
|
|
80
|
|
81 private Image backgroundImage;
|
|
82
|
|
83 private Image gradientImage;
|
|
84
|
|
85 HashMap!(String,Object) colors;
|
|
86
|
|
87 private int flags;
|
|
88
|
|
89 private GradientInfo gradientInfo;
|
|
90
|
|
91 private ToolBarManager toolBarManager;
|
|
92
|
|
93 private SizeCache toolbarCache = new SizeCache();
|
|
94
|
|
95 private SizeCache clientCache = new SizeCache();
|
|
96
|
|
97 private SizeCache messageCache = new SizeCache();
|
|
98
|
|
99 private TitleRegion titleRegion;
|
|
100
|
|
101 private MessageRegion messageRegion;
|
|
102
|
|
103 private IMessageToolTipManager messageToolTipManager;
|
|
104
|
|
105 private Control headClient;
|
|
106
|
|
107 private class DefaultMessageToolTipManager :
|
|
108 IMessageToolTipManager {
|
|
109 public void createToolTip(Control control, bool imageLabel) {
|
|
110 }
|
|
111
|
|
112 public void update() {
|
|
113 String details = getMessageType() is 0 ? null : MessageManager
|
|
114 .createDetails(getChildrenMessages());
|
|
115 if (messageRegion !is null)
|
|
116 messageRegion.updateToolTip(details);
|
|
117 if (getMessageType() > 0
|
|
118 && (details is null || details.length() is 0))
|
|
119 details = getMessage();
|
|
120 titleRegion.updateToolTip(details);
|
|
121 }
|
|
122 }
|
|
123
|
|
124 private class GradientInfo {
|
|
125 Color[] gradientColors;
|
|
126
|
|
127 int[] percents;
|
|
128
|
|
129 bool vertical;
|
|
130 }
|
|
131
|
|
132 private class FormHeadingLayout : Layout, ILayoutExtension {
|
|
133 public int computeMinimumWidth(Composite composite, bool flushCache) {
|
|
134 return computeSize(composite, 5, DWT.DEFAULT, flushCache).x;
|
|
135 }
|
|
136
|
|
137 public int computeMaximumWidth(Composite composite, bool flushCache) {
|
|
138 return computeSize(composite, DWT.DEFAULT, DWT.DEFAULT, flushCache).x;
|
|
139 }
|
|
140
|
|
141 public Point computeSize(Composite composite, int wHint, int hHint,
|
|
142 bool flushCache) {
|
|
143 return layout(composite, false, 0, 0, wHint, hHint, flushCache);
|
|
144 }
|
|
145
|
|
146 protected void layout(Composite composite, bool flushCache) {
|
|
147 Rectangle rect = composite.getClientArea();
|
|
148 layout(composite, true, rect.x, rect.y, rect.width, rect.height,
|
|
149 flushCache);
|
|
150 }
|
|
151
|
|
152 private Point layout(Composite composite, bool move, int x, int y,
|
|
153 int width, int height, bool flushCache) {
|
|
154 Point tsize = null;
|
|
155 Point msize = null;
|
|
156 Point tbsize = null;
|
|
157 Point clsize = null;
|
|
158
|
|
159 if (flushCache) {
|
|
160 clientCache.flush();
|
|
161 messageCache.flush();
|
|
162 toolbarCache.flush();
|
|
163 }
|
|
164 if (hasToolBar()) {
|
|
165 ToolBar tb = toolBarManager.getControl();
|
|
166 toolbarCache.setControl(tb);
|
|
167 tbsize = toolbarCache.computeSize(DWT.DEFAULT, DWT.DEFAULT);
|
|
168 }
|
|
169 if (headClient !is null) {
|
|
170 clientCache.setControl(headClient);
|
|
171 int cwhint = width;
|
|
172 if (cwhint !is DWT.DEFAULT) {
|
|
173 cwhint -= HMARGIN * 2;
|
|
174 if (tbsize !is null && getToolBarAlignment() is DWT.BOTTOM)
|
|
175 cwhint -= tbsize.x + SPACING;
|
|
176 }
|
|
177 clsize = clientCache.computeSize(cwhint, DWT.DEFAULT);
|
|
178 }
|
|
179 int totalFlexWidth = width;
|
|
180 int flexWidth = totalFlexWidth;
|
|
181 if (totalFlexWidth !is DWT.DEFAULT) {
|
|
182 totalFlexWidth -= TITLE_HMARGIN * 2;
|
|
183 // complete right margin
|
|
184 if (hasToolBar() && getToolBarAlignment() is DWT.TOP
|
|
185 || hasMessageRegion())
|
|
186 totalFlexWidth -= SPACING;
|
|
187 // subtract tool bar
|
|
188 if (hasToolBar() && getToolBarAlignment() is DWT.TOP)
|
|
189 totalFlexWidth -= tbsize.x + SPACING;
|
|
190 flexWidth = totalFlexWidth;
|
|
191 if (hasMessageRegion()) {
|
|
192 // remove message region spacing and divide by 2
|
|
193 flexWidth -= SPACING;
|
|
194 // flexWidth /= 2;
|
|
195 }
|
|
196 }
|
|
197 /*
|
|
198 * // compute text and message sizes tsize =
|
|
199 * titleRegion.computeSize(flexWidth, DWT.DEFAULT); if (flexWidth !is
|
|
200 * DWT.DEFAULT && tsize.x < flexWidth) flexWidth += flexWidth -
|
|
201 * tsize.x;
|
|
202 *
|
|
203 * if (hasMessageRegion()) {
|
|
204 * messageCache.setControl(messageRegion.getMessageControl()); msize =
|
|
205 * messageCache.computeSize(flexWidth, DWT.DEFAULT); int maxWidth =
|
|
206 * messageCache.computeSize(DWT.DEFAULT, DWT.DEFAULT).x; if
|
|
207 * (maxWidth < msize.x) { msize.x = maxWidth; // recompute title
|
|
208 * with the reclaimed width int tflexWidth = totalFlexWidth -
|
|
209 * SPACING - msize.x; tsize = titleRegion.computeSize(tflexWidth,
|
|
210 * DWT.DEFAULT); } }
|
|
211 */
|
|
212 if (!hasMessageRegion()) {
|
|
213 tsize = titleRegion.computeSize(flexWidth, DWT.DEFAULT);
|
|
214 } else {
|
|
215 // Total flexible area in the first row is flexWidth.
|
|
216 // Try natural widths of title and
|
|
217 Point tsizeNatural = titleRegion.computeSize(DWT.DEFAULT,
|
|
218 DWT.DEFAULT);
|
|
219 messageCache.setControl(messageRegion.getMessageControl());
|
|
220 Point msizeNatural = messageCache.computeSize(DWT.DEFAULT,
|
|
221 DWT.DEFAULT);
|
|
222 // try to fit all
|
|
223 tsize = tsizeNatural;
|
|
224 msize = msizeNatural;
|
|
225 if (flexWidth !is DWT.DEFAULT) {
|
|
226 int needed = tsizeNatural.x + msizeNatural.x;
|
|
227 if (needed > flexWidth) {
|
|
228 // too big - try to limit the message
|
|
229 int mwidth = flexWidth - tsizeNatural.x;
|
|
230 if (mwidth >= MESSAGE_AREA_LIMIT) {
|
|
231 msize.x = mwidth;
|
|
232 } else {
|
|
233 // message is squeezed to the limit
|
|
234 int flex = flexWidth - MESSAGE_AREA_LIMIT;
|
|
235 tsize = titleRegion.computeSize(flex, DWT.DEFAULT);
|
|
236 msize.x = MESSAGE_AREA_LIMIT;
|
|
237 }
|
|
238 }
|
|
239 }
|
|
240 }
|
|
241
|
|
242 Point size = new Point(width, height);
|
|
243 if (!move) {
|
|
244 // compute sizes
|
|
245 int width1 = 2 * TITLE_HMARGIN;
|
|
246 width1 += tsize.x;
|
|
247 if (msize !is null)
|
|
248 width1 += SPACING + msize.x;
|
|
249 if (tbsize !is null && getToolBarAlignment() is DWT.TOP)
|
|
250 width1 += SPACING + tbsize.x;
|
|
251 if (msize !is null
|
|
252 || (tbsize !is null && getToolBarAlignment() is DWT.TOP))
|
|
253 width1 += SPACING;
|
|
254 size.x = width1;
|
|
255 if (clsize !is null) {
|
|
256 int width2 = clsize.x;
|
|
257 if (tbsize !is null && getToolBarAlignment() is DWT.BOTTOM)
|
|
258 width2 += SPACING + tbsize.x;
|
|
259 width2 += 2 * HMARGIN;
|
|
260 size.x = Math.max(width1, width2);
|
|
261 }
|
|
262 // height, first row
|
|
263 size.y = tsize.y;
|
|
264 if (msize !is null)
|
|
265 size.y = Math.max(msize.y, size.y);
|
|
266 if (tbsize !is null && getToolBarAlignment() is DWT.TOP)
|
|
267 size.y = Math.max(tbsize.y, size.y);
|
|
268 if (size.y > 0)
|
|
269 size.y += VMARGIN * 2;
|
|
270 // add second row
|
|
271 int height2 = 0;
|
|
272 if (tbsize !is null && getToolBarAlignment() is DWT.BOTTOM)
|
|
273 height2 = tbsize.y;
|
|
274 if (clsize !is null)
|
|
275 height2 = Math.max(height2, clsize.y);
|
|
276 if (height2 > 0)
|
|
277 size.y += VSPACING + height2 + CLIENT_MARGIN;
|
|
278 // add separator
|
|
279 if (size.y > 0 && isSeparatorVisible())
|
|
280 size.y += SEPARATOR_HEIGHT;
|
|
281 } else {
|
|
282 // position controls
|
|
283 int xloc = x;
|
|
284 int yloc = y + VMARGIN;
|
|
285 int row1Height = tsize.y;
|
|
286 if (hasMessageRegion())
|
|
287 row1Height = Math.max(row1Height, msize.y);
|
|
288 if (hasToolBar() && getToolBarAlignment() is DWT.TOP)
|
|
289 row1Height = Math.max(row1Height, tbsize.y);
|
|
290 titleRegion.setBounds(xloc,
|
|
291 // yloc + row1Height / 2 - tsize.y / 2,
|
|
292 yloc, tsize.x, tsize.y);
|
|
293 xloc += tsize.x;
|
|
294
|
|
295 if (hasMessageRegion()) {
|
|
296 xloc += SPACING;
|
|
297 int messageOffset = 0;
|
|
298 if (tsize.y > 0) {
|
|
299 // space between title area and title text
|
|
300 int titleLeadingSpace = (tsize.y - titleRegion.getFontHeight()) / 2;
|
|
301 // space between message control and message text
|
|
302 int messageLeadingSpace = (msize.y - messageRegion.getFontHeight()) / 2;
|
|
303 // how much to offset the message so baselines align
|
|
304 messageOffset = (titleLeadingSpace + titleRegion.getFontBaselineHeight())
|
|
305 - (messageLeadingSpace + messageRegion.getFontBaselineHeight());
|
|
306 }
|
|
307
|
|
308 messageRegion
|
|
309 .getMessageControl()
|
|
310 .setBounds(
|
|
311 xloc,
|
|
312 tsize.y > 0 ? (yloc + messageOffset)
|
|
313 : (yloc + row1Height / 2 - msize.y / 2),
|
|
314 msize.x, msize.y);
|
|
315 xloc += msize.x;
|
|
316 }
|
|
317 if (toolBarManager !is null)
|
|
318 toolBarManager.getControl().setVisible(
|
|
319 !toolBarManager.isEmpty());
|
|
320 if (tbsize !is null && getToolBarAlignment() is DWT.TOP) {
|
|
321 ToolBar tbar = toolBarManager.getControl();
|
|
322 tbar.setBounds(x + width - 1 - tbsize.x - HMARGIN, yloc
|
|
323 + row1Height - 1 - tbsize.y, tbsize.x, tbsize.y);
|
|
324 }
|
|
325 // second row
|
|
326 xloc = HMARGIN;
|
|
327 yloc += row1Height + VSPACING;
|
|
328 int tw = 0;
|
|
329
|
|
330 if (tbsize !is null && getToolBarAlignment() is DWT.BOTTOM) {
|
|
331 ToolBar tbar = toolBarManager.getControl();
|
|
332 tbar.setBounds(x + width - 1 - tbsize.x - HMARGIN, yloc,
|
|
333 tbsize.x, tbsize.y);
|
|
334 tw = tbsize.x + SPACING;
|
|
335 }
|
|
336 if (headClient !is null) {
|
|
337 int carea = width - HMARGIN * 2 - tw;
|
|
338 headClient.setBounds(xloc, yloc, carea, clsize.y);
|
|
339 }
|
|
340 }
|
|
341 return size;
|
|
342 }
|
|
343 }
|
|
344
|
|
345 /* (non-Javadoc)
|
|
346 * @see dwt.widgets.Control#forceFocus()
|
|
347 */
|
|
348 public bool forceFocus() {
|
|
349 return false;
|
|
350 }
|
|
351
|
|
352 private bool hasToolBar() {
|
|
353 return toolBarManager !is null && !toolBarManager.isEmpty();
|
|
354 }
|
|
355
|
|
356 private bool hasMessageRegion() {
|
|
357 return messageRegion !is null && !messageRegion.isEmpty();
|
|
358 }
|
|
359
|
|
360 private class MessageRegion {
|
|
361 private String message;
|
|
362 private int messageType;
|
|
363 private CLabel messageLabel;
|
|
364 private IMessage[] messages;
|
|
365 private Hyperlink messageHyperlink;
|
|
366 private ListenerList listeners;
|
|
367 private Color fg;
|
|
368 private int fontHeight = -1;
|
|
369 private int fontBaselineHeight = -1;
|
|
370
|
|
371 public this() {
|
|
372 }
|
|
373
|
|
374 public bool isDisposed() {
|
|
375 Control c = getMessageControl();
|
|
376 return c !is null && c.isDisposed();
|
|
377 }
|
|
378
|
|
379 public bool isEmpty() {
|
|
380 Control c = getMessageControl();
|
|
381 if (c is null)
|
|
382 return true;
|
|
383 return !c.getVisible();
|
|
384 }
|
|
385
|
|
386 public int getFontHeight() {
|
|
387 if (fontHeight is -1) {
|
|
388 Control c = getMessageControl();
|
|
389 if (c is null)
|
|
390 return 0;
|
|
391 GC gc = new GC(c.getDisplay());
|
|
392 gc.setFont(c.getFont());
|
|
393 fontHeight = gc.getFontMetrics().getHeight();
|
|
394 gc.dispose();
|
|
395 }
|
|
396 return fontHeight;
|
|
397 }
|
|
398
|
|
399 public int getFontBaselineHeight() {
|
|
400 if (fontBaselineHeight is -1) {
|
|
401 Control c = getMessageControl();
|
|
402 if (c is null)
|
|
403 return 0;
|
|
404 GC gc = new GC(c.getDisplay());
|
|
405 gc.setFont(c.getFont());
|
|
406 FontMetrics fm = gc.getFontMetrics();
|
|
407 fontBaselineHeight = fm.getHeight() - fm.getDescent();
|
|
408 gc.dispose();
|
|
409 }
|
|
410 return fontBaselineHeight;
|
|
411 }
|
|
412
|
|
413 public void showMessage(String newMessage, int newType,
|
|
414 IMessage[] messages) {
|
|
415 Control oldControl = getMessageControl();
|
|
416 int oldType = messageType;
|
|
417 this.message = newMessage;
|
|
418 this.messageType = newType;
|
|
419 this.messages = messages;
|
|
420 if (newMessage is null) {
|
|
421 // clearing of the message
|
|
422 if (oldControl !is null && oldControl.getVisible())
|
|
423 oldControl.setVisible(false);
|
|
424 return;
|
|
425 }
|
|
426 ensureControlExists();
|
|
427 if (needHyperlink()) {
|
|
428 messageHyperlink.setText(newMessage);
|
|
429 messageHyperlink.setHref(messages);
|
|
430 } else {
|
|
431 messageLabel.setText(newMessage);
|
|
432 }
|
|
433 if (oldType !is newType)
|
|
434 updateForeground();
|
|
435 }
|
|
436
|
|
437 public void updateToolTip(String toolTip) {
|
|
438 Control control = getMessageControl();
|
|
439 if (control !is null)
|
|
440 control.setToolTipText(toolTip);
|
|
441 }
|
|
442
|
|
443 public String getMessage() {
|
|
444 return message;
|
|
445 }
|
|
446
|
|
447 public int getMessageType() {
|
|
448 return messageType;
|
|
449 }
|
|
450
|
|
451 public IMessage[] getChildrenMessages() {
|
|
452 return messages;
|
|
453 }
|
|
454
|
|
455 public String getDetailedMessage() {
|
|
456 Control c = getMessageControl();
|
|
457 if (c !is null)
|
|
458 return c.getToolTipText();
|
|
459 return null;
|
|
460 }
|
|
461
|
|
462 public Control getMessageControl() {
|
|
463 if (needHyperlink() && messageHyperlink !is null)
|
|
464 return messageHyperlink;
|
|
465 return messageLabel;
|
|
466 }
|
|
467
|
|
468 public Image getMessageImage() {
|
|
469 switch (messageType) {
|
|
470 case IMessageProvider.INFORMATION:
|
|
471 return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_INFO);
|
|
472 case IMessageProvider.WARNING:
|
|
473 return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING);
|
|
474 case IMessageProvider.ERROR:
|
|
475 return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR);
|
|
476 default:
|
|
477 return null;
|
|
478 }
|
|
479 }
|
|
480
|
|
481 public void addMessageHyperlinkListener(IHyperlinkListener listener) {
|
|
482 if (listeners is null)
|
|
483 listeners = new ListenerList();
|
|
484 listeners.add(listener);
|
|
485 ensureControlExists();
|
|
486 if (messageHyperlink !is null)
|
|
487 messageHyperlink.addHyperlinkListener(listener);
|
|
488 if (listeners.size() is 1)
|
|
489 updateForeground();
|
|
490 }
|
|
491
|
|
492 private void removeMessageHyperlinkListener(IHyperlinkListener listener) {
|
|
493 if (listeners !is null) {
|
|
494 listeners.remove(listener);
|
|
495 if (messageHyperlink !is null)
|
|
496 messageHyperlink.removeHyperlinkListener(listener);
|
|
497 if (listeners.isEmpty())
|
|
498 listeners = null;
|
|
499 ensureControlExists();
|
|
500 if (listeners is null && !isDisposed())
|
|
501 updateForeground();
|
|
502 }
|
|
503 }
|
|
504
|
|
505 private void ensureControlExists() {
|
|
506 if (needHyperlink()) {
|
|
507 if (messageLabel !is null)
|
|
508 messageLabel.setVisible(false);
|
|
509 if (messageHyperlink is null) {
|
|
510 messageHyperlink = new Hyperlink(this.outer, DWT.NULL);
|
|
511 messageHyperlink.setUnderlined(true);
|
|
512 messageHyperlink.setText(message);
|
|
513 messageHyperlink.setHref(messages);
|
|
514 Object[] llist = listeners.getListeners();
|
|
515 for (int i = 0; i < llist.length; i++)
|
|
516 messageHyperlink
|
|
517 .addHyperlinkListener(cast(IHyperlinkListener) llist[i]);
|
|
518 if (messageToolTipManager !is null)
|
|
519 messageToolTipManager.createToolTip(messageHyperlink, false);
|
|
520 } else if (!messageHyperlink.getVisible()) {
|
|
521 messageHyperlink.setText(message);
|
|
522 messageHyperlink.setHref(messages);
|
|
523 messageHyperlink.setVisible(true);
|
|
524 }
|
|
525 } else {
|
|
526 // need a label
|
|
527 if (messageHyperlink !is null)
|
|
528 messageHyperlink.setVisible(false);
|
|
529 if (messageLabel is null) {
|
|
530 messageLabel = new CLabel(this.outer, DWT.NULL);
|
|
531 messageLabel.setText(message);
|
|
532 if (messageToolTipManager !is null)
|
|
533 messageToolTipManager.createToolTip(messageLabel, false);
|
|
534 } else if (!messageLabel.getVisible()) {
|
|
535 messageLabel.setText(message);
|
|
536 messageLabel.setVisible(true);
|
|
537 }
|
|
538 }
|
|
539 layout(true);
|
|
540 }
|
|
541
|
|
542 private bool needHyperlink() {
|
|
543 return messageType > 0 && listeners !is null;
|
|
544 }
|
|
545
|
|
546 public void setBackground(Color bg) {
|
|
547 if (messageHyperlink !is null)
|
|
548 messageHyperlink.setBackground(bg);
|
|
549 if (messageLabel !is null)
|
|
550 messageLabel.setBackground(bg);
|
|
551 }
|
|
552
|
|
553 public void setForeground(Color fg) {
|
|
554 this.fg = fg;
|
|
555 }
|
|
556
|
|
557 private void updateForeground() {
|
|
558 Color theFg;
|
|
559
|
|
560 switch (messageType) {
|
|
561 case IMessageProvider.ERROR:
|
|
562 theFg = getDisplay().getSystemColor(DWT.COLOR_RED);
|
|
563 break;
|
|
564 case IMessageProvider.WARNING:
|
|
565 theFg = getDisplay().getSystemColor(DWT.COLOR_DARK_YELLOW);
|
|
566 break;
|
|
567 default:
|
|
568 theFg = fg;
|
|
569 }
|
|
570 getMessageControl().setForeground(theFg);
|
|
571 }
|
|
572 }
|
|
573
|
|
574 /**
|
|
575 * Creates the form content control as a child of the provided parent.
|
|
576 *
|
|
577 * @param parent
|
|
578 * the parent widget
|
|
579 */
|
|
580 public this(Composite parent, int style) {
|
|
581 colors = new HashMap!(String,Object);
|
|
582 toolbarCache = new SizeCache();
|
|
583 clientCache = new SizeCache();
|
|
584 messageCache = new SizeCache();
|
|
585 messageToolTipManager = new DefaultMessageToolTipManager();
|
|
586
|
|
587 super(parent, style);
|
|
588 setBackgroundMode(DWT.INHERIT_DEFAULT);
|
|
589 addListener(DWT.Paint, new class Listener {
|
|
590 public void handleEvent(Event e) {
|
|
591 onPaint(e.gc);
|
|
592 }
|
|
593 });
|
|
594 addListener(DWT.Dispose, new class Listener {
|
|
595 public void handleEvent(Event e) {
|
|
596 if (gradientImage !is null) {
|
|
597 FormImages.getInstance().markFinished(gradientImage);
|
|
598 gradientImage = null;
|
|
599 }
|
|
600 }
|
|
601 });
|
|
602 addListener(DWT.Resize, new class Listener {
|
|
603 public void handleEvent(Event e) {
|
|
604 if (gradientInfo !is null
|
|
605 || (backgroundImage !is null && !isBackgroundImageTiled()))
|
|
606 updateGradientImage();
|
|
607 }
|
|
608 });
|
|
609 addMouseMoveListener(new class MouseMoveListener {
|
|
610 public void mouseMove(MouseEvent e) {
|
|
611 updateTitleRegionHoverState(e);
|
|
612 }
|
|
613 });
|
|
614 addMouseTrackListener(new class MouseTrackListener {
|
|
615 public void mouseEnter(MouseEvent e) {
|
|
616 updateTitleRegionHoverState(e);
|
|
617 }
|
|
618
|
|
619 public void mouseExit(MouseEvent e) {
|
|
620 titleRegion.setHoverState(TitleRegion.STATE_NORMAL);
|
|
621 }
|
|
622
|
|
623 public void mouseHover(MouseEvent e) {
|
|
624 }
|
|
625 });
|
|
626 super.setLayout(new FormHeadingLayout());
|
|
627 titleRegion = new TitleRegion(this);
|
|
628 }
|
|
629
|
|
630 /**
|
|
631 * Fully delegates the size computation to the internal layout manager.
|
|
632 */
|
|
633 public final Point computeSize(int wHint, int hHint, bool changed) {
|
|
634 return (cast(FormHeadingLayout) getLayout()).computeSize(this, wHint,
|
|
635 hHint, changed);
|
|
636 }
|
|
637
|
|
638 /**
|
|
639 * Prevents from changing the custom control layout.
|
|
640 */
|
|
641 public final void setLayout(Layout layout) {
|
|
642 }
|
|
643
|
|
644 /**
|
|
645 * Returns the title text that will be rendered at the top of the form.
|
|
646 *
|
|
647 * @return the title text
|
|
648 */
|
|
649 public String getText() {
|
|
650 return titleRegion.getText();
|
|
651 }
|
|
652
|
|
653 /**
|
|
654 * Returns the title image that will be rendered to the left of the title.
|
|
655 *
|
|
656 * @return the title image
|
|
657 * @since 3.2
|
|
658 */
|
|
659 public Image getImage() {
|
|
660 return titleRegion.getImage();
|
|
661 }
|
|
662
|
|
663 /**
|
|
664 * Sets the background color of the header.
|
|
665 */
|
|
666 public void setBackground(Color bg) {
|
|
667 super.setBackground(bg);
|
|
668 internalSetBackground(bg);
|
|
669 }
|
|
670
|
|
671 private void internalSetBackground(Color bg) {
|
|
672 titleRegion.setBackground(bg);
|
|
673 if (messageRegion !is null)
|
|
674 messageRegion.setBackground(bg);
|
|
675 if (toolBarManager !is null)
|
|
676 toolBarManager.getControl().setBackground(bg);
|
|
677 putColor(COLOR_BASE_BG, bg);
|
|
678 }
|
|
679
|
|
680 /**
|
|
681 * Sets the foreground color of the header.
|
|
682 */
|
|
683 public void setForeground(Color fg) {
|
|
684 super.setForeground(fg);
|
|
685 titleRegion.setForeground(fg);
|
|
686 if (messageRegion !is null)
|
|
687 messageRegion.setForeground(fg);
|
|
688 }
|
|
689
|
|
690 /**
|
|
691 * Sets the text to be rendered at the top of the form above the body as a
|
|
692 * title.
|
|
693 *
|
|
694 * @param text
|
|
695 * the title text
|
|
696 */
|
|
697 public void setText(String text) {
|
|
698 titleRegion.setText(text);
|
|
699 }
|
|
700
|
|
701 public void setFont(Font font) {
|
|
702 super.setFont(font);
|
|
703 titleRegion.setFont(font);
|
|
704 }
|
|
705
|
|
706 /**
|
|
707 * Sets the image to be rendered to the left of the title.
|
|
708 *
|
|
709 * @param image
|
|
710 * the title image or <code>null</code> to show no image.
|
|
711 * @since 3.2
|
|
712 */
|
|
713 public void setImage(Image image) {
|
|
714 titleRegion.setImage(image);
|
|
715 if (messageRegion !is null)
|
|
716 titleRegion.updateImage(messageRegion.getMessageImage(), true);
|
|
717 else
|
|
718 titleRegion.updateImage(null, true);
|
|
719 }
|
|
720
|
|
721 public void setTextBackground(Color[] gradientColors, int[] percents,
|
|
722 bool vertical) {
|
|
723 if (gradientColors !is null) {
|
|
724 gradientInfo = new GradientInfo();
|
|
725 gradientInfo.gradientColors = gradientColors;
|
|
726 gradientInfo.percents = percents;
|
|
727 gradientInfo.vertical = vertical;
|
|
728 setBackground(null);
|
|
729 updateGradientImage();
|
|
730 } else {
|
|
731 // reset
|
|
732 gradientInfo = null;
|
|
733 if (gradientImage !is null) {
|
|
734 FormImages.getInstance().markFinished(gradientImage);
|
|
735 gradientImage = null;
|
|
736 setBackgroundImage(null);
|
|
737 }
|
|
738 }
|
|
739 }
|
|
740
|
|
741 public void setHeadingBackgroundImage(Image image) {
|
|
742 this.backgroundImage = image;
|
|
743 if (image !is null)
|
|
744 setBackground(null);
|
|
745 if (isBackgroundImageTiled()) {
|
|
746 setBackgroundImage(image);
|
|
747 } else
|
|
748 updateGradientImage();
|
|
749 }
|
|
750
|
|
751 public Image getHeadingBackgroundImage() {
|
|
752 return backgroundImage;
|
|
753 }
|
|
754
|
|
755 public void setBackgroundImageTiled(bool tiled) {
|
|
756 if (tiled)
|
|
757 flags |= BACKGROUND_IMAGE_TILED;
|
|
758 else
|
|
759 flags &= ~BACKGROUND_IMAGE_TILED;
|
|
760 setHeadingBackgroundImage(this.backgroundImage);
|
|
761 }
|
|
762
|
|
763 public bool isBackgroundImageTiled() {
|
|
764 return (flags & BACKGROUND_IMAGE_TILED) !is 0;
|
|
765 }
|
|
766
|
|
767 public void setBackgroundImage(Image image) {
|
|
768 super.setBackgroundImage(image);
|
|
769 if (image !is null) {
|
|
770 internalSetBackground(null);
|
|
771 }
|
|
772 }
|
|
773
|
|
774 /**
|
|
775 * Returns the tool bar manager that is used to manage tool items in the
|
|
776 * form's title area.
|
|
777 *
|
|
778 * @return form tool bar manager
|
|
779 */
|
|
780 public IToolBarManager getToolBarManager() {
|
|
781 if (toolBarManager is null) {
|
|
782 toolBarManager = new ToolBarManager(DWT.FLAT);
|
|
783 ToolBar toolbar = toolBarManager.createControl(this);
|
|
784 toolbar.setBackground(getBackground());
|
|
785 toolbar.setForeground(getForeground());
|
|
786 toolbar.setCursor(FormsResources.getHandCursor());
|
|
787 addDisposeListener(new class DisposeListener {
|
|
788 public void widgetDisposed(DisposeEvent e) {
|
|
789 if (toolBarManager !is null) {
|
|
790 toolBarManager.dispose();
|
|
791 toolBarManager = null;
|
|
792 }
|
|
793 }
|
|
794 });
|
|
795 }
|
|
796 return toolBarManager;
|
|
797 }
|
|
798
|
|
799 /**
|
|
800 * Returns the menu manager that is used to manage tool items in the form's
|
|
801 * title area.
|
|
802 *
|
|
803 * @return form drop-down menu manager
|
|
804 * @since 3.3
|
|
805 */
|
|
806 public IMenuManager getMenuManager() {
|
|
807 return titleRegion.getMenuManager();
|
|
808 }
|
|
809
|
|
810 /**
|
|
811 * Updates the local tool bar manager if used. Does nothing if local tool
|
|
812 * bar manager has not been created yet.
|
|
813 */
|
|
814 public void updateToolBar() {
|
|
815 if (toolBarManager !is null)
|
|
816 toolBarManager.update(false);
|
|
817 }
|
|
818
|
|
819 private void onPaint(GC gc) {
|
|
820 if (!isSeparatorVisible() && getBackgroundImage() is null)
|
|
821 return;
|
|
822 Rectangle carea = getClientArea();
|
|
823 Image buffer = new Image(getDisplay(), carea.width, carea.height);
|
|
824 buffer.setBackground(getBackground());
|
|
825 GC igc = new GC(buffer);
|
|
826 igc.setBackground(getBackground());
|
|
827 igc.fillRectangle(0, 0, carea.width, carea.height);
|
|
828 if (getBackgroundImage() !is null) {
|
|
829 if (gradientInfo !is null)
|
|
830 drawBackground(igc, carea.x, carea.y, carea.width, carea.height);
|
|
831 else {
|
|
832 Image bgImage = getBackgroundImage();
|
|
833 Rectangle ibounds = bgImage.getBounds();
|
|
834 drawBackground(igc, carea.x, carea.y, ibounds.width,
|
|
835 ibounds.height);
|
|
836 }
|
|
837 }
|
|
838
|
|
839 if (isSeparatorVisible()) {
|
|
840 // bg separator
|
|
841 if (hasColor(IFormColors.H_BOTTOM_KEYLINE1))
|
|
842 igc.setForeground(getColor(IFormColors.H_BOTTOM_KEYLINE1));
|
|
843 else
|
|
844 igc.setForeground(getBackground());
|
|
845 igc.drawLine(carea.x, carea.height - 2, carea.x + carea.width - 1,
|
|
846 carea.height - 2);
|
|
847 if (hasColor(IFormColors.H_BOTTOM_KEYLINE2))
|
|
848 igc.setForeground(getColor(IFormColors.H_BOTTOM_KEYLINE2));
|
|
849 else
|
|
850 igc.setForeground(getForeground());
|
|
851 igc.drawLine(carea.x, carea.height - 1, carea.x + carea.width - 1,
|
|
852 carea.height - 1);
|
|
853 }
|
|
854 igc.dispose();
|
|
855 gc.drawImage(buffer, carea.x, carea.y);
|
|
856 buffer.dispose();
|
|
857 }
|
|
858
|
|
859 private void updateTitleRegionHoverState(MouseEvent e) {
|
|
860 Rectangle titleRect = titleRegion.getBounds();
|
|
861 titleRect.width += titleRect.x + 15;
|
|
862 titleRect.height += titleRect.y + 15;
|
|
863 titleRect.x = 0;
|
|
864 titleRect.y = 0;
|
|
865 if (titleRect.contains(e.x, e.y))
|
|
866 titleRegion.setHoverState(TitleRegion.STATE_HOVER_LIGHT);
|
|
867 else
|
|
868 titleRegion.setHoverState(TitleRegion.STATE_NORMAL);
|
|
869 }
|
|
870
|
|
871 private void updateGradientImage() {
|
|
872 Rectangle rect = getBounds();
|
|
873 if (gradientImage !is null) {
|
|
874 FormImages.getInstance().markFinished(gradientImage);
|
|
875 gradientImage = null;
|
|
876 }
|
|
877 if (gradientInfo !is null) {
|
|
878 gradientImage = FormImages.getInstance().getGradient(getDisplay(), gradientInfo.gradientColors, gradientInfo.percents,
|
|
879 gradientInfo.vertical ? rect.height : rect.width, gradientInfo.vertical, getColor(COLOR_BASE_BG));
|
|
880 } else if (backgroundImage !is null && !isBackgroundImageTiled()) {
|
|
881 gradientImage = new Image(getDisplay(), Math.max(rect.width, 1),
|
|
882 Math.max(rect.height, 1));
|
|
883 gradientImage.setBackground(getBackground());
|
|
884 GC gc = new GC(gradientImage);
|
|
885 gc.drawImage(backgroundImage, 0, 0);
|
|
886 gc.dispose();
|
|
887 }
|
|
888 setBackgroundImage(gradientImage);
|
|
889 }
|
|
890
|
|
891 public bool isSeparatorVisible() {
|
|
892 return (flags & SEPARATOR) !is 0;
|
|
893 }
|
|
894
|
|
895 public void setSeparatorVisible(bool addSeparator) {
|
|
896 if (addSeparator)
|
|
897 flags |= SEPARATOR;
|
|
898 else
|
|
899 flags &= ~SEPARATOR;
|
|
900 }
|
|
901
|
|
902 public void setToolBarAlignment(int alignment) {
|
|
903 if (alignment is DWT.BOTTOM)
|
|
904 flags |= BOTTOM_TOOLBAR;
|
|
905 else
|
|
906 flags &= ~BOTTOM_TOOLBAR;
|
|
907 }
|
|
908
|
|
909 public int getToolBarAlignment() {
|
|
910 return (flags & BOTTOM_TOOLBAR) !is 0 ? DWT.BOTTOM : DWT.TOP;
|
|
911 }
|
|
912
|
|
913 public void addMessageHyperlinkListener(IHyperlinkListener listener) {
|
|
914 ensureMessageRegionExists();
|
|
915 messageRegion.addMessageHyperlinkListener(listener);
|
|
916 }
|
|
917
|
|
918 public void removeMessageHyperlinkListener(IHyperlinkListener listener) {
|
|
919 if (messageRegion !is null)
|
|
920 messageRegion.removeMessageHyperlinkListener(listener);
|
|
921 }
|
|
922
|
|
923 public String getMessage() {
|
|
924 return messageRegion !is null ? messageRegion.getMessage() : null;
|
|
925 }
|
|
926
|
|
927 public int getMessageType() {
|
|
928 return messageRegion !is null ? messageRegion.getMessageType() : 0;
|
|
929 }
|
|
930
|
|
931 public IMessage[] getChildrenMessages() {
|
|
932 return messageRegion !is null ? messageRegion.getChildrenMessages()
|
|
933 : NULL_MESSAGE_ARRAY;
|
|
934 }
|
|
935
|
|
936 private void ensureMessageRegionExists() {
|
|
937 // ensure message region exists
|
|
938 if (messageRegion is null)
|
|
939 messageRegion = new MessageRegion();
|
|
940 }
|
|
941
|
|
942 public void showMessage(String newMessage, int type, IMessage[] messages) {
|
|
943 if (messageRegion is null) {
|
|
944 // check the trivial case
|
|
945 if (newMessage is null)
|
|
946 return;
|
|
947 } else if (messageRegion.isDisposed())
|
|
948 return;
|
|
949 ensureMessageRegionExists();
|
|
950 messageRegion.showMessage(newMessage, type, messages);
|
|
951 titleRegion.updateImage(messageRegion.getMessageImage(), false);
|
|
952 if (messageToolTipManager !is null)
|
|
953 messageToolTipManager.update();
|
|
954 layout();
|
|
955 redraw();
|
|
956 }
|
|
957
|
|
958 /**
|
|
959 * Tests if the form is in the 'busy' state.
|
|
960 *
|
|
961 * @return <code>true</code> if busy, <code>false</code> otherwise.
|
|
962 */
|
|
963
|
|
964 public bool isBusy() {
|
|
965 return titleRegion.isBusy();
|
|
966 }
|
|
967
|
|
968 /**
|
|
969 * Sets the form's busy state. Busy form will display 'busy' animation in
|
|
970 * the area of the title image.
|
|
971 *
|
|
972 * @param busy
|
|
973 * the form's busy state
|
|
974 */
|
|
975
|
|
976 public void setBusy(bool busy) {
|
|
977 if (titleRegion.setBusy(busy))
|
|
978 layout();
|
|
979 }
|
|
980
|
|
981 public Control getHeadClient() {
|
|
982 return headClient;
|
|
983 }
|
|
984
|
|
985 public void setHeadClient(Control headClient) {
|
|
986 if (headClient !is null)
|
|
987 Assert.isTrue(headClient.getParent() is this);
|
|
988 this.headClient = headClient;
|
|
989 layout();
|
|
990 }
|
|
991
|
|
992 public void putColor(String key, Color color) {
|
|
993 if (color is null)
|
|
994 colors.remove(key);
|
|
995 else
|
|
996 colors.put(key, color);
|
|
997 }
|
|
998
|
|
999 public Color getColor(String key) {
|
|
1000 return cast(Color) colors.get(key);
|
|
1001 }
|
|
1002
|
|
1003 public bool hasColor(String key) {
|
|
1004 return colors.containsKey(key);
|
|
1005 }
|
|
1006
|
|
1007 public void addDragSupport(int operations, Transfer[] transferTypes,
|
|
1008 DragSourceListener listener) {
|
|
1009 titleRegion.addDragSupport(operations, transferTypes, listener);
|
|
1010 }
|
|
1011
|
|
1012 public void addDropSupport(int operations, Transfer[] transferTypes,
|
|
1013 DropTargetListener listener) {
|
|
1014 titleRegion.addDropSupport(operations, transferTypes, listener);
|
|
1015 }
|
|
1016
|
|
1017 public IMessageToolTipManager getMessageToolTipManager() {
|
|
1018 return messageToolTipManager;
|
|
1019 }
|
|
1020
|
|
1021 public void setMessageToolTipManager(
|
|
1022 IMessageToolTipManager messageToolTipManager) {
|
|
1023 this.messageToolTipManager = messageToolTipManager;
|
|
1024 }
|
|
1025 }
|