Mercurial > projects > dwt-linux
changeset 79:eb0144eddf0f
ExpandBar and ExpandItem
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 15 Jan 2008 17:11:43 +0100 |
parents | 3acb1029ed5c |
children | f9349a0d8101 |
files | dwt/internal/gtk/OS.d dwt/widgets/Composite.d dwt/widgets/ExpandBar.d dwt/widgets/ExpandItem.d |
diffstat | 4 files changed, 1342 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/dwt/internal/gtk/OS.d Tue Jan 15 16:35:35 2008 +0100 +++ b/dwt/internal/gtk/OS.d Tue Jan 15 17:11:43 2008 +0100 @@ -2152,17 +2152,17 @@ /* Field accessors */ - static void GTK_ACCEL_LABEL_SET_ACCEL_STRING( GtkAccelLabel *arg0, gchar * arg1 ) - { arg0.accel_string = arg1; } - static gchar* GTK_ACCEL_LABEL_GET_ACCEL_STRING( GtkAccelLabel* arg0) - { return arg0.accel_string; } + static void GTK_ACCEL_LABEL_SET_ACCEL_STRING( void *arg0, gchar * arg1 ) + { (cast(GtkAccelLabel*)arg0).accel_string = arg1; } + static gchar* GTK_ACCEL_LABEL_GET_ACCEL_STRING( void* arg0) + { return (cast(GtkAccelLabel*)arg0).accel_string; } - static GtkWidget* GTK_SCROLLED_WINDOW_HSCROLLBAR( GtkScrolledWindow* arg0 ) - { return arg0.hscrollbar; } - static GtkWidget* GTK_SCROLLED_WINDOW_VSCROLLBAR( GtkScrolledWindow* arg0 ) - { return arg0.vscrollbar; } + static GtkWidget* GTK_SCROLLED_WINDOW_HSCROLLBAR( void* arg0 ) + { return (cast(GtkScrolledWindow*)arg0).hscrollbar; } + static GtkWidget* GTK_SCROLLED_WINDOW_VSCROLLBAR( void* arg0 ) + { return (cast(GtkScrolledWindow*)arg0).vscrollbar; } - static int GTK_SCROLLED_WINDOW_SCROLLBAR_SPACING( GtkScrolledWindow* arg0) + static int GTK_SCROLLED_WINDOW_SCROLLBAR_SPACING( void* arg0) { return ((cast(GtkScrolledWindowClass*) ((cast(GTypeInstance*) arg0).g_class) ).scrollbar_spacing >= 0 ? (cast(GtkScrolledWindowClass*) ((cast(GTypeInstance*) arg0).g_class)).scrollbar_spacing : 3) ;
--- a/dwt/widgets/Composite.d Tue Jan 15 16:35:35 2008 +0100 +++ b/dwt/widgets/Composite.d Tue Jan 15 17:11:43 2008 +0100 @@ -491,6 +491,7 @@ return super.focusHandle (); } +alias Scrollable.forceFocus forceFocus; override bool forceFocus (GtkWidget* focusHandle) { if (socketHandle !is null) OS.GTK_WIDGET_SET_FLAGS (focusHandle, OS.GTK_CAN_FOCUS); bool result = super.forceFocus (focusHandle);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/widgets/ExpandBar.d Tue Jan 15 17:11:43 2008 +0100 @@ -0,0 +1,709 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.widgets.ExpandBar; + + +import dwt.DWT; +import dwt.DWTException; +import dwt.events.ExpandAdapter; +import dwt.events.ExpandEvent; +import dwt.events.ExpandListener; +import dwt.graphics.FontMetrics; +import dwt.graphics.GC; +import dwt.graphics.GCData; +import dwt.graphics.Point; +import dwt.internal.gtk.OS; +import dwt.widgets.ExpandItem; +import dwt.widgets.Composite; +import dwt.widgets.ScrollBar; +import dwt.widgets.TypedListener; +import dwt.widgets.Event; +import dwt.widgets.Control; + +import Math = tango.math.Math; + +/** + * Instances of this class support the layout of selectable + * expand bar items. + * <p> + * The item children that may be added to instances of this class + * must be of type <code>ExpandItem</code>. + * </p><p> + * <dl> + * <dt><b>Styles:</b></dt> + * <dd>V_SCROLL</dd> + * <dt><b>Events:</b></dt> + * <dd>Expand, Collapse</dd> + * </dl> + * </p><p> + * IMPORTANT: This class is <em>not</em> intended to be subclassed. + * </p> + * + * @see ExpandItem + * @see ExpandEvent + * @see ExpandListener + * @see ExpandAdapter + * + * @since 3.2 + */ +public class ExpandBar : Composite { + ExpandItem [] items; + ExpandItem lastFocus; + int itemCount; + int spacing; + int yCurrentScroll; + +/** + * 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>DWT</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>DWT</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 DWTException <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 Widget#checkSubclass + * @see Widget#getStyle + */ +public this (Composite parent, int style) { + super (parent, style); +} + +/** + * Adds the listener to the collection of listeners who will + * be notified when an item in the receiver is expanded or collapsed + * by sending it one of the messages defined in the <code>ExpandListener</code> + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception DWTException <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> + * + * @see ExpandListener + * @see #removeExpandListener + */ +public void addExpandListener (ExpandListener listener) { + checkWidget (); + if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener (listener); + addListener (DWT.Expand, typedListener); + addListener (DWT.Collapse, typedListener); +} + +protected void checkSubclass () { + if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS); +} + +public Point computeSize (int wHint, int hHint, bool changed) { + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + if (wHint !is DWT.DEFAULT && wHint < 0) wHint = 0; + if (hHint !is DWT.DEFAULT && hHint < 0) hHint = 0; + Point size = computeNativeSize (handle, wHint, hHint, changed); + int border = OS.gtk_container_get_border_width (handle); + size.x += 2 * border; + size.y += 2 * border; + return size; + } else { + int height = 0, width = 0; + if (wHint is DWT.DEFAULT || hHint is DWT.DEFAULT) { + if (itemCount > 0) { + height += spacing; + GC gc = new GC (this); + for (int i = 0; i < itemCount; i++) { + ExpandItem item = items [i]; + height += item.getHeaderHeight (); + if (item.expanded) height += item.height; + height += spacing; + width = Math.max (width, item.getPreferredWidth (gc)); + } + gc.dispose (); + } + } + if (width is 0) width = DEFAULT_WIDTH; + if (height is 0) height = DEFAULT_HEIGHT; + if (wHint !is DWT.DEFAULT) width = wHint; + if (hHint !is DWT.DEFAULT) height = hHint; + return new Point (width, height); + } +} + +void createHandle (int index) { + state |= HANDLE; + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + fixedHandle = cast(GtkWidget*)OS.g_object_new (display.gtk_fixed_get_type (), null); + if (fixedHandle is null) error (DWT.ERROR_NO_HANDLES); + OS.gtk_fixed_set_has_window (fixedHandle, true); + handle = cast(GtkWidget*)OS.gtk_vbox_new (false, 0); + if (handle is null) error (DWT.ERROR_NO_HANDLES); + if ((style & DWT.V_SCROLL) !is 0) { + scrolledHandle = cast(GtkWidget*)OS.gtk_scrolled_window_new (null, null); + if (scrolledHandle is null) error (DWT.ERROR_NO_HANDLES); + int vsp = (style & DWT.V_SCROLL) !is 0 ? OS.GTK_POLICY_AUTOMATIC : OS.GTK_POLICY_NEVER; + OS.gtk_scrolled_window_set_policy (scrolledHandle, OS.GTK_POLICY_NEVER, vsp); + OS.gtk_container_add (fixedHandle, scrolledHandle); + OS.gtk_scrolled_window_add_with_viewport (scrolledHandle, handle); + } else { + OS.gtk_container_add (fixedHandle, handle); + } + OS.gtk_container_set_border_width (handle, 0); + } else { + auto topHandle = cast(GtkWidget*)OS.g_object_new (display.gtk_fixed_get_type (), null); + if (topHandle is null) error (DWT.ERROR_NO_HANDLES); + OS.gtk_fixed_set_has_window (topHandle, true); + if ((style & DWT.V_SCROLL) !is 0) { + fixedHandle = topHandle; + scrolledHandle = cast(GtkWidget*)OS.gtk_scrolled_window_new (null, null); + if (scrolledHandle is null) error (DWT.ERROR_NO_HANDLES); + handle = cast(GtkWidget*)OS.g_object_new (display.gtk_fixed_get_type (), null); + if (handle is null) error (DWT.ERROR_NO_HANDLES); + OS.gtk_fixed_set_has_window (handle, true); + OS.gtk_container_add (fixedHandle, scrolledHandle); + + /* + * Force the scrolledWindow to have a single child that is + * not scrolled automatically. Calling gtk_container_add() + * seems to add the child correctly but cause a warning. + */ + bool warnings = display.getWarnings (); + display.setWarnings (false); + OS.gtk_container_add (scrolledHandle, handle); + display.setWarnings (warnings); + } else { + handle = topHandle; + } + OS.GTK_WIDGET_SET_FLAGS (handle, OS.GTK_CAN_FOCUS); + } +} + +void createItem (ExpandItem item, int style, int index) { + if (!(0 <= index && index <= itemCount)) error (DWT.ERROR_INVALID_RANGE); + if (itemCount is items.length) { + ExpandItem [] newItems = new ExpandItem [itemCount + 4]; + System.arraycopy (items, 0, newItems, 0, items.length); + items = newItems; + } + System.arraycopy (items, index, items, index + 1, itemCount - index); + items [index] = item; + itemCount++; + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + if (lastFocus is null) lastFocus = item; + } + item.width = Math.max (0, getClientArea ().width - spacing * 2); + layoutItems (index, true); +} + +void createWidget (int index) { + super.createWidget (index); + items = new ExpandItem [4]; +} + +void destroyItem (ExpandItem item) { + int index = 0; + while (index < itemCount) { + if (items [index] is item) break; + index++; + } + if (index is itemCount) return; + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + if (item is lastFocus) { + int focusIndex = index > 0 ? index - 1 : 1; + if (focusIndex < itemCount) { + lastFocus = items [focusIndex]; + lastFocus.redraw (); + } else { + lastFocus = null; + } + } + } + System.arraycopy (items, index + 1, items, index, --itemCount - index); + items [itemCount] = null; + item.redraw (); + layoutItems (index, true); +} + +GtkWidget* eventHandle () { + return OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0) ? fixedHandle : handle; +} + +alias Composite.forceFocus forceFocus; +override bool forceFocus (GtkWidget* focusHandle) { + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + if (lastFocus !is null && lastFocus.setFocus ()) return true; + for (int i = 0; i < itemCount; i++) { + ExpandItem item = items [i]; + if (item.setFocus ()) return true; + } + } + return super.forceFocus (focusHandle); +} + +bool hasFocus () { + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + for (int i=0; i<itemCount; i++) { + ExpandItem item = items [i]; + if (item.hasFocus ()) return true; + } + } + return super.hasFocus(); +} + +int getBandHeight () { + if (font is null) return ExpandItem.CHEVRON_SIZE; + GC gc = new GC (this); + FontMetrics metrics = gc.getFontMetrics (); + gc.dispose (); + return Math.max (ExpandItem.CHEVRON_SIZE, metrics.getHeight ()); +} + +GdkColor* getForegroundColor () { + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + if ((state & FOREGROUND) is 0) { + return display.getSystemColor (DWT.COLOR_TITLE_FOREGROUND).handle; + } + } + return super.getForegroundColor (); +} + +/** + * 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 DWTException <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 ExpandItem getItem (int index) { + checkWidget(); + if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); + return items [index]; +} + +/** + * Returns the number of items contained in the receiver. + * + * @return the number of items + * + * @exception DWTException <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(); + return itemCount; +} + +/** + * Returns an array of <code>ExpandItem</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 DWTException <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 ExpandItem [] getItems () { + checkWidget (); + ExpandItem [] result = new ExpandItem [itemCount]; + System.arraycopy (items, 0, result, 0, itemCount); + return result; +} + +/** + * Returns the receiver's spacing. + * + * @return the spacing + * + * @exception DWTException <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 getSpacing () { + checkWidget (); + return spacing; +} + +override int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* gdkEvent) { + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + int x = cast(int)gdkEvent.x; + int y = cast(int)gdkEvent.y; + for (int i = 0; i < itemCount; i++) { + ExpandItem item = items[i]; + bool hover = item.x <= x && x < (item.x + item.width) && item.y <= y && y < (item.y + getBandHeight ()); + if (hover && item !is lastFocus) { + lastFocus.redraw (); + lastFocus = item; + lastFocus.redraw (); + forceFocus (); + break; + } + } + } + return super.gtk_button_press_event (widget, gdkEvent); +} + +override int /*long*/ gtk_button_release_event (GtkWidget* widget, GdkEventButton* gdkEvent) { + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + if (lastFocus !is null) { + int x = cast(int)gdkEvent.x; + int y = cast(int)gdkEvent.y; + bool hover = lastFocus.x <= x && x < (lastFocus.x + lastFocus.width) && lastFocus.y <= y && y < (lastFocus.y + getBandHeight ()); + if (hover) { + Event ev = new Event (); + ev.item = lastFocus; + notifyListeners (lastFocus.expanded ? DWT.Collapse : DWT.Expand, ev); + lastFocus.expanded = !lastFocus.expanded; + showItem (lastFocus); + } + } + } + return super.gtk_button_release_event (widget, gdkEvent); +} + +override int /*long*/ gtk_expose_event (GtkWidget* widget, GdkEventExpose* gdkEvent) { + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + GCData data = new GCData (); + data.damageRgn = gdkEvent.region; + GC gc = GC.gtk_new (this, data); + OS.gdk_gc_set_clip_region (gc.handle, gdkEvent.region); + bool hasFocus = isFocusControl (); + for (int i = 0; i < itemCount; i++) { + ExpandItem item = items [i]; + item.drawItem (gc, hasFocus && item is lastFocus); + } + gc.dispose (); + } + return super.gtk_expose_event (widget, gdkEvent); +} + +override int /*long*/ gtk_focus_in_event (GtkWidget* widget, GdkEventFocus* event) { + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + if (lastFocus !is null) lastFocus.redraw (); + } + return super.gtk_focus_in_event(widget, event); +} + +override int /*long*/ gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) { + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + if (lastFocus !is null) lastFocus.redraw (); + } + return super.gtk_focus_out_event (widget, event); +} + +override int /*long*/ gtk_key_press_event (GtkWidget* widget, GdkEventKey* gdkEvent) { + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + if (!hasFocus ()) return 0; + auto result = super.gtk_key_press_event (widget, gdkEvent); + if (result !is 0) return result; + int index = 0; + while (index < itemCount) { + if (items [index].hasFocus ()) break; + index++; + } + bool next = false; + switch (gdkEvent.keyval) { + case OS.GDK_Up: + case OS.GDK_Left: next = false; break; + case OS.GDK_Down: + case OS.GDK_Right: next = true; break; + default: return result; + } + int start = index, offset = next ? 1 : -1; + while ((index = (index + offset + itemCount) % itemCount) !is start) { + ExpandItem item = items [index]; + if (item.setFocus ()) return result; + } + return result; + } else { + if (lastFocus !is null) { + switch (gdkEvent.keyval) { + case OS.GDK_Return: + case OS.GDK_space: + Event ev = new Event (); + ev.item = lastFocus; + sendEvent (lastFocus.expanded ? DWT.Collapse :DWT.Expand, ev); + lastFocus.expanded = !lastFocus.expanded; + showItem (lastFocus); + break; + case OS.GDK_Up: + case OS.GDK_KP_Up: { + int focusIndex = indexOf (lastFocus); + if (focusIndex > 0) { + lastFocus.redraw (); + lastFocus = items [focusIndex - 1]; + lastFocus.redraw (); + } + break; + } + case OS.GDK_Down: + case OS.GDK_KP_Down: { + int focusIndex = indexOf (lastFocus); + if (focusIndex < itemCount - 1) { + lastFocus.redraw (); + lastFocus = items [focusIndex + 1]; + lastFocus.redraw (); + } + break; + } + default: + } + } + } + return super.gtk_key_press_event (widget, gdkEvent); +} + +/** + * 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 item is null</li> + * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> + * </ul> + * @exception DWTException <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 (ExpandItem item) { + checkWidget(); + if (item is null) error (DWT.ERROR_NULL_ARGUMENT); + for (int i = 0; i < itemCount; i++) { + if (items [i] is item) return i; + } + return -1; +} + +void layoutItems (int index, bool setScrollbar_) { + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + for (int i = 0; i < itemCount; i++) { + ExpandItem item = items [i]; + if (item !is null) item.resizeControl (yCurrentScroll); + } + } else { + if (index < itemCount) { + int y = spacing - yCurrentScroll; + for (int i = 0; i < index; i++) { + ExpandItem item = items [i]; + if (item.expanded) y += item.height; + y += item.getHeaderHeight() + spacing; + } + for (int i = index; i < itemCount; i++) { + ExpandItem item = items [i]; + item.setBounds (spacing, y, 0, 0, true, false); + if (item.expanded) y += item.height; + y += item.getHeaderHeight() + spacing; + } + } + if (setScrollbar_) setScrollbar (); + } +} + +GtkWidget* parentingHandle () { + return OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0) ? fixedHandle : handle; +} + +void releaseChildren (bool destroy) { + for (int i = 0; i < itemCount; i++) { + ExpandItem item = items [i]; + if (item !is null && !item.isDisposed ()) { + item.release (false); + } + } + super.releaseChildren (destroy); +} + +/** + * Removes the listener from the collection of listeners who will + * be notified when items in the receiver are expanded or collapsed. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception DWTException <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> + * + * @see ExpandListener + * @see #addExpandListener + */ +public void removeExpandListener (ExpandListener listener) { + checkWidget (); + if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); + if (eventTable is null) return; + eventTable.unhook (DWT.Expand, listener); + eventTable.unhook (DWT.Collapse, listener); +} + +int setBounds (int x, int y, int width, int height, bool move, bool resize) { + int result = super.setBounds (x, y, width, height, move, resize); + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + if (resize) { + if ((style & DWT.V_SCROLL) !is 0) { + setScrollbar (); + } else { + for (int i = 0; i < itemCount; i++) { + ExpandItem item = items [i]; + int newWidth = Math.max (0, getClientArea ().width - spacing * 2); + if (item.width !is newWidth) { + item.setBounds (0, 0, newWidth, item.height, false, true); + } + } + } + } + } + return result; +} + +void setFontDescription (PangoFontDescription* font) { + super.setFontDescription (font); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + for (int i = 0; i < itemCount; i++) { + items[i].setFontDescription (font); + } + layoutItems (0, true); + } +} + +void setForegroundColor (GdkColor* color) { + super.setForegroundColor (color); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + for (int i = 0; i < itemCount; i++) { + items[i].setForegroundColor (color); + } + } +} + +void setScrollbar () { + if (itemCount is 0) return; + if ((style & DWT.V_SCROLL) is 0) return; + int height = getClientArea ().height; + ExpandItem item = items [itemCount - 1]; + int maxHeight = item.y + getBandHeight () + spacing; + if (item.expanded) maxHeight += item.height; + auto adjustmentHandle = OS.gtk_scrolled_window_get_vadjustment (scrolledHandle); + yCurrentScroll = cast(int)adjustmentHandle.value; + + //claim bottom free space + if (yCurrentScroll > 0 && height > maxHeight) { + yCurrentScroll = Math.max (0, yCurrentScroll + maxHeight - height); + layoutItems (0, false); + } + maxHeight += yCurrentScroll; + adjustmentHandle.value = Math.min (yCurrentScroll, maxHeight); + adjustmentHandle.upper = maxHeight; + adjustmentHandle.page_size = height; + OS.gtk_adjustment_changed (adjustmentHandle); + int policy = maxHeight > height ? OS.GTK_POLICY_ALWAYS : OS.GTK_POLICY_NEVER; + OS.gtk_scrolled_window_set_policy (scrolledHandle, OS.GTK_POLICY_NEVER, policy); + int width = OS.GTK_WIDGET_WIDTH (fixedHandle) - spacing * 2; + if (policy is OS.GTK_POLICY_ALWAYS) { + auto vHandle = OS.GTK_SCROLLED_WINDOW_VSCROLLBAR (scrolledHandle); + GtkRequisition requisition; + OS.gtk_widget_size_request (vHandle, &requisition); + width -= requisition.width; + } + width = Math.max (0, width); + for (int i = 0; i < itemCount; i++) { + ExpandItem item2 = items[i]; + item2.setBounds (0, 0, width, item2.height, false, true); + } +} + +/** + * Sets the receiver's spacing. Spacing specifies the number of pixels allocated around + * each item. + * + * @exception DWTException <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 void setSpacing (int spacing) { + checkWidget (); + if (spacing < 0) return; + if (spacing is this.spacing) return; + this.spacing = spacing; + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + OS.gtk_box_set_spacing (handle, spacing); + OS.gtk_container_set_border_width (handle, spacing); + } else { + if ((style & DWT.V_SCROLL) is 0) { + int width = Math.max (0, getClientArea ().width - spacing * 2); + for (int i = 0; i < itemCount; i++) { + ExpandItem item = items [i]; + if (item.width !is width) item.setBounds (0, 0, width, item.height, false, true); + } + } + layoutItems (0, true); + redraw (); + } +} + +void showItem (ExpandItem item) { + Control control = item.control; + if (control !is null && !control.isDisposed ()) { + control.setVisible (item.expanded); + } + item.redraw (); + int index = indexOf (item); + layoutItems (index + 1, true); +} + +void updateScrollBarValue (ScrollBar bar) { + yCurrentScroll = bar.getSelection(); + layoutItems (0, false); +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/widgets/ExpandItem.d Tue Jan 15 17:11:43 2008 +0100 @@ -0,0 +1,623 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.widgets.ExpandItem; + + +import dwt.DWT; +import dwt.DWTException; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.internal.Converter; +import dwt.internal.gtk.OS; +import dwt.widgets.Item; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.ExpandBar; +import dwt.widgets.ImageList; +import dwt.widgets.Event; + +import Math = tango.math.Math; +static import tango.stdc.stringz; + +/** + * Instances of this class represent a selectable user interface object + * that represents a expandable item in a expand bar. + * <p> + * <dl> + * <dt><b>Styles:</b></dt> + * <dd>(none)</dd> + * <dt><b>Events:</b></dt> + * <dd>(none)</dd> + * </dl> + * </p><p> + * IMPORTANT: This class is <em>not</em> intended to be subclassed. + * </p> + * + * @see ExpandBar + * + * @since 3.2 + */ +public class ExpandItem : Item { + ExpandBar parent; + Control control; + ImageList imageList; + GtkWidget* clientHandle, boxHandle, labelHandle, imageHandle; + bool expanded; + int x, y, width, height; + int imageHeight, imageWidth; + static final int TEXT_INSET = 6; + static final int BORDER = 1; + static final int CHEVRON_SIZE = 24; + +/** + * 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>DWT</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>DWT</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 DWTException <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 Widget#checkSubclass + * @see Widget#getStyle + */ +public this (ExpandBar parent, int style) { + super (parent, style); + this.parent = parent; + createWidget (parent.getItemCount ()); +} + +/** + * Constructs a new instance of this class given its parent, a + * style value describing its behavior and appearance, and the index + * at which to place it in the items maintained by its parent. + * <p> + * The style value is either one of the style constants defined in + * class <code>DWT</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>DWT</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 + * @param index the zero-relative index to store the receiver in its parent + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> + * </ul> + * @exception DWTException <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 Widget#checkSubclass + * @see Widget#getStyle + */ +public this (ExpandBar parent, int style, int index) { + super (parent, style); + this.parent = parent; + createWidget (index); +} + +protected void checkSubclass () { + if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS); +} + +void createHandle (int index) { + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + state |= HANDLE; + handle = OS.gtk_expander_new (null); + if (handle is null) error (DWT.ERROR_NO_HANDLES); + clientHandle = cast(GtkWidget*)OS.g_object_new (display.gtk_fixed_get_type (), null); + if (clientHandle is null) error (DWT.ERROR_NO_HANDLES); + OS.gtk_container_add (handle, clientHandle); + boxHandle = cast(GtkWidget*)OS.gtk_hbox_new (false, 4); + if (boxHandle is null) error (DWT.ERROR_NO_HANDLES); + labelHandle = cast(GtkWidget*)OS.gtk_label_new (null); + if (labelHandle is null) error (DWT.ERROR_NO_HANDLES); + imageHandle = cast(GtkWidget*)OS.gtk_image_new (); + if (imageHandle is null) error (DWT.ERROR_NO_HANDLES); + OS.gtk_container_add (boxHandle, imageHandle); + OS.gtk_container_add (boxHandle, labelHandle); + OS.gtk_expander_set_label_widget (handle, boxHandle); + OS.GTK_WIDGET_SET_FLAGS (handle, OS.GTK_CAN_FOCUS); + } +} + +void createWidget (int index) { + super.createWidget (index); + showWidget (index); + parent.createItem (this, style, index); +} + +void deregister() { + super.deregister(); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + display.removeWidget (clientHandle); + display.removeWidget (boxHandle); + display.removeWidget (labelHandle); + display.removeWidget (imageHandle); + } +} + +void destroyWidget () { + parent.destroyItem (this); + super.destroyWidget (); +} + +void drawChevron (GC gc, int x, int y) { + int [] polyline1, polyline2; + if (expanded) { + int px = x + 4 + 5; + int py = y + 4 + 7; + polyline1 = [ + px,py, px+1,py, px+1,py-1, px+2,py-1, px+2,py-2, px+3,py-2, px+3,py-3, + px+3,py-2, px+4,py-2, px+4,py-1, px+5,py-1, px+5,py, px+6,py]; + py += 4; + polyline2 = [ + px,py, px+1,py, px+1,py-1, px+2,py-1, px+2,py-2, px+3,py-2, px+3,py-3, + px+3,py-2, px+4,py-2, px+4,py-1, px+5,py-1, px+5,py, px+6,py]; + } else { + int px = x + 4 + 5; + int py = y + 4 + 4; + polyline1 = [ + px,py, px+1,py, px+1,py+1, px+2,py+1, px+2,py+2, px+3,py+2, px+3,py+3, + px+3,py+2, px+4,py+2, px+4,py+1, px+5,py+1, px+5,py, px+6,py]; + py += 4; + polyline2 = [ + px,py, px+1,py, px+1,py+1, px+2,py+1, px+2,py+2, px+3,py+2, px+3,py+3, + px+3,py+2, px+4,py+2, px+4,py+1, px+5,py+1, px+5,py, px+6,py]; + } + gc.setForeground (display.getSystemColor (DWT.COLOR_TITLE_FOREGROUND)); + gc.drawPolyline (polyline1); + gc.drawPolyline (polyline2); +} + +void drawItem (GC gc, bool drawFocus) { + int headerHeight = parent.getBandHeight (); + Display display = getDisplay (); + gc.setForeground (display.getSystemColor (DWT.COLOR_TITLE_BACKGROUND)); + gc.setBackground (display.getSystemColor (DWT.COLOR_TITLE_BACKGROUND_GRADIENT)); + gc.fillGradientRectangle (x, y, width, headerHeight, true); + if (expanded) { + gc.setForeground (display.getSystemColor (DWT.COLOR_TITLE_BACKGROUND_GRADIENT)); + gc.drawLine (x, y + headerHeight, x, y + headerHeight + height - 1); + gc.drawLine (x, y + headerHeight + height - 1, x + width - 1, y + headerHeight + height - 1); + gc.drawLine (x + width - 1, y + headerHeight + height - 1, x + width - 1, y + headerHeight); + } + int drawX = x; + if (image !is null) { + drawX += ExpandItem.TEXT_INSET; + if (imageHeight > headerHeight) { + gc.drawImage (image, drawX, y + headerHeight - imageHeight); + } else { + gc.drawImage (image, drawX, y + (headerHeight - imageHeight) / 2); + } + drawX += imageWidth; + } + if (text.length > 0) { + drawX += ExpandItem.TEXT_INSET; + Point size = gc.stringExtent (text); + gc.setForeground (parent.getForeground ()); + gc.drawString (text, drawX, y + (headerHeight - size.y) / 2, true); + } + int chevronSize = ExpandItem.CHEVRON_SIZE; + drawChevron (gc, x + width - chevronSize, y + (headerHeight - chevronSize) / 2); + if (drawFocus) { + gc.drawFocus (x + 1, y + 1, width - 2, headerHeight - 2); + } +} + +/** + * Returns the control that is shown when the item is expanded. + * If no control has been set, return <code>null</code>. + * + * @return the control + * + * @exception DWTException <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 Control getControl () { + checkWidget (); + return control; +} + +/** + * Returns <code>true</code> if the receiver is expanded, + * and false otherwise. + * + * @return the expanded state + * + * @exception DWTException <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 bool getExpanded () { + checkWidget (); + return expanded; +} + +/** + * Returns the height of the receiver's header + * + * @return the height of the header + * + * @exception DWTException <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 getHeaderHeight () { + checkWidget (); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + auto widget = OS.gtk_expander_get_label_widget (handle); + return OS.GTK_WIDGET_HEIGHT (widget); + } + return Math.max (parent.getBandHeight (), imageHeight); +} + +/** + * Gets the height of the receiver. + * + * @return the height + * + * @exception DWTException <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 getHeight () { + checkWidget (); + return height; +} + +/** + * Returns the receiver's parent, which must be a <code>ExpandBar</code>. + * + * @return the receiver's parent + * + * @exception DWTException <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 ExpandBar getParent () { + checkWidget(); + return parent; +} + +int getPreferredWidth (GC gc) { + int width = ExpandItem.TEXT_INSET * 2 + ExpandItem.CHEVRON_SIZE; + if (image !is null) { + width += ExpandItem.TEXT_INSET + imageWidth; + } + if (text.length > 0) { + width += gc.stringExtent (text).x; + } + return width; +} + +override int /*long*/ gtk_activate (GtkWidget* widget) { + Event event = new Event (); + event.item = this; + int type = OS.gtk_expander_get_expanded (handle) ? DWT.Collapse : DWT.Expand; + parent.sendEvent (type, event); + return 0; +} + +override int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* event) { + setFocus (); + return 0; +} + +override int /*long*/ gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) { + OS.GTK_WIDGET_UNSET_FLAGS (handle, OS.GTK_CAN_FOCUS); + parent.lastFocus = this; + return 0; +} + +override int /*long*/ gtk_size_allocate (GtkWidget* widget, int /*long*/ allocation) { + parent.layoutItems (0, false); + return 0; +} + +override int /*long*/ gtk_enter_notify_event (GtkWidget* widget, GdkEventCrossing* event) { + parent.gtk_enter_notify_event(widget, event); + return 0; +} + +bool hasFocus () { + return OS.GTK_WIDGET_HAS_FOCUS (handle); +} + +void hookEvents () { + super.hookEvents (); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + OS.g_signal_connect_closure (handle, OS.activate.ptr, display.closures [ACTIVATE], false); + OS.g_signal_connect_closure (handle, OS.activate.ptr, display.closures [ACTIVATE_INVERSE], true); + OS.g_signal_connect_closure_by_id (handle, display.signalIds [BUTTON_PRESS_EVENT], 0, display.closures [BUTTON_PRESS_EVENT], false); + OS.g_signal_connect_closure_by_id (handle, display.signalIds [FOCUS_OUT_EVENT], 0, display.closures [FOCUS_OUT_EVENT], false); + OS.g_signal_connect_closure (clientHandle, OS.size_allocate.ptr, display.closures [SIZE_ALLOCATE], true); + OS.g_signal_connect_closure_by_id (handle, display.signalIds [ENTER_NOTIFY_EVENT], 0, display.closures [ENTER_NOTIFY_EVENT], false); + } +} + +void redraw () { + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + int headerHeight = parent.getBandHeight (); + if (imageHeight > headerHeight) { + parent.redraw (x + ExpandItem.TEXT_INSET, y + headerHeight - imageHeight, imageWidth, imageHeight, false); + } + parent.redraw (x, y, width, headerHeight + height, false); + } +} + +void register () { + super.register (); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + display.addWidget (clientHandle, this); + display.addWidget (boxHandle, this); + display.addWidget (labelHandle, this); + display.addWidget (imageHandle, this); + } +} + +void releaseHandle () { + super.releaseHandle (); + clientHandle = boxHandle = labelHandle = imageHandle = null; + parent = null; +} + +void releaseWidget () { + super.releaseWidget (); + if (imageList !is null) imageList.dispose (); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + if (parent.lastFocus is this) parent.lastFocus = null; + } + imageList = null; + control = null; +} + +void resizeControl (int yScroll) { + if (control !is null && !control.isDisposed ()) { + bool visible =cast(bool) OS.gtk_expander_get_expanded (handle); + if (visible) { + int x = OS.GTK_WIDGET_X (clientHandle); + int y = OS.GTK_WIDGET_Y (clientHandle); + if (x !is -1 && y !is -1) { + int width = OS.GTK_WIDGET_WIDTH (clientHandle); + int height = OS.GTK_WIDGET_HEIGHT (clientHandle); + int property; + OS.gtk_widget_style_get1 (handle, OS.focus_line_width.ptr, &property); + y += property * 2; + height -= property * 2; + control.setBounds (x, y - yScroll, width, Math.max (0, height), true, true); + } + } + control.setVisible (visible); + } +} + +void setBounds (int x, int y, int width, int height, bool move, bool size) { + redraw (); + int headerHeight = parent.getBandHeight (); + if (move) { + if (imageHeight > headerHeight) { + y += (imageHeight - headerHeight); + } + this.x = x; + this.y = y; + redraw (); + } + if (size) { + this.width = width; + this.height = height; + redraw (); + } + if (control !is null && !control.isDisposed ()) { + if (move) control.setLocation (x + BORDER, y + headerHeight); + if (size) control.setSize (Math.max (0, width - 2 * BORDER), Math.max (0, height - BORDER)); + } +} + +/** + * Sets the control that is shown when the item is expanded. + * + * @param control the new control (or null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> + * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li> + * </ul> + * @exception DWTException <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 void setControl (Control control) { + checkWidget (); + if (control !is null) { + if (control.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); + if (control.parent !is parent) error (DWT.ERROR_INVALID_PARENT); + } + if (this.control is control) return; + this.control = control; + if (control !is null) { + control.setVisible (expanded); + if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { + int headerHeight = parent.getBandHeight (); + control.setBounds (x + BORDER, y + headerHeight, Math.max (0, width - 2 * BORDER), Math.max (0, height - BORDER)); + } + } + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + parent.layoutItems (0, true); + } +} + +/** + * Sets the expanded state of the receiver. + * + * @param expanded the new expanded state + * + * @exception DWTException <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 void setExpanded (bool expanded) { + checkWidget (); + this.expanded = expanded; + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + OS.gtk_expander_set_expanded (handle, expanded); + parent.layoutItems (0, true); + } else { + parent.showItem (this); + } +} + +bool setFocus () { + if (!OS.gtk_widget_get_child_visible (handle)) return false; + OS.GTK_WIDGET_SET_FLAGS (handle, OS.GTK_CAN_FOCUS); + OS.gtk_widget_grab_focus (handle); + bool result = cast(bool)OS.gtk_widget_is_focus (handle); + if (!result) OS.GTK_WIDGET_UNSET_FLAGS (handle, OS.GTK_CAN_FOCUS); + return result; +} + +void setFontDescription (PangoFontDescription* font) { + OS.gtk_widget_modify_font (handle, font); + if (labelHandle !is null) OS.gtk_widget_modify_font (labelHandle, font); + if (imageHandle !is null) OS.gtk_widget_modify_font (imageHandle, font); +} + +alias Item.setForegroundColor setForegroundColor; +void setForegroundColor (GdkColor* color) { + setForegroundColor (handle, color); + if (labelHandle !is null) setForegroundColor (labelHandle, color); + if (imageHandle !is null) setForegroundColor (imageHandle, color); +} + +/** + * Sets the height of the receiver. This is height of the item when it is expanded, + * excluding the height of the header. + * + * @param height the new height + * + * @exception DWTException <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 void setHeight (int height) { + checkWidget (); + if (height < 0) return; + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + this.height = height; + OS.gtk_widget_set_size_request (clientHandle, -1, height); + parent.layoutItems (0, false); + } else { + setBounds (0, 0, width, height, false, true); + if (expanded) parent.layoutItems (parent.indexOf (this) + 1, true); + } +} + +public void setImage (Image image) { + super.setImage (image); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + if (imageList !is null) imageList.dispose (); + imageList = null; + if (image !is null) { + if (image.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); + imageList = new ImageList (); + int imageIndex = imageList.add (image); + auto pixbuf = imageList.getPixbuf (imageIndex); + OS.gtk_image_set_from_pixbuf (imageHandle, pixbuf); + if (text.length is 0) OS.gtk_widget_hide (labelHandle); + OS.gtk_widget_show (imageHandle); + } else { + OS.gtk_image_set_from_pixbuf (imageHandle, null); + OS.gtk_widget_show (labelHandle); + OS.gtk_widget_hide (imageHandle); + } + } else { + int oldImageHeight = imageHeight; + if (image !is null) { + Rectangle bounds = image.getBounds (); + imageHeight = bounds.height; + imageWidth = bounds.width; + } else { + imageHeight = imageWidth = 0; + } + if (oldImageHeight !is imageHeight) { + parent.layoutItems (parent.indexOf (this), true); + } else { + redraw (); + } + } +} + +public void setText (char[] string) { + super.setText (string); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + OS.gtk_label_set_text (labelHandle, tango.stdc.stringz.toStringz(string)); + } else { + redraw (); + } +} + +void showWidget (int index) { + if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { + OS.gtk_widget_show (handle); + OS.gtk_widget_show (clientHandle); + OS.gtk_container_add (parent.handle, handle); + OS.gtk_box_set_child_packing (parent.handle, handle, false, false, 0, OS.GTK_PACK_START); + if (boxHandle !is null) OS.gtk_widget_show (boxHandle); + if (labelHandle !is null) OS.gtk_widget_show (labelHandle); + } +} + +alias Item.windowProc windowProc; +override int /*long*/ windowProc (GtkWidget* handle, int /*long*/ user_data) { + switch (cast(int)/*64*/user_data) { + case ACTIVATE_INVERSE: { + expanded = cast(bool)OS.gtk_expander_get_expanded (handle); + parent.layoutItems (0, false); + return 0; + } + default: + } + return super.windowProc (handle, user_data); +} +}