Mercurial > projects > dwt-addons
annotate dwtx/ui/internal/forms/widgets/FormHeading.d @ 104:04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
These new wrappers now use the tango.util.containers instead of the tango.util.collections.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 07 Aug 2008 15:01:33 +0200 |
parents | e193036d82c9 |
children |
rev | line source |
---|---|
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; | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
76
diff
changeset
|
61 import dwtx.dwtxhelper.Collection; |
75 | 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 | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
76
diff
changeset
|
87 Hashtable colors; |
75 | 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); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
76
diff
changeset
|
435 messageHyperlink.setHref(new ArrayWrapperObject(arraycast!(Object)(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); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
76
diff
changeset
|
519 messageHyperlink.setHref(new ArrayWrapperObject(arraycast!(Object)(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); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
76
diff
changeset
|
528 messageHyperlink.setHref(new ArrayWrapperObject(arraycast!(Object)(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) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
76
diff
changeset
|
587 colors = new Hashtable(); |
75 | 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) | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
76
diff
changeset
|
1000 colors.remove(key); |
75 | 1001 else |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
76
diff
changeset
|
1002 colors.put(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 } |