Mercurial > projects > dwt-addons
annotate dwtx/jface/fieldassist/DecoratedField.d @ 192:c3583c6ec027
Added missing default cases for switch statements
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 03 Nov 2008 22:52:26 +0100 |
parents | 46a6e0e6ccd4 |
children |
rev | line source |
---|---|
17 | 1 /******************************************************************************* |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
2 * Copyright (c) 2005, 2008 IBM Corporation and others. |
17 | 3 * All rights reserved. This program and the accompanying materials |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.jface.fieldassist.DecoratedField; | |
14 | |
15 import dwtx.jface.fieldassist.FieldDecoration; | |
16 import dwtx.jface.fieldassist.FieldDecorationRegistry; | |
17 import dwtx.jface.fieldassist.IControlCreator; | |
18 | |
19 import dwt.DWT; | |
20 import dwt.events.DisposeEvent; | |
21 import dwt.events.DisposeListener; | |
22 import dwt.events.FocusEvent; | |
23 import dwt.events.FocusListener; | |
24 import dwt.events.MouseAdapter; | |
25 import dwt.events.MouseEvent; | |
26 import dwt.events.MouseTrackListener; | |
27 import dwt.events.PaintEvent; | |
28 import dwt.events.PaintListener; | |
29 import dwt.graphics.GC; | |
30 import dwt.graphics.Image; | |
31 import dwt.graphics.Point; | |
32 import dwt.graphics.Region; | |
33 import dwt.layout.FormAttachment; | |
34 import dwt.layout.FormData; | |
35 import dwt.layout.FormLayout; | |
36 import dwt.widgets.Composite; | |
37 import dwt.widgets.Control; | |
38 import dwt.widgets.Display; | |
39 import dwt.widgets.Label; | |
40 import dwt.widgets.Shell; | |
41 import dwtx.core.runtime.Assert; | |
42 | |
43 import dwt.dwthelper.utils; | |
44 | |
45 /** | |
46 * DecoratedField manages image decorations around a control. It allows clients | |
47 * to specify an image decoration and a position for the decoration relative to | |
48 * the field. Decorations may be assigned descriptions, which are shown when the | |
49 * user hovers over the decoration. Clients can decorate any kind of control by | |
50 * supplying a {@link IControlCreator} to create the control that is decorated. | |
51 * <p> | |
52 * Decorations always appear on either horizontal side of the field, never above | |
53 * or below it. Decorations can be positioned at the top or bottom of either | |
54 * side. Future implementations may provide additional positioning options for | |
55 * decorations. | |
56 * <p> | |
57 * By default, DecoratedField will consult the {@link FieldDecorationRegistry} | |
58 * to determine how much space should be reserved for each decoration. This | |
59 * allows fields with decorations from different sources to align properly on | |
60 * the same dialog, since the registry tracks the size of all decorations | |
61 * registered. Therefore, it is recommended, but not required, that clients of | |
62 * DecoratedField register the decorations used. In cases where alignment | |
63 * between different fields is not a concern, clients can use | |
64 * <code>setUseMaximumDecorationWidth(false)</code> and need not register | |
65 * their decorations. | |
66 * <p> | |
67 * This class is not intended to be subclassed. | |
68 * | |
69 * @since 3.2 | |
70 * @deprecated As of 3.3, clients should use {@link ControlDecoration} instead. | |
71 */ | |
72 public class DecoratedField { | |
73 | |
74 /** | |
75 * Cached platform flags for dealing with platform-specific issues. | |
76 */ | |
35 | 77 private static bool CARBON(){ |
78 return "carbon".equals(DWT.getPlatform()); //$NON-NLS-1$ | |
79 } | |
17 | 80 |
81 /** | |
82 * Constants describing the array indices used to hold the decorations in | |
83 * array slots. | |
84 */ | |
85 | |
86 private static const int LEFT_TOP = 0; | |
87 | |
88 private static const int LEFT_BOTTOM = 1; | |
89 | |
90 private static const int RIGHT_TOP = 2; | |
91 | |
92 private static const int RIGHT_BOTTOM = 3; | |
93 | |
94 private static const int DECORATION_SLOTS = 4; | |
95 | |
96 /** | |
97 * Simple data structure class for specifying the internals for a field | |
98 * decoration. This class contains data specific to the implementation of | |
99 * field decorations as labels attached to the field. Clients should use | |
100 * <code>FieldDecoration</code> for specifying a decoration. | |
101 */ | |
102 private class FieldDecorationData { | |
103 | |
104 /* Package */FieldDecoration decoration; | |
105 | |
106 /* Package */Label label; | |
107 | |
108 /* Package */FormData data; | |
109 | |
110 /* Package */bool showOnFocus; | |
111 | |
112 /* Package */bool visible = true; | |
113 | |
114 /** | |
115 * Create a decoration data representing the specified decoration, using | |
116 * the specified label and form data for its representation. | |
117 * | |
118 * @param decoration | |
119 * the decoration whose data is kept. | |
120 * @param label | |
121 * the label used to represent the decoration. | |
122 * @param formData | |
123 * the form data used to attach the decoration to its field. | |
124 * @param showOnFocus | |
125 * a bool specifying whether the decoration should only be | |
126 * shown when the field has focus. | |
127 */ | |
128 this(FieldDecoration decoration, Label label, | |
129 FormData formData, bool showOnFocus) { | |
130 this.decoration = decoration; | |
131 this.label = label; | |
132 this.data = formData; | |
133 this.showOnFocus = showOnFocus; | |
134 } | |
135 } | |
136 | |
137 /** | |
138 * Decorations keyed by position. | |
139 */ | |
140 private FieldDecorationData[] decDatas; | |
141 | |
142 /** | |
143 * The associated control | |
144 */ | |
145 private Control control; | |
146 | |
147 /** | |
148 * The composite with form layout used to manage decorations. | |
149 */ | |
150 private Composite form; | |
151 | |
152 /** | |
153 * The bool that indicates whether the maximum decoration width is used | |
154 * when allocating space for decorations. | |
155 */ | |
156 private bool useMaxDecorationWidth = true; | |
157 | |
158 /** | |
159 * The hover used for showing description text | |
160 */ | |
161 private Hover hover; | |
162 | |
163 /** | |
164 * The hover used to show a decoration image's description. | |
165 */ | |
166 class Hover { | |
167 private static const String EMPTY = ""; //$NON-NLS-1$ | |
168 | |
169 /** | |
170 * Offset of info hover arrow from the left or right side. | |
171 */ | |
172 private int hao = 10; | |
173 | |
174 /** | |
175 * Width of info hover arrow. | |
176 */ | |
177 private int haw = 8; | |
178 | |
179 /** | |
180 * Height of info hover arrow. | |
181 */ | |
182 private int hah = 10; | |
183 | |
184 /** | |
185 * Margin around info hover text. | |
186 */ | |
187 private int hm = 2; | |
188 | |
189 /** | |
190 * This info hover's shell. | |
191 */ | |
192 Shell hoverShell; | |
193 | |
194 /** | |
195 * The info hover text. | |
196 */ | |
197 String text = EMPTY; | |
198 | |
199 /** | |
200 * The region used to manage the shell shape | |
201 */ | |
202 Region region; | |
203 | |
204 /** | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
205 * Boolean indicating whether the last computed polygon location had an |
17 | 206 * arrow on left. (true if left, false if right). |
207 */ | |
208 bool arrowOnLeft = true; | |
209 | |
210 /* | |
211 * Create a hover parented by the specified shell. | |
212 */ | |
213 this(Shell parent) { | |
214 final Display display = parent.getDisplay(); | |
215 hoverShell = new Shell(parent, DWT.NO_TRIM | DWT.ON_TOP | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
216 | DWT.NO_FOCUS | DWT.TOOL); |
17 | 217 hoverShell.setBackground(display |
218 .getSystemColor(DWT.COLOR_INFO_BACKGROUND)); | |
219 hoverShell.setForeground(display | |
220 .getSystemColor(DWT.COLOR_INFO_FOREGROUND)); | |
221 hoverShell.addPaintListener(new class PaintListener { | |
222 public void paintControl(PaintEvent pe) { | |
223 pe.gc.drawString(text, hm, hm); | |
224 if (!CARBON) { | |
225 pe.gc.drawPolygon(getPolygon(true)); | |
226 } | |
227 } | |
228 }); | |
229 hoverShell.addMouseListener(new class MouseAdapter { | |
230 public void mouseDown(MouseEvent e) { | |
231 hideHover(); | |
232 } | |
233 }); | |
234 } | |
235 | |
236 /* | |
237 * Compute a polygon that represents a hover with an arrow pointer. If | |
238 * border is true, compute the polygon inset by 1-pixel border. Consult | |
239 * the arrowOnLeft flag to determine which side the arrow is on. | |
240 */ | |
241 int[] getPolygon(bool border) { | |
242 Point e = getExtent(); | |
243 int b = border ? 1 : 0; | |
244 if (arrowOnLeft) { | |
245 return [ 0, 0, e.x - b, 0, e.x - b, e.y - b, | |
246 hao + haw, e.y - b, hao + haw / 2, e.y + hah - b, hao, | |
247 e.y - b, 0, e.y - b, 0, 0 ]; | |
248 } | |
249 return [ 0, 0, e.x - b, 0, e.x - b, e.y - b, | |
250 e.x - hao - b, e.y - b, e.x - hao - haw / 2, e.y + hah - b, | |
251 e.x - hao - haw, e.y - b, 0, e.y - b, 0, 0 ]; | |
252 } | |
253 | |
254 /* | |
255 * Dispose the hover, it is no longer needed. Dispose any resources | |
256 * allocated by the hover. | |
257 */ | |
258 void dispose() { | |
259 if (!hoverShell.isDisposed()) { | |
260 hoverShell.dispose(); | |
261 } | |
262 if (region !is null) { | |
263 region.dispose(); | |
264 } | |
265 } | |
266 | |
267 /* | |
268 * Set the visibility of the hover. | |
269 */ | |
270 void setVisible(bool visible) { | |
271 if (visible) { | |
272 if (!hoverShell.isVisible()) { | |
273 hoverShell.setVisible(true); | |
274 } | |
275 } else { | |
276 if (hoverShell.isVisible()) { | |
277 hoverShell.setVisible(false); | |
278 } | |
279 } | |
280 } | |
281 | |
282 /* | |
283 * Set the text of the hover to the specified text. Recompute the size | |
284 * and location of the hover to hover near the specified control, | |
285 * pointing the arrow toward the target control. | |
286 */ | |
287 void setText(String t, Control hoverNear, Control targetControl) { | |
288 if (t is null) { | |
289 t = EMPTY; | |
290 } | |
291 if (!t.equals(text)) { | |
292 Point oldSize = getExtent(); | |
293 text = t; | |
294 hoverShell.redraw(); | |
295 Point newSize = getExtent(); | |
296 if (!oldSize.opEquals(newSize)) { | |
297 // set a flag that indicates the direction of arrow | |
298 arrowOnLeft = hoverNear.getLocation().x <= targetControl | |
299 .getLocation().x; | |
300 setNewShape(); | |
301 } | |
302 } | |
303 | |
304 if (hoverNear !is null) { | |
305 Point extent = getExtent(); | |
306 int y = -extent.y - hah + 1; | |
307 int x = arrowOnLeft ? -hao + haw / 2 : -extent.x + hao + haw | |
308 / 2; | |
309 | |
310 hoverShell.setLocation(hoverNear.toDisplay(x, y)); | |
311 } | |
312 | |
313 } | |
314 | |
315 /* | |
316 * Return whether or not the hover (shell) is visible. | |
317 */ | |
318 bool isVisible() { | |
319 return hoverShell.isVisible(); | |
320 } | |
321 | |
322 /* | |
323 * Compute the extent of the hover for the current text. | |
324 */ | |
325 Point getExtent() { | |
326 GC gc = new GC(hoverShell); | |
327 Point e = gc.textExtent(text); | |
328 gc.dispose(); | |
329 e.x += hm * 2; | |
330 e.y += hm * 2; | |
331 return e; | |
332 } | |
333 | |
334 /* | |
335 * Compute a new shape for the hover shell. | |
336 */ | |
337 void setNewShape() { | |
338 Region oldRegion = region; | |
339 region = new Region(); | |
340 region.add(getPolygon(false)); | |
341 hoverShell.setRegion(region); | |
342 if (oldRegion !is null) { | |
343 oldRegion.dispose(); | |
344 } | |
345 | |
346 } | |
347 } | |
348 | |
349 /** | |
350 * Construct a decorated field which is parented by the specified composite | |
351 * and has the given style bits. Use the controlCreator to create the | |
352 * specific kind of control that is decorated inside the field. | |
353 * | |
354 * @param parent | |
355 * the parent of the decorated field. | |
356 * @param style | |
357 * the desired style bits for the field. | |
358 * @param controlCreator | |
359 * the IControlCreator used to specify the specific kind of | |
360 * control that is to be decorated. | |
361 * | |
362 * @see IControlCreator | |
363 */ | |
364 public this(Composite parent, int style, | |
365 IControlCreator controlCreator) { | |
366 decDatas = new FieldDecorationData[DECORATION_SLOTS]; | |
367 this.form = createForm(parent); | |
368 this.control = controlCreator.createControl(form, style); | |
369 | |
370 addControlListeners(); | |
371 form.setTabList([ control ]); | |
372 | |
373 // Set up the initial layout data. | |
374 FormData data = new FormData(); | |
375 data.left = new FormAttachment(0, 0); | |
376 data.top = new FormAttachment(0, 0); | |
377 data.right = new FormAttachment(100, 0); | |
378 data.bottom = new FormAttachment(100, 0); | |
379 control.setLayoutData(data); | |
380 | |
381 } | |
382 | |
383 /** | |
384 * Adds an image decoration to the field. | |
385 * | |
386 * @param decoration | |
387 * A FieldDecoration describing the image and description for the | |
388 * decoration | |
389 * | |
390 * @param position | |
391 * The DWT constant indicating the position of the decoration | |
392 * relative to the field's control. The position should include | |
393 * style bits describing both the vertical and horizontal | |
394 * orientation. <code>DWT.LEFT</code> and | |
395 * <code>DWT.RIGHT</code> describe the horizontal placement of | |
396 * the decoration relative to the field, and the constants | |
397 * <code>DWT.TOP</code> and <code>DWT.BOTTOM</code> describe | |
398 * the vertical alignment of the decoration relative to the | |
399 * field. Decorations always appear on either horizontal side of | |
400 * the field, never above or below it. For example, a decoration | |
401 * appearing on the left side of the field, at the top, is | |
402 * specified as DWT.LEFT | DWT.TOP. If an image decoration | |
403 * already exists in the specified position, it will be replaced | |
404 * by the one specified. | |
405 * @param showOnFocus | |
406 * <code>true</code> if the decoration should only be shown | |
407 * when the associated control has focus, <code>false</code> if | |
408 * it should always be shown. | |
409 * | |
410 */ | |
411 public void addFieldDecoration(FieldDecoration decoration, int position, | |
412 bool showOnFocus) { | |
413 Label label; | |
414 FormData formData; | |
415 int i = indexForPosition(position); | |
416 if (decDatas[i] is null) { | |
417 formData = createFormDataForIndex(i, decoration.getImage()); | |
418 label = new Label(form, DWT.HORIZONTAL | DWT.VERTICAL | DWT.CENTER); | |
39 | 419 label.addMouseTrackListener(new class(label) MouseTrackListener { |
17 | 420 Label label_; |
39 | 421 this(Label a){ |
422 label_=a; | |
17 | 423 } |
424 public void mouseHover(MouseEvent event) { | |
425 FieldDecorationData decData = cast(FieldDecorationData) event.widget | |
426 .getData(); | |
427 String desc = decData.decoration.getDescription(); | |
428 if (desc !is null) { | |
429 showHoverText(desc, label_); | |
430 } | |
431 } | |
432 | |
433 public void mouseEnter(MouseEvent event) { | |
434 } | |
435 | |
436 public void mouseExit(MouseEvent event) { | |
437 hideHover(); | |
438 } | |
439 }); | |
440 decDatas[i] = new FieldDecorationData(decoration, label, formData, | |
441 showOnFocus); | |
442 } else { | |
443 label = decDatas[i].label; | |
444 formData = decDatas[i].data; | |
445 decDatas[i].decoration = decoration; | |
446 decDatas[i].showOnFocus = showOnFocus; | |
447 } | |
448 label.setImage(decDatas[i].decoration.getImage()); | |
449 label.setData(decDatas[i]); | |
450 label.setLayoutData(formData); | |
451 label.setVisible(!showOnFocus); | |
452 | |
453 // Since sizes may have changed or there could be a new position | |
454 // defined, we need to update layout data on the control. | |
455 updateControlAttachments(i, decDatas[i]); | |
456 } | |
457 | |
458 /* | |
459 * A decoration at the specified index has been added. Update the control's | |
460 * attachments if it has not previously been attached on that side or if it | |
461 * was attached to a decoration with a lesser width. | |
462 */ | |
463 private void updateControlAttachments(int index, FieldDecorationData decData) { | |
464 FormData formData = cast(FormData) control.getLayoutData(); | |
465 int newWidth = widthOf(decData.decoration.getImage()); | |
466 // opposing represents the location of the decoration above or below | |
467 // the one in question. | |
468 int opposing; | |
469 | |
470 switch (index) { | |
471 case LEFT_TOP: | |
472 case LEFT_BOTTOM: | |
473 if (index is LEFT_TOP) { | |
474 opposing = LEFT_BOTTOM; | |
475 } else { | |
476 opposing = LEFT_TOP; | |
477 } | |
478 if (decDatas[opposing] is null) { | |
479 // No decorator on the opposing side. | |
480 // Attach the control to this decorator | |
481 formData.left = new FormAttachment(decData.label); | |
482 } else if (decDatas[opposing].data.width < newWidth) { | |
483 // Decorator on opposing side is the smaller one. Attach | |
484 // control to the new one. | |
485 formData.left = new FormAttachment(decData.label); | |
486 // Center align the smaller one relative to the larger one. | |
487 decDatas[opposing].data.left.alignment = DWT.CENTER; | |
488 decDatas[opposing].data.left.control = decData.label; | |
489 } else { | |
490 // The new decorator is the smaller one. Keep the | |
491 // control attached to the opposing one. | |
492 formData = null; | |
493 // Horizontally center the smaller one relative to the larger | |
494 // one. | |
495 decData.data.left.alignment = DWT.CENTER; | |
496 decData.data.left.control = decDatas[opposing].label; | |
497 } | |
498 break; | |
499 /* | |
500 * The only real difference in right side cases is that we are attaching | |
501 * the right side of the control to the wider decoration rather than the | |
502 * left side of the control. Other concerns (horizontally aligning the | |
503 * smaller decoration relative to the larger one) are the same. | |
504 */ | |
505 case RIGHT_TOP: | |
506 case RIGHT_BOTTOM: | |
507 if (index is RIGHT_TOP) { | |
508 opposing = RIGHT_BOTTOM; | |
509 } else { | |
510 opposing = RIGHT_TOP; | |
511 } | |
512 if (decDatas[opposing] is null) { | |
513 // No decorator on the opposing side. | |
514 // Attach the control to this decorator. | |
515 formData.right = new FormAttachment(decData.label); | |
516 } else if (decDatas[opposing].data.width < newWidth) { | |
517 // Decorator on opposing side is the smaller one. Attach | |
518 // control to the new one. | |
519 formData.right = new FormAttachment(decData.label); | |
520 // Center align the smaller one to the larger one. | |
521 // Note that this could be done using the left or right | |
522 // attachment, we use the right since it is already | |
523 // created for all right-side decorations. | |
524 decDatas[opposing].data.right.alignment = DWT.CENTER; | |
525 decDatas[opposing].data.right.control = decData.label; | |
526 } else { | |
527 // The new decorator is the smaller one. Keep the | |
528 // control attached to the opposing one. | |
529 formData = null; | |
530 // Horizontally center align the smaller one to the | |
531 // larger one. | |
532 decData.data.right.alignment = DWT.CENTER; | |
533 decData.data.right.control = decDatas[opposing].label; | |
534 } | |
535 break; | |
536 default: | |
537 return; | |
538 } | |
539 if (formData !is null) { | |
540 // Form data was updated. | |
541 control.setLayoutData(formData); | |
542 form.layout(); | |
543 } | |
544 } | |
545 | |
546 /** | |
547 * Get the control that is decorated by the receiver. | |
548 * | |
549 * @return the Control decorated by the receiver, or <code>null</code> if | |
550 * none has been created yet. | |
551 */ | |
552 public Control getControl() { | |
553 return control; | |
554 } | |
555 | |
556 /** | |
557 * Get the control that represents the decorated field. This composite | |
558 * should be used to lay out the field within its parent. | |
559 * | |
560 * @return the Control that should be layed out in the field's parent's | |
561 * layout. This is typically not the control itself, since | |
562 * additional controls are used to represent the decorations. | |
563 */ | |
564 public Control getLayoutControl() { | |
565 return form; | |
566 } | |
567 | |
568 /** | |
569 * Create the parent composite and a form layout that will be used to manage | |
570 * decorations. | |
571 */ | |
572 private Composite createForm(Composite parent) { | |
573 Composite composite = new Composite(parent, DWT.NO_FOCUS); | |
574 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=126553 | |
575 composite.setBackgroundMode(DWT.INHERIT_DEFAULT); | |
576 composite.setLayout(new FormLayout()); | |
577 return composite; | |
578 } | |
579 | |
580 /** | |
581 * Add any listeners needed on the target control. | |
582 */ | |
583 private void addControlListeners() { | |
584 control.addDisposeListener(new class DisposeListener { | |
585 public void widgetDisposed(DisposeEvent event) { | |
586 if (hover !is null) { | |
587 hover.dispose(); | |
588 } | |
589 } | |
590 }); | |
591 control.addFocusListener(new class FocusListener { | |
592 public void focusGained(FocusEvent event) { | |
593 controlFocusGained(); | |
594 } | |
595 | |
596 public void focusLost(FocusEvent event) { | |
597 controlFocusLost(); | |
598 } | |
599 | |
600 }); | |
601 } | |
602 | |
603 /* | |
604 * Return the index in the array of decoration datas that represents the | |
605 * specified DWT position. | |
606 * | |
607 * @param position The DWT constant indicating the position of the | |
608 * decoration relative to the field's control. The position should include | |
609 * style bits describing both the vertical and horizontal orientation. | |
610 * <code>DWT.LEFT</code> and <code>DWT.RIGHT</code> describe the | |
611 * horizontal placement of the decoration relative to the field, and the | |
612 * constants <code>DWT.TOP</code> and <code>DWT.BOTTOM</code> describe | |
613 * the vertical alignment of the decoration relative to the field. | |
614 * Decorations always appear on either horizontal side of the field, never | |
615 * above or below it. For example, a decoration appearing on the left side | |
616 * of the field, at the top, is specified as DWT.LEFT | DWT.TOP. | |
617 * | |
618 * @return index the index in the array of decorations that represents the | |
619 * specified DWT position. If the position is not an expected position, the | |
620 * index representing the top left position will be returned. | |
621 * | |
622 */ | |
623 private int indexForPosition(int position) { | |
624 switch (position) { | |
625 case DWT.LEFT | DWT.BOTTOM: | |
626 return LEFT_BOTTOM; | |
627 case DWT.RIGHT | DWT.TOP: | |
628 return RIGHT_TOP; | |
629 case DWT.RIGHT | DWT.BOTTOM: | |
630 return RIGHT_BOTTOM; | |
631 default: | |
632 return LEFT_TOP; | |
633 } | |
634 } | |
635 | |
636 /* | |
637 * Create a form data that will place the decoration at the specified | |
638 * position. | |
639 * | |
640 * @param index the index in the decDatas describing the position of the | |
641 * decoration. | |
642 * | |
643 * @param image the image shown in the decoration. | |
644 * | |
645 */ | |
646 private FormData createFormDataForIndex(int index, Image image) { | |
647 Assert.isTrue(index >= 0 && index < DECORATION_SLOTS, | |
648 "Index out of range"); //$NON-NLS-1$ | |
649 | |
650 FormData data = new FormData(); | |
651 switch (index) { | |
652 case LEFT_TOP: | |
653 data.left = new FormAttachment(0, 0); | |
654 data.top = new FormAttachment(0, 0); | |
655 break; | |
656 case LEFT_BOTTOM: | |
657 data.left = new FormAttachment(0, 0); | |
658 data.bottom = new FormAttachment(100, 0); | |
659 break; | |
660 case RIGHT_TOP: | |
661 data.right = new FormAttachment(100, 0); | |
662 data.top = new FormAttachment(0, 0); | |
663 break; | |
664 case RIGHT_BOTTOM: | |
665 data.right = new FormAttachment(100, 0); | |
666 data.bottom = new FormAttachment(100, 0); | |
667 break; | |
192
c3583c6ec027
Added missing default cases for switch statements
Frank Benoit <benoit@tionex.de>
parents:
70
diff
changeset
|
668 default: |
17 | 669 } |
670 data.width = widthOf(image); | |
671 data.height = DWT.DEFAULT; | |
672 | |
673 return data; | |
674 } | |
675 | |
676 /** | |
677 * Show the specified text using the same hover dialog as is used to show | |
678 * decorator descriptions. Normally, a decoration's description text will be | |
679 * shown in an info hover over the field's control whenever the mouse hovers | |
680 * over the decoration. This method can be used to show a decoration's | |
681 * description text at other times (such as when the control receives | |
682 * focus), or to show other text associated with the field. | |
683 * | |
684 * <p> | |
685 * If there is currently a hover visible, the hover's text will be replaced | |
686 * with the specified text. | |
687 * | |
688 * @param text | |
689 * the text to be shown in the info hover, or <code>null</code> | |
690 * if no text should be shown. | |
691 */ | |
692 public void showHoverText(String text) { | |
693 showHoverText(text, control); | |
694 } | |
695 | |
696 /** | |
697 * Hide any hover popups that are currently showing on the control. | |
698 * Normally, a decoration's description text will be shown in an info hover | |
699 * over the field's control as long as the mouse hovers over the decoration, | |
700 * and will be hidden when the mouse exits the control. This method can be | |
701 * used to hide a hover that was shown using <code>showHoverText</code>, | |
702 * or to programatically hide the current decoration hover. | |
703 * | |
704 * <p> | |
705 * This message has no effect if there is no current hover. | |
706 * | |
707 */ | |
708 public void hideHover() { | |
709 if (hover !is null) { | |
710 hover.setVisible(false); | |
711 } | |
712 } | |
713 | |
714 /* | |
715 * The target control gained focus. Any decorations that should show only | |
716 * when they have the focus should be shown here. | |
717 */ | |
718 private void controlFocusGained() { | |
719 for (int i = 0; i < DECORATION_SLOTS; i++) { | |
720 if (decDatas[i] !is null && decDatas[i].showOnFocus) { | |
721 setVisible(decDatas[i], true); | |
722 } | |
723 } | |
724 } | |
725 | |
726 /* | |
727 * The target control lost focus. Any decorations that should show only when | |
728 * they have the focus should be hidden here. | |
729 */ | |
730 private void controlFocusLost() { | |
731 for (int i = 0; i < DECORATION_SLOTS; i++) { | |
732 if (decDatas[i] !is null && decDatas[i].showOnFocus) { | |
733 setVisible(decDatas[i], false); | |
734 } | |
735 } | |
736 } | |
737 | |
738 /** | |
739 * Show the specified decoration. This message has no effect if the | |
740 * decoration is already showing, or was not already added to the field | |
741 * using <code>addFieldDecoration</code>. | |
742 * | |
743 * @param decoration | |
744 * the decoration to be shown. | |
745 */ | |
746 public void showDecoration(FieldDecoration decoration) { | |
747 FieldDecorationData data = getDecorationData(decoration); | |
748 if (data is null) { | |
749 return; | |
750 } | |
751 // record the fact that client would like it to be visible | |
752 data.visible = true; | |
753 // even if it is supposed to be shown, if the field does not have focus, | |
754 // do not show it (yet) | |
755 if (!data.showOnFocus || control.isFocusControl()) { | |
756 setVisible(data, true); | |
757 } | |
758 } | |
759 | |
760 /** | |
761 * Hide the specified decoration. This message has no effect if the | |
762 * decoration is already hidden, or was not already added to the field using | |
763 * <code>addFieldDecoration</code>. | |
764 * | |
765 * @param decoration | |
766 * the decoration to be hidden. | |
767 */ | |
768 public void hideDecoration(FieldDecoration decoration) { | |
769 FieldDecorationData data = getDecorationData(decoration); | |
770 if (data is null) { | |
771 return; | |
772 } | |
773 // Store the desired visibility in the decData. We remember the | |
774 // client's instructions so that changes in visibility caused by | |
775 // field focus changes won't violate the client's visibility setting. | |
776 data.visible = false; | |
777 setVisible(data, false); | |
778 } | |
779 | |
780 /** | |
781 * Update the specified decoration. This message should be used if the image | |
782 * or description in the decoration have changed. This message has no | |
783 * immediate effect if the decoration is not visible, and no effect at all | |
784 * if the decoration was not previously added to the field. | |
785 * | |
786 * @param decoration | |
787 * the decoration to be hidden. | |
788 */ | |
789 public void updateDecoration(FieldDecoration decoration) { | |
790 FieldDecorationData data = getDecorationData(decoration); | |
791 if (data is null) { | |
792 return; | |
793 } | |
794 if (data.label !is null) { | |
795 data.label.setImage(decoration.getImage()); | |
796 // If the decoration is being shown, and a hover is active, | |
797 // update the hover text to display the new description. | |
798 if (data.label.getVisible() is true && hover !is null) { | |
799 showHoverText(decoration.getDescription(), data.label); | |
800 } | |
801 } | |
802 } | |
803 | |
804 /* | |
805 * Set the visibility of the specified decoration data. This method does not | |
806 * change the visibility value stored in the decData, but instead consults | |
807 * it to determine how the visibility should be changed. This method is | |
808 * called any time visibility of a decoration might change, whether by | |
809 * client API or focus changes. | |
810 */ | |
811 private void setVisible(FieldDecorationData decData, bool visible) { | |
812 // Check the decData visibility flag, since it contains the client's | |
813 // instructions for visibility. | |
814 if (visible && decData.visible) { | |
815 decData.label.setVisible(true); | |
816 } else { | |
817 decData.label.setVisible(false); | |
818 } | |
819 } | |
820 | |
821 /* | |
822 * Get the FieldDecorationData that corresponds to the given decoration. | |
823 */ | |
824 private FieldDecorationData getDecorationData(FieldDecoration dec) { | |
825 for (int i = 0; i < DECORATION_SLOTS; i++) { | |
826 if (decDatas[i] !is null && dec is decDatas[i].decoration | |
827 && decDatas[i].label !is null | |
828 && !decDatas[i].label.isDisposed()) { | |
829 return decDatas[i]; | |
830 } | |
831 } | |
832 return null; | |
833 } | |
834 | |
835 /* | |
836 * Show the specified text in the hover, positioning the hover near the | |
837 * specified control. | |
838 */ | |
839 private void showHoverText(String text, Control hoverNear) { | |
840 if (text is null) { | |
841 hideHover(); | |
842 return; | |
843 } | |
844 | |
845 if (hover is null) { | |
846 hover = new Hover(hoverNear.getShell()); | |
847 } | |
848 hover.setText(text, hoverNear, control); | |
849 hover.setVisible(true); | |
850 } | |
851 | |
852 /** | |
853 * Set a bool that indicates whether the receiver should use the | |
854 * decoration registry's maximum decoration width when allocating space for | |
855 * decorations. The default value is <code>true</code>. Using the maximum | |
856 * decoration width is useful so that decorated fields on the same dialog | |
857 * that have different decoration widths will all align. This also allows | |
858 * client dialogs to align non-decorated fields with decorated fields by | |
859 * consulting the maximum decoration width. | |
860 * </p> | |
861 * <p> | |
862 * Clients may wish to set this value to <code>false</code> in cases where | |
863 * space usage is more important than alignment of fields. This value must | |
864 * be set before the decorations are added in order to ensure proper | |
865 * alignment. | |
866 * </p> | |
867 * | |
868 * @param useMaximumWidth | |
869 * <code>true</code> if the maximum decoration width should be | |
870 * used as the size for all decorations, <code>false</code> if | |
871 * only the decoration size should be used. | |
872 * | |
873 * @see FieldDecorationRegistry#getMaximumDecorationWidth() | |
874 */ | |
875 public void setUseMaximumDecorationWidth(bool useMaximumWidth) { | |
876 useMaxDecorationWidth = useMaximumWidth; | |
877 } | |
878 | |
879 /* | |
880 * Return the width appropriate for the specified decoration image. | |
881 */ | |
882 private int widthOf(Image image) { | |
883 if (image is null) { | |
884 return 0; | |
885 } | |
886 return useMaxDecorationWidth ? FieldDecorationRegistry.getDefault() | |
887 .getMaximumDecorationWidth() : image.getBounds().width; | |
888 } | |
889 } |