]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - FormUtil.java
37e95435e61e610a9d78e50443d8341a0706948c
1 package org
.argeo
.eclipse
.ui
.forms
;
3 import org
.eclipse
.swt
.SWT
;
4 import org
.eclipse
.swt
.custom
.ScrolledComposite
;
5 import org
.eclipse
.swt
.events
.MouseEvent
;
6 //import org.eclipse.swt.graphics.Device;
7 import org
.eclipse
.swt
.graphics
.FontMetrics
;
8 import org
.eclipse
.swt
.graphics
.GC
;
9 //import org.eclipse.swt.graphics.Image;
10 //import org.eclipse.swt.graphics.ImageData;
11 import org
.eclipse
.swt
.graphics
.Point
;
12 import org
.eclipse
.swt
.graphics
.Rectangle
;
13 import org
.eclipse
.swt
.layout
.GridData
;
14 import org
.eclipse
.swt
.widgets
.Combo
;
15 import org
.eclipse
.swt
.widgets
.Composite
;
16 import org
.eclipse
.swt
.widgets
.Control
;
17 import org
.eclipse
.swt
.widgets
.Label
;
18 import org
.eclipse
.swt
.widgets
.Layout
;
19 //import org.eclipse.swt.widgets.ScrollBar;
20 import org
.eclipse
.swt
.widgets
.Text
;
21 //import org.eclipse.ui.forms.widgets.ColumnLayout;
22 //import org.eclipse.ui.forms.widgets.Form;
23 //import org.eclipse.ui.forms.widgets.FormText;
24 //import org.eclipse.ui.forms.widgets.FormToolkit;
25 //import org.eclipse.ui.forms.widgets.ILayoutExtension;
27 import com
.ibm
.icu
.text
.BreakIterator
;
29 public class FormUtil
{
30 public static final String PLUGIN_ID
= "org.eclipse.ui.forms"; //$NON-NLS-1$
32 static final int H_SCROLL_INCREMENT
= 5;
34 static final int V_SCROLL_INCREMENT
= 64;
36 public static final String DEBUG
= PLUGIN_ID
+ "/debug"; //$NON-NLS-1$
38 public static final String DEBUG_TEXT
= DEBUG
+ "/text"; //$NON-NLS-1$
39 public static final String DEBUG_TEXTSIZE
= DEBUG
+ "/textsize"; //$NON-NLS-1$
41 public static final String DEBUG_FOCUS
= DEBUG
+ "/focus"; //$NON-NLS-1$
43 public static final String FOCUS_SCROLLING
= "focusScrolling"; //$NON-NLS-1$
45 public static final String IGNORE_BODY
= "__ignore_body__"; //$NON-NLS-1$
47 public static Text
createText(Composite parent
, String label
,
48 FormToolkit factory
) {
49 return createText(parent
, label
, factory
, 1);
52 public static Text
createText(Composite parent
, String label
,
53 FormToolkit factory
, int span
) {
54 factory
.createLabel(parent
, label
);
55 Text text
= factory
.createText(parent
, ""); //$NON-NLS-1$
56 int hfill
= span
== 1 ? GridData
.FILL_HORIZONTAL
57 : GridData
.HORIZONTAL_ALIGN_FILL
;
58 GridData gd
= new GridData(hfill
| GridData
.VERTICAL_ALIGN_CENTER
);
59 gd
.horizontalSpan
= span
;
60 text
.setLayoutData(gd
);
64 public static Text
createText(Composite parent
, String label
,
65 FormToolkit factory
, int span
, int style
) {
66 Label l
= factory
.createLabel(parent
, label
);
67 if ((style
& SWT
.MULTI
) != 0) {
68 GridData gd
= new GridData(GridData
.VERTICAL_ALIGN_BEGINNING
);
71 Text text
= factory
.createText(parent
, "", style
); //$NON-NLS-1$
72 int hfill
= span
== 1 ? GridData
.FILL_HORIZONTAL
73 : GridData
.HORIZONTAL_ALIGN_FILL
;
74 GridData gd
= new GridData(hfill
| GridData
.VERTICAL_ALIGN_CENTER
);
75 gd
.horizontalSpan
= span
;
76 text
.setLayoutData(gd
);
80 public static Text
createText(Composite parent
, FormToolkit factory
,
82 Text text
= factory
.createText(parent
, ""); //$NON-NLS-1$
83 int hfill
= span
== 1 ? GridData
.FILL_HORIZONTAL
84 : GridData
.HORIZONTAL_ALIGN_FILL
;
85 GridData gd
= new GridData(hfill
| GridData
.VERTICAL_ALIGN_CENTER
);
86 gd
.horizontalSpan
= span
;
87 text
.setLayoutData(gd
);
91 public static int computeMinimumWidth(GC gc
, String text
) {
92 BreakIterator wb
= BreakIterator
.getWordInstance();
98 for (int loc
= wb
.first(); loc
!= BreakIterator
.DONE
; loc
= wb
.next()) {
99 String word
= text
.substring(last
, loc
);
100 Point extent
= gc
.textExtent(word
);
101 width
= Math
.max(width
, extent
.x
);
104 String lastWord
= text
.substring(last
);
105 Point extent
= gc
.textExtent(lastWord
);
106 width
= Math
.max(width
, extent
.x
);
110 public static Point
computeWrapSize(GC gc
, String text
, int wHint
) {
111 BreakIterator wb
= BreakIterator
.getWordInstance();
113 FontMetrics fm
= gc
.getFontMetrics();
114 int lineHeight
= fm
.getHeight();
118 int height
= lineHeight
;
120 for (int loc
= wb
.first(); loc
!= BreakIterator
.DONE
; loc
= wb
.next()) {
121 String word
= text
.substring(saved
, loc
);
122 Point extent
= gc
.textExtent(word
);
123 if (extent
.x
> wHint
) {
127 // switch to current word so maxWidth will accommodate very long single words
128 word
= text
.substring(last
, loc
);
129 extent
= gc
.textExtent(word
);
131 maxWidth
= Math
.max(maxWidth
, extent
.x
);
135 * Correct the height attribute in case it was calculated wrong due to wHint being less than maxWidth.
136 * The recursive call proved to be the only thing that worked in all cases. Some attempts can be made
137 * to estimate the height, but the algorithm needs to be run again to be sure.
139 if (maxWidth
> wHint
)
140 return computeWrapSize(gc
, text
, maxWidth
);
141 return new Point(maxWidth
, height
);
144 // RAP [rh] paintWrapText unnecessary
145 // public static void paintWrapText(GC gc, String text, Rectangle bounds) {
146 // paintWrapText(gc, text, bounds, false);
149 // RAP [rh] paintWrapText unnecessary
150 // public static void paintWrapText(GC gc, String text, Rectangle bounds,
151 // boolean underline) {
152 // BreakIterator wb = BreakIterator.getWordInstance();
154 // FontMetrics fm = gc.getFontMetrics();
155 // int lineHeight = fm.getHeight();
156 // int descent = fm.getDescent();
161 // int width = bounds.width;
163 // for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) {
164 // String line = text.substring(saved, loc);
165 // Point extent = gc.textExtent(line);
167 // if (extent.x > width) {
169 // String prevLine = text.substring(saved, last);
170 // gc.drawText(prevLine, bounds.x, y, true);
172 // Point prevExtent = gc.textExtent(prevLine);
173 // int lineY = y + lineHeight - descent + 1;
175 // .drawLine(bounds.x, lineY, bounds.x + prevExtent.x,
184 // // paint the last line
185 // String lastLine = text.substring(saved, last);
186 // gc.drawText(lastLine, bounds.x, y, true);
188 // int lineY = y + lineHeight - descent + 1;
189 // Point lastExtent = gc.textExtent(lastLine);
190 // gc.drawLine(bounds.x, lineY, bounds.x + lastExtent.x, lineY);
194 public static ScrolledComposite
getScrolledComposite(Control c
) {
195 Composite parent
= c
.getParent();
197 while (parent
!= null) {
198 if (parent
instanceof ScrolledComposite
) {
199 return (ScrolledComposite
) parent
;
201 parent
= parent
.getParent();
206 public static void ensureVisible(Control c
) {
207 ScrolledComposite scomp
= getScrolledComposite(c
);
209 Object data
= scomp
.getData(FOCUS_SCROLLING
);
210 if (data
== null || !data
.equals(Boolean
.FALSE
))
211 FormUtil
.ensureVisible(scomp
, c
);
215 public static void ensureVisible(ScrolledComposite scomp
, Control control
) {
216 // if the control is a FormText we do not need to scroll since it will
217 // ensure visibility of its segments as necessary
218 // if (control instanceof FormText)
220 Point controlSize
= control
.getSize();
221 Point controlOrigin
= getControlLocation(scomp
, control
);
222 ensureVisible(scomp
, controlOrigin
, controlSize
);
225 public static void ensureVisible(ScrolledComposite scomp
,
226 Point controlOrigin
, Point controlSize
) {
227 Rectangle area
= scomp
.getClientArea();
228 Point scompOrigin
= scomp
.getOrigin();
230 int x
= scompOrigin
.x
;
231 int y
= scompOrigin
.y
;
233 // horizontal right, but only if the control is smaller
234 // than the client area
235 if (controlSize
.x
< area
.width
236 && (controlOrigin
.x
+ controlSize
.x
> scompOrigin
.x
238 x
= controlOrigin
.x
+ controlSize
.x
- area
.width
;
240 // horizontal left - make sure the left edge of
241 // the control is showing
242 if (controlOrigin
.x
< x
) {
243 if (controlSize
.x
< area
.width
)
244 x
= controlOrigin
.x
+ controlSize
.x
- area
.width
;
249 if (controlSize
.y
< area
.height
250 && (controlOrigin
.y
+ controlSize
.y
> scompOrigin
.y
252 y
= controlOrigin
.y
+ controlSize
.y
- area
.height
;
254 // vertical top - make sure the top of
255 // the control is showing
256 if (controlOrigin
.y
< y
) {
257 if (controlSize
.y
< area
.height
)
258 y
= controlOrigin
.y
+ controlSize
.y
- area
.height
;
263 if (scompOrigin
.x
!= x
|| scompOrigin
.y
!= y
) {
265 scomp
.setOrigin(x
, y
);
269 public static void ensureVisible(ScrolledComposite scomp
, Control control
,
271 Point controlOrigin
= getControlLocation(scomp
, control
);
272 int rX
= controlOrigin
.x
+ e
.x
;
273 int rY
= controlOrigin
.y
+ e
.y
;
274 Rectangle area
= scomp
.getClientArea();
275 Point scompOrigin
= scomp
.getOrigin();
277 int x
= scompOrigin
.x
;
278 int y
= scompOrigin
.y
;
279 // System.out.println("Ensure: area="+area+", origin="+scompOrigin+",
280 // cloc="+controlOrigin+", csize="+controlSize+", x="+x+", y="+y);
283 if (rX
> scompOrigin
.x
+ area
.width
) {
291 if (rY
> scompOrigin
.y
+ area
.height
) {
292 y
= rY
- area
.height
;
299 if (scompOrigin
.x
!= x
|| scompOrigin
.y
!= y
) {
301 scomp
.setOrigin(x
, y
);
305 public static Point
getControlLocation(ScrolledComposite scomp
,
309 Control content
= scomp
.getContent();
310 Control currentControl
= control
;
312 if (currentControl
== content
)
314 Point location
= currentControl
.getLocation();
315 // if (location.x > 0)
317 // if (location.y > 0)
321 currentControl
= currentControl
.getParent();
323 return new Point(x
, y
);
326 static void scrollVertical(ScrolledComposite scomp
, boolean up
) {
327 scroll(scomp
, 0, up ?
-V_SCROLL_INCREMENT
: V_SCROLL_INCREMENT
);
330 static void scrollHorizontal(ScrolledComposite scomp
, boolean left
) {
331 scroll(scomp
, left ?
-H_SCROLL_INCREMENT
: H_SCROLL_INCREMENT
, 0);
334 static void scrollPage(ScrolledComposite scomp
, boolean up
) {
335 Rectangle clientArea
= scomp
.getClientArea();
336 int increment
= up ?
-clientArea
.height
: clientArea
.height
;
337 scroll(scomp
, 0, increment
);
340 static void scroll(ScrolledComposite scomp
, int xoffset
, int yoffset
) {
341 Point origin
= scomp
.getOrigin();
342 Point contentSize
= scomp
.getContent().getSize();
343 int xorigin
= origin
.x
+ xoffset
;
344 int yorigin
= origin
.y
+ yoffset
;
345 xorigin
= Math
.max(xorigin
, 0);
346 xorigin
= Math
.min(xorigin
, contentSize
.x
- 1);
347 yorigin
= Math
.max(yorigin
, 0);
348 yorigin
= Math
.min(yorigin
, contentSize
.y
- 1);
349 scomp
.setOrigin(xorigin
, yorigin
);
352 // RAP [rh] FormUtil#updatePageIncrement: empty implementation
353 public static void updatePageIncrement(ScrolledComposite scomp
) {
354 // ScrollBar vbar = scomp.getVerticalBar();
355 // if (vbar != null) {
356 // Rectangle clientArea = scomp.getClientArea();
357 // int increment = clientArea.height - 5;
358 // vbar.setPageIncrement(increment);
360 // ScrollBar hbar = scomp.getHorizontalBar();
361 // if (hbar != null) {
362 // Rectangle clientArea = scomp.getClientArea();
363 // int increment = clientArea.width - 5;
364 // hbar.setPageIncrement(increment);
368 public static void processKey(int keyCode
, Control c
) {
369 if (c
.isDisposed()) {
372 ScrolledComposite scomp
= FormUtil
.getScrolledComposite(c
);
374 if (c
instanceof Combo
)
378 if (scomp
.getData("novarrows") == null) //$NON-NLS-1$
379 FormUtil
.scrollVertical(scomp
, false);
382 if (scomp
.getData("novarrows") == null) //$NON-NLS-1$
383 FormUtil
.scrollVertical(scomp
, true);
386 FormUtil
.scrollHorizontal(scomp
, true);
388 case SWT
.ARROW_RIGHT
:
389 FormUtil
.scrollHorizontal(scomp
, false);
392 FormUtil
.scrollPage(scomp
, true);
395 FormUtil
.scrollPage(scomp
, false);
401 public static boolean isWrapControl(Control c
) {
402 if ((c
.getStyle() & SWT
.WRAP
) != 0)
404 if (c
instanceof Composite
) {
406 // return ((Composite) c).getLayout() instanceof ILayoutExtension;
411 public static int getWidthHint(int wHint
, Control c
) {
412 boolean wrap
= isWrapControl(c
);
413 return wrap ? wHint
: SWT
.DEFAULT
;
416 public static int getHeightHint(int hHint
, Control c
) {
417 if (c
instanceof Composite
) {
418 Layout layout
= ((Composite
) c
).getLayout();
419 // if (layout instanceof ColumnLayout)
425 public static int computeMinimumWidth(Control c
, boolean changed
) {
426 if (c
instanceof Composite
) {
427 Layout layout
= ((Composite
) c
).getLayout();
428 // if (layout instanceof ILayoutExtension)
429 // return ((ILayoutExtension) layout).computeMinimumWidth(
430 // (Composite) c, changed);
432 return c
.computeSize(FormUtil
.getWidthHint(5, c
), SWT
.DEFAULT
, changed
).x
;
435 public static int computeMaximumWidth(Control c
, boolean changed
) {
436 if (c
instanceof Composite
) {
437 Layout layout
= ((Composite
) c
).getLayout();
438 // if (layout instanceof ILayoutExtension)
439 // return ((ILayoutExtension) layout).computeMaximumWidth(
440 // (Composite) c, changed);
442 return c
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
, changed
).x
;
445 // public static Form getForm(Control c) {
446 // Composite parent = c.getParent();
447 // while (parent != null) {
448 // if (parent instanceof Form) {
449 // return (Form) parent;
451 // parent = parent.getParent();
456 // RAP [rh] FormUtil#createAlphaMashImage unnecessary
457 // public static Image createAlphaMashImage(Device device, Image srcImage) {
458 // Rectangle bounds = srcImage.getBounds();
461 // ImageData data = srcImage.getImageData();
462 // // Create a new image with alpha values alternating
463 // // between fully transparent (0) and fully opaque (255).
464 // // This image will show the background through the
465 // // transparent pixels.
466 // for (int i = 0; i < bounds.height; i++) {
469 // for (int j = 0; j < bounds.width; j++) {
471 // data.setAlpha(j, i, alpha);
472 // alpha = alpha == 255 ? 0 : 255;
474 // calpha = calpha == 255 ? 0 : 255;
476 // return new Image(device, data);
479 public static boolean mnemonicMatch(String text
, char key
) {
480 char mnemonic
= findMnemonic(text
);
481 if (mnemonic
== '\0')
483 return Character
.toUpperCase(key
) == Character
.toUpperCase(mnemonic
);
486 private static char findMnemonic(String string
) {
488 int length
= string
.length();
490 while (index
< length
&& string
.charAt(index
) != '&')
492 if (++index
>= length
)
494 if (string
.charAt(index
) != '&')
495 return string
.charAt(index
);
497 } while (index
< length
);
501 public static void setFocusScrollingEnabled(Control c
, boolean enabled
) {
502 ScrolledComposite scomp
= null;
504 if (c
instanceof ScrolledComposite
)
505 scomp
= (ScrolledComposite
)c
;
507 scomp
= getScrolledComposite(c
);
509 scomp
.setData(FormUtil
.FOCUS_SCROLLING
, enabled?
null:Boolean
.FALSE
);
512 // RAP [rh] FormUtil#setAntialias unnecessary
513 // public static void setAntialias(GC gc, int style) {
514 // if (!gc.getAdvanced()) {
515 // gc.setAdvanced(true);
516 // if (!gc.getAdvanced())
519 // gc.setAntialias(style);