KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > forms > widgets > TitleRegion


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  *******************************************************************************/

11 package org.eclipse.ui.internal.forms.widgets;
12
13 import org.eclipse.jface.action.IMenuManager;
14 import org.eclipse.jface.action.MenuManager;
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.dnd.DragSource;
17 import org.eclipse.swt.dnd.DragSourceEffect;
18 import org.eclipse.swt.dnd.DragSourceEvent;
19 import org.eclipse.swt.dnd.DragSourceListener;
20 import org.eclipse.swt.dnd.DropTarget;
21 import org.eclipse.swt.dnd.DropTargetListener;
22 import org.eclipse.swt.dnd.Transfer;
23 import org.eclipse.swt.events.MouseEvent;
24 import org.eclipse.swt.events.MouseMoveListener;
25 import org.eclipse.swt.events.MouseTrackListener;
26 import org.eclipse.swt.events.PaintEvent;
27 import org.eclipse.swt.events.PaintListener;
28 import org.eclipse.swt.graphics.Color;
29 import org.eclipse.swt.graphics.Font;
30 import org.eclipse.swt.graphics.FontMetrics;
31 import org.eclipse.swt.graphics.GC;
32 import org.eclipse.swt.graphics.Image;
33 import org.eclipse.swt.graphics.Point;
34 import org.eclipse.swt.graphics.Rectangle;
35 import org.eclipse.swt.widgets.Canvas;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Control;
38 import org.eclipse.swt.widgets.Event;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.Layout;
41 import org.eclipse.swt.widgets.Listener;
42 import org.eclipse.swt.widgets.Menu;
43 import org.eclipse.ui.forms.IFormColors;
44 import org.eclipse.ui.forms.widgets.ILayoutExtension;
45 import org.eclipse.ui.forms.widgets.SizeCache;
46 import org.eclipse.ui.forms.widgets.Twistie;
47 import org.eclipse.ui.internal.forms.IMessageToolTipManager;
48
49 /**
50  * Form heading title.
51  */

52 public class TitleRegion extends Canvas {
53     public static final int STATE_NORMAL = 0;
54     public static final int STATE_HOVER_LIGHT = 1;
55     public static final int STATE_HOVER_FULL = 2;
56     private int hoverState;
57     private static final int HMARGIN = 1;
58     private static final int VMARGIN = 5;
59     private static final int SPACING = 5;
60     private static final int ARC_WIDTH = 20;
61     private static final int ARC_HEIGHT = 20;
62     private Image image;
63     private BusyIndicator busyLabel;
64     private Label titleLabel;
65     private SizeCache titleCache;
66     private int fontHeight = -1;
67     private int fontBaselineHeight = -1;
68     private MenuHyperlink menuHyperlink;
69     private MenuManager menuManager;
70     private boolean dragSupport;
71     private int dragOperations;
72     private Transfer[] dragTransferTypes;
73     private DragSourceListener dragListener;
74     private DragSource dragSource;
75     private Image dragImage;
76
77     private class HoverListener implements MouseTrackListener,
78             MouseMoveListener {
79
80         public void mouseEnter(MouseEvent e) {
81             setHoverState(STATE_HOVER_FULL);
82         }
83
84         public void mouseExit(MouseEvent e) {
85             setHoverState(STATE_NORMAL);
86         }
87
88         public void mouseHover(MouseEvent e) {
89         }
90
91         public void mouseMove(MouseEvent e) {
92             if (e.button > 0)
93                 setHoverState(STATE_NORMAL);
94             else
95                 setHoverState(STATE_HOVER_FULL);
96         }
97     }
98
99     private class MenuHyperlink extends Twistie {
100         private boolean firstTime = true;
101
102         public MenuHyperlink(Composite parent, int style) {
103             super(parent, style);
104             setExpanded(true);
105         }
106
107         public void setExpanded(boolean expanded) {
108             if (firstTime) {
109                 super.setExpanded(expanded);
110                 firstTime = false;
111             } else {
112                 Menu menu = menuManager.createContextMenu(menuHyperlink);
113                 menu.setVisible(true);
114             }
115         }
116     }
117
118     private class TitleRegionLayout extends Layout implements ILayoutExtension {
119
120         protected Point computeSize(Composite composite, int wHint, int hHint,
121                 boolean flushCache) {
122             return layout(composite, false, 0, 0, wHint, hHint, flushCache);
123         }
124
125         protected void layout(Composite composite, boolean flushCache) {
126             Rectangle carea = composite.getClientArea();
127             layout(composite, true, carea.x, carea.y, carea.width,
128                     carea.height, flushCache);
129         }
130
131         private Point layout(Composite composite, boolean move, int x, int y,
132                 int width, int height, boolean flushCache) {
133             int iwidth = width == SWT.DEFAULT ? SWT.DEFAULT : width - HMARGIN
134                     * 2;
135             Point bsize = null;
136             Point tsize = null;
137             Point msize = null;
138
139             if (busyLabel != null) {
140                 bsize = busyLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT);
141             }
142             if (menuManager != null) {
143                 menuHyperlink.setVisible(!menuManager.isEmpty()
144                         && titleLabel.getVisible());
145                 if (menuHyperlink.getVisible())
146                     msize = menuHyperlink.computeSize(SWT.DEFAULT, SWT.DEFAULT);
147             }
148             if (flushCache)
149                 titleCache.flush();
150             titleCache.setControl(titleLabel);
151             int twidth = iwidth == SWT.DEFAULT ? iwidth : iwidth - SPACING * 2;
152             if (bsize != null && twidth != SWT.DEFAULT)
153                 twidth -= bsize.x + SPACING;
154             if (msize != null && twidth != SWT.DEFAULT)
155                 twidth -= msize.x + SPACING;
156             if (titleLabel.getVisible()) {
157                 tsize = titleCache.computeSize(twidth, SWT.DEFAULT);
158                 if (twidth != SWT.DEFAULT) {
159                     // correct for the case when width hint is larger
160
// than the maximum width - this is when the text
161
// can be rendered on one line with width to spare
162
int maxWidth = titleCache.computeSize(SWT.DEFAULT,
163                             SWT.DEFAULT).x;
164                     tsize.x = Math.min(tsize.x, maxWidth);
165                     // System.out.println("twidth="+twidth+",
166
// tsize.x="+tsize.x); //$NON-NLS-1$//$NON-NLS-2$
167
}
168             } else
169                 tsize = new Point(0, 0);
170             Point size = new Point(width, height);
171             if (!move) {
172                 // compute size
173
size.x = tsize.x > 0 ? HMARGIN * 2 + SPACING * 2 + tsize.x : 0;
174                 size.y = tsize.y;
175                 if (bsize != null) {
176                     size.x += bsize.x + SPACING;
177                     size.y = Math.max(size.y, bsize.y);
178                 }
179                 if (msize != null) {
180                     size.x += msize.x + SPACING;
181                     size.y = Math.max(size.y, msize.y);
182                 }
183                 if (size.y > 0)
184                     size.y += VMARGIN * 2;
185                 // System.out.println("Compute size: width="+width+",
186
// size.x="+size.x); //$NON-NLS-1$ //$NON-NLS-2$
187
} else {
188                 // position controls
189
int xloc = x + HMARGIN + SPACING;
190                 int yloc = y + VMARGIN;
191                 if (bsize != null) {
192                     busyLabel.setBounds(xloc,
193                             // yloc + height / 2 - bsize.y / 2,
194
yloc + getFontHeight() - 1 - bsize.y,
195                             bsize.x, bsize.y);
196                     xloc += bsize.x + SPACING;
197                 }
198                 if (titleLabel.getVisible()) {
199                     int tw = width - HMARGIN * 2 - SPACING * 2;
200                     if (bsize != null)
201                         tw -= bsize.x + SPACING;
202                     if (msize != null)
203                         tw -= msize.x + SPACING;
204                     titleLabel.setBounds(xloc,
205                     // yloc + height / 2 - tsize.y / 2,
206
yloc, tw, tsize.y);
207                     // System.out.println("tw="+tw); //$NON-NLS-1$
208
xloc += tw + SPACING;
209                 }
210                 if (msize != null) {
211                     menuHyperlink.setBounds(xloc, yloc
212                             + getFontHeight() / 2 - msize.y / 2,
213                             msize.x, msize.y);
214                 }
215             }
216             return size;
217         }
218
219         public int computeMaximumWidth(Composite parent, boolean changed) {
220             return computeSize(parent, SWT.DEFAULT, SWT.DEFAULT, changed).x;
221         }
222
223         public int computeMinimumWidth(Composite parent, boolean changed) {
224             return computeSize(parent, 0, SWT.DEFAULT, changed).x;
225         }
226     }
227
228     public TitleRegion(Composite parent) {
229         super(parent, SWT.NULL);
230         titleLabel = new Label(this, SWT.WRAP);
231         titleLabel.setVisible(false);
232         titleCache = new SizeCache();
233         super.setLayout(new TitleRegionLayout());
234         hookHoverListeners();
235         addListener(SWT.Dispose, new Listener() {
236             public void handleEvent(Event e) {
237                 if (dragImage != null) {
238                     dragImage.dispose();
239                     dragImage = null;
240                 }
241             }
242         });
243     }
244
245     private Color getColor(String JavaDoc key) {
246         return (Color) ((FormHeading) getParent()).colors.get(key);
247     }
248
249     private void hookHoverListeners() {
250         HoverListener listener = new HoverListener();
251         addMouseTrackListener(listener);
252         addMouseMoveListener(listener);
253         titleLabel.addMouseTrackListener(listener);
254         titleLabel.addMouseMoveListener(listener);
255         addPaintListener(new PaintListener() {
256             public void paintControl(PaintEvent e) {
257                 onPaint(e);
258             }
259         });
260     }
261
262     private void onPaint(PaintEvent e) {
263         if (hoverState == STATE_NORMAL)
264             return;
265         GC gc = e.gc;
266         Rectangle carea = getClientArea();
267         gc.setBackground(getHoverBackground());
268         int savedAntialias = gc.getAntialias();
269         FormUtil.setAntialias(gc, SWT.ON);
270         gc.fillRoundRectangle(carea.x + HMARGIN, carea.y + 2, carea.width
271                 - HMARGIN * 2, carea.height - 4, ARC_WIDTH, ARC_HEIGHT);
272         FormUtil.setAntialias(gc, savedAntialias);
273     }
274
275     private Color getHoverBackground() {
276         if (hoverState == STATE_NORMAL)
277             return null;
278         Color color = getColor(hoverState == STATE_HOVER_FULL ? IFormColors.H_HOVER_FULL
279                 : IFormColors.H_HOVER_LIGHT);
280         if (color == null)
281             color = getDisplay()
282                     .getSystemColor(
283                             hoverState == STATE_HOVER_FULL ? SWT.COLOR_WIDGET_BACKGROUND
284                                     : SWT.COLOR_WIDGET_LIGHT_SHADOW);
285         return color;
286     }
287
288     public void setHoverState(int state) {
289         if (dragSource == null || this.hoverState == state)
290             return;
291         this.hoverState = state;
292         Color color = getHoverBackground();
293         titleLabel.setBackground(color != null ? color
294                 : getColor(FormHeading.COLOR_BASE_BG));
295         if (busyLabel != null)
296             busyLabel.setBackground(color != null ? color
297                     : getColor(FormHeading.COLOR_BASE_BG));
298         if (menuHyperlink != null)
299             menuHyperlink.setBackground(color != null ? color
300                     : getColor(FormHeading.COLOR_BASE_BG));
301         redraw();
302     }
303
304     /**
305      * Fully delegates the size computation to the internal layout manager.
306      */

307     public final Point computeSize(int wHint, int hHint, boolean changed) {
308         return ((TitleRegionLayout) getLayout()).computeSize(this, wHint,
309                 hHint, changed);
310     }
311
312     public final void setLayout(Layout layout) {
313         // do nothing
314
}
315
316     public Image getImage() {
317         return image;
318     }
319
320     public void setImage(Image image) {
321         this.image = image;
322     }
323
324     public void updateImage(Image newImage, boolean doLayout) {
325         Image theImage = newImage != null ? newImage : this.image;
326
327         if (theImage != null) {
328             ensureBusyLabelExists();
329         } else if (busyLabel != null) {
330             if (!busyLabel.isBusy()) {
331                 busyLabel.dispose();
332                 busyLabel = null;
333             }
334         }
335         if (busyLabel != null) {
336             busyLabel.setImage(theImage);
337         }
338         if (doLayout)
339             layout();
340     }
341
342     public void updateToolTip(String JavaDoc toolTip) {
343         if (busyLabel != null)
344             busyLabel.setToolTipText(toolTip);
345     }
346
347     public void setBackground(Color bg) {
348         super.setBackground(bg);
349         titleLabel.setBackground(bg);
350         if (busyLabel != null)
351             busyLabel.setBackground(bg);
352         if (menuHyperlink != null)
353             menuHyperlink.setBackground(bg);
354     }
355
356     public void setForeground(Color fg) {
357         super.setForeground(fg);
358         titleLabel.setForeground(fg);
359         if (menuHyperlink != null)
360             menuHyperlink.setForeground(fg);
361     }
362
363     public void setText(String JavaDoc text) {
364         if (text != null)
365             titleLabel.setText(text);
366         titleLabel.setVisible(text != null);
367         layout();
368         redraw();
369     }
370
371     public String JavaDoc getText() {
372         return titleLabel.getText();
373     }
374
375     public void setFont(Font font) {
376         super.setFont(font);
377         titleLabel.setFont(font);
378         fontHeight = -1;
379         fontBaselineHeight = -1;
380         layout();
381     }
382
383     private void ensureBusyLabelExists() {
384         if (busyLabel == null) {
385             busyLabel = new BusyIndicator(this, SWT.NULL);
386             busyLabel.setBackground(getColor(FormHeading.COLOR_BASE_BG));
387             HoverListener listener = new HoverListener();
388             busyLabel.addMouseTrackListener(listener);
389             busyLabel.addMouseMoveListener(listener);
390             if (menuManager != null)
391                 busyLabel.setMenu(menuManager.createContextMenu(this));
392             if (dragSupport)
393                 addDragSupport(busyLabel, dragOperations, dragTransferTypes, dragListener);
394             IMessageToolTipManager mng = ((FormHeading) getParent())
395                     .getMessageToolTipManager();
396             if (mng != null)
397                 mng.createToolTip(busyLabel, true);
398         }
399     }
400
401     private void createMenuHyperlink() {
402         menuHyperlink = new MenuHyperlink(this, SWT.NULL);
403         menuHyperlink.setBackground(getColor(FormHeading.COLOR_BASE_BG));
404         menuHyperlink.setDecorationColor(getForeground());
405         menuHyperlink.setHoverDecorationColor(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
406         HoverListener listener = new HoverListener();
407         menuHyperlink.addMouseTrackListener(listener);
408         menuHyperlink.addMouseMoveListener(listener);
409         if (dragSupport)
410             addDragSupport(menuHyperlink, dragOperations, dragTransferTypes, dragListener);
411     }
412
413     /**
414      * Sets the form's busy state. Busy form will display 'busy' animation in
415      * the area of the title image.
416      *
417      * @param busy
418      * the form's busy state
419      */

420
421     public boolean setBusy(boolean busy) {
422         if (busy)
423             ensureBusyLabelExists();
424         else if (busyLabel == null)
425             return false;
426         if (busy == busyLabel.isBusy())
427             return false;
428         busyLabel.setBusy(busy);
429         if (busyLabel.getImage() == null) {
430             layout();
431             return true;
432         }
433         return false;
434     }
435
436     public boolean isBusy() {
437         return busyLabel != null && busyLabel.isBusy();
438     }
439
440     /*
441      * Returns the complete height of the font.
442      */

443     public int getFontHeight() {
444         if (fontHeight == -1) {
445             Font font = getFont();
446             GC gc = new GC(getDisplay());
447             gc.setFont(font);
448             FontMetrics fm = gc.getFontMetrics();
449             fontHeight = fm.getHeight();
450             gc.dispose();
451         }
452         return fontHeight;
453     }
454
455     /*
456      * Returns the height of the font starting at the baseline,
457      * i.e. without the descent.
458      */

459     public int getFontBaselineHeight() {
460         if (fontBaselineHeight == -1) {
461             Font font = getFont();
462             GC gc = new GC(getDisplay());
463             gc.setFont(font);
464             FontMetrics fm = gc.getFontMetrics();
465             fontBaselineHeight = fm.getHeight() - fm.getDescent();
466             gc.dispose();
467         }
468         return fontBaselineHeight;
469     }
470
471     public IMenuManager getMenuManager() {
472         if (menuManager == null) {
473             menuManager = new MenuManager();
474             Menu menu = menuManager.createContextMenu(this);
475             setMenu(menu);
476             titleLabel.setMenu(menu);
477             if (busyLabel != null)
478                 busyLabel.setMenu(menu);
479             createMenuHyperlink();
480         }
481         return menuManager;
482     }
483
484     public void addDragSupport(int operations, Transfer[] transferTypes,
485             DragSourceListener listener) {
486         dragSupport = true;
487         dragOperations = operations;
488         dragTransferTypes = transferTypes;
489         dragListener = listener;
490         dragSource = addDragSupport(titleLabel, operations, transferTypes,
491                 listener);
492         addDragSupport(this, operations, transferTypes, listener);
493         if (busyLabel != null)
494             addDragSupport(busyLabel, operations, transferTypes, listener);
495         if (menuHyperlink != null)
496             addDragSupport(menuHyperlink, operations, transferTypes, listener);
497     }
498
499     private DragSource addDragSupport(Control control, int operations,
500             Transfer[] transferTypes, DragSourceListener listener) {
501         DragSource source = new DragSource(control, operations);
502         source.setTransfer(transferTypes);
503         source.addDragListener(listener);
504         source.setDragSourceEffect(new DragSourceEffect(control) {
505             public void dragStart(DragSourceEvent event) {
506                 event.image = createDragEffectImage();
507             }
508         });
509         return source;
510     }
511
512     private Image createDragEffectImage() {
513         /*
514          * if (dragImage != null) { dragImage.dispose(); } GC gc = new GC(this);
515          * Point size = getSize(); dragImage = new Image(getDisplay(), size.x,
516          * size.y); gc.copyArea(dragImage, 0, 0); gc.dispose(); return
517          * dragImage;
518          */

519         return null;
520     }
521
522     public void addDropSupport(int operations, Transfer[] transferTypes,
523             DropTargetListener listener) {
524         final DropTarget target = new DropTarget(this, operations);
525         target.setTransfer(transferTypes);
526         target.addDropListener(listener);
527     }
528 }
Popular Tags