Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/eclipse/swt/widgets/ToolBar.java


1   /*******************************************************************************
2    * Copyright (c) 2000, 2004 IBM Corporation and others.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Common Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/cpl-v10.html
7    * 
8    * Contributors:
9    *     IBM Corporation - initial API and implementation
10   *******************************************************************************/
11  package org.eclipse.swt.widgets;
12  
13  
14  import org.eclipse.swt.*;
15  import org.eclipse.swt.internal.*;
16  import org.eclipse.swt.internal.gtk.*;
17  import org.eclipse.swt.graphics.*;
18  
19  /**
20   * Instances of this class support the layout of selectable
21   * tool bar items.
22   * <p>
23   * The item children that may be added to instances of this class
24   * must be of type <code>ToolItem</code>.
25   * </p><p>
26   * Note that although this class is a subclass of <code>Composite</code>,
27   * it does not make sense to add <code>Control</code> children to it,
28   * or set a layout on it.
29   * </p><p>
30   * <dl>
31   * <dt><b>Styles:</b></dt>
32   * <dd>FLAT, WRAP, RIGHT, HORIZONTAL, VERTICAL, SHADOW_OUT</dd>
33   * <dt><b>Events:</b></dt>
34   * <dd>(none)</dd>
35   * </dl>
36   * <p>
37   * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
38   * </p><p>
39   * IMPORTANT: This class is <em>not</em> intended to be subclassed.
40   * </p>
41   */
42  public class ToolBar extends Composite {
43    ToolItem lastFocus;
44  
45  /**
46   * Constructs a new instance of this class given its parent
47   * and a style value describing its behavior and appearance.
48   * <p>
49   * The style value is either one of the style constants defined in
50   * class <code>SWT</code> which is applicable to instances of this
51   * class, or must be built by <em>bitwise OR</em>'ing together 
52   * (that is, using the <code>int</code> "|" operator) two or more
53   * of those <code>SWT</code> style constants. The class description
54   * lists the style constants that are applicable to the class.
55   * Style bits are also inherited from superclasses.
56   * </p>
57   *
58   * @param parent a composite control which will be the parent of the new instance (cannot be null)
59   * @param style the style of control to construct
60   *
61   * @exception IllegalArgumentException <ul>
62   *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
63   * </ul>
64   * @exception SWTException <ul>
65   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
66   *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
67   * </ul>
68   *
69   * @see SWT#FLAT
70   * @see SWT#WRAP
71   * @see SWT#RIGHT
72   * @see SWT#HORIZONTAL
73   * @see SWT#SHADOW_OUT
74   * @see SWT#VERTICAL
75   * @see Widget#checkSubclass()
76   * @see Widget#getStyle()
77   */
78  public ToolBar (Composite parent, int style) {
79    super (parent, checkStyle (style));
80    /*
81    * Ensure that either of HORIZONTAL or VERTICAL is set.
82    * NOTE: HORIZONTAL and VERTICAL have the same values
83    * as H_SCROLL and V_SCROLL so it is necessary to first
84    * clear these bits to avoid scroll bars and then reset
85    * the bits using the original style supplied by the
86    * programmer.
87    */
88    if ((style & SWT.VERTICAL) != 0) {
89      this.style |= SWT.VERTICAL;
90    } else {
91      this.style |= SWT.HORIZONTAL;
92    }
93    int orientation = (style & SWT.VERTICAL) != 0 ? OS.GTK_ORIENTATION_VERTICAL : OS.GTK_ORIENTATION_HORIZONTAL;
94    OS.gtk_toolbar_set_orientation (handle, orientation);
95  }
96  
97  Control [] _getChildren () {
98    Control [] children = super._getChildren ();
99    int count = 0;
100   ToolItem [] items = getItems ();
101   for (int i=0; i<items.length; i++) {
102     ToolItem item = items [i];
103     if (item != null && item.control != null) count++;
104   }
105   if (count == 0) return children;
106   Control [] newChildren = new Control [children.length + count];
107   System.arraycopy (children, 0, newChildren, 0, children.length);
108   int index = children.length;
109   for (int i=0; i<items.length; i++) {
110     ToolItem item = items [i];
111     if (item != null && item.control != null) newChildren [index++] = item.control;
112   }
113   return newChildren;
114 }
115 
116 static int checkStyle (int style) {
117   /*
118   * Feature in GTK.  It is not possible to create
119   * a toolbar that wraps.  Therefore, no matter what 
120   * style bits are specified,  clear the WRAP bits so 
121   * that the style matches the behavior.
122   */
123   if ((style & SWT.WRAP) != 0) style &= ~SWT.WRAP;
124   /*
125   * Even though it is legal to create this widget
126   * with scroll bars, they serve no useful purpose
127   * because they do not automatically scroll the
128   * widget's client area.  The fix is to clear
129   * the SWT style.
130   */
131   return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
132 }
133 
134 void createHandle (int index) {
135   state |= HANDLE;
136   fixedHandle = OS.gtk_fixed_new ();
137   if (fixedHandle == 0) error (SWT.ERROR_NO_HANDLES);
138   OS.gtk_fixed_set_has_window (fixedHandle, true);
139   handle = OS.gtk_toolbar_new ();
140   if (handle == 0) error (SWT.ERROR_NO_HANDLES);
141   long /*int*/ parentHandle = parent.parentingHandle ();
142   OS.gtk_container_add (parentHandle, fixedHandle);
143   OS.gtk_container_add (fixedHandle, handle);
144   OS.gtk_widget_show (fixedHandle);
145   OS.gtk_widget_show (handle);
146   if ((style & SWT.FLAT) != 0) {
147     byte [] swt_toolbar_flat = Converter.wcsToMbcs (null, "swt-toolbar-flat", true);
148     OS.gtk_widget_set_name (handle, swt_toolbar_flat);
149   }
150 }
151 
152 public Point computeSize (int wHint, int hHint, boolean changed) {
153   checkWidget ();
154   if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
155   if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
156   if (layout != null) super.computeSize(wHint, hHint, changed);
157   return computeNativeSize(handle, wHint, hHint, changed);
158 }
159 
160 long /*int*/ eventHandle () {
161   return fixedHandle;
162 }
163 
164 boolean forceFocus (long /*int*/ focusHandle) {
165   if (lastFocus != null && lastFocus.setFocus ()) return true;
166   ToolItem [] items = getItems ();
167   for (int i = 0; i < items.length; i++) {
168     ToolItem item = items [i];
169     if (item.setFocus ()) return true;
170   }
171   return super.forceFocus (focusHandle);
172 }
173 
174 /**
175  * Returns the item at the given, zero-relative index in the
176  * receiver. Throws an exception if the index is out of range.
177  *
178  * @param index the index of the item to return
179  * @return the item at the given index
180  *
181  * @exception IllegalArgumentException <ul>
182  *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
183  * </ul>
184  * @exception SWTException <ul>
185  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
186  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
187  * </ul>
188  */
189 public ToolItem getItem (int index) {
190   checkWidget();
191   if (!(0 <= index && index < getItemCount())) error (SWT.ERROR_INVALID_RANGE);
192   return getItems()[index];
193 }
194 
195 /**
196  * Returns the item at the given point in the receiver
197  * or null if no such item exists. The point is in the
198  * coordinate system of the receiver.
199  *
200  * @param point the point used to locate the item
201  * @return the item at the given point
202  *
203  * @exception IllegalArgumentException <ul>
204  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
205  * </ul>
206  * @exception SWTException <ul>
207  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
208  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
209  * </ul>
210  */
211 public ToolItem getItem (Point point) {
212   checkWidget();
213   if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
214   ToolItem[] items = getItems();
215   for (int i=0; i<items.length; i++) {
216     if (items[i].getBounds().contains(point)) return items[i];
217   }
218   return null;
219 }
220 
221 /**
222  * Returns the number of items contained in the receiver.
223  *
224  * @return the number of items
225  *
226  * @exception SWTException <ul>
227  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
228  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
229  * </ul>
230  */
231 public int getItemCount () {
232   checkWidget();
233   long /*int*/ list = OS.gtk_container_get_children (handle);
234   if (list == 0) return 0;
235   int itemCount = OS.g_list_length (list);
236   OS.g_list_free (list);
237   return itemCount;
238 }
239 
240 /**
241  * Returns an array of <code>ToolItem</code>s which are the items
242  * in the receiver. 
243  * <p>
244  * Note: This is not the actual structure used by the receiver
245  * to maintain its list of items, so modifying the array will
246  * not affect the receiver. 
247  * </p>
248  *
249  * @return the items in the receiver
250  *
251  * @exception SWTException <ul>
252  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
253  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
254  * </ul>
255  */
256 public ToolItem [] getItems () {
257   checkWidget();
258   long /*int*/ list = OS.gtk_container_get_children (handle);
259   if (list == 0) return new ToolItem [0];
260   int count = OS.g_list_length (list);
261   ToolItem [] result = new ToolItem [count];
262   for (int i=0; i<count; i++) {
263     long /*int*/ data = OS.g_list_nth_data (list, i);
264     Widget widget = display.getWidget (data);
265     result [i] = (ToolItem) widget;
266   }
267   OS.g_list_free (list);
268   return result;
269 }
270 
271 /**
272  * Returns the number of rows in the receiver. When
273  * the receiver has the <code>WRAP</code> style, the
274  * number of rows can be greater than one.  Otherwise,
275  * the number of rows is always one.
276  *
277  * @return the number of items
278  *
279  * @exception SWTException <ul>
280  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
281  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
282  * </ul>
283  */
284 public int getRowCount () {
285   checkWidget();
286    /* On GTK, toolbars cannot wrap */
287   return 1;
288 }
289 
290 long /*int*/ gtk_key_press_event (long /*int*/ widget, long /*int*/ eventPtr) {
291   if (!hasFocus ()) return 0;
292   long /*int*/ result = super.gtk_key_press_event (widget, eventPtr);
293   if (result != 0) return result;
294   ToolItem [] items = getItems ();
295   int length = items.length;
296   int index = 0;
297   while (index < length) {
298     if (items [index].hasFocus ()) break;
299     index++;
300   }
301   GdkEventKey gdkEvent = new GdkEventKey ();
302   OS.memmove (gdkEvent, eventPtr, GdkEventKey.sizeof);
303   boolean next = false;
304   switch (gdkEvent.keyval) {
305     case OS.GDK_Up:
306     case OS.GDK_Left: next = false; break;
307     case OS.GDK_Down: {
308       if (0 <= index && index < length) {
309         ToolItem item = items [index];
310         if ((item.style & SWT.DROP_DOWN) != 0) {
311           Event event = new Event ();
312           event.detail = SWT.ARROW;
313           long /*int*/ topHandle = item.topHandle ();
314           event.x = OS.GTK_WIDGET_X (topHandle);
315           event.y = OS.GTK_WIDGET_Y (topHandle) + OS.GTK_WIDGET_HEIGHT (topHandle);
316           item.postEvent (SWT.Selection, event);
317           return result;
318         }
319       }
320       //FALL THROUGH
321     }
322     case OS.GDK_Right: next = true; break;
323     default: return result;
324   }
325   int start = index, offset = next ? 1 : -1;
326   while ((index = (index + offset + length) % length) != start) {
327     ToolItem item = items [index];
328     if (item.setFocus ()) return result;
329   }
330   return result;
331 }
332 
333 boolean hasFocus () {
334   ToolItem [] items = getItems ();
335   for (int i=0; i<items.length; i++) {
336     ToolItem item = items [i];
337     if (item.hasFocus ()) return true;
338   }
339   return super.hasFocus();
340 }
341 
342 /**
343  * Searches the receiver's list starting at the first item
344  * (index 0) until an item is found that is equal to the 
345  * argument, and returns the index of that item. If no item
346  * is found, returns -1.
347  *
348  * @param item the search item
349  * @return the index of the item
350  *
351  * @exception IllegalArgumentException <ul>
352  *    <li>ERROR_NULL_ARGUMENT - if the tool item is null</li>
353  *    <li>ERROR_INVALID_ARGUMENT - if the tool item has been disposed</li>
354  * </ul>
355  * @exception SWTException <ul>
356  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
357  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
358  * </ul>
359  */
360 public int indexOf (ToolItem item) {
361   checkWidget();
362   if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
363   // TEMPORARY CODE
364   ToolItem [] items = getItems ();
365   for (int i=0; i<items.length; i++) {
366     if (item == items[i]) return i;
367   }
368   return -1;
369 }
370 
371 boolean mnemonicHit (char key) {
372   ToolItem [] items = getItems ();
373   for (int i=0; i<items.length; i++) {
374     long /*int*/ labelHandle = items [i].labelHandle;
375     if (labelHandle != 0 && mnemonicHit (labelHandle, key)) return true;
376   }
377   return false;
378 }
379 
380 boolean mnemonicMatch (char key) {
381   ToolItem [] items = getItems ();
382   for (int i=0; i<items.length; i++) {
383     long /*int*/ labelHandle = items [i].labelHandle;
384     if (labelHandle != 0 && mnemonicMatch (labelHandle, key)) return true;
385   }
386   return false;
387 }
388 
389 void releaseWidget () {
390   ToolItem [] items = getItems ();
391   for (int i=0; i<items.length; i++) {
392     ToolItem item = items [i];
393     if (!item.isDisposed ()) item.releaseResources ();
394   }
395   items = null;
396   super.releaseWidget ();
397 }
398 
399 void removeControl (Control control) {
400   super.removeControl (control);
401   ToolItem [] items = getItems ();
402   for (int i=0; i<items.length; i++) {
403     ToolItem item = items [i];
404     if (item != null && item.control == control) {
405       item.setControl (null);
406     }
407   }
408 }
409 
410 void setFontDescription (long /*int*/ font) {
411   super.setFontDescription (font);
412   ToolItem [] items = getItems ();
413   for (int i = 0; i < items.length; i++) {
414     if (items[i] != null) {
415       items[i].setFontDescription (font);
416     }
417   }
418 }
419 
420 void setForegroundColor (GdkColor color) {
421   super.setForegroundColor (color);
422   ToolItem [] items = getItems ();
423   for (int i = 0; i < items.length; i++) {
424     if (items[i] != null) {
425       items[i].setForegroundColor (color);
426     }
427   }
428 }
429 
430 public void setToolTipText (String string) {
431   checkWidget();
432   super.setToolTipText (string);
433   Shell shell = _getShell ();
434   ToolItem [] items = getItems ();
435   for (int i = 0; i < items.length; i++) {
436     shell.setToolTipText (items [i].handle, string != null ? null : items [i].toolTipText);
437   }
438 }
439 
440 }