diff options
author | Bogdan Gheorghe <gheorghe> | 2007-08-17 21:48:24 +0000 |
---|---|---|
committer | Bogdan Gheorghe <gheorghe> | 2007-08-17 21:48:24 +0000 |
commit | 28aa455ae3ab9d2b8c756bcae7568a88b06cc8eb (patch) | |
tree | 8d93b2622f436723ce446f1579e79ea359453060 | |
parent | 5d5d6c8770a1d46c82c940b44d6a2e4884862a10 (diff) | |
download | eclipse.platform.swt-28aa455ae3ab9d2b8c756bcae7568a88b06cc8eb.tar.gz eclipse.platform.swt-28aa455ae3ab9d2b8c756bcae7568a88b06cc8eb.tar.xz eclipse.platform.swt-28aa455ae3ab9d2b8c756bcae7568a88b06cc8eb.zip |
200083 Support BIDI on Linux GTK
18 files changed, 290 insertions, 25 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cairo/org/eclipse/swt/graphics/Pattern.java b/bundles/org.eclipse.swt/Eclipse SWT/cairo/org/eclipse/swt/graphics/Pattern.java index 61052e5527..983bd9926e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cairo/org/eclipse/swt/graphics/Pattern.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cairo/org/eclipse/swt/graphics/Pattern.java @@ -41,6 +41,8 @@ public class Pattern extends Resource { * </p> */ public int /*long*/ handle; + + int /*long*/ surface; /** * Constructs a new Pattern given an image. Drawing with the resulting @@ -78,7 +80,8 @@ public Pattern(Device device, Image image) { handle = Cairo.cairo_pattern_create_for_surface(image.surface); if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); Cairo.cairo_pattern_set_extend(handle, Cairo.CAIRO_EXTEND_REPEAT); - if (device.tracking) device.new_Object(this); + surface = image.surface; + if (device.tracking) device.new_Object(this); } /** @@ -178,7 +181,7 @@ public void dispose() { if (handle == 0) return; if (device.isDisposed()) return; Cairo.cairo_pattern_destroy(handle); - handle = 0; + handle = surface = 0; if (device.tracking) device.dispose_Object(this); device = null; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/coolbar/org/eclipse/swt/widgets/CoolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/coolbar/org/eclipse/swt/widgets/CoolItem.java index a76e8f53d2..47eab064a9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/coolbar/org/eclipse/swt/widgets/CoolItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/emulated/coolbar/org/eclipse/swt/widgets/CoolItem.java @@ -253,7 +253,7 @@ Image createArrowImage (int width, int height) { imageData.transparentPixel = 1; Image image = new Image (display, imageData); - GC gc = new GC (image); + GC gc = new GC (image, parent.getStyle() & SWT.RIGHT_TO_LEFT); gc.setBackground (background); gc.fillRectangle (0, 0, width, height); gc.setForeground (black); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java index 0dcd0c5b22..6033019930 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java @@ -205,7 +205,17 @@ void checkGC (int mask) { data.state &= ~FOREGROUND; } if (pattern != null) { - Cairo.cairo_set_source(cairo, pattern.handle); + if ((data.style & SWT.MIRRORED) != 0 && pattern.surface != 0) { + int newPattern = Cairo.cairo_pattern_create_for_surface(pattern.surface); + if (newPattern == 0) SWT.error(SWT.ERROR_NO_HANDLES); + Cairo.cairo_pattern_set_extend(newPattern, Cairo.CAIRO_EXTEND_REPEAT); + double[] matrix = {-1, 0, 0, 1, 0, 0}; + Cairo.cairo_pattern_set_matrix(newPattern, matrix); + Cairo.cairo_set_source(cairo, newPattern); + Cairo.cairo_pattern_destroy(newPattern); + } else { + Cairo.cairo_set_source(cairo, pattern.handle); + } } else { Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF); } @@ -505,7 +515,7 @@ void createLayout() { if (layout == 0) SWT.error(SWT.ERROR_NO_HANDLES); data.layout = layout; OS.pango_context_set_language(context, OS.gtk_get_default_language()); - OS.pango_context_set_base_dir(context, OS.PANGO_DIRECTION_LTR); + OS.pango_context_set_base_dir(context, (data.style & SWT.MIRRORED) != 0 ? OS.PANGO_DIRECTION_RTL : OS.PANGO_DIRECTION_LTR); OS.gdk_pango_context_set_colormap(context, OS.gdk_colormap_get_system()); if (OS.GTK_VERSION >= OS.VERSION(2, 4, 0)) { OS.pango_layout_set_auto_dir(layout, false); @@ -766,6 +776,10 @@ void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, if (data.alpha != 0) { srcImage.createSurface(); Cairo.cairo_save(cairo); + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_scale(cairo, -1f, 1); + Cairo.cairo_translate(cairo, - 2 * destX - destWidth, 0); + } Cairo.cairo_rectangle(cairo, destX , destY, destWidth, destHeight); Cairo.cairo_clip(cairo); Cairo.cairo_translate(cairo, destX - srcX, destY - srcY); @@ -1609,8 +1623,18 @@ public void drawText (String string, int x, int y, int flags) { Cairo.cairo_fill(cairo); } checkGC(FOREGROUND | FONT); + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_save(cairo); + int[] width = new int[1], height = new int[1]; + OS.pango_layout_get_size(data.layout, width, height); + Cairo.cairo_scale(cairo, -1f, 1); + Cairo.cairo_translate(cairo, -2 * x - OS.PANGO_PIXELS(width[0]), 0); + } Cairo.cairo_move_to(cairo, x, y); OS.pango_cairo_show_layout(cairo, data.layout); + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_restore(cairo); + } return; } checkGC(FOREGROUND | FONT | BACKGROUND_BG); @@ -2674,6 +2698,9 @@ public void getTransform(Transform transform) { int /*long*/ cairo = data.cairo; if (cairo != 0) { Cairo.cairo_get_matrix(cairo, transform.handle); + double[] identity = identity(); + Cairo.cairo_matrix_invert(identity); + Cairo.cairo_matrix_multiply(transform.handle, transform.handle, identity); } else { transform.setElements(1, 0, 0, 1, 0, 0); } @@ -2716,6 +2743,18 @@ public int hashCode() { return (int)/*64*/handle; } +double[] identity() { + double[] identity = new double[6]; + if ((data.style & SWT.MIRRORED) != 0) { + int[] w = new int[1], h = new int[1]; + OS.gdk_drawable_get_size(data.drawable, w, h); + Cairo.cairo_matrix_init(identity, -1, 0, 0, 1, w[0], 0); + } else { + Cairo.cairo_matrix_init_identity(identity); + } + return identity; +} + void init(Drawable drawable, GCData data, int /*long*/ gdkGC) { if (data.foreground != null) data.state &= ~FOREGROUND; if (data.background != null) data.state &= ~(BACKGROUND | BACKGROUND_BG); @@ -2734,6 +2773,11 @@ void init(Drawable drawable, GCData data, int /*long*/ gdkGC) { this.drawable = drawable; this.data = data; handle = gdkGC; + if ((data.style & SWT.MIRRORED) != 0) { + initCairo(); + int /*long*/ cairo = data.cairo; + Cairo.cairo_set_matrix(cairo, identity()); + } } void initCairo() { @@ -2852,6 +2896,19 @@ boolean isIdentity(double[] matrix) { */ public void setAdvanced(boolean advanced) { if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + if ((data.style & SWT.MIRRORED) != 0) { + if (!advanced) { + setAlpha(0xFF); + setAntialias(SWT.DEFAULT); + setBackgroundPattern(null); + setClipping(0); + setForegroundPattern(null); + setInterpolation(SWT.DEFAULT); + setTextAntialias(SWT.DEFAULT); + setTransform(null); + } + return; + } if (advanced && data.cairo != 0) return; if (advanced) { try { @@ -3766,11 +3823,11 @@ public void setTransform(Transform transform) { if (data.cairo == 0 && transform == null) return; initCairo(); int /*long*/ cairo = data.cairo; + double[] identity = identity(); if (transform != null) { - Cairo.cairo_set_matrix(cairo, transform.handle); - } else { - Cairo.cairo_identity_matrix(cairo); - } + Cairo.cairo_matrix_multiply(identity, transform.handle, identity); + } + Cairo.cairo_set_matrix(cairo, identity); data.state &= ~DRAW_OFFSET; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index 423de196c8..47f2151bb1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -1079,6 +1079,10 @@ public int /*long*/ internal_new_GC (GCData data) { int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; if ((data.style & mask) == 0) { data.style |= SWT.LEFT_TO_RIGHT; + } else { + if ((data.style & SWT.RIGHT_TO_LEFT) != 0) { + data.style |= SWT.MIRRORED; + } } data.device = device; data.drawable = pixmap; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java index a4c1b9f1a4..be4a451a5b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java @@ -448,8 +448,18 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo if (length == 0) return; if (!hasSelection) { if (cairo != 0 && OS.GTK_VERSION >= OS.VERSION(2, 8, 0)) { + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_save(cairo); + int[] width = new int[1], height = new int[1]; + OS.pango_layout_get_size(layout, width, height); + Cairo.cairo_scale(cairo, -1f, 1); + Cairo.cairo_translate(cairo, -2 * x - OS.PANGO_PIXELS(width[0]), 0); + } Cairo.cairo_move_to(cairo, x, y); OS.pango_cairo_show_layout(cairo, layout); + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_restore(cairo); + } } else { OS.gdk_draw_layout(data.drawable, gc.handle, x, y, layout); } @@ -465,7 +475,17 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo if (fullSelection) { if (cairo != 0 && OS.GTK_VERSION >= OS.VERSION(2, 8, 0)) { int /*long*/ ptr = OS.pango_layout_get_text(layout); + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_save(cairo); + int[] width = new int[1], height = new int[1]; + OS.pango_layout_get_size(layout, width, height); + Cairo.cairo_scale(cairo, -1f, 1); + Cairo.cairo_translate(cairo, -2 * x - OS.PANGO_PIXELS(width[0]), 0); + } drawWithCairo(cairo, x, y, 0, OS.strlen(ptr), fullSelection, selectionBackground.handle, selectionForeground.handle); + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_restore(cairo); + } } else { OS.gdk_draw_layout_with_colors(data.drawable, gc.handle, x, y, layout, selectionForeground.handle, selectionBackground.handle); } @@ -477,7 +497,17 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo byteSelStart = Math.min(byteSelStart, strlen); byteSelEnd = Math.min(byteSelEnd, strlen); if (cairo != 0 && OS.GTK_VERSION >= OS.VERSION(2, 8, 0)) { + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_save(cairo); + int[] width = new int[1], height = new int[1]; + OS.pango_layout_get_size(layout, width, height); + Cairo.cairo_scale(cairo, -1f, 1); + Cairo.cairo_translate(cairo, -2 * x - OS.PANGO_PIXELS(width[0]), 0); + } drawWithCairo(cairo, x, y, byteSelStart, byteSelEnd, fullSelection, selectionBackground.handle, selectionForeground.handle); + if ((data.style & SWT.MIRRORED) != 0) { + Cairo.cairo_restore(cairo); + } } else { Region clipping = new Region(); gc.getClipping(clipping); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java index 999fb82a97..24a5809536 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java @@ -187,6 +187,11 @@ void releaseChildren (boolean destroy) { public void scroll (int destX, int destY, int x, int y, int width, int height, boolean all) { checkWidget(); if (width <= 0 || height <= 0) return; + if ((style & SWT.MIRRORED) != 0) { + int clientWidth = getClientWidth (); + x = clientWidth - width - x; + destX = clientWidth - width - destX; + } int deltaX = destX - x, deltaY = destY - y; if (deltaX == 0 && deltaY == 0) return; if (!isVisible ()) return; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java index 3cdddb5bfd..90c4402e63 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Caret.java @@ -103,11 +103,15 @@ boolean drawCaret () { if (image != null && !image.isDisposed() && image.mask == 0) { int[] width = new int[1]; int[] height = new int[1]; OS.gdk_drawable_get_size(image.pixmap, width, height); - OS.gdk_draw_drawable(window, gc, image.pixmap, 0, 0, x, y, width[0], height[0]); + int nX = x; + if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - width[0] - nX; + OS.gdk_draw_drawable(window, gc, image.pixmap, 0, 0, nX, y, width[0], height[0]); } else { int nWidth = width, nHeight = height; if (nWidth <= 0) nWidth = 1; - OS.gdk_draw_rectangle (window, gc, 1, x, y, nWidth, nHeight); + int nX = x; + if ((parent.style & SWT.MIRRORED) != 0) nX = parent.getClientWidth () - nWidth - nX; + OS.gdk_draw_rectangle (window, gc, 1, nX, y, nWidth, nHeight); } OS.g_object_unref (gc); OS.gdk_colormap_free_colors (colormap, color, 1); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java index 010d62b689..f6a69a3c04 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java @@ -299,7 +299,7 @@ void createHandle (int index, boolean fixed, boolean scrolled) { if (socketHandle == 0) SWT.error (SWT.ERROR_NO_HANDLES); OS.gtk_container_add (handle, socketHandle); } - if ((style & SWT.NO_REDRAW_RESIZE) != 0) { + if ((style & SWT.NO_REDRAW_RESIZE) != 0 && (style & SWT.RIGHT_TO_LEFT) == 0) { OS.gtk_widget_set_redraw_on_allocate (handle, false); } /* @@ -554,6 +554,10 @@ public Rectangle getClientArea () { return super.getClientArea(); } +int getClientWidth() { + return (state & ZERO_WIDTH) != 0 ? 0 : OS.GTK_WIDGET_WIDTH (clientHandle ()); +} + /** * Returns layout which is associated with the receiver, or * null if one has not been set. @@ -660,6 +664,7 @@ int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) { event.y = rect.y; event.width = rect.width; event.height = rect.height; + if ((style & SWT.MIRRORED) != 0) event.x = getClientWidth () - event.width - event.x; int /*long*/ damageRgn = OS.gdk_region_new (); OS.gdk_region_union_with_rect (damageRgn, rect); GCData data = new GCData (); @@ -1057,6 +1062,41 @@ void moveBelow (int /*long*/ child, int /*long*/ sibling) { OS.memmove (parentHandle, fixed); } +void moveChildren(int oldWidth) { + Control[] children = _getChildren (); + for (int i = 0; i < children.length; i++) { + Control child = children[i]; + int /*long*/ topHandle = child.topHandle (); + int x = OS.GTK_WIDGET_X (topHandle); + int y = OS.GTK_WIDGET_Y (topHandle); + int controlWidth = (child.state & ZERO_WIDTH) != 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); + x = oldWidth - controlWidth - x; + int clientWidth = getClientWidth (); + x = clientWidth - controlWidth - x; + if (child.enableWindow != 0) { + OS.gdk_window_move (child.enableWindow, x, y); + } + child.moveHandle (x, y); + /* + * Cause a size allocation this widget's topHandle. Note that + * all calls to gtk_widget_size_allocate() must be preceded by + * a call to gtk_widget_size_request(). + */ + GtkRequisition requisition = new GtkRequisition (); + gtk_widget_size_request (topHandle, requisition); + GtkAllocation allocation = new GtkAllocation (); + allocation.x = x; + allocation.y = y; + allocation.width = OS.GTK_WIDGET_WIDTH (topHandle); + allocation.height = OS.GTK_WIDGET_HEIGHT (topHandle); + OS.gtk_widget_size_allocate (topHandle, allocation); + Control control = child.findBackgroundControl (); + if (control != null && control.backgroundImage != null) { + if (child.isVisible ()) child.redrawWidget (0, 0, 0, 0, true, true, true); + } + } +} + Point minimumSize (int wHint, int hHint, boolean changed) { Control [] children = _getChildren (); int width = 0, height = 0; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index 336a9a9dbe..3f77af90fe 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -103,6 +103,7 @@ boolean drawGripper (int x, int y, int width, int height, boolean vertical) { int /*long*/ window = OS.GTK_WIDGET_WINDOW (paintHandle); if (window == 0) return false; int orientation = vertical ? OS.GTK_ORIENTATION_HORIZONTAL : OS.GTK_ORIENTATION_VERTICAL; + if ((style & SWT.MIRRORED) != 0) x = getClientWidth () - width - x; OS.gtk_paint_handle (OS.gtk_widget_get_style (paintHandle), window, OS.GTK_STATE_NORMAL, OS.GTK_SHADOW_OUT, null, paintHandle, new byte [1], x, y, width, height, orientation); return true; } @@ -371,6 +372,14 @@ void checkBorder () { if (getBorderWidth () == 0) style &= ~SWT.BORDER; } +void checkMirrored () { + if ((style & SWT.RIGHT_TO_LEFT) != 0) { + if ((state & CANVAS) != 0) { + style |= SWT.MIRRORED; + } + } +} + int /*long*/ childStyle () { return parent.childStyle (); } @@ -386,6 +395,7 @@ void createWidget (int index) { setInitialBounds (); setZOrder (null, false, false); setRelations (); + checkMirrored (); checkBorder (); } @@ -512,6 +522,7 @@ public Rectangle getBounds () { int y = OS.GTK_WIDGET_Y (topHandle); int width = (state & ZERO_WIDTH) != 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); int height = (state & ZERO_HEIGHT) != 0 ? 0 : OS.GTK_WIDGET_HEIGHT (topHandle); + if ((parent.style & SWT.MIRRORED) != 0) x = parent.getClientWidth () - width - x; return new Rectangle (x, y, width, height); } @@ -598,6 +609,20 @@ void resizeHandle (int width, int height) { int setBounds (int x, int y, int width, int height, boolean move, boolean resize) { int /*long*/ topHandle = topHandle (); + boolean sendMove = move; + if ((parent.style & SWT.MIRRORED) != 0) { + int clientWidth = parent.getClientWidth (); + int oldWidth = (state & ZERO_WIDTH) != 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); + int oldX = clientWidth - oldWidth - OS.GTK_WIDGET_X (topHandle); + if (move) { + sendMove &= x != oldX; + x = clientWidth - (resize ? width : oldWidth) - x; + } else { + move = true; + x = clientWidth - (resize ? width : oldWidth) - oldX; + y = OS.GTK_WIDGET_Y (topHandle); + } + } boolean sameOrigin = true, sameExtent = true; if (move) { int oldX = OS.GTK_WIDGET_X (topHandle); @@ -610,10 +635,12 @@ int setBounds (int x, int y, int width, int height, boolean move, boolean resize moveHandle (x, y); } } + int clientWidth = 0; if (resize) { int oldWidth = (state & ZERO_WIDTH) != 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); int oldHeight = (state & ZERO_HEIGHT) != 0 ? 0 : OS.GTK_WIDGET_HEIGHT (topHandle); sameExtent = width == oldWidth && height == oldHeight; + if (!sameExtent && (style & SWT.MIRRORED) != 0) clientWidth = getClientWidth (); if (!sameExtent && !(width == 0 && height == 0)) { int newWidth = Math.max (1, width); int newHeight = Math.max (1, height); @@ -672,6 +699,7 @@ int setBounds (int x, int y, int width, int height, boolean move, boolean resize OS.gtk_widget_show (topHandle); } } + if ((style & SWT.MIRRORED) != 0) moveChildren (clientWidth); } int result = 0; if (move && !sameOrigin) { @@ -679,7 +707,7 @@ int setBounds (int x, int y, int width, int height, boolean move, boolean resize if (control != null && control.backgroundImage != null) { if (isVisible ()) redrawWidget (0, 0, 0, 0, true, true, true); } - sendEvent (SWT.Move); + if (sendMove) sendEvent (SWT.Move); result |= MOVED; } if (resize && !sameExtent) { @@ -707,6 +735,10 @@ public Point getLocation () { int /*long*/ topHandle = topHandle (); int x = OS.GTK_WIDGET_X (topHandle); int y = OS.GTK_WIDGET_Y (topHandle); + if ((parent.style & SWT.MIRRORED) != 0) { + int width = (state & ZERO_WIDTH) != 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); + x = parent.getClientWidth () - width - x; + } return new Point (x, y); } @@ -906,6 +938,9 @@ public void moveBelow (Control control) { 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 @@ -983,7 +1018,10 @@ public Point toControl (int x, int y) { int /*long*/ window = eventWindow (); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (window, origin_x, origin_y); - return new Point (x - origin_x [0], y - origin_y [0]); + x -= origin_x [0]; + y -= origin_y [0]; + if ((style & SWT.MIRRORED) != 0) x = getClientWidth () - x; + return new Point (x, y); } /** @@ -1029,7 +1067,10 @@ public Point toDisplay (int x, int y) { int /*long*/ window = eventWindow (); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (window, origin_x, origin_y); - return new Point (origin_x [0] + x, origin_y [0] + y); + if ((style & SWT.MIRRORED) != 0) x = getClientWidth () - x; + x += origin_x [0]; + y += origin_y [0]; + return new Point (x, y); } /** @@ -2002,6 +2043,10 @@ public int getBorderWidth () { return 0; } +int getClientWidth () { + return 0; +} + /** * Returns the receiver's cursor, or null if it has not been set. * <p> @@ -2468,6 +2513,7 @@ int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) { event.y = gdkEvent.area_y; event.width = gdkEvent.area_width; event.height = gdkEvent.area_height; + if ((style & SWT.MIRRORED) != 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); @@ -2707,6 +2753,10 @@ public int /*long*/ internal_new_GC (GCData data) { int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; if ((data.style & mask) == 0) { data.style |= style & (mask | SWT.MIRRORED); + } else { + if ((data.style & SWT.RIGHT_TO_LEFT) != 0) { + data.style |= SWT.MIRRORED; + } } data.drawable = window; data.device = display; @@ -2943,6 +2993,7 @@ void redraw (boolean all) { public void redraw (int x, int y, int width, int height, boolean all) { checkWidget(); if (!OS.GTK_WIDGET_VISIBLE (topHandle ())) return; + if ((style & SWT.MIRRORED) != 0) x = getClientWidth () - width - x; redrawWidget (x, y, width, height, false, all, false); } @@ -3027,6 +3078,7 @@ boolean sendDragEvent (int button, int stateMask, int x, int y, boolean isStateM event.button = button; event.x = x; event.y = y; + if ((style & SWT.MIRRORED) != 0) event.x = getClientWidth () - event.x; if (isStateMask) { event.stateMask = stateMask; } else { @@ -3102,6 +3154,7 @@ boolean sendMouseEvent (int type, int button, int count, int detail, boolean sen event.x = (int)x - origin_x [0]; event.y = (int)y - origin_y [0]; } + if ((style & SWT.MIRRORED) != 0) event.x = getClientWidth () - event.x; setInputState (event, state); if (send) { sendEvent (type, event); @@ -3500,7 +3553,11 @@ void setInitialBounds () { * expected by SWT. */ int /*long*/ topHandle = topHandle (); - OS.GTK_WIDGET_SET_X (topHandle, 0); + if ((parent.style & SWT.MIRRORED) != 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); @@ -3576,6 +3633,16 @@ public boolean setParent (Composite parent) { if (parent.isDisposed()) SWT.error (SWT.ERROR_INVALID_ARGUMENT); if (this.parent == parent) return true; if (!isReparentable ()) return false; + int /*long*/ topHandle = topHandle (); + int x = OS.GTK_WIDGET_X (topHandle); + int width = (state & ZERO_WIDTH) != 0 ? 0 : OS.GTK_WIDGET_WIDTH (topHandle); + if ((this.parent.style & SWT.MIRRORED) != 0) { + x = this.parent.getClientWidth () - width - x; + } + if ((parent.style & SWT.MIRRORED) != 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 (); @@ -3585,10 +3652,7 @@ public boolean setParent (Composite parent) { newDecorations.fixAccelGroup (); oldDecorations.fixAccelGroup (); } - int /*long*/ topHandle = topHandle (); int /*long*/ 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 (newParent, topHandle, x, y); this.parent = parent; @@ -4030,6 +4094,9 @@ boolean translateTraversal (GdkEventKey keyEvent) { case OS.GDK_Down: case OS.GDK_Right: { boolean next = key == OS.GDK_Down || key == OS.GDK_Right; + if (parent != null && (parent.style & SWT.MIRRORED) != 0) { + if (key == OS.GDK_Left || key == OS.GDK_Right) next = !next; + } detail = next ? SWT.TRAVERSE_ARROW_NEXT : SWT.TRAVERSE_ARROW_PREVIOUS; break; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java index ee481b3179..9f7afe2311 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java @@ -264,8 +264,8 @@ public class Display extends Device { /* Fixed Subclass */ static int /*long*/ fixed_type; static int /*long*/ fixed_info_ptr; - static Callback fixedClassInitCallback, fixedMapCallback; - static int /*long*/ fixedClassInitProc, fixedMapProc; + static Callback fixedClassInitCallback, fixedMapCallback, fixedSizeAllocateCallback; + static int /*long*/ fixedClassInitProc, fixedMapProc, fixedSizeAllocateProc, oldFixedSizeAllocateProc; /* Renderer Subclass */ static int /*long*/ text_renderer_type, pixbuf_renderer_type, toggle_renderer_type; @@ -843,6 +843,9 @@ void createDisplay (DeviceData data) { fixedMapCallback = new Callback (getClass (), "fixedMapProc", 1); fixedMapProc = fixedMapCallback.getAddress (); if (fixedMapProc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); + fixedSizeAllocateCallback = new Callback (getClass (), "fixedSizeAllocateProc", 2); + fixedSizeAllocateProc = fixedSizeAllocateCallback.getAddress (); + if (fixedSizeAllocateProc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); GTypeInfo fixed_info = new GTypeInfo (); fixed_info.class_size = (short) OS.GtkFixedClass_sizeof (); fixed_info.class_init = fixedClassInitProc; @@ -1268,6 +1271,8 @@ static int /*long*/ fixedClassInitProc (int /*long*/ g_class, int /*long*/ class GtkWidgetClass klass = new GtkWidgetClass (); OS.memmove (klass, g_class); klass.map = fixedMapProc; + oldFixedSizeAllocateProc = klass.size_allocate; + klass.size_allocate = fixedSizeAllocateProc; OS.memmove (g_class, klass); return 0; } @@ -1279,6 +1284,13 @@ static int /*long*/ fixedMapProc (int /*long*/ handle) { return 0; } +static int /*long*/ fixedSizeAllocateProc (int /*long*/ handle, int /*long*/ allocation) { + Display display = getCurrent (); + Widget widget = display.getWidget (handle); + if (widget != null) return widget.fixedSizeAllocateProc (handle, allocation); + return OS.Call (oldFixedSizeAllocateProc, handle, allocation); +} + static int /*long*/ rendererClassInitProc (int /*long*/ g_class, int /*long*/ class_data) { GtkCellRendererClass klass = new GtkCellRendererClass (); OS.memmove (klass, g_class); @@ -2649,6 +2661,7 @@ public Point map (Control from, Control to, int x, int y) { int /*long*/ window = from.eventWindow (); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (window, origin_x, origin_y); + if ((from.style & SWT.MIRRORED) != 0) point.x = from.getClientWidth () - point.x; point.x += origin_x [0]; point.y += origin_y [0]; } @@ -2658,6 +2671,7 @@ public Point map (Control from, Control to, int x, int y) { OS.gdk_window_get_origin (window, origin_x, origin_y); point.x -= origin_x [0]; point.y -= origin_y [0]; + if ((to.style & SWT.MIRRORED) != 0) point.x = to.getClientWidth () - point.x; } return point; } @@ -2771,10 +2785,12 @@ public Rectangle map (Control from, Control to, int x, int y, int width, int hei if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); Rectangle rect = new Rectangle (x, y, width, height); if (from == to) return rect; + boolean fromRTL = false, toRTL = false; if (from != null) { int /*long*/ window = from.eventWindow (); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (window, origin_x, origin_y); + if (fromRTL = (from.style & SWT.MIRRORED) != 0) rect.x = from.getClientWidth() - rect.x; rect.x += origin_x [0]; rect.y += origin_y [0]; } @@ -2784,7 +2800,9 @@ public Rectangle map (Control from, Control to, int x, int y, int width, int hei OS.gdk_window_get_origin (window, origin_x, origin_y); rect.x -= origin_x [0]; rect.y -= origin_y [0]; + if (toRTL = (to.style & SWT.MIRRORED) != 0) rect.x = to.getClientWidth () - rect.x; } + if (fromRTL != toRTL) rect.x -= rect.width; return rect; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java index 94d265f0cc..9ba7518da6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java @@ -88,6 +88,12 @@ static int checkStyle (int style) { return style & ~(SWT.H_SCROLL | SWT.V_SCROLL); } +void checkMirrored() { + if ((style & SWT.RIGHT_TO_LEFT) != 0) { + style |= SWT.MIRRORED; + } +} + protected void checkSubclass () { if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java index a262644d63..0e2680ccbe 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java @@ -377,6 +377,7 @@ int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ eventPtr) { event.y = gdkEvent.area_y; event.width = gdkEvent.area_width; event.height = gdkEvent.area_height; + if ((style & SWT.MIRRORED) != 0) event.x = getClientWidth () - event.width - event.x; event.gc = gc; sendEvent (SWT.Paint, event); event.gc = null; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java index 352f3b3ec8..9ac40ee3a0 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java @@ -186,14 +186,16 @@ int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ eventPtr) if ((style & SWT.SMOOTH) == 0) { event.detail = SWT.DRAG; } + if ((parent.style & SWT.MIRRORED) != 0) event.x = parent.getClientWidth () - width - event.x; sendEvent (SWT.Selection, event); if (isDisposed ()) return 0; if (event.doit) { dragging = true; lastX = event.x; lastY = event.y; + if ((parent.style & SWT.MIRRORED) != 0) lastX = parent.getClientWidth () - width - lastX; parent.update (true, (style & SWT.SMOOTH) == 0); - drawBand (event.x, event.y, width, height); + drawBand (lastX, event.y, width, height); if ((style & SWT.SMOOTH) != 0) { setBounds (event.x, event.y, width, height); // widget could be disposed at this point @@ -220,6 +222,7 @@ int /*long*/ gtk_button_release_event (int /*long*/ widget, int /*long*/ eventPt event.width = width; event.height = height; drawBand (lastX, lastY, width, height); + if ((parent.style & SWT.MIRRORED) != 0) event.x = parent.getClientWidth () - width - event.x; sendEvent (SWT.Selection, event); if (isDisposed ()) return result; if (event.doit) { @@ -290,6 +293,7 @@ int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) { event.y = newY; event.width = width; event.height = height; + if ((parent.style & SWT.MIRRORED) != 0) event.x = parent.getClientWidth () - width - event.x; sendEvent (SWT.Selection, event); if (ptrGrabResult == OS.GDK_GRAB_SUCCESS) OS.gdk_pointer_ungrab (OS.GDK_CURRENT_TIME); if (isDisposed ()) break; @@ -297,6 +301,7 @@ int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ eventPtr) { if (event.doit) { lastX = event.x; lastY = event.y; + if ((parent.style & SWT.MIRRORED) != 0) lastX = parent.getClientWidth () - width - lastX; if ((style & SWT.SMOOTH) != 0) { setBounds (event.x, event.y, width, height); if (isDisposed ()) break; @@ -361,16 +366,18 @@ int /*long*/ gtk_motion_notify_event (int /*long*/ widget, int /*long*/ eventPtr if ((style & SWT.SMOOTH) == 0) { event.detail = SWT.DRAG; } + if ((parent.style & SWT.MIRRORED) != 0) event.x = parent.getClientWidth() - width - event.x; sendEvent (SWT.Selection, event); if (isDisposed ()) return 0; if (event.doit) { lastX = event.x; lastY = event.y; + if ((parent.style & SWT.MIRRORED) != 0) lastX = parent.getClientWidth () - width - lastX; } parent.update (true, (style & SWT.SMOOTH) == 0); drawBand (lastX, lastY, width, height); if ((style & SWT.SMOOTH) != 0) { - setBounds (lastX, lastY, width, height); + setBounds (event.x, lastY, width, height); // widget could be disposed at this point } return result; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ScrollBar.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ScrollBar.java index 6cd8180e42..0e25896873 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ScrollBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ScrollBar.java @@ -595,6 +595,15 @@ public void setMinimum (int value) { OS.g_signal_handlers_unblock_matched (adjustmentHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED); } +void setOrientation () { + super.setOrientation (); + if ((parent.style & SWT.MIRRORED) != 0) { + if ((style & SWT.HORIZONTAL) != 0) { + OS.gtk_range_set_inverted (handle, true); + } + } +} + /** * Sets the amount that the receiver's value will be * modified by when the page increment/decrement areas diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java index 249d6eff4c..289593e4aa 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java @@ -139,6 +139,7 @@ ScrollBar createScrollBar (int style) { bar.handle = OS.GTK_SCROLLED_WINDOW_VSCROLLBAR (scrolledHandle); bar.adjustmentHandle = OS.gtk_scrolled_window_get_vadjustment (scrolledHandle); } + bar.setOrientation(); bar.hookEvents (); bar.register (); return bar; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java index 2df08efc7f..abacfa1c33 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java @@ -761,6 +761,14 @@ void fixShell (Shell newShell, Control control) { } } +int /*long*/ fixedSizeAllocateProc(int /*long*/ widget, int /*long*/ allocationPtr) { + int clientWidth = 0; + if ((style & SWT.MIRRORED) != 0) clientWidth = getClientWidth (); + int result = super.fixedSizeAllocateProc (widget, allocationPtr); + if ((style & SWT.MIRRORED) != 0) moveChildren (clientWidth); + return result; +} + void fixStyle (int /*long*/ handle) { } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java index 9be913b09c..a8c08a94e7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java @@ -516,12 +516,13 @@ int /*long*/ gtk_clicked (int /*long*/ widget) { OS.gdk_event_get_coords (eventPtr, x_win, y_win); int x = OS.GTK_WIDGET_X (arrowHandle) - OS.GTK_WIDGET_X (handle); int width = OS.GTK_WIDGET_WIDTH (arrowHandle); - if ((((state & SWT.RIGHT_TO_LEFT) == 0) && x <= (int)x_win [0]) - || (((state & SWT.RIGHT_TO_LEFT) != 0) && (int)x_win [0] <= x + width)) { + if ((((parent.style & SWT.RIGHT_TO_LEFT) == 0) && x <= (int)x_win [0]) + || (((parent.style & SWT.RIGHT_TO_LEFT) != 0) && (int)x_win [0] <= x + width)) { event.detail = SWT.ARROW; int /*long*/ topHandle = topHandle (); event.x = OS.GTK_WIDGET_X (topHandle); event.y = OS.GTK_WIDGET_Y (topHandle) + OS.GTK_WIDGET_HEIGHT (topHandle); + if ((parent.style & SWT.RIGHT_TO_LEFT) != 0) event.x += OS.GTK_WIDGET_WIDTH (topHandle); } break; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java index 0acfa294ba..9605ef4fb8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java @@ -815,6 +815,10 @@ int /*long*/ fixedMapProc (int /*long*/ widget) { return 0; } +int /*long*/ fixedSizeAllocateProc(int /*long*/ widget, int /*long*/ allocationPtr) { + return OS.Call (Display.oldFixedSizeAllocateProc, widget, allocationPtr); +} + char [] fixMnemonic (String string) { int length = string.length (); char [] text = new char [length]; |