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