KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > forms > widgets > Section


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  * Michael Williamson (eclipse-bugs@magnaworks.com) - patch (see Bugzilla #92545)
11  *
12  *******************************************************************************/

13 package org.eclipse.ui.forms.widgets;
14
15 import java.util.Hashtable JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.PaintEvent;
20 import org.eclipse.swt.graphics.Color;
21 import org.eclipse.swt.graphics.GC;
22 import org.eclipse.swt.graphics.Image;
23 import org.eclipse.swt.graphics.Point;
24 import org.eclipse.swt.graphics.Rectangle;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Control;
27 import org.eclipse.swt.widgets.Event;
28 import org.eclipse.swt.widgets.Listener;
29 import org.eclipse.swt.widgets.Text;
30 import org.eclipse.ui.internal.forms.widgets.FormUtil;
31
32 /**
33  * A variation of the expandable composite that adds optional description below
34  * the title. Section is often used as a basic building block in forms because
35  * it provides for logical grouping of information.
36  * <p>
37  * In case of the TITLE_BAR style, Section renders the title bar in a way
38  * compatible with the rest of the workbench. Since it is a widget, all the
39  * colors must be supplied directly. When created by the form toolkit, these
40  * colors are supplied by the toolkit. The toolkit initializes these colors
41  * based on the system colors. For this reason, it is recommended to create the
42  * section by the toolkit instead of through its own constructor.
43  * <p>
44  * Since 3.1, it is possible to set a control to be used for section
45  * description. If used, <code>DESCRIPTION</code> style should not be set. A
46  * typical way to take advantage of the new method is to set an instance of
47  * <code>FormText</code> to provide for hyperlinks and images in the
48  * description area.
49  *
50  * @since 3.0
51  */

52 public class Section extends ExpandableComposite {
53     /**
54      * Description style. If used, description will be rendered below the title.
55      */

56     public static final int DESCRIPTION = 1 << 7;
57
58     private Control descriptionControl;
59
60     private Control separator;
61
62     private Hashtable JavaDoc titleColors;
63
64     private static final String JavaDoc COLOR_BG = "bg"; //$NON-NLS-1$
65

66     private static final String JavaDoc COLOR_GBG = "gbg"; //$NON-NLS-1$
67

68     private static final String JavaDoc COLOR_BORDER = "border"; //$NON-NLS-1$
69

70     /**
71      * Creates a new section instance in the provided parent.
72      *
73      * @param parent
74      * the parent composite
75      * @param style
76      * the style to use
77      */

78     public Section(Composite parent, int style) {
79         this(parent, SWT.NULL, style);
80     }
81
82     Section(Composite parent, int cstyle, int style) {
83         super(parent, cstyle | getBackgroundStyle(style), style);
84         int rtl = cstyle & SWT.RIGHT_TO_LEFT;
85         if ((style & DESCRIPTION) != 0) {
86             descriptionControl = new Text(this, SWT.READ_ONLY | SWT.WRAP | rtl);
87         }
88         if ((style & TITLE_BAR) != 0) {
89             Listener listener = new Listener() {
90                 public void handleEvent(Event e) {
91                     Image image = Section.super.getBackgroundImage();
92                     if (image != null)
93                         image.dispose();
94                     Section.super.setBackgroundImage(null);
95                 }
96             };
97             addListener(SWT.Dispose, listener);
98             addListener(SWT.Resize, listener);
99         }
100     }
101
102     private static int getBackgroundStyle(int estyle) {
103         return ((estyle & TITLE_BAR) != 0) ? SWT.NO_BACKGROUND : SWT.NULL;
104     }
105
106     protected void internalSetExpanded(boolean expanded) {
107         super.internalSetExpanded(expanded);
108         if ((getExpansionStyle() & TITLE_BAR) != 0) {
109             if (!expanded)
110                 super.setBackgroundImage(null);
111         }
112         reflow();
113     }
114
115     /**
116      * Reflows this section and all the parents up the hierarchy until a
117      * ScrolledForm is reached.
118      */

119     protected void reflow() {
120         Composite c = this;
121         while (c != null) {
122             c.setRedraw(false);
123             c = c.getParent();
124             if (c instanceof ScrolledForm) {
125                 break;
126             }
127         }
128         c = this;
129         while (c != null) {
130             c.layout(true);
131             c = c.getParent();
132             if (c instanceof ScrolledForm) {
133                 ((ScrolledForm) c).reflow(true);
134                 break;
135             }
136         }
137         c = this;
138         while (c != null) {
139             c.setRedraw(true);
140             c = c.getParent();
141             if (c instanceof ScrolledForm) {
142                 break;
143             }
144         }
145     }
146
147     /**
148      * Sets the description text. Has no effect if DESCRIPTION style was not
149      * used to create the control.
150      *
151      * @param description
152      */

153     public void setDescription(String JavaDoc description) {
154         if (descriptionControl instanceof Text)
155             ((Text) descriptionControl).setText(description);
156     }
157
158     /**
159      * Returns the current description text.
160      *
161      * @return description text or <code>null</code> if DESCRIPTION style was
162      * not used to create the control.
163      */

164     public String JavaDoc getDescription() {
165         if (descriptionControl instanceof Text)
166             return ((Text) descriptionControl).getText();
167         return null;
168     }
169
170     /**
171      * Sets the separator control of this section. The separator must not be
172      * <samp>null </samp> and must be a direct child of this container. If
173      * defined, separator will be placed below the title text and will remain
174      * visible regardless of the expansion state.
175      *
176      * @param separator
177      * the separator that will be placed below the title text.
178      */

179     public void setSeparatorControl(Control separator) {
180         Assert.isTrue(separator != null && separator.getParent().equals(this));
181         this.separator = separator;
182     }
183
184     /**
185      * Returns the control that is used as a separator betweeen the title and
186      * the client, or <samp>null </samp> if not set.
187      *
188      * @return separator control or <samp>null </samp> if not set.
189      */

190     public Control getSeparatorControl() {
191         return separator;
192     }
193
194     /**
195      * Sets the background of the section.
196      *
197      * @param bg
198      * the new background
199      */

200     public void setBackground(Color bg) {
201         super.setBackground(bg);
202         if (descriptionControl != null
203                 && (getExpansionStyle() & DESCRIPTION) != 0)
204             descriptionControl.setBackground(bg);
205     }
206
207     /**
208      * Sets the foreground of the section.
209      *
210      * @param fg
211      * the new foreground.
212      */

213     public void setForeground(Color fg) {
214         super.setForeground(fg);
215         if (descriptionControl != null
216                 && (getExpansionStyle() & DESCRIPTION) != 0)
217             descriptionControl.setForeground(fg);
218     }
219
220     /**
221      * Returns the control used to render the description. In 3.1, this method
222      * was promoted to public.
223      *
224      * @return description control or <code>null</code> if DESCRIPTION style
225      * was not used to create the control and description control was
226      * not set by the client.
227      * @see #setDescriptionControl(org.eclipse.swt.widgets.Control)
228      */

229     public Control getDescriptionControl() {
230         return descriptionControl;
231     }
232
233     /**
234      * Sets the description control of this section. The control must not be
235      * <samp>null</samp> and must be a direct child of this container. If
236      * defined, contol will be placed below the title text and the separator and
237      * will be hidden int he collapsed state.
238      * <p>
239      * This method and <code>DESCRIPTION</code> style are mutually exclusive.
240      * Use the method only if you want to create the description control
241      * yourself.
242      *
243      * @since 3.1
244      * @param descriptionControl
245      * the control that will be placed below the title text.
246      */

247     public void setDescriptionControl(Control descriptionControl) {
248         Assert.isTrue((getExpansionStyle() & DESCRIPTION) == 0);
249         Assert.isTrue(descriptionControl != null
250                 && descriptionControl.getParent().equals(this));
251         this.descriptionControl = descriptionControl;
252     }
253
254     /**
255      * Sets the color of the title bar border when TITLE_BAR style is used.
256      *
257      * @param color
258      * the title bar border color
259      */

260     public void setTitleBarBorderColor(Color color) {
261         putTitleBarColor(COLOR_BORDER, color);
262     }
263
264     /**
265      * Sets the color of the title bar background when TITLE_BAR style is used.
266      * This color is used as a starting color for the vertical gradient.
267      *
268      * @param color
269      * the title bar border background
270      */

271     public void setTitleBarBackground(Color color) {
272         putTitleBarColor(COLOR_BG, color);
273     }
274
275     /**
276      * Sets the color of the title bar gradient background when TITLE_BAR style
277      * is used. This color is used at the height where title controls end
278      * (toggle, tool bar).
279      *
280      * @param color
281      * the title bar gradient background
282      */

283     public void setTitleBarGradientBackground(Color color) {
284         putTitleBarColor(COLOR_GBG, color);
285     }
286
287     /**
288      * Returns the title bar border color when TITLE_BAR style is used.
289      *
290      * @return the title bar border color
291      */

292     public Color getTitleBarBorderColor() {
293         if (titleColors == null)
294             return null;
295         return (Color) titleColors.get(COLOR_BORDER);
296     }
297
298     /**
299      * Returns the title bar gradient background color when TITLE_BAR style is
300      * used.
301      *
302      * @return the title bar gradient background
303      */

304     public Color getTitleBarGradientBackground() {
305         if (titleColors == null)
306             return null;
307         if ((getExpansionStyle() & SHORT_TITLE_BAR) != 0)
308             return getBackground();
309         return (Color) titleColors.get(COLOR_GBG);
310     }
311
312     /**
313      * Returns the title bar background when TITLE_BAR style is used.
314      *
315      * @return the title bar background
316      */

317     public Color getTitleBarBackground() {
318         if (titleColors == null)
319             return null;
320         return (Color) titleColors.get(COLOR_BG);
321     }
322
323     private void putTitleBarColor(String JavaDoc key, Color color) {
324         if (color == null)
325             return;
326         if (titleColors == null)
327             titleColors = new Hashtable JavaDoc();
328         titleColors.put(key, color);
329     }
330
331     protected void onPaint(PaintEvent e) {
332         Color bg = null;
333         Color fg = null;
334         Color border = null;
335
336         GC gc = e.gc;
337         Image buffer = null;
338         Rectangle bounds = getClientArea();
339
340         if ((getExpansionStyle() & TITLE_BAR) != 0) {
341             buffer = new Image(getDisplay(), bounds.width, bounds.height);
342             buffer.setBackground(getBackground());
343             gc = new GC(buffer);
344         }
345         if (titleColors != null) {
346             bg = (Color) titleColors.get(COLOR_BG);
347             fg = getTitleBarForeground();
348             border = (Color) titleColors.get(COLOR_BORDER);
349         }
350         if (bg == null)
351             bg = getBackground();
352         if (fg == null)
353             fg = getForeground();
354         if (border == null)
355             border = fg;
356         int theight = 0;
357         int gradientheight = 0;
358         int tvmargin = IGAP;
359         if ((getExpansionStyle() & TITLE_BAR) != 0) {
360             Point tsize = null;
361             Point tcsize = null;
362             if (toggle != null)
363                 tsize = toggle.getSize();
364             int twidth = bounds.width - marginWidth - marginWidth;
365             if (tsize != null)
366                 twidth -= tsize.x + IGAP;
367             if (getTextClient() != null)
368                 tcsize = getTextClient().getSize();
369             if (tcsize != null)
370                 twidth -= tcsize.x + IGAP;
371             Point size = textLabel.getSize();
372             if (tsize != null)
373                 theight += Math.max(theight, tsize.y);
374             gradientheight = theight;
375             if (tcsize != null) {
376                 theight = Math.max(theight, tcsize.y);
377             }
378             theight = Math.max(theight, size.y);
379             gradientheight = Math.max(gradientheight, size.y);
380             theight += tvmargin + tvmargin;
381             gradientheight += tvmargin + tvmargin;
382         } else {
383             theight = 5;
384         }
385         if ((getExpansionStyle() & TITLE_BAR) != 0) {
386             if (getBackgroundImage() == null)
387                 updateHeaderImage(bg, bounds, gradientheight, theight);
388             gc.setBackground(getBackground());
389             gc.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height);
390             drawBackground(gc, bounds.x, bounds.y, bounds.width, theight);
391             if (marginWidth > 0) {
392                 // fix up margins
393
gc.setBackground(getBackground());
394                 gc.fillRectangle(0, 0, marginWidth, theight);
395                 gc.fillRectangle(bounds.x + bounds.width - marginWidth, 0,
396                         marginWidth, theight);
397             }
398         } else if (isExpanded()) {
399             gc.setForeground(bg);
400             gc.setBackground(getBackground());
401             gc.fillGradientRectangle(marginWidth, marginHeight, bounds.width
402                     - marginWidth - marginWidth, theight, true);
403         }
404         gc.setBackground(getBackground());
405         FormUtil.setAntialias(gc, SWT.ON);
406         // repair the upper left corner
407
gc.fillPolygon(new int[] { marginWidth, marginHeight, marginWidth,
408                 marginHeight + 2, marginWidth + 2, marginHeight });
409         // repair the upper right corner
410
gc.fillPolygon(new int[] { bounds.width - marginWidth - 3,
411                 marginHeight, bounds.width - marginWidth, marginHeight,
412                 bounds.width - marginWidth, marginHeight + 3 });
413         gc.setForeground(border);
414         if (isExpanded() || (getExpansionStyle() & TITLE_BAR) != 0) {
415             // top left curve
416
gc.drawLine(marginWidth, marginHeight + 2, marginWidth + 2,
417                     marginHeight);
418             // top edge
419
gc.drawLine(marginWidth + 2, marginHeight, bounds.width
420                     - marginWidth - 3, marginHeight);
421             // top right curve
422
gc.drawLine(bounds.width - marginWidth - 3, marginHeight,
423                     bounds.width - marginWidth - 1, marginHeight + 2);
424         } else {
425             // collapsed short title bar
426
// top edge
427
gc.drawLine(marginWidth, marginHeight, bounds.width - 1,
428                     marginHeight);
429         }
430         if ((getExpansionStyle() & TITLE_BAR) != 0 || isExpanded()) {
431             // left vertical edge gradient
432
gc.fillGradientRectangle(marginWidth, marginHeight + 2, 1,
433                     gradientheight - 2, true);
434             // right vertical edge gradient
435
gc.fillGradientRectangle(bounds.width - marginWidth - 1,
436                     marginHeight + 2, 1, gradientheight - 2, true);
437         }
438         if ((getExpansionStyle() & TITLE_BAR) != 0) {
439             // New in 3.3 - edge treatmant
440
gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
441             gc.drawPolyline(new int[] { marginWidth + 1,
442                     marginHeight + gradientheight - 1, marginWidth + 1,
443                     marginHeight + 2, marginWidth + 2, marginHeight + 2,
444                     marginWidth + 2, marginHeight + 1,
445                     bounds.width - marginWidth - 3, marginHeight + 1,
446                     bounds.width - marginWidth - 3, marginHeight + 2,
447                     bounds.width - marginWidth - 2, marginHeight + 2,
448                     bounds.width - marginWidth - 2,
449                     marginHeight + gradientheight - 1 });
450         }
451         if (buffer != null) {
452             gc.dispose();
453             e.gc.drawImage(buffer, 0, 0);
454             buffer.dispose();
455         }
456     }
457
458     private void updateHeaderImage(Color bg, Rectangle bounds, int theight,
459             int realtheight) {
460         Image image = new Image(getDisplay(), 1, realtheight);
461         image.setBackground(getBackground());
462         GC gc = new GC(image);
463         gc.setBackground(getBackground());
464         gc.fillRectangle(0, 0, 1, realtheight);
465         gc.setForeground(bg);
466         gc.setBackground(getBackground());
467         gc.fillGradientRectangle(0, marginHeight + 2, 1, theight - 2, true);
468         gc.dispose();
469         super.setBackgroundImage(image);
470     }
471
472     /**
473      * Background image is used for the title gradient - does nothing.
474      */

475     public final void setBackgroundImage(Image image) {
476     }
477 }
478
Popular Tags