blob: b17667dc0bf6a5884b5e0ff5b3821a83c6fc1443 [file] [log] [blame]
package org.eclipse.swt.widgets;
/*
* Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
* This file is made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*/
import org.eclipse.swt.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.graphics.*;
/**
* Instances of this class support the layout of selectable
* tool bar items.
* <p>
* The item children that may be added to instances of this class
* must be of type <code>ToolItem</code>.
* </p><p>
* Note that although this class is a subclass of <code>Composite</code>,
* it does not make sense to add <code>Control</code> children to it,
* or set a layout on it.
* </p><p>
* <dl>
* <dt><b>Styles:</b></dt>
* <dd>FLAT, WRAP, RIGHT, HORIZONTAL, VERTICAL, SHADOW_OUT</dd>
* <dt><b>Events:</b></dt>
* <dd>(none)</dd>
* </dl>
* <p>
* Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
* </p><p>
* IMPORTANT: This class is <em>not</em> intended to be subclassed.
* </p>
*/
public class ToolBar extends Composite {
int tooltipsHandle;
/**
* Constructs a new instance of this class given its parent
* and a style value describing its behavior and appearance.
* <p>
* The style value is either one of the style constants defined in
* class <code>SWT</code> which is applicable to instances of this
* class, or must be built by <em>bitwise OR</em>'ing together
* (that is, using the <code>int</code> "|" operator) two or more
* of those <code>SWT</code> style constants. The class description
* lists the style constants that are applicable to the class.
* Style bits are also inherited from superclasses.
* </p>
*
* @param parent a composite control which will be the parent of the new instance (cannot be null)
* @param style the style of control to construct
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
* <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
* </ul>
*
* @see SWT#FLAT
* @see SWT#WRAP
* @see SWT#RIGHT
* @see SWT#HORIZONTAL
* @see SWT#SHADOW_OUT
* @see SWT#VERTICAL
* @see Widget#checkSubclass
* @see Widget#getStyle
*/
public ToolBar (Composite parent, int style) {
super (parent, checkStyle (style));
/*
* Ensure that either of HORIZONTAL or VERTICAL is set.
* NOTE: HORIZONTAL and VERTICAL have the same values
* as H_SCROLL and V_SCROLL so it is necessary to first
* clear these bits to avoid scroll bars and then reset
* the bits using the original style supplied by the
* programmer.
*/
if ((style & SWT.VERTICAL) != 0) {
this.style |= SWT.VERTICAL;
} else {
this.style |= SWT.HORIZONTAL;
}
int orientation = (style & SWT.VERTICAL) != 0 ? OS.GTK_ORIENTATION_VERTICAL : OS.GTK_ORIENTATION_HORIZONTAL;
OS.gtk_toolbar_set_orientation (handle, orientation);
}
void createHandle (int index) {
state |= HANDLE;
fixedHandle = OS.gtk_fixed_new ();
if (fixedHandle == 0) error (SWT.ERROR_NO_HANDLES);
OS.gtk_fixed_set_has_window (fixedHandle, true);
handle = OS.gtk_toolbar_new ();
if (handle == 0) error (SWT.ERROR_NO_HANDLES);
int parentHandle = parent.parentingHandle ();
OS.gtk_container_add (parentHandle, fixedHandle);
OS.gtk_container_add (fixedHandle, handle);
OS.gtk_widget_show (fixedHandle);
OS.gtk_widget_show (handle);
if ((style & SWT.FLAT) != 0) {
int style = OS.gtk_widget_get_modifier_style (handle);
OS.gtk_rc_style_set_xthickness (style, 0);
OS.gtk_rc_style_set_ythickness (style, 0);
OS.gtk_widget_modify_style (handle, style);
}
}
void enableWidget (boolean enabled) {
/* Do nothing - Tool bar items are individually enabled by the application */
}
public Point computeSize (int wHint, int hHint, boolean changed) {
checkWidget ();
if (layout != null) super.computeSize(wHint, hHint, changed);
return computeNativeSize(handle, wHint, hHint, changed);
}
int eventHandle () {
return fixedHandle;
}
/**
* Returns the item at the given, zero-relative index in the
* receiver. Throws an exception if the index is out of range.
*
* @param index the index of the item to return
* @return the item at the given index
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public ToolItem getItem (int index) {
checkWidget();
if (!(0 <= index && index < getItemCount())) error (SWT.ERROR_INVALID_RANGE);
return getItems()[index];
}
/**
* Returns the item at the given point in the receiver
* or null if no such item exists. The point is in the
* coordinate system of the receiver.
*
* @param point the point used to locate the item
* @return the item at the given point
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public ToolItem getItem (Point point) {
ToolItem[] items = getItems();
for (int i=0; i<items.length; i++) {
if (items[i].getBounds().contains(point)) return items[i];
}
return null;
}
/**
* Returns the number of items contained in the receiver.
*
* @return the number of items
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public int getItemCount () {
checkWidget();
int list = OS.gtk_container_get_children (handle);
if (list == 0) return 0;
int itemCount = OS.g_list_length (list);
OS.g_list_free (list);
return itemCount;
}
/**
* Returns an array of <code>TabItem</code>s which are the items
* in the receiver.
* <p>
* Note: This is not the actual structure used by the receiver
* to maintain its list of items, so modifying the array will
* not affect the receiver.
* </p>
*
* @return the items in the receiver
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public ToolItem [] getItems () {
checkWidget();
int list = OS.gtk_container_get_children (handle);
if (list == 0) return new ToolItem [0];
int count = OS.g_list_length (list);
ToolItem [] result = new ToolItem [count];
for (int i=0; i<count; i++) {
int data = OS.g_list_nth_data (list, i);
Widget widget = WidgetTable.get (data);
result [i] = (ToolItem) widget;
}
OS.g_list_free (list);
return result;
}
/**
* Returns the number of rows in the receiver. When
* the receiver has the <code>WRAP</code> style, the
* number of rows can be greater than one. Otherwise,
* the number of rows is always one.
*
* @return the number of items
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public int getRowCount () {
checkWidget();
return 1; /* On GTK, toolbars never wrap */
}
/**
* Searches the receiver's list starting at the first item
* (index 0) until an item is found that is equal to the
* argument, and returns the index of that item. If no item
* is found, returns -1.
*
* @param item the search item
* @return the index of the item
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the tool item is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the tool item has been disposed</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public int indexOf (ToolItem item) {
checkWidget();
if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
// TEMPORARY CODE
ToolItem [] items = getItems ();
for (int i=0; i<items.length; i++) {
if (item == items[i]) return i;
}
return -1;
}
void releaseWidget () {
ToolItem [] items = getItems ();
for (int i=0; i<items.length; i++) {
ToolItem item = items [i];
if (!item.isDisposed ()) item.releaseResources ();
}
items = null;
super.releaseWidget ();
if (tooltipsHandle != 0) OS.g_object_unref (tooltipsHandle);
tooltipsHandle = 0;
}
static int checkStyle (int style) {
/*
* Even though it is legal to create this widget
* with scroll bars, they serve no useful purpose
* because they do not automatically scroll the
* widget's client area. The fix is to clear
* the SWT style.
*/
return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
}
void setFontDescription (int font) {
super.setFontDescription (font);
ToolItem [] items = getItems ();
for (int i = 0; i < items.length; i++) {
if (items[i] != null) {
items[i].setFontDescription (font);
}
}
}
void setForegroundColor (GdkColor color) {
super.setForegroundColor (color);
ToolItem [] items = getItems ();
for (int i = 0; i < items.length; i++) {
if (items[i] != null) {
items[i].setForegroundColor (color);
}
}
}
public void setToolTipText (String string) {
checkWidget();
super.setToolTipText (string);
int tooltipsHandle = tooltipsHandle ();
if (string == null) {
OS.gtk_tooltips_enable (tooltipsHandle);
} else {
OS.gtk_tooltips_disable (tooltipsHandle);
}
}
int tooltipsHandle() {
if (tooltipsHandle == 0) {
tooltipsHandle = OS.gtk_tooltips_new ();
if (tooltipsHandle == 0) error (SWT.ERROR_NO_HANDLES);
OS.g_object_ref (tooltipsHandle);
OS.gtk_object_sink (tooltipsHandle);
}
return tooltipsHandle;
}
}