1   package org.argeo.cms.ui.eclipse.forms;
2   
3   import org.eclipse.swt.SWT;
4   import org.eclipse.swt.custom.ScrolledComposite;
5   import org.eclipse.swt.events.MouseEvent;
6   
7   import org.eclipse.swt.graphics.FontMetrics;
8   import org.eclipse.swt.graphics.GC;
9   
10  
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  
20  import org.eclipse.swt.widgets.Text;
21  
22  
23  
24  
25  
26  
27  
28  
29  public class FormUtil {
30  	public static final String PLUGIN_ID = "org.eclipse.ui.forms"; 
31  
32  	static final int H_SCROLL_INCREMENT = 5;
33  
34  	static final int V_SCROLL_INCREMENT = 64;
35  
36  	public static final String DEBUG = PLUGIN_ID + "/debug"; 
37  
38  	public static final String DEBUG_TEXT = DEBUG + "/text"; 
39  	public static final String DEBUG_TEXTSIZE = DEBUG + "/textsize"; 
40  
41  	public static final String DEBUG_FOCUS = DEBUG + "/focus"; 
42  
43  	public static final String FOCUS_SCROLLING = "focusScrolling"; 
44  	
45  	public static final String IGNORE_BODY = "__ignore_body__"; 
46  
47  	public static Text createText(Composite parent, String label,
48  			FormToolkit factory) {
49  		return createText(parent, label, factory, 1);
50  	}
51  
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, ""); 
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);
61  		return text;
62  	}
63  
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);
69  			l.setLayoutData(gd);
70  		}
71  		Text text = factory.createText(parent, "", style); 
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);
77  		return text;
78  	}
79  
80  	public static Text createText(Composite parent, FormToolkit factory,
81  			int span) {
82  		Text text = factory.createText(parent, ""); 
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);
88  		return text;
89  	}
90  
91  	public static int computeMinimumWidth(GC gc, String text) {
92  
93  
94  
95  
96  
97  
98  
99  
100 
101 
102 
103 
104 
105 
106 
107 
108 		return 0;
109 	}
110 	
111 	public static Point computeWrapSize(GC gc, String text, int wHint) {	
112 
113 
114 		FontMetrics fm = gc.getFontMetrics();
115 		int lineHeight = fm.getHeight();
116 		
117 		int saved = 0;
118 		int last = 0;
119 		int height = lineHeight;
120 		int maxWidth = 0;
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 		
136 
137 
138 
139 
140 		if (maxWidth > wHint)
141 			return computeWrapSize(gc, text, maxWidth);		  
142 		return new Point(maxWidth, height);
143 	}
144 
145 
146 
147 
148 
149 	
150 
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193 
194 
195 	public static ScrolledComposite getScrolledComposite(Control c) {
196 		Composite parent = c.getParent();
197 
198 		while (parent != null) {
199 			if (parent instanceof ScrolledComposite) {
200 				return (ScrolledComposite) parent;
201 			}
202 			parent = parent.getParent();
203 		}
204 		return null;
205 	}
206 
207 	public static void ensureVisible(Control c) {
208 		ScrolledComposite scomp = getScrolledComposite(c);
209 		if (scomp != null) {
210 			Object data = scomp.getData(FOCUS_SCROLLING);
211 			if (data == null || !data.equals(Boolean.FALSE))
212 				FormUtil.ensureVisible(scomp, c);
213 		}
214 	}
215 
216 	public static void ensureVisible(ScrolledComposite scomp, Control control) {
217 		
218 		
219 
220 
221 		Point controlSize = control.getSize();
222 		Point controlOrigin = getControlLocation(scomp, control);
223 		ensureVisible(scomp, controlOrigin, controlSize);
224 	}
225 
226 	public static void ensureVisible(ScrolledComposite scomp,
227 			Point controlOrigin, Point controlSize) {
228 		Rectangle area = scomp.getClientArea();
229 		Point scompOrigin = scomp.getOrigin();
230 
231 		int x = scompOrigin.x;
232 		int y = scompOrigin.y;
233 
234 		
235 		
236 		if (controlSize.x < area.width
237 				&& (controlOrigin.x + controlSize.x > scompOrigin.x
238 						+ area.width)) {
239 			x = controlOrigin.x + controlSize.x - area.width;
240 		}
241 		
242 		
243 		if (controlOrigin.x < x) {
244 			if (controlSize.x < area.width)
245 				x = controlOrigin.x + controlSize.x - area.width;
246 			else
247 				x = controlOrigin.x;
248 		}
249 		
250 		if (controlSize.y < area.height
251 				&& (controlOrigin.y + controlSize.y > scompOrigin.y
252 						+ area.height)) {
253 			y = controlOrigin.y + controlSize.y - area.height;
254 		}
255 		
256 		
257 		if (controlOrigin.y < y) {
258 			if (controlSize.y < area.height)
259 				y = controlOrigin.y + controlSize.y - area.height;
260 			else
261 				y = controlOrigin.y;
262 		}
263 
264 		if (scompOrigin.x != x || scompOrigin.y != y) {
265 			
266 			scomp.setOrigin(x, y);
267 		}
268 	}
269 
270 	public static void ensureVisible(ScrolledComposite scomp, Control control,
271 			MouseEvent e) {
272 		Point controlOrigin = getControlLocation(scomp, control);
273 		int rX = controlOrigin.x + e.x;
274 		int rY = controlOrigin.y + e.y;
275 		Rectangle area = scomp.getClientArea();
276 		Point scompOrigin = scomp.getOrigin();
277 
278 		int x = scompOrigin.x;
279 		int y = scompOrigin.y;
280 		
281 		
282 
283 		
284 		if (rX > scompOrigin.x + area.width) {
285 			x = rX - area.width;
286 		}
287 		
288 		else if (rX < x) {
289 			x = rX;
290 		}
291 		
292 		if (rY > scompOrigin.y + area.height) {
293 			y = rY - area.height;
294 		}
295 		
296 		else if (rY < y) {
297 			y = rY;
298 		}
299 
300 		if (scompOrigin.x != x || scompOrigin.y != y) {
301 			
302 			scomp.setOrigin(x, y);
303 		}
304 	}
305 
306 	public static Point getControlLocation(ScrolledComposite scomp,
307 			Control control) {
308 		int x = 0;
309 		int y = 0;
310 		Control content = scomp.getContent();
311 		Control currentControl = control;
312 		for (;;) {
313 			if (currentControl == content)
314 				break;
315 			Point location = currentControl.getLocation();
316 			
317 			
318 			
319 			
320 			x += location.x;
321 			y += location.y;
322 			currentControl = currentControl.getParent();
323 		}
324 		return new Point(x, y);
325 	}
326 
327 	static void scrollVertical(ScrolledComposite scomp, boolean up) {
328 		scroll(scomp, 0, up ? -V_SCROLL_INCREMENT : V_SCROLL_INCREMENT);
329 	}
330 
331 	static void scrollHorizontal(ScrolledComposite scomp, boolean left) {
332 		scroll(scomp, left ? -H_SCROLL_INCREMENT : H_SCROLL_INCREMENT, 0);
333 	}
334 
335 	static void scrollPage(ScrolledComposite scomp, boolean up) {
336 		Rectangle clientArea = scomp.getClientArea();
337 		int increment = up ? -clientArea.height : clientArea.height;
338 		scroll(scomp, 0, increment);
339 	}
340 
341 	static void scroll(ScrolledComposite scomp, int xoffset, int yoffset) {
342 		Point origin = scomp.getOrigin();
343 		Point contentSize = scomp.getContent().getSize();
344 		int xorigin = origin.x + xoffset;
345 		int yorigin = origin.y + yoffset;
346 		xorigin = Math.max(xorigin, 0);
347 		xorigin = Math.min(xorigin, contentSize.x - 1);
348 		yorigin = Math.max(yorigin, 0);
349 		yorigin = Math.min(yorigin, contentSize.y - 1);
350 		scomp.setOrigin(xorigin, yorigin);
351 	}
352 
353 
354 	public static void updatePageIncrement(ScrolledComposite scomp) {
355 
356 
357 
358 
359 
360 
361 
362 
363 
364 
365 
366 
367 	}
368 
369 	public static void processKey(int keyCode, Control c) {
370 		if (c.isDisposed()) {
371 			return;
372 		}
373 		ScrolledComposite scomp = FormUtil.getScrolledComposite(c);
374 		if (scomp != null) {
375 			if (c instanceof Combo)
376 				return;
377 			switch (keyCode) {
378 			case SWT.ARROW_DOWN:
379 				if (scomp.getData("novarrows") == null) 
380 					FormUtil.scrollVertical(scomp, false);
381 				break;
382 			case SWT.ARROW_UP:
383 				if (scomp.getData("novarrows") == null) 
384 					FormUtil.scrollVertical(scomp, true);
385 				break;
386 			case SWT.ARROW_LEFT:
387 				FormUtil.scrollHorizontal(scomp, true);
388 				break;
389 			case SWT.ARROW_RIGHT:
390 				FormUtil.scrollHorizontal(scomp, false);
391 				break;
392 			case SWT.PAGE_UP:
393 				FormUtil.scrollPage(scomp, true);
394 				break;
395 			case SWT.PAGE_DOWN:
396 				FormUtil.scrollPage(scomp, false);
397 				break;
398 			}
399 		}
400 	}
401 
402 	public static boolean isWrapControl(Control c) {
403 		if ((c.getStyle() & SWT.WRAP) != 0)
404 			return true;
405 		if (c instanceof Composite) {
406 			return false;
407 
408 		}
409 		return false;
410 	}
411 
412 	public static int getWidthHint(int wHint, Control c) {
413 		boolean wrap = isWrapControl(c);
414 		return wrap ? wHint : SWT.DEFAULT;
415 	}
416 
417 	public static int getHeightHint(int hHint, Control c) {
418 		if (c instanceof Composite) {
419 			Layout layout = ((Composite) c).getLayout();
420 
421 
422 		}
423 		return SWT.DEFAULT;
424 	}
425 
426 	public static int computeMinimumWidth(Control c, boolean changed) {
427 		if (c instanceof Composite) {
428 			Layout layout = ((Composite) c).getLayout();
429 
430 
431 
432 		}
433 		return c.computeSize(FormUtil.getWidthHint(5, c), SWT.DEFAULT, changed).x;
434 	}
435 
436 	public static int computeMaximumWidth(Control c, boolean changed) {
437 		if (c instanceof Composite) {
438 			Layout layout = ((Composite) c).getLayout();
439 
440 
441 
442 		}
443 		return c.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed).x;
444 	}
445 
446 
447 
448 
449 
450 
451 
452 
453 
454 
455 
456 
457 
458 
459 
460 
461 
462 
463 
464 
465 
466 
467 
468 
469 
470 
471 
472 
473 
474 
475 
476 
477 
478 
479 
480 	public static boolean mnemonicMatch(String text, char key) {
481 		char mnemonic = findMnemonic(text);
482 		if (mnemonic == '\0')
483 			return false;
484 		return Character.toUpperCase(key) == Character.toUpperCase(mnemonic);
485 	}
486 
487 	private static char findMnemonic(String string) {
488 		int index = 0;
489 		int length = string.length();
490 		do {
491 			while (index < length && string.charAt(index) != '&')
492 				index++;
493 			if (++index >= length)
494 				return '\0';
495 			if (string.charAt(index) != '&')
496 				return string.charAt(index);
497 			index++;
498 		} while (index < length);
499 		return '\0';
500 	}
501 	
502 	public static void setFocusScrollingEnabled(Control c, boolean enabled) {
503 		ScrolledComposite scomp = null;
504 		
505 		if (c instanceof ScrolledComposite)
506 			scomp = (ScrolledComposite)c;
507 		else
508 			scomp = getScrolledComposite(c);
509 		if (scomp!=null)
510 			scomp.setData(FormUtil.FOCUS_SCROLLING, enabled?null:Boolean.FALSE);
511 	}
512 	
513 	
514 
515 
516 
517 
518 
519 
520 
521 
522 }