Mercurial > projects > dwt-linux
diff dwt/widgets/Control.d @ 240:ce446666f5a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 12 May 2008 19:13:01 +0200 |
parents | 380bad9f6852 |
children | 5a30aa9820f3 |
line wrap: on
line diff
--- a/dwt/widgets/Control.d Mon May 12 15:36:37 2008 +0200 +++ b/dwt/widgets/Control.d Mon May 12 19:13:01 2008 +0200 @@ -39,6 +39,7 @@ import dwt.graphics.Image; import dwt.graphics.Point; import dwt.graphics.Rectangle; +import dwt.graphics.Region; import dwt.internal.Converter; import dwt.internal.DWTEventListener; import dwt.internal.accessibility.gtk.ATK; @@ -96,6 +97,7 @@ Menu menu; Image backgroundImage; Font font; + Region region; String toolTipText; Object layoutData; Accessible accessible; @@ -137,8 +139,8 @@ createWidget (0); } -PangoFontDescription* defaultFont () { - return display.getSystemFont ().handle; +Font defaultFont () { + return display.getSystemFont (); } override void deregister () { @@ -153,6 +155,7 @@ auto window = OS.GTK_WIDGET_WINDOW (paintHandle); if (window is null) return false; int orientation = vertical ? OS.GTK_ORIENTATION_HORIZONTAL : OS.GTK_ORIENTATION_VERTICAL; + if ((style & DWT.MIRRORED) !is 0) x = getClientWidth () - width - x; char dummy; OS.gtk_paint_handle (OS.gtk_widget_get_style (paintHandle), window, OS.GTK_STATE_NORMAL, OS.GTK_SHADOW_OUT, null, paintHandle, &dummy, x, y, width, height, orientation); return true; @@ -241,8 +244,7 @@ /* Connect the mouse signals */ auto eventHandle = eventHandle (); - int eventMask = OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_PRESS_MASK | - OS.GDK_BUTTON_RELEASE_MASK; + int eventMask = OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_PRESS_MASK | OS.GDK_BUTTON_RELEASE_MASK; OS.gtk_widget_add_events (eventHandle, eventMask); OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [BUTTON_PRESS_EVENT], 0, display.closures [BUTTON_PRESS_EVENT], false); OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [BUTTON_RELEASE_EVENT], 0, display.closures [BUTTON_RELEASE_EVENT], false); @@ -296,8 +298,8 @@ OS.g_signal_connect_closure_by_id (paintHandle, display.signalIds [STYLE_SET], 0, display.closures [STYLE_SET], false); - auto topHandle = topHandle (); - OS.g_signal_connect_closure_by_id (topHandle, display.signalIds [MAP], 0, display.closures [MAP], true); + auto topHandle_ = topHandle (); + OS.g_signal_connect_closure_by_id (topHandle_, display.signalIds [MAP], 0, display.closures [MAP], true); } override int /*long*/ hoverProc (GtkWidget* widget) { @@ -315,9 +317,9 @@ } GtkWidget* paintHandle () { - auto topHandle = topHandle (); + auto topHandle_ = topHandle (); auto paintHandle = handle; - while (paintHandle !is topHandle) { + while (paintHandle !is topHandle_) { if ((OS.GTK_WIDGET_FLAGS (paintHandle) & OS.GTK_NO_WINDOW) is 0) break; paintHandle = OS.gtk_widget_get_parent (paintHandle); } @@ -330,6 +332,91 @@ return OS.GTK_WIDGET_WINDOW (paintHandle); } +public bool print (GC gc) { + checkWidget (); + if (gc is null) error (DWT.ERROR_NULL_ARGUMENT); + if (gc.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); + auto topHandle_ = topHandle (); + OS.gtk_widget_realize (topHandle_); + auto window = OS.GTK_WIDGET_WINDOW (topHandle_); + GCData data = gc.getGCData (); + OS.gdk_window_process_updates (window, cast(int)true); + printWidget (gc, data.drawable, OS.gdk_drawable_get_depth (data.drawable), 0, 0); + return true; +} + +void printWidget (GC gc, GdkDrawable* drawable, int depth, int x, int y) { + bool obscured = (state & OBSCURED) !is 0; + state &= ~OBSCURED; + auto topHandle_ = topHandle (); + auto window = OS.GTK_WIDGET_WINDOW (topHandle_); + printWindow (true, this, gc.handle, drawable, depth, window, x, y); + if (obscured) state |= OBSCURED; +} + +void printWindow (bool first, Control control, GdkGC* gc, GdkDrawable* drawable, int depth, GdkDrawable* window, int x, int y) { + if (OS.gdk_drawable_get_depth (window) !is depth) return; + GdkRectangle rect; + int width, height; + OS.gdk_drawable_get_size (window, &width, &height); + rect.width = width; + rect.height = height; + OS.gdk_window_begin_paint_rect (window, &rect); + GdkDrawable* real_drawable; + int x_offset, y_offset; + OS.gdk_window_get_internal_paint_info (window, &real_drawable, &x_offset, &y_offset); + void* userData; + OS.gdk_window_get_user_data (window, &userData); + if (userData !is null) { + GdkEventExpose* event = cast(GdkEventExpose*) OS.gdk_event_new (OS.GDK_EXPOSE); + event.type = OS.GDK_EXPOSE; + event.window = cast(GdkDrawable*)OS.g_object_ref (window); + event.area.width = rect.width; + event.area.height = rect.height; + event.region = OS.gdk_region_rectangle (&rect); + OS.gtk_widget_send_expose (userData, cast(GdkEvent*)event); + OS.gdk_event_free (cast(GdkEvent*)event); + } + int srcX = x_offset, srcY = y_offset; + int destX = x, destY = y, destWidth = width, destHeight = height; + if (!first) { + int cX, cY; + OS.gdk_window_get_position (window, &cX, &cY); + auto parentWindow = OS.gdk_window_get_parent (window); + int pW, pH; + OS.gdk_drawable_get_size (parentWindow, &pW, &pH); + srcX = x_offset - cX; + srcY = y_offset - cY; + destX = x - cX; + destY = y - cY; + destWidth = Math.min (cX + width, pW); + destHeight = Math.min (cY + height, pH); + } + OS.gdk_draw_drawable (drawable, gc, real_drawable, srcX, srcY, destX, destY, destWidth, destHeight); + OS.gdk_window_end_paint (window); + auto children = OS.gdk_window_get_children (window); + if (children !is null) { + auto windows = children; + while (windows !is null) { + auto child = cast(GdkDrawable*) OS.g_list_data (windows); + if (OS.gdk_window_is_visible (child)) { + void* data; + OS.gdk_window_get_user_data (child, &data); + if (data !is null) { + Widget widget = display.findWidget ( cast(GtkWidget*) data); + if (widget is null || widget is control) { + int x_pos, y_pos; + OS.gdk_window_get_position (child, &x_pos, &y_pos); + printWindow (false, control, gc, drawable, depth, child, x + x_pos, y + y_pos); + } + } + } + windows = OS.g_list_next (windows); + } + OS.g_list_free (children); + } +} + /** * Returns the preferred size of the receiver. * <p> @@ -423,6 +510,10 @@ if (getBorderWidth () is 0) style &= ~DWT.BORDER; } +void checkMirrored () { + if ((style & DWT.RIGHT_TO_LEFT) !is 0) style |= DWT.MIRRORED; +} + GtkStyle* childStyle () { return parent.childStyle (); } @@ -438,6 +529,7 @@ setInitialBounds (); setZOrder (null, false, false); setRelations (); + checkMirrored (); checkBorder (); } @@ -508,15 +600,15 @@ * topHandle. Note that all calls to gtk_widget_size_allocate() * must be preceded by a call to gtk_widget_size_request(). */ - auto topHandle = topHandle (); + auto topHandle_ = topHandle (); GtkRequisition requisition; - gtk_widget_size_request (topHandle, &requisition); + gtk_widget_size_request (topHandle_, &requisition); GtkAllocation allocation; - allocation.x = OS.GTK_WIDGET_X (topHandle); - allocation.y = OS.GTK_WIDGET_Y (topHandle); - allocation.width = OS.GTK_WIDGET_WIDTH (topHandle); - allocation.height = OS.GTK_WIDGET_HEIGHT (topHandle); - OS.gtk_widget_size_allocate (topHandle, &allocation); + allocation.x = OS.GTK_WIDGET_X (topHandle_); + allocation.y = OS.GTK_WIDGET_Y (topHandle_); + allocation.width = OS.GTK_WIDGET_WIDTH (topHandle_); + allocation.height = OS.GTK_WIDGET_HEIGHT (topHandle_); + OS.gtk_widget_size_allocate (topHandle_, &allocation); } /** @@ -559,11 +651,12 @@ */ public Rectangle getBounds () { checkWidget(); - auto topHandle = topHandle (); - int x = OS.GTK_WIDGET_X (topHandle); - int y = OS.GTK_WIDGET_Y (topHandle); - int width = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); - int height = (state & ZERO_HEIGHT) !is 0 ? 0 : OS.GTK_WIDGET_HEIGHT (topHandle); + auto topHandle_ = topHandle (); + int x = OS.GTK_WIDGET_X (topHandle_); + int y = OS.GTK_WIDGET_Y (topHandle_); + int width = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle_); + int height = (state & ZERO_HEIGHT) !is 0 ? 0 : OS.GTK_WIDGET_HEIGHT (topHandle_); + if ((parent.style & DWT.MIRRORED) !is 0) x = parent.getClientWidth () - width - x; return new Rectangle (x, y, width, height); } @@ -623,8 +716,18 @@ /* Do nothing */ } +override void modifyStyle (GtkWidget* handle, GtkRcStyle* style) { + super.modifyStyle(handle, style); + /* + * Bug in GTK. When changing the style of a control that + * has had a region set on it, the region is lost. The + * fix is to set the region again. + */ + if (region !is null) OS.gdk_window_shape_combine_region (OS.GTK_WIDGET_WINDOW (topHandle ()), region.handle, 0, 0); +} + void moveHandle (int x, int y) { - auto topHandle = topHandle (); + auto topHandle_ = topHandle (); auto parentHandle = parent.parentingHandle (); /* * Feature in GTK. Calling gtk_fixed_move() to move a child causes @@ -636,24 +739,38 @@ */ int flags = OS.GTK_WIDGET_FLAGS (parentHandle); OS.GTK_WIDGET_UNSET_FLAGS (parentHandle, OS.GTK_VISIBLE); - OS.gtk_fixed_move (cast(GtkFixed*)parentHandle, topHandle, x, y); + OS.gtk_fixed_move (cast(GtkFixed*)parentHandle, topHandle_, x, y); if ((flags & OS.GTK_VISIBLE) !is 0) { OS.GTK_WIDGET_SET_FLAGS (parentHandle, OS.GTK_VISIBLE); } } void resizeHandle (int width, int height) { - auto topHandle = topHandle (); - OS.gtk_widget_set_size_request (topHandle, width, height); - if (topHandle !is handle) OS.gtk_widget_set_size_request (handle, width, height); + auto topHandle_ = topHandle (); + OS.gtk_widget_set_size_request (topHandle_, width, height); + if (topHandle_ !is handle) OS.gtk_widget_set_size_request (handle, width, height); } int setBounds (int x, int y, int width, int height, bool move, bool resize) { - auto topHandle = topHandle (); + auto topHandle_ = topHandle (); + bool sendMove = move; + if ((parent.style & DWT.MIRRORED) !is 0) { + int clientWidth = parent.getClientWidth (); + int oldWidth = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle_); + int oldX = clientWidth - oldWidth - OS.GTK_WIDGET_X (topHandle_); + if (move) { + sendMove &= x !is oldX; + x = clientWidth - (resize ? width : oldWidth) - x; + } else { + move = true; + x = clientWidth - (resize ? width : oldWidth) - oldX; + y = OS.GTK_WIDGET_Y (topHandle_); + } + } bool sameOrigin = true, sameExtent = true; if (move) { - int oldX = OS.GTK_WIDGET_X (topHandle); - int oldY = OS.GTK_WIDGET_Y (topHandle); + int oldX = OS.GTK_WIDGET_X (topHandle_); + int oldY = OS.GTK_WIDGET_Y (topHandle_); sameOrigin = x is oldX && y is oldY; if (!sameOrigin) { if (enableWindow !is null) { @@ -662,10 +779,12 @@ moveHandle (x, y); } } + int clientWidth = 0; if (resize) { - int oldWidth = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); - int oldHeight = (state & ZERO_HEIGHT) !is 0 ? 0 : OS.GTK_WIDGET_HEIGHT (topHandle); + int oldWidth = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle_); + int oldHeight = (state & ZERO_HEIGHT) !is 0 ? 0 : OS.GTK_WIDGET_HEIGHT (topHandle_); sameExtent = width is oldWidth && height is oldHeight; + if (!sameExtent && (style & DWT.MIRRORED) !is 0) clientWidth = getClientWidth (); if (!sameExtent && !(width is 0 && height is 0)) { int newWidth = Math.max (1, width); int newHeight = Math.max (1, height); @@ -685,23 +804,23 @@ * a call to gtk_widget_size_request(). */ GtkRequisition requisition; - gtk_widget_size_request (topHandle, &requisition); + gtk_widget_size_request (topHandle_, &requisition); GtkAllocation allocation; if (move) { allocation.x = x; allocation.y = y; } else { - allocation.x = OS.GTK_WIDGET_X (topHandle); - allocation.y = OS.GTK_WIDGET_Y (topHandle); + allocation.x = OS.GTK_WIDGET_X (topHandle_); + allocation.y = OS.GTK_WIDGET_Y (topHandle_); } if (resize) { allocation.width = width; allocation.height = height; } else { - allocation.width = OS.GTK_WIDGET_WIDTH (topHandle); - allocation.height = OS.GTK_WIDGET_HEIGHT (topHandle); + allocation.width = OS.GTK_WIDGET_WIDTH (topHandle_); + allocation.height = OS.GTK_WIDGET_HEIGHT (topHandle_); } - OS.gtk_widget_size_allocate (topHandle, &allocation); + OS.gtk_widget_size_allocate (topHandle_, &allocation); } /* * Bug in GTK. Widgets cannot be sized smaller than 1x1. @@ -715,15 +834,16 @@ if (enableWindow !is null) { OS.gdk_window_hide (enableWindow); } - OS.gtk_widget_hide (topHandle); + OS.gtk_widget_hide (topHandle_); } else { if ((state & HIDDEN) is 0) { if (enableWindow !is null) { OS.gdk_window_show_unraised (enableWindow); } - OS.gtk_widget_show (topHandle); + OS.gtk_widget_show (topHandle_); } } + if ((style & DWT.MIRRORED) !is 0) moveChildren (clientWidth); } int result = 0; if (move && !sameOrigin) { @@ -731,7 +851,7 @@ if (control !is null && control.backgroundImage !is null) { if (isVisible ()) redrawWidget (0, 0, 0, 0, true, true, true); } - sendEvent (DWT.Move); + if (sendMove) sendEvent (DWT.Move); result |= MOVED; } if (resize && !sameExtent) { @@ -756,9 +876,13 @@ */ public Point getLocation () { checkWidget(); - auto topHandle = topHandle (); - int x = OS.GTK_WIDGET_X (topHandle); - int y = OS.GTK_WIDGET_Y (topHandle); + auto topHandle_ = topHandle (); + int x = OS.GTK_WIDGET_X (topHandle_); + int y = OS.GTK_WIDGET_Y (topHandle_); + if ((parent.style & DWT.MIRRORED) !is 0) { + int width = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle_); + x = parent.getClientWidth () - width - x; + } return new Point (x, y); } @@ -817,9 +941,9 @@ */ public Point getSize () { checkWidget(); - auto topHandle = topHandle (); - int width = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); - int height = (state & ZERO_HEIGHT) !is 0 ? 0 : OS.GTK_WIDGET_HEIGHT (topHandle); + auto topHandle_ = topHandle (); + int width = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle_); + int height = (state & ZERO_HEIGHT) !is 0 ? 0 : OS.GTK_WIDGET_HEIGHT (topHandle_); return new Point (width, height); } @@ -847,6 +971,16 @@ setBounds (0, 0, Math.max (0, size.x), Math.max (0, size.y), false, true); } +public void setRegion (Region region) { + checkWidget (); + if ((style & DWT.NO_TRIM) is 0) return; + if (region !is null && region.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT); + auto window = OS.GTK_WIDGET_WINDOW (topHandle ()); + auto shape_region = (region is null) ? null : region.handle; + OS.gdk_window_shape_combine_region (window, shape_region, 0, 0); + this.region = region; +} + void setRelations () { auto parentHandle = parent.parentingHandle (); auto list = OS.gtk_container_get_children (cast(GtkContainer*)parentHandle); @@ -899,6 +1033,10 @@ return true; } +bool isFocusHandle (GtkWidget* widget) { + return widget is focusHandle (); +} + /** * Moves the receiver above the specified control in the * drawing order. If the argument is null, then the receiver @@ -957,6 +1095,9 @@ setZOrder (control, false, true); } +void moveChildren (int oldWidth) { +} + /** * Causes the receiver to be resized to its preferred size. * For a composite, this involves computing the preferred size @@ -1034,7 +1175,10 @@ auto window = eventWindow (); int origin_x, origin_y; OS.gdk_window_get_origin (window, &origin_x, &origin_y); - return new Point (x - origin_x , y - origin_y ); + x -= origin_x ; + y -= origin_y ; + if ((style & DWT.MIRRORED) !is 0) x = getClientWidth () - x; + return new Point (x, y); } /** @@ -1080,7 +1224,10 @@ auto window = eventWindow (); int origin_x, origin_y; OS.gdk_window_get_origin (window, &origin_x, &origin_y); - return new Point (origin_x + x, origin_y + y); + if ((style & DWT.MIRRORED) !is 0) x = getClientWidth () - x; + x += origin_x ; + y += origin_y ; + return new Point (x, y); } /** @@ -1939,6 +2086,9 @@ return 0; } +void fixModal(GtkWidget* group, GtkWidget* modalGroup) { +} + /** * Forces the receiver to have the <em>keyboard focus</em>, causing * all keyboard events to be delivered to it. @@ -2051,6 +2201,10 @@ return 0; } +int getClientWidth () { + return 0; +} + /** * Returns the receiver's cursor, or null if it has not been set. * <p> @@ -2120,8 +2274,7 @@ */ public Font getFont () { checkWidget(); - if (font !is null) return font; - return Font.gtk_new (display, defaultFont ()); + return font !is null ? font : defaultFont (); } PangoFontDescription* getFontDescription () { @@ -2278,6 +2431,11 @@ return result; } +public Region getRegion () { + checkWidget (); + return region; +} + /** * Returns the receiver's shell. For all controls other than * shells, this simply returns the control's nearest ancestor @@ -2341,6 +2499,7 @@ override int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* gdkEvent) { if (gdkEvent.type is OS.GDK_3BUTTON_PRESS) return 0; + /* * When a shell is created with DWT.ON_TOP and DWT.NO_FOCUS, * do not activate the shell when the user clicks on the @@ -2427,6 +2586,21 @@ } override int /*long*/ gtk_enter_notify_event (GtkWidget* widget, GdkEventCrossing* gdkEvent) { + if (OS.GTK_VERSION >= OS.buildVERSION (2, 12, 0)) { + /* + * Feature in GTK. Children of a shell will inherit and display the shell's + * tooltip if they do not have a tooltip of their own. The fix is to use the + * new tooltip API in GTK 2.12 to null the shell's tooltip when the control + * being entered does not have any tooltip text set. + */ + char* buffer = null; + if (toolTipText !is null && toolTipText.length !is 0) { + char [] chars = fixMnemonic (toolTipText, false); + buffer = tango.stdc.stringz.toStringz(chars); + } + auto toolHandle = getShell().handle; + OS.gtk_widget_set_tooltip_text (toolHandle, buffer); + } if (display.currentControl is this) return 0; if (gdkEvent.mode !is OS.GDK_CROSSING_NORMAL && gdkEvent.mode !is OS.GDK_CROSSING_UNGRAB) return 0; if ((gdkEvent.state & (OS.GDK_BUTTON1_MASK | OS.GDK_BUTTON2_MASK | OS.GDK_BUTTON3_MASK)) !is 0) return 0; @@ -2459,7 +2633,7 @@ break; } case OS.GDK_FOCUS_CHANGE: { - if (widget !is focusHandle ()) break; + if (!isFocusHandle (widget)) break; GdkEventFocus* gdkEventFocus = cast(GdkEventFocus*)gdkEvent; /* @@ -2503,6 +2677,7 @@ event.y = gdkEvent.area.y; event.width = gdkEvent.area.width; event.height = gdkEvent.area.height; + if ((style & DWT.MIRRORED) !is 0) event.x = getClientWidth () - event.width - event.x; GCData data = new GCData (); data.damageRgn = gdkEvent.region; GC gc = event.gc = GC.gtk_new (this, data); @@ -2733,6 +2908,10 @@ int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; if ((data.style & mask) is 0) { data.style |= style & (mask | DWT.MIRRORED); + } else { + if ((data.style & DWT.RIGHT_TO_LEFT) !is 0) { + data.style |= DWT.MIRRORED; + } } data.drawable = cast(GdkDrawable*)window; data.device = display; @@ -2740,7 +2919,7 @@ Control control = findBackgroundControl (); if (control is null) control = this; data.background = control.getBackgroundColor (); - data.font = font !is null ? font.handle : defaultFont (); + data.font = font !is null ? font : defaultFont (); } return gdkGC; } @@ -2969,6 +3148,7 @@ public void redraw (int x, int y, int width, int height, bool all) { checkWidget(); if (!OS.GTK_WIDGET_VISIBLE (topHandle ())) return; + if ((style & DWT.MIRRORED) !is 0) x = getClientWidth () - width - x; redrawWidget (x, y, width, height, false, all, false); } @@ -3046,6 +3226,7 @@ toolTipText = null; layoutData = null; accessible = null; + region = null; } bool sendDragEvent (int button, int stateMask, int x, int y, bool isStateMask) { @@ -3053,6 +3234,7 @@ event.button = button; event.x = x; event.y = y; + if ((style & DWT.MIRRORED) !is 0) event.x = getClientWidth () - event.x; if (isStateMask) { event.stateMask = stateMask; } else { @@ -3129,6 +3311,7 @@ event.x = cast(int)x - origin_x; event.y = cast(int)y - origin_y; } + if ((style & DWT.MIRRORED) !is 0) event.x = getClientWidth () - event.x; setInputState (event, state); if (send) { sendEvent (type, event); @@ -3207,7 +3390,7 @@ int flags = OS.gtk_rc_style_get_color_flags (style, index); flags = (color is null) ? flags & ~OS.GTK_RC_BG : flags | OS.GTK_RC_BG; OS.gtk_rc_style_set_color_flags (style, index, flags); - OS.gtk_widget_modify_style (handle, style); + modifyStyle (handle, style); } void setBackgroundColor (GdkColor* color) { @@ -3379,8 +3562,8 @@ } } else { OS.gtk_widget_realize (handle); - auto parentHandle = parent.parentingHandle (); - auto window = OS.GTK_WIDGET_WINDOW (parentHandle); + auto parentHandle = parent.eventHandle (); + auto window = parent.eventWindow(); Rectangle rect = getBounds (); GdkWindowAttr attributes; attributes.x = rect.x; @@ -3392,12 +3575,12 @@ attributes.window_type = OS.GDK_WINDOW_CHILD; enableWindow = OS.gdk_window_new (window, &attributes, OS.GDK_WA_X | OS.GDK_WA_Y); if (enableWindow !is null) { - auto topHandle = topHandle (); + auto topHandle_ = topHandle (); OS.gdk_window_set_user_data (enableWindow, parentHandle); if (!OS.GDK_WINDOWING_X11 ()) { OS.gdk_window_raise (enableWindow); } else { - auto topWindow = OS.GTK_WIDGET_WINDOW (topHandle); + auto topWindow = OS.GTK_WIDGET_WINDOW (topHandle_); auto xDisplay = OS.gdk_x11_drawable_get_xdisplay (cast(GdkDrawable*)topWindow); auto xWindow = OS.gdk_x11_drawable_get_xid (cast(GdkDrawable*)enableWindow); int xScreen = OS.XDefaultScreen (xDisplay); @@ -3407,7 +3590,7 @@ changes.stack_mode = OS.Above; OS.XReconfigureWMWindow (xDisplay, xWindow, xScreen, flags, &changes); } - if (OS.GTK_WIDGET_VISIBLE (topHandle)) OS.gdk_window_show_unraised (enableWindow); + if (OS.GTK_WIDGET_VISIBLE (topHandle_)) OS.gdk_window_show_unraised (enableWindow); } } if (fixFocus_) fixFocus (control); @@ -3454,7 +3637,7 @@ this.font = font; PangoFontDescription* fontDesc; if (font is null) { - fontDesc = defaultFont (); + fontDesc = defaultFont ().handle; } else { if (font.isDisposed ()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); fontDesc = font.handle; @@ -3526,9 +3709,13 @@ * first sized. The fix is to set the value to (0, 0) as * expected by DWT. */ - auto topHandle = topHandle (); - OS.GTK_WIDGET_SET_X (topHandle, 0); - OS.GTK_WIDGET_SET_Y (topHandle, 0); + auto topHandle_ = topHandle (); + if ((parent.style & DWT.MIRRORED) !is 0) { + OS.GTK_WIDGET_SET_X (topHandle_, parent.getClientWidth ()); + } else { + OS.GTK_WIDGET_SET_X (topHandle_, 0); + } + OS.GTK_WIDGET_SET_Y (topHandle_, 0); } else { resizeHandle (1, 1); forceResize (); @@ -3603,6 +3790,16 @@ if (parent.isDisposed()) DWT.error (DWT.ERROR_INVALID_ARGUMENT); if (this.parent is parent) return true; if (!isReparentable ()) return false; + auto topHandle_ = topHandle (); + int x = OS.GTK_WIDGET_X (topHandle_); + int width = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle_); + if ((this.parent.style & DWT.MIRRORED) !is 0) { + x = this.parent.getClientWidth () - width - x; + } + if ((parent.style & DWT.MIRRORED) !is 0) { + x = parent.getClientWidth () - width - x; + } + int y = OS.GTK_WIDGET_Y (topHandle_); releaseParent (); Shell newShell = parent.getShell (), oldShell = getShell (); Decorations newDecorations = parent.menuShell (), oldDecorations = menuShell (); @@ -3612,12 +3809,9 @@ newDecorations.fixAccelGroup (); oldDecorations.fixAccelGroup (); } - auto topHandle = topHandle (); auto newParent = parent.parentingHandle(); - int x = OS.GTK_WIDGET_X (topHandle); - int y = OS.GTK_WIDGET_Y (topHandle); - OS.gtk_widget_reparent (topHandle, newParent); - OS.gtk_fixed_move (cast(GtkFixed*)newParent, topHandle, x, y); + OS.gtk_widget_reparent (topHandle_, newParent); + OS.gtk_fixed_move (cast(GtkFixed*)newParent, topHandle_, x, y); this.parent = parent; setZOrder (null, false, true); return true; @@ -3723,7 +3917,25 @@ } void setToolTipText (Shell shell, String newString) { - shell.setToolTipText (eventHandle (), newString); + if (OS.GTK_VERSION >= OS.buildVERSION (2, 12, 0)) { + /* + * Feature in GTK. In order to prevent children widgets + * from inheriting their parent's tooltip, the tooltip is + * a set on a shell only. In order to force the shell tooltip + * to update when a new tip string is set, the existing string + * in the tooltip is set to null, followed by running a query. + * The real tip text can then be set. + * + * Note that this will only run if the control for which the + * tooltip is being set is the current control (i.e. the control + * under the pointer). + */ + if (display.currentControl is this) { + shell.setToolTipText (shell.handle, eventHandle (), newString); + } + } else { + shell.setToolTipText (eventHandle (), newString); + } } /** @@ -3745,7 +3957,7 @@ public void setVisible (bool visible) { checkWidget(); if (((state & HIDDEN) is 0) is visible) return; - auto topHandle = topHandle(); + auto topHandle_ = topHandle(); if (visible) { /* * It is possible (but unlikely), that application @@ -3757,7 +3969,7 @@ state &= ~HIDDEN; if ((state & (ZERO_WIDTH | ZERO_HEIGHT)) is 0) { if (enableWindow !is null) OS.gdk_window_show_unraised (enableWindow); - OS.gtk_widget_show (topHandle); + OS.gtk_widget_show (topHandle_); } } else { /* @@ -3777,12 +3989,12 @@ } state |= HIDDEN; if (fixFocus_) { - OS.GTK_WIDGET_UNSET_FLAGS (topHandle, OS.GTK_VISIBLE); + OS.GTK_WIDGET_UNSET_FLAGS (topHandle_, OS.GTK_VISIBLE); fixFocus (control); if (isDisposed ()) return; - OS.GTK_WIDGET_SET_FLAGS (topHandle, OS.GTK_VISIBLE); + OS.GTK_WIDGET_SET_FLAGS (topHandle_, OS.GTK_VISIBLE); } - OS.gtk_widget_hide (topHandle); + OS.gtk_widget_hide (topHandle_); if (isDisposed ()) return; if (enableWindow !is null) OS.gdk_window_hide (enableWindow); sendEvent (DWT.Hide); @@ -3826,9 +4038,9 @@ } } - auto topHandle = topHandle (); + auto topHandle_ = topHandle (); auto siblingHandle = sibling !is null ? sibling.topHandle () : null; - auto window = OS.GTK_WIDGET_WINDOW (topHandle); + auto window = OS.GTK_WIDGET_WINDOW (topHandle_); if (window !is null) { GdkWindow* siblingWindow; if (sibling !is null) { @@ -3877,9 +4089,9 @@ } if (fixChildren) { if (above) { - parent.moveAbove (topHandle, siblingHandle); + parent.moveAbove (topHandle_, siblingHandle); } else { - parent.moveBelow (topHandle, siblingHandle); + parent.moveBelow (topHandle_, siblingHandle); } } /* Make sure that the parent internal windows are on the bottom of the stack */ @@ -3922,10 +4134,10 @@ void setWidgetBackground () { if (fixedHandle !is null) { auto style = OS.gtk_widget_get_modifier_style (fixedHandle); - OS.gtk_widget_modify_style (fixedHandle, style); + modifyStyle (fixedHandle, style); } auto style = OS.gtk_widget_get_modifier_style (handle); - OS.gtk_widget_modify_style (handle, style); + modifyStyle (handle, style); } bool showMenu (int x, int y) { @@ -3950,11 +4162,11 @@ void showWidget () { // Comment this line to disable zero-sized widgets state |= ZERO_WIDTH | ZERO_HEIGHT; - auto topHandle = topHandle (); + auto topHandle_ = topHandle (); auto parentHandle = parent.parentingHandle (); - parent.setParentWindow (topHandle); - OS.gtk_container_add (cast(GtkContainer*)parentHandle, topHandle); - if (handle !is null && handle !is topHandle) OS.gtk_widget_show (handle); + parent.setParentWindow (topHandle_); + OS.gtk_container_add (cast(GtkContainer*)parentHandle, topHandle_); + if (handle !is null && handle !is topHandle_) OS.gtk_widget_show (handle); if ((state & (ZERO_WIDTH | ZERO_HEIGHT)) is 0) { if (fixedHandle !is null) OS.gtk_widget_show (fixedHandle); } @@ -4057,6 +4269,9 @@ case OS.GDK_Down: case OS.GDK_Right: { bool next = key is OS.GDK_Down || key is OS.GDK_Right; + if (parent !is null && (parent.style & DWT.MIRRORED) !is 0) { + if (key is OS.GDK_Left || key is OS.GDK_Right) next = !next; + } detail = next ? DWT.TRAVERSE_ARROW_NEXT : DWT.TRAVERSE_ARROW_PREVIOUS; break; }