Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Heidrich2003-09-09 11:29:48 -0400
committerFelipe Heidrich2003-09-09 11:29:48 -0400
commit70a784b179fbea69720ec286ca6c2ce3db492b26 (patch)
tree858677ec86e4ab1949aa80e61e45b1e8f1ccaac1
parent02c0962d3ecfa4815336b69d17b9ecb5bf7b8e0d (diff)
downloadeclipse.platform.swt-70a784b179fbea69720ec286ca6c2ce3db492b26.tar.gz
eclipse.platform.swt-70a784b179fbea69720ec286ca6c2ce3db492b26.tar.xz
eclipse.platform.swt-70a784b179fbea69720ec286ca6c2ce3db492b26.zip
Bidi back port 3.0 M3 -> 2.1.2 (PR# 42426)
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java13
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CLabel.java2
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java9
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java3
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/PopupList.java18
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/SashForm.java2
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ScrolledComposite.java2
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java579
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java149
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java17
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTree.java12
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ViewForm.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/swt.c27
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java11
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Printing/motif/org/eclipse/swt/printing/Printer.java4
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Printing/win32/org/eclipse/swt/printing/Printer.java5
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GC.java12
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Display.java238
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java60
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java8
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java15
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java4
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java4
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java206
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GC.java15
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GCData.java1
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/Image.java4
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Control.java4
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Display.java190
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GC.java15
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GCData.java1
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/Image.java4
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java4
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Display.java194
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java143
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java2
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java5
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java150
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java30
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java19
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java32
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java183
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MessageBox.java6
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Slider.java27
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java38
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java47
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tracker.java18
48 files changed, 2074 insertions, 461 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java
index 18fc637809..50b0a55f86 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java
@@ -84,6 +84,7 @@ public CCombo (Composite parent, int style) {
int listStyle = SWT.SINGLE | SWT.V_SCROLL;
if ((style & SWT.FLAT) != 0) listStyle |= SWT.FLAT;
+ if ((style & SWT.RIGHT_TO_LEFT) != 0) listStyle |= SWT.RIGHT_TO_LEFT;
list = new List (popup, listStyle);
int arrowStyle = SWT.ARROW | SWT.DOWN;
@@ -134,7 +135,7 @@ public CCombo (Composite parent, int style) {
initAccessible();
}
static int checkStyle (int style) {
- int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT;
+ int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
return style & mask;
}
/**
@@ -341,15 +342,17 @@ void dropDown (boolean drop) {
text.setFocus();
return;
}
+
int index = list.getSelectionIndex ();
if (index != -1) list.setTopIndex (index);
Rectangle listRect = list.getBounds ();
- Point point = getParent().toDisplay (getLocation ());
- Point comboSize = getSize();
+ Display display = getDisplay ();
+ Rectangle rect = display.map (getParent (), null, getBounds ());
+ Point comboSize = getSize ();
int width = Math.max (comboSize.x, listRect.width + 2);
- popup.setBounds (point.x, point.y + comboSize.y, width, listRect.height + 2);
+ popup.setBounds (rect.x, rect.y + comboSize.y, width, listRect.height + 2);
popup.setVisible (true);
- list.setFocus();
+ list.setFocus ();
}
public Control [] getChildren () {
checkWidget();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CLabel.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CLabel.java
index 9c8cfff482..7b0fdea9b0 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CLabel.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CLabel.java
@@ -120,7 +120,7 @@ public CLabel(Composite parent, int style) {
* Check the style bits to ensure that no invalid styles are applied.
*/
private static int checkStyle (int style) {
- int mask = SWT.SHADOW_IN | SWT.SHADOW_OUT | SWT.SHADOW_NONE;
+ int mask = SWT.SHADOW_IN | SWT.SHADOW_OUT | SWT.SHADOW_NONE | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
style = style & mask;
style |= SWT.NO_FOCUS;
if ((style & (SWT.CENTER | SWT.RIGHT)) == 0) style |= SWT.LEFT;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
index 7ccc95452f..4fcea2fdbe 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
@@ -237,7 +237,7 @@ public CTabFolder(Composite parent, int style) {
}
private static int checkStyle (int style) {
- int mask = SWT.TOP | SWT.BOTTOM | SWT.FLAT;
+ int mask = SWT.TOP | SWT.BOTTOM | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
style = style & mask;
// TOP and BOTTOM are mutually exlusive.
// TOP is the default
@@ -509,12 +509,13 @@ void destroyItem (CTabItem item) {
redrawTabArea(-1);
}
private void onKeyDown(Event e) {
- if (e.keyCode == SWT.ARROW_LEFT) {
+ if (e.keyCode != SWT.ARROW_LEFT && e.keyCode != SWT.ARROW_RIGHT) return;
+ int leadKey = (getStyle() & SWT.MIRRORED) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT;
+ if (e.keyCode == leadKey) {
if (selectedIndex > 0) {
setSelection(selectedIndex - 1, true);
}
- }
- if (e.keyCode == SWT.ARROW_RIGHT) {
+ } else {
if (selectedIndex < items.length - 1) {
setSelection(selectedIndex + 1, true);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java
index 424413010b..38aeda8c10 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java
@@ -76,6 +76,7 @@ protected void drawLineSelectionBackground(String line, int lineOffset, StyleRan
int lineEndSpaceWidth = getLineEndSpaceWidth();
int lineHeight = getLineHeight();
boolean wordWrap = parent.internalGetWordWrap();
+ boolean isRightOriented = (parent.getStyle() & SWT.MIRRORED) != 0;
if (selectionEnd == selectionStart || selectionEnd < 0 || selectionStart > lineLength) {
return;
@@ -129,7 +130,7 @@ protected void drawLineSelectionBackground(String line, int lineOffset, StyleRan
// if the selection extends past this line, render an additional
// whitespace background at the end of the line to represent the
// selected line break
- if (bidi != null && selectionEnd > 0 && bidi.isRightToLeft(selectionEnd - 1)) {
+ if (bidi != null && selectionEnd > 0 && (bidi.isRightToLeft(selectionEnd - 1) || (isRightOriented && bidi.isRightToLeft(selectionEnd - 1) == false))) {
int lineEndX = bidi.getTextWidth();
gc.fillRectangle(lineEndX - horizontalScrollOffset + leftMargin, paintY, lineEndSpaceWidth, lineHeight);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/PopupList.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/PopupList.java
index e624ca2d71..81e39cd9d2 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/PopupList.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/PopupList.java
@@ -31,8 +31,18 @@ public class PopupList {
* Creates a PopupList above the specified shell.
*/
public PopupList(Shell parent) {
-
- shell = new Shell(parent, 0);
+ this (parent, 0);
+}
+/**
+* Creates a PopupList above the specified shell.
+*
+* @param parent a widget which will be the parent of the new instance (cannot be null)
+* @param style the style of widget to construct
+*
+* @since 2.1.2
+*/
+public PopupList(Shell parent, int style) {
+ shell = new Shell(parent, checkStyle(style));
list = new List(shell, SWT.SINGLE | SWT.V_SCROLL);
@@ -70,6 +80,10 @@ public PopupList(Shell parent) {
});
}
+private static int checkStyle (int style) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ return style & mask;
+}
/**
* Gets the widget font.
* <p>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/SashForm.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/SashForm.java
index a017acac2e..3aa8f773ca 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/SashForm.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/SashForm.java
@@ -85,7 +85,7 @@ public SashForm(Composite parent, int style) {
};
}
private static int checkStyle (int style) {
- int mask = SWT.BORDER;
+ int mask = SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
return style & mask;
}
public Point computeSize (int wHint, int hHint, boolean changed) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ScrolledComposite.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ScrolledComposite.java
index 9f3cef8c20..70e9d401f5 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ScrolledComposite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ScrolledComposite.java
@@ -173,7 +173,7 @@ public ScrolledComposite(Composite parent, int style) {
}
private static int checkStyle (int style) {
- int mask = SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER;
+ int mask = SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
return style & mask;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
index 80353beea8..03513c4915 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
@@ -140,6 +140,7 @@ public class StyledText extends Canvas {
int lastTextChangeReplaceLineCount; // text changed handler
int lastTextChangeReplaceCharCount;
boolean isBidi;
+ boolean isMirrored;
boolean bidiColoring = false; // apply the BIDI algorithm on text segments of the same color
Image leftCaretBitmap = null;
Image rightCaretBitmap = null;
@@ -1590,7 +1591,8 @@ public StyledText(Composite parent, int style) {
super.setForeground(getForeground());
super.setBackground(getBackground());
Display display = getDisplay();
- isBidi = StyledTextBidi.isBidiPlatform();
+ isMirrored = (getStyle() & SWT.MIRRORED) != 0;
+ isBidi = StyledTextBidi.isBidiPlatform() || isMirrored;
if ((style & SWT.READ_ONLY) != 0) {
setEditable(false);
}
@@ -1612,6 +1614,9 @@ public StyledText(Composite parent, int style) {
}
else {
createCaretBitmaps();
+ if (isMirrored) {
+ BidiUtil.setKeyboardLanguage(BidiUtil.KEYBOARD_BIDI);
+ }
new Caret(this, SWT.NULL);
setBidiCaretDirection();
Runnable runnable = new Runnable() {
@@ -2233,32 +2238,49 @@ void createKeyBindings() {
setKeyBinding(SWT.ARROW_DOWN, ST.LINE_DOWN);
setKeyBinding(SWT.HOME, ST.LINE_START);
setKeyBinding(SWT.END, ST.LINE_END);
- setKeyBinding(SWT.ARROW_LEFT, ST.COLUMN_PREVIOUS);
- setKeyBinding(SWT.ARROW_RIGHT, ST.COLUMN_NEXT);
setKeyBinding(SWT.PAGE_UP, ST.PAGE_UP);
setKeyBinding(SWT.PAGE_DOWN, ST.PAGE_DOWN);
- setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1, ST.WORD_PREVIOUS);
- setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1, ST.WORD_NEXT);
setKeyBinding(SWT.HOME | SWT.MOD1, ST.TEXT_START);
setKeyBinding(SWT.END | SWT.MOD1, ST.TEXT_END);
setKeyBinding(SWT.PAGE_UP | SWT.MOD1, ST.WINDOW_START);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1, ST.WINDOW_END);
+ if (isMirrored()) {
+ setKeyBinding(SWT.ARROW_LEFT, ST.COLUMN_NEXT);
+ setKeyBinding(SWT.ARROW_RIGHT, ST.COLUMN_PREVIOUS);
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1, ST.WORD_NEXT);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1, ST.WORD_PREVIOUS);
+ }
+ else {
+ setKeyBinding(SWT.ARROW_LEFT, ST.COLUMN_PREVIOUS);
+ setKeyBinding(SWT.ARROW_RIGHT, ST.COLUMN_NEXT);
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1, ST.WORD_PREVIOUS);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1, ST.WORD_NEXT);
+ }
+
// Selection
setKeyBinding(SWT.ARROW_UP | SWT.MOD2, ST.SELECT_LINE_UP);
setKeyBinding(SWT.ARROW_DOWN | SWT.MOD2, ST.SELECT_LINE_DOWN);
setKeyBinding(SWT.HOME | SWT.MOD2, ST.SELECT_LINE_START);
setKeyBinding(SWT.END | SWT.MOD2, ST.SELECT_LINE_END);
- setKeyBinding(SWT.ARROW_LEFT | SWT.MOD2, ST.SELECT_COLUMN_PREVIOUS);
- setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD2, ST.SELECT_COLUMN_NEXT);
setKeyBinding(SWT.PAGE_UP | SWT.MOD2, ST.SELECT_PAGE_UP);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD2, ST.SELECT_PAGE_DOWN);
- setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_PREVIOUS);
- setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_NEXT);
setKeyBinding(SWT.HOME | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_START);
setKeyBinding(SWT.END | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_END);
setKeyBinding(SWT.PAGE_UP | SWT.MOD1 | SWT.MOD2, ST.SELECT_WINDOW_START);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1 | SWT.MOD2, ST.SELECT_WINDOW_END);
-
+ if (isMirrored()) {
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD2, ST.SELECT_COLUMN_NEXT);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD2, ST.SELECT_COLUMN_PREVIOUS);
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_NEXT);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_PREVIOUS);
+ }
+ else {
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD2, ST.SELECT_COLUMN_PREVIOUS);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD2, ST.SELECT_COLUMN_NEXT);
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_PREVIOUS);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_NEXT);
+ }
+
// Modification
// Cut, Copy, Paste
setKeyBinding('X' | SWT.MOD1, ST.CUT);
@@ -2285,6 +2307,7 @@ void createKeyBindings() {
*/
void createCaretBitmaps() {
int caretWidth = BIDI_CARET_WIDTH;
+ int gcStyle = isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT;
Display display = getDisplay();
if (caretPalette == null) {
@@ -2295,7 +2318,9 @@ void createCaretBitmaps() {
}
ImageData imageData = new ImageData(caretWidth, lineHeight, 1, caretPalette);
leftCaretBitmap = new Image(display, imageData);
- GC gc = new GC (leftCaretBitmap);
+ // mirror the caret gc because when the bitmap is rendered on the screen it will be
+ // mirrored since the GC for the canvas is mirrored
+ GC gc = new GC (leftCaretBitmap, gcStyle);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawLine(0,0,0,lineHeight);
gc.drawLine(0,0,caretWidth-1,0);
@@ -2306,7 +2331,9 @@ void createCaretBitmaps() {
rightCaretBitmap.dispose();
}
rightCaretBitmap = new Image(display, imageData);
- gc = new GC (rightCaretBitmap);
+ // mirror the caret gc because when the bitmap is rendered on the screen it will be
+ // mirrored since the GC for the canvas is mirrored
+ gc = new GC (rightCaretBitmap, gcStyle);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawLine(caretWidth-1,0,caretWidth-1,lineHeight);
gc.drawLine(0,0,caretWidth-1,0);
@@ -2363,11 +2390,11 @@ void doAutoScroll(Event event) {
}
else
if (event.x < leftMargin && wordWrap == false) {
- doAutoScroll(SWT.LEFT);
+ doAutoScroll(ST.COLUMN_PREVIOUS);
}
else
if (event.x > area.width - leftMargin - rightMargin && wordWrap == false) {
- doAutoScroll(SWT.RIGHT);
+ doAutoScroll(ST.COLUMN_NEXT);
}
else {
endAutoScroll();
@@ -2377,7 +2404,7 @@ void doAutoScroll(Event event) {
* Initiates autoscrolling.
* <p>
*
- * @param direction SWT.UP, SWT.DOWN, SWT.RIGHT, SWT.LEFT
+ * @param direction SWT.UP, SWT.DOWN, SWT.COLUMN_NEXT, SWT.COLUMN_PREVIOUS
*/
void doAutoScroll(int direction) {
Runnable timer = null;
@@ -2409,24 +2436,24 @@ void doAutoScroll(int direction) {
}
}
};
- } else if (direction == SWT.RIGHT) {
+ } else if (direction == ST.COLUMN_NEXT) {
timer = new Runnable() {
public void run() {
- if (autoScrollDirection == SWT.RIGHT) {
- doColumnRight();
+ if (autoScrollDirection == ST.COLUMN_NEXT) {
+ doVisualNext();
setMouseWordSelectionAnchor();
- doSelection(SWT.RIGHT);
+ doMouseSelection();
display.timerExec(TIMER_INTERVAL, this);
}
}
};
- } else if (direction == SWT.LEFT) {
+ } else if (direction == ST.COLUMN_PREVIOUS) {
timer = new Runnable() {
public void run() {
- if (autoScrollDirection == SWT.LEFT) {
- doColumnLeft();
+ if (autoScrollDirection == ST.COLUMN_PREVIOUS) {
+ doVisualPrevious();
setMouseWordSelectionAnchor();
- doSelection(SWT.LEFT);
+ doMouseSelection();
display.timerExec(TIMER_INTERVAL, this);
}
}
@@ -2467,208 +2494,6 @@ void doBackspace() {
}
}
/**
- * Moves the caret one character to the left. Do not go to the previous line.
- * When in a bidi locale and at a R2L character the caret is moved to the
- * beginning of the R2L segment (visually right) and then one character to the
- * left (visually left because it's now in a L2R segment).
- */
-void doColumnLeft() {
- int line = content.getLineAtOffset(caretOffset);
- int lineOffset = content.getOffsetAtLine(line);
- int offsetInLine = caretOffset - lineOffset;
-
- if (isBidi()) {
- String lineText = content.getLine(line);
- int lineLength = lineText.length();
- GC gc = getGC();
- StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
-
- if (horizontalScrollOffset > 0 || offsetInLine > 0) {
- if (offsetInLine < lineLength && bidi.isRightToLeft(offsetInLine)) {
- // advance caret logically if in R2L segment (move visually left)
- caretOffset++;
- doSelection(SWT.RIGHT);
- if (caretOffset - lineOffset == lineLength) {
- // if the line end is reached in a R2L segment, make the
- // caret position (visual left border) visible before
- // jumping to segment start
- showCaret();
- }
- // end of R2L segment reached (visual left side)?
- if (bidi.isRightToLeft(caretOffset - lineOffset) == false) {
- if (bidi.getTextPosition(caretOffset - lineOffset) < horizontalScrollOffset) {
- // make beginning of R2L segment visible before going
- // left, to L2R segment important if R2L segment ends
- // at visual left in order to scroll all the way to the
- // left. Fixes 1GKM3XS
- showCaret();
- }
- // go to beginning of R2L segment (visually end of next L2R
- // segment)/beginning of line
- caretOffset--;
- while (caretOffset - lineOffset > 0 &&
- bidi.isRightToLeft(caretOffset - lineOffset)) {
- caretOffset--;
- }
- }
- }
- else
- if (offsetInLine == lineLength &&
- bidi.getTextPosition(lineLength) != XINSET) {
- // at logical line end in R2L segment but there's more text (a
- // L2R segment) go to end of R2L segment (visually left of next
- // L2R segment)/end of line
- caretOffset--;
- while (caretOffset - lineOffset > 0 &&
- bidi.isRightToLeft(caretOffset - lineOffset)) {
- caretOffset--;
- }
- }
- else
- if (offsetInLine > 0 && bidi.isRightToLeft(offsetInLine) == false) {
- // decrease caret logically if in L2R segment (move visually left)
- caretOffset--;
- doSelection(SWT.LEFT);
- // end of L2R segment reached (visual left side of preceeding R2L
- // segment)?
- if (caretOffset - lineOffset > 0 &&
- bidi.isRightToLeft(caretOffset - lineOffset - 1)) {
- // go to beginning of R2L segment (visually start of next L2R
- // segment)/beginning of line
- caretOffset--;
- while (caretOffset - lineOffset > 0 &&
- bidi.isRightToLeft(caretOffset - lineOffset - 1)) {
- caretOffset--;
- }
- }
- }
- // if new caret position is to the left of the client area
- if (bidi.getTextPosition(caretOffset - lineOffset) < horizontalScrollOffset) {
- // scroll to the caret position
- showCaret();
- }
- else {
- // otherwise just update caret position without scrolling it into view
- setBidiCaretLocation(null);
- setBidiKeyboardLanguage();
- }
- // Beginning of line reached (auto scroll finished) but not scrolled
- // completely to the left? Fixes 1GKM193
- if (caretOffset - lineOffset == 0 && horizontalScrollOffset > 0 &&
- horizontalScrollOffset <= XINSET) {
- scrollHorizontalBar(-horizontalScrollOffset);
- }
- }
- gc.dispose();
- }
- else
- if (offsetInLine > 0) {
- caretOffset--;
- showCaret();
- }
-}
-/**
- * Moves the caret one character to the right. Do not go to the next line.
- * When in a bidi locale and at a R2L character the caret is moved to the
- * end of the R2L segment (visually left) and then one character to the
- * right (visually right because it's now in a L2R segment).
- */
-void doColumnRight() {
- int line = content.getLineAtOffset(caretOffset);
- int lineOffset = content.getOffsetAtLine(line);
- int offsetInLine = caretOffset - lineOffset;
- String lineText = content.getLine(line);
- int lineLength = lineText.length();
-
- if (isBidi()) {
- GC gc = getGC();
- StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
- if (bidi.getTextWidth() + leftMargin > horizontalScrollOffset + getClientArea().width ||
- offsetInLine < lineLength) {
- if (bidi.isRightToLeft(offsetInLine) == false &&
- offsetInLine < lineLength) {
- // advance caret logically if in L2R segment (move visually right)
- caretOffset++;
- doSelection(SWT.RIGHT);
- // end of L2R segment reached (visual right side)?
- if (bidi.isRightToLeft(caretOffset - lineOffset)) {
- // go to end of R2L segment (visually left of next R2L segment)/
- // end of line
- caretOffset++;
- while (caretOffset < lineOffset + lineLength &&
- bidi.isRightToLeft(caretOffset - lineOffset)) {
- caretOffset++;
- }
- }
- }
- else
- if (offsetInLine > 0 &&
- (bidi.isRightToLeft(offsetInLine) ||
- bidi.getTextWidth() + leftMargin > horizontalScrollOffset + getClientArea().width ||
- offsetInLine < lineLength)) {
- // advance caret visually if in R2L segment or logically at line end
- // but right end of line is not fully visible yet
- caretOffset--;
- doSelection(SWT.LEFT);
- offsetInLine = caretOffset - lineOffset;
- // end of R2L segment reached (visual right side)?
- if (offsetInLine > 0 && bidi.isRightToLeft(offsetInLine) == false) {
- // go to end of R2L segment (visually left of next L2R segment)/
- // end of line
- caretOffset++;
- while (caretOffset < lineOffset + lineLength &&
- bidi.isRightToLeft(caretOffset - lineOffset)) {
- caretOffset++;
- }
- }
- }
- else
- if (offsetInLine == 0 && bidi.getTextPosition(0) != bidi.getTextWidth()) {
- // at logical line start in R2L segment but there's more text (a L2R
- // segment) go to end of R2L segment (visually left of next L2R
- // segment)/end of line
- caretOffset++;
- while (caretOffset < lineOffset + lineLength &&
- bidi.isRightToLeft(caretOffset - lineOffset - 1)) {
- caretOffset++;
- }
- }
- offsetInLine = caretOffset - lineOffset;
- // if new caret position is to the right of the client area
- if (bidi.getTextPosition(offsetInLine) >= horizontalScrollOffset) {
- // scroll to the caret position
- showCaret();
- }
- else {
- // otherwise just update caret position without scrolling it into view
- setBidiCaretLocation(null);
- setBidiKeyboardLanguage();
- }
- if (offsetInLine > 0 && offsetInLine < lineLength - 1) {
- int clientAreaEnd = horizontalScrollOffset + getClientArea().width;
- boolean directionChange = bidi.isRightToLeft(offsetInLine - 1) == false && bidi.isRightToLeft(offsetInLine);
- int textWidth = bidi.getTextWidth() + leftMargin;
- // between L2R and R2L segment and second character of R2L segment is
- // left of right border and logical line end is left of right border
- // but visual line end is not left of right border
- if (directionChange &&
- bidi.isRightToLeft(offsetInLine + 1) &&
- bidi.getTextPosition(offsetInLine + 1) + leftMargin < clientAreaEnd &&
- bidi.getTextPosition(lineLength) + leftMargin < clientAreaEnd && textWidth > clientAreaEnd) {
- // make visual line end visible
- scrollHorizontalBar(textWidth - clientAreaEnd);
- }
- }
- }
- gc.dispose();
- }
- else
- if (offsetInLine < lineLength) {
- caretOffset++;
- showCaret();
- }
-}
-/**
* Replaces the selection with the character or insert the character at the
* current caret position if no selection exists.
* If a carriage return was typed replace it with the line break character
@@ -2860,7 +2685,9 @@ int doLineDown() {
if (caretLine < content.getLineCount() - 1) {
caretLine++;
if (isBidi()) {
- caretOffset = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ caretOffset = offsetDirection[0];
+ lastCaretDirection = offsetDirection[1];
}
else {
caretOffset = getOffsetAtMouseLocation(columnX, caretLine);
@@ -2907,7 +2734,9 @@ int doLineUp() {
if (caretLine > 0) {
caretLine--;
if (isBidi()) {
- caretOffset = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ caretOffset = offsetDirection[0];
+ lastCaretDirection = offsetDirection[1];
}
else {
caretOffset = getOffsetAtMouseLocation(columnX, caretLine);
@@ -2929,6 +2758,7 @@ void doMouseLocationChange(int x, int y, boolean select) {
int lineCount = content.getLineCount();
int newCaretOffset;
int newCaretLine;
+ int newCaretDirection = lastCaretDirection;
if (line > lineCount - 1) {
line = lineCount - 1;
@@ -2939,7 +2769,9 @@ void doMouseLocationChange(int x, int y, boolean select) {
return;
}
if (isBidi()) {
- newCaretOffset = getBidiOffsetAtMouseLocation(x, line);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(x, line);
+ newCaretOffset = offsetDirection[0];
+ newCaretDirection = offsetDirection[1];
}
else {
newCaretOffset = getOffsetAtMouseLocation(x, line);
@@ -2953,8 +2785,9 @@ void doMouseLocationChange(int x, int y, boolean select) {
// a different line? If not the autoscroll selection
// could be incorrectly reset. Fixes 1GKM3XS
if (y >= 0 && y < getClientArea().height &&
- (x >= 0 || newCaretLine != content.getLineAtOffset(caretOffset))) {
+ (x >= 0 && x < getClientArea().width || newCaretLine != content.getLineAtOffset(caretOffset))) {
if (newCaretOffset != caretOffset) {
+ lastCaretDirection = newCaretDirection;
caretOffset = newCaretOffset;
if (select) {
doMouseSelection();
@@ -2963,6 +2796,7 @@ void doMouseLocationChange(int x, int y, boolean select) {
}
}
if (select == false) {
+ lastCaretDirection = newCaretDirection;
clearSelection(true);
}
}
@@ -2973,10 +2807,10 @@ void doMouseSelection() {
if (caretOffset <= selection.x ||
(caretOffset > selection.x &&
caretOffset < selection.y && selectionAnchor == selection.x)) {
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
}
else {
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
}
}
/**
@@ -3053,13 +2887,15 @@ void doPageDown(boolean select) {
scrollLines = Math.max(1, scrollLines);
caretLine += scrollLines;
if (isBidi()) {
- caretOffset = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ caretOffset = offsetDirection[0];
+ lastCaretDirection = offsetDirection[1];
}
else {
caretOffset = getOffsetAtMouseLocation(columnX, caretLine);
}
if (select) {
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
}
// scroll one page down or to the bottom
scrollOffset = verticalScrollOffset + scrollLines * getVerticalIncrement();
@@ -3125,7 +2961,9 @@ void doPageUp() {
caretLine -= scrollLines;
if (isBidi()) {
- caretOffset = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ caretOffset = offsetDirection[0];
+ lastCaretDirection = offsetDirection[1];
}
else {
caretOffset = getOffsetAtMouseLocation(columnX, caretLine);
@@ -3152,7 +2990,7 @@ void doSelection(int direction) {
if (selectionAnchor == -1) {
selectionAnchor = selection.x;
}
- if (direction == SWT.LEFT) {
+ if (direction == ST.COLUMN_PREVIOUS) {
if (caretOffset < selection.x) {
// grow selection
redrawEnd = selection.x;
@@ -3281,7 +3119,7 @@ void doSelectionLineDown() {
setMouseWordSelectionAnchor();
// select first and then scroll to reduce flash when key
// repeat scrolls lots of lines
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
// explicitly go to the calculated caret line. may be different
// from content.getLineAtOffset(caretOffset) when in word wrap mode
showCaret(caretLine);
@@ -3316,7 +3154,7 @@ void doSelectionLineUp() {
// explicitly go to the calculated caret line. may be different
// from content.getLineAtOffset(caretOffset) when in word wrap mode
showCaret(caretLine);
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
// save the original horizontal caret position
columnX = oldColumnX;
}
@@ -3401,6 +3239,159 @@ void doSelectionWordPrevious() {
showCaret(caretLine);
}
/**
+ * Moves the caret one character to the left. Do not go to the previous line.
+ * When in a bidi locale and at a R2L character the caret is moved to the
+ * beginning of the R2L segment (visually right) and then one character to the
+ * left (visually left because it's now in a L2R segment).
+ */
+void doVisualPrevious() {
+ int line = content.getLineAtOffset(caretOffset);
+ int lineOffset = content.getOffsetAtLine(line);
+ int offsetInLine = caretOffset - lineOffset;
+
+ if (isBidi()) {
+ // check if caret location is at the visual beginning of the line
+ if (columnX <= XINSET && horizontalScrollOffset == 0) {
+ return;
+ }
+ String lineText = content.getLine(line);
+ int lineLength = lineText.length();
+ GC gc = getGC();
+ StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
+ int visualOffset = -1;
+
+ if (offsetInLine == lineLength) {
+ //logical end of line may not be visual end, setup visualOffset to process as usual
+ visualOffset = bidi.getVisualOffset(offsetInLine - 1);
+ }
+ else
+ if (offsetInLine < lineLength) {
+ visualOffset = bidi.getVisualOffset(offsetInLine);
+ }
+ if (visualOffset != -1) {
+ if (visualOffset > 0) {
+ visualOffset--;
+ offsetInLine = bidi.getLogicalOffset(visualOffset);
+ }
+ else
+ if (visualOffset == 0) {
+ boolean isRightOriented = isMirrored();
+
+ //move to visual line end (i.e., behind L2R character/in front of R2L character at visual 0)
+ if ((isRightOriented && bidi.isRightToLeft(offsetInLine) == false) ||
+ (isRightOriented == false && bidi.isRightToLeft(offsetInLine))) {
+ offsetInLine++;
+ }
+
+ if (offsetInLine > 0 && offsetInLine < lineLength) {
+ if (isRightOriented) {
+ boolean rightToLeftStart = bidi.isRightToLeft(offsetInLine) && bidi.isRightToLeft(offsetInLine - 1) == false;
+ if (rightToLeftStart) {
+ //moving from LtoR segment to RtoL segment
+ lastCaretDirection = ST.COLUMN_NEXT;
+ }
+ }
+ else {
+ boolean leftToRightStart = bidi.isRightToLeft(offsetInLine) == false && bidi.isRightToLeft(offsetInLine - 1);
+ if (bidi.isLatinNumber(offsetInLine) && bidi.isRightToLeftInput(offsetInLine - 1)) {
+ //moving from LtoR segment to latin number
+ lastCaretDirection = ST.COLUMN_PREVIOUS;
+ }
+ else
+ if (leftToRightStart) {
+ //moving from RtoL segment to LtoR segment
+ lastCaretDirection = ST.COLUMN_NEXT;
+ }
+ }
+ }
+ }
+ caretOffset = lineOffset + offsetInLine;
+ showCaret();
+ }
+ if (bidi.getTextPosition(offsetInLine, ST.COLUMN_NEXT) == XINSET) {
+ //scroll to origin if caret is at origin
+ scrollHorizontalBar(-horizontalScrollOffset);
+ }
+ gc.dispose();
+ }
+ else
+ if (offsetInLine > 0) {
+ caretOffset--;
+ showCaret();
+ }
+}
+/**
+ * Moves the caret one character to the right. Do not go to the next line.
+ * When in a bidi locale and at a R2L character the caret is moved to the
+ * end of the R2L segment (visually left) and then one character to the
+ * right (visually right because it's now in a L2R segment).
+ */
+void doVisualNext() {
+ int line = content.getLineAtOffset(caretOffset);
+ int lineOffset = content.getOffsetAtLine(line);
+ int offsetInLine = caretOffset - lineOffset;
+ String lineText = content.getLine(line);
+ int lineLength = lineText.length();
+
+ if (isBidi()) {
+ GC gc = getGC();
+ StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
+ // Fixes bug 39032
+ int lineEndPixel = Math.max(bidi.getTextWidth(), XINSET);
+
+ // check if caret location is at the visual end of the line (can't use
+ // caret location here since it's location is dependent on current keyboard
+ // language direction)
+ if (bidi.getTextPosition(offsetInLine, lastCaretDirection) == lineEndPixel) {
+ gc.dispose();
+ return;
+ }
+ int visualOffset = -1;
+ if (offsetInLine == lineLength) {
+ //logical end of line may not be visual end, setup visualOffset to process as usual
+ visualOffset = bidi.getVisualOffset(offsetInLine - 1);
+ }
+ else
+ if (offsetInLine < lineLength) {
+ visualOffset = bidi.getVisualOffset(offsetInLine);
+ }
+ if (visualOffset != -1) {
+ visualOffset++;
+ offsetInLine = bidi.getLogicalOffset(visualOffset);
+ if (offsetInLine > 0 && offsetInLine < lineLength) {
+ boolean isRightOriented = isMirrored();
+ if (isRightOriented) {
+ boolean leftToRightStart = bidi.isRightToLeft(offsetInLine) == false && bidi.isRightToLeft(offsetInLine - 1);
+ if (leftToRightStart) {
+ //moving from RtoL segment to LtoR segment
+ lastCaretDirection = ST.COLUMN_PREVIOUS;
+ }
+ }
+ else {
+ boolean rightToLeftStart = bidi.isRightToLeft(offsetInLine) && bidi.isRightToLeft(offsetInLine - 1) == false;
+ if (bidi.isRightToLeftInput(offsetInLine) && bidi.isLatinNumber(offsetInLine - 1)) {
+ //moving from latin number to RtoL segment
+ lastCaretDirection = ST.COLUMN_NEXT;
+ }
+ else
+ if (rightToLeftStart) {
+ //moving from LtoR segment to RtoL segment
+ lastCaretDirection = ST.COLUMN_PREVIOUS;
+ }
+ }
+ }
+ caretOffset = lineOffset + offsetInLine;
+ showCaret();
+ }
+ gc.dispose();
+ }
+ else
+ if (offsetInLine < lineLength) {
+ caretOffset++;
+ showCaret();
+ }
+}
+/**
* Moves the caret to the end of the next word.
* If a selection exists, move the caret to the end of the selection
* and remove the selection.
@@ -3511,30 +3502,28 @@ public boolean getBidiColoring() {
return bidiColoring;
}
/**
- * Returns the offset at the specified x location in the specified line.
- * Also sets the caret direction so that the caret is placed correctly
- * depending on whether the mouse location is in a R2L or L2R segment.
+ * Returns the offset and caret direction at the specified x location
+ * in the specified line.
+ * The returned caret direction needs to be set in order to place the
+ * caret correctly based on whether the mouse location is in a R2L
+ * or L2R segment.
* <p>
*
* @param x x location of the mouse location
* @param line line the mouse location is in
- * @return the offset at the specified x location in the specified line,
- * relative to the beginning of the document
+ * @return int array, first element is the offset at the specified x
+ * location in the specified line, relative to the beginning of the
+ * document. second element is the caret direction.
*/
-int getBidiOffsetAtMouseLocation(int x, int line) {
+int[] getBidiOffsetAtMouseLocation(int x, int line) {
String lineText = content.getLine(line);
int lineOffset = content.getOffsetAtLine(line);
GC gc = getGC();
StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
- int[] values;
- int offsetInLine;
- x += horizontalScrollOffset;
- values = bidi.getCaretOffsetAndDirectionAtX(x - leftMargin);
- offsetInLine = values[0];
- lastCaretDirection = values[1];
- gc.dispose();
+ int[] values = bidi.getCaretOffsetAndDirectionAtX(x + horizontalScrollOffset - leftMargin);
- return lineOffset + offsetInLine;
+ gc.dispose();
+ return new int[] {lineOffset + values[0], values[1]};
}
/**
* Returns the x position of the character at the specified offset
@@ -5561,50 +5550,50 @@ public void invokeAction(int action) {
break;
case ST.SELECT_LINE_START:
doLineStart();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_LINE_END:
doLineEnd();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
case ST.SELECT_COLUMN_PREVIOUS:
doSelectionCursorPrevious();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_COLUMN_NEXT:
doSelectionCursorNext();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
case ST.SELECT_PAGE_UP:
doSelectionPageUp();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_PAGE_DOWN:
doSelectionPageDown();
break;
case ST.SELECT_WORD_PREVIOUS:
doSelectionWordPrevious();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_WORD_NEXT:
doSelectionWordNext();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
case ST.SELECT_TEXT_START:
doContentStart();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_TEXT_END:
doContentEnd();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
case ST.SELECT_WINDOW_START:
doPageStart();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_WINDOW_END:
doPageEnd();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
// Modification
case ST.CUT:
@@ -5658,6 +5647,16 @@ boolean isLineDelimiter(int offset) {
return offsetInLine > content.getLine(line).length();
}
/**
+ * Returns whether the widget is mirrored (right oriented/right to left
+ * writing order).
+ *
+ * @return isMirrored true=the widget is right oriented, false=the widget
+ * is left oriented
+ */
+boolean isMirrored() {
+ return isMirrored;
+}
+/**
* Returns whether or not the given lines are visible.
* <p>
*
@@ -5894,6 +5893,7 @@ void performPaint(GC gc,int startLine,int startY, int renderHeight) {
Color foreground = getForeground();
int lineCount = content.getLineCount();
int paintY = 0;
+ int gcStyle = isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT;
if (isSingleLine()) {
lineCount = 1;
@@ -5902,7 +5902,7 @@ void performPaint(GC gc,int startLine,int startY, int renderHeight) {
}
}
Image lineBuffer = new Image(getDisplay(), clientArea.width, renderHeight);
- GC lineGC = new GC(lineBuffer);
+ GC lineGC = new GC(lineBuffer, gcStyle);
lineGC.setFont(getFont());
renderer.setCurrentFontStyle(SWT.NORMAL);
@@ -6056,7 +6056,12 @@ public void redraw() {
* @see Control#update
*/
public void redraw(int x, int y, int width, int height, boolean all) {
- super.redraw(x, y, width, height, all);
+ if (isBidi()) {
+ // workaround for bug 4776
+ super.redraw(x, y, width + 1, height, all);
+ } else {
+ super.redraw(x, y, width, height, all);
+ }
if (height > 0) {
int lineCount = content.getLineCount();
int startLine = (getTopPixel() + y) / lineHeight;
@@ -6092,9 +6097,9 @@ void redrawBidiLines(int firstLine, int offsetInFirstLine, int lastLine, int end
String line = content.getLine(firstLine);
GC gc = getGC();
StyledTextBidi bidi = getStyledTextBidi(line, firstLineOffset, gc);
-
+
bidi.redrawRange(
- this, offsetInFirstLine,
+ this, offsetInFirstLine,
Math.min(line.length(), endOffset) - offsetInFirstLine,
leftMargin - horizontalScrollOffset, redrawY + topMargin, lineHeight);
// redraw line break marker (either space or full client area width)
@@ -6903,6 +6908,7 @@ void setBidiCaretLocation(StyledTextBidi bidi, int caretLine) {
int lineStartOffset = content.getOffsetAtLine(caretLine);
int offsetInLine = caretOffset - lineStartOffset;
GC gc = null;
+ boolean isRightOriented = isMirrored();
if (bidi == null) {
gc = getGC();
@@ -6913,7 +6919,10 @@ void setBidiCaretLocation(StyledTextBidi bidi, int caretLine) {
} else {
columnX = bidi.getTextPosition(offsetInLine, lastCaretDirection) + leftMargin - horizontalScrollOffset;
}
- if (StyledTextBidi.getKeyboardLanguageDirection() == SWT.RIGHT) {
+ // take the width of the caret into account
+ int keyboardDirection = StyledTextBidi.getKeyboardLanguageDirection();
+ if ((keyboardDirection == SWT.RIGHT && isRightOriented == false) ||
+ (keyboardDirection == SWT.LEFT && isRightOriented)){
columnX -= (getCaretWidth() - 1);
}
if (caret != null) {
@@ -7407,6 +7416,42 @@ void setMouseWordSelectionAnchor() {
}
}
/**
+ * Sets the widget orientation (writing order). Text will be right aligned
+ * for right to left writing order.
+ * <p>
+ *
+ * @param newOrientation one of SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
+ */
+void setOrientation(int orientation) {
+ if ((orientation & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT)) == 0) {
+ return;
+ }
+ if ((orientation & SWT.RIGHT_TO_LEFT) != 0 && (orientation & SWT.LEFT_TO_RIGHT) != 0) {
+ return;
+ }
+ if ((orientation & SWT.RIGHT_TO_LEFT) != 0 && isMirrored()) {
+ return;
+ }
+ if ((orientation & SWT.LEFT_TO_RIGHT) != 0 && isMirrored() == false) {
+ return;
+ }
+ if (StyledTextBidi.setOrientation(this, orientation) == false) {
+ return;
+ }
+ isMirrored = (orientation & SWT.RIGHT_TO_LEFT) != 0;
+ isBidi = StyledTextBidi.isBidiPlatform() || isMirrored();
+ initializeRenderer();
+ if (isBidi()) {
+ caretDirection = SWT.NULL;
+ createCaretBitmaps();
+ setBidiCaretDirection();
+ }
+ setCaretLocation();
+ keyActionMap.clear();
+ createKeyBindings();
+ super.redraw();
+}
+/**
* Adjusts the maximum and the page size of the scroll bars to
* reflect content width/length changes.
*/
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
index c443b65772..e097698ded 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
@@ -31,6 +31,7 @@ class StyledTextBidi {
private int[] dx; // distance between character cells. in visual order. renderPositions[iV + 1] = renderPositions[iV] + dx[iV]
private byte[] classBuffer; // the character types in logical order, see BidiUtil for the possible types
private char[] glyphBuffer; // the glyphs in visual order as they will be rendered on screen.
+ private boolean isRightOriented;// writing orientation
/**
* This class describes a text segment of a single direction, either
@@ -106,6 +107,7 @@ class StyledTextBidi {
*/
public StyledTextBidi(GC gc, int tabWidth, String text, StyleRange[] ranges, Font boldFont, int[] offsets) {
int length = text.length();
+ isRightOriented = (gc.getStyle() & SWT.MIRRORED) != 0;
this.gc = gc;
bidiSegments = offsets;
@@ -155,6 +157,7 @@ public StyledTextBidi(GC gc, int tabWidth, String text, StyleRange[] ranges, Fon
*/
public StyledTextBidi(GC gc, String text, int[] offsets) {
int length = text.length();
+ isRightOriented = (gc.getStyle() & SWT.MIRRORED) != 0;
this.gc = gc;
bidiSegments = offsets;
order = new int[length];
@@ -381,8 +384,6 @@ void fillBackground(int logicalStart, int length, int xOffset, int yOffset, int
*/
int[] getCaretOffsetAndDirectionAtX(int x) {
int lineLength = getTextLength();
- int offset;
- int direction;
if (lineLength == 0) {
return new int[] {0, 0};
@@ -395,9 +396,16 @@ int[] getCaretOffsetAndDirectionAtX(int x) {
int visualOffset = getVisualOffsetAtX(x);
// figure out if the character was clicked on the right or left
int halfway = renderPositions[visualOffset] + dx[visualOffset] / 2;
- boolean visualLeft = (x <= halfway);
- offset = getLogicalOffset(visualOffset);
+ boolean visualLeft;
+ int offset = getLogicalOffset(visualOffset);
+ int direction;
+ if (isRightOriented) {
+ visualLeft = (x > halfway);
+ }
+ else {
+ visualLeft = (x <= halfway);
+ }
if (isRightToLeft(offset)) {
if (visualLeft) {
if (isLigated(gc)) {
@@ -413,23 +421,23 @@ int[] getCaretOffsetAndDirectionAtX(int x) {
}
else {
// position the caret as if the caret is to the left
- // of the character at location x and the PREVIOUS key is
- // pressed
- direction = ST.COLUMN_PREVIOUS;
+ // of the character at location x and the PREVIOUS
+ // key is pressed
+ direction = ST.COLUMN_PREVIOUS;
}
}
else {
if (visualLeft) {
- // position the caret as if the caret is to the right
- // of the character at location x and the PREVIOUS key is
- // pressed
- direction = ST.COLUMN_PREVIOUS;
+ // position the caret as if the caret is to the left
+ // of the character at location x and the PREVIOUS
+ // key is pressed
+ direction = ST.COLUMN_PREVIOUS;
}
else {
- // position the caret as if the caret is to the left
+ offset++;
+ // position the caret as if the caret is to the right
// of the character at location x and the NEXT key is
// pressed
- offset++;
direction = ST.COLUMN_NEXT;
}
}
@@ -457,6 +465,7 @@ private Vector getDirectionRuns(int logicalStart, int length) {
int logicalEnd = logicalStart + length - 1;
int segmentLogicalStart = logicalStart;
int segmentLogicalEnd = segmentLogicalStart;
+ int checkSide = isRightOriented ? -1 : 1;
if (logicalEnd < getTextLength()) {
int bidiSegmentIndex = 0;
@@ -481,8 +490,9 @@ private Vector getDirectionRuns(int logicalStart, int length) {
// is no direction change.
// If our segment type is LtoR, the order index for the next character will be one more if there is
// no direction change.
- ((isRightToLeftSegment && (order[segmentLogicalEnd + 1]+ 1 == order[segmentLogicalEnd])) ||
- (isRightToLeftSegment == false && (order[segmentLogicalEnd + 1]- 1 == order[segmentLogicalEnd]))) &&
+ (order[segmentLogicalEnd + 1] == order[segmentLogicalEnd] || // treat ligatures as part of the direction segment
+ (isRightToLeftSegment && (order[segmentLogicalEnd + 1] + checkSide == order[segmentLogicalEnd])) ||
+ (isRightToLeftSegment == false && (order[segmentLogicalEnd + 1] - checkSide == order[segmentLogicalEnd]))) &&
segmentLogicalEnd + 1 < bidiSegmentEnd) {
segmentLogicalEnd++;
}
@@ -555,7 +565,7 @@ int getLigatureStartOffset(int offset) {
* @param visualOffset the visual offset
* @return the logical offset of the character at <code>visualOffset</code>.
*/
-private int getLogicalOffset(int visualOffset) {
+int getLogicalOffset(int visualOffset) {
int logicalOffset = 0;
while (logicalOffset < order.length && order[logicalOffset] != visualOffset) {
@@ -697,26 +707,29 @@ int getTextPosition(int logicalOffset, int direction) {
if (getTextLength() == 0 || logicalOffset < 0) {
return StyledText.XINSET;
}
+
+ boolean isRightToLeft = isRightToLeft(logicalOffset);
// at or past end of line?
if (logicalOffset >= order.length) {
logicalOffset = Math.min(logicalOffset, order.length - 1);
+ isRightToLeft = isRightToLeft(logicalOffset);
int visualOffset = order[logicalOffset];
- if (isRightToLeft(logicalOffset)) {
- caretX = renderPositions[visualOffset];
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
+ caretX = renderPositions[visualOffset] + dx[visualOffset];
}
else {
- caretX = renderPositions[visualOffset] + dx[visualOffset];
+ caretX = renderPositions[visualOffset];
}
}
else
// at beginning of line?
if (logicalOffset == 0) {
int visualOffset = order[logicalOffset];
- if (isRightToLeft(logicalOffset)) {
- caretX = renderPositions[visualOffset] + dx[visualOffset];
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
+ caretX = renderPositions[visualOffset];
}
else {
- caretX = renderPositions[visualOffset];
+ caretX = renderPositions[visualOffset] + dx[visualOffset];
}
}
else
@@ -733,14 +746,12 @@ int getTextPosition(int logicalOffset, int direction) {
// do not consider local numbers as R2L here, to determine position,
// because local numbers are navigated L2R and we want the caret to
// be to the right of the number. see 1GK9API
- if (isRightToLeft(logicalOffset - 1)) {
- // moving from RtoL to LtoR
- caretX = renderPositions[visualOffset];
- }
- else {
- // moving from LtoR to RtoL
+ isRightToLeft = isRightToLeft(logicalOffset - 1);
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
caretX = renderPositions[visualOffset] + dx[visualOffset];
- }
+ } else {
+ caretX = renderPositions[visualOffset];
+ }
}
else
// consider local numbers as R2L in determining direction boundaries.
@@ -752,23 +763,22 @@ int getTextPosition(int logicalOffset, int direction) {
// consider local numbers as R2L here, to determine position, because
// we want to stay in L2R segment and place the cursor to the left of
// first L2R character. see 1GK9API
- if (isRightToLeftInput(logicalOffset - 1)) {
- // moving from LtoR to RtoL
+ isRightToLeft = isRightToLeft(logicalOffset - 1);
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
+ caretX = renderPositions[visualOffset] + dx[visualOffset];
+ } else {
+ caretX = renderPositions[visualOffset];
+ }
+ }
+ else {
+ int visualOffset = order[logicalOffset];
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
caretX = renderPositions[visualOffset];
}
else {
- // moving from RtoL to LtoR
caretX = renderPositions[visualOffset] + dx[visualOffset];
}
}
- else
- if (isRightToLeft(logicalOffset)) {
- int visualOffset = order[logicalOffset];
- caretX = renderPositions[visualOffset] + dx[visualOffset];
- }
- else {
- caretX = renderPositions[order[logicalOffset]];
- }
return caretX;
}
/**
@@ -786,6 +796,17 @@ int getTextWidth() {
return width;
}
/**
+ * Returns the visual offset of the character at the specified
+ * logical offset.
+ * <p>
+ *
+ * @param logicalOffset the logical offset
+ * @return the visual offset of the character at <code>logicalOffset</code>.
+ */
+int getVisualOffset(int logicalOffset) {
+ return order[logicalOffset];
+}
+/**
* Returns the visual offset of the character at the specified x
* location.
* <p>
@@ -820,6 +841,23 @@ private int getVisualOffsetAtX(int x) {
return high;
}
/**
+ * Returns if the character at the given offset is a latin number.
+ * <p>
+ *
+ * @param logicalIndex the index of the character
+ * @return
+ * true=the character at the specified index is a latin number
+ * false=the character at the specified index is not a latin number
+ */
+boolean isLatinNumber(int logicalIndex) {
+ boolean isLatinNumber = false;
+
+ if (logicalIndex >= 0 && logicalIndex < classBuffer.length) {
+ isLatinNumber = classBuffer[logicalIndex] == BidiUtil.CLASS_LATINNUMBER;
+ }
+ return isLatinNumber;
+}
+/**
* Returns if the character at the given offset is a local number.
* <p>
*
@@ -968,7 +1006,6 @@ private void prepareFontStyledText(String textline, int logicalStart, int length
*/
void redrawRange(Control parent, int logicalStart, int length, int xOffset, int yOffset, int height) {
Enumeration directionRuns;
-
if (logicalStart < 0 || logicalStart + length > getTextLength()) {
return;
}
@@ -976,8 +1013,22 @@ void redrawRange(Control parent, int logicalStart, int length, int xOffset, int
while (directionRuns.hasMoreElements()) {
DirectionRun run = (DirectionRun) directionRuns.nextElement();
int startX = run.getRenderStartX();
+ int endX = run.getRenderStopX();
+ int runStartOffset = run.getVisualStart();
+ int runEndOffset = run.getVisualEnd();
- parent.redraw(xOffset + startX, yOffset, run.getRenderStopX() - startX, height, true);
+ // expand the redraw area by one character in both directions.
+ // fixes bug 40019
+ if (runStartOffset > 0) {
+ startX = renderPositions[runStartOffset - 1];
+ }
+ else {
+ startX = 0;
+ }
+ if (runEndOffset < renderPositions.length - 1) {
+ endX = renderPositions[runEndOffset + 1] + dx[runEndOffset + 1];
+ }
+ parent.redraw(xOffset + startX, yOffset, endX - startX, height, true);
}
}
/**
@@ -1011,6 +1062,18 @@ void setKeyboardLanguage(int logicalIndex) {
BidiUtil.setKeyboardLanguage(language);
}
/**
+ * Sets the orientation (writing order) of the specified control. Text will
+ * be right aligned for right to left writing order.
+ * <p>
+ *
+ * @param orientation one of SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
+ * @return true if the orientation was changed, false if the orientation
+ * could not be changed
+ */
+static boolean setOrientation(Control control, int orientation) {
+ return BidiUtil.setOrientation(control.handle, orientation);
+}
+/**
* Returns a string representation of the receiver.
* <p>
*
@@ -1059,4 +1122,4 @@ public String toString() {
buf.append("}}");
return buf.toString();
}
-}
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java
index 8055dc73fb..714a1b80ac 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java
@@ -298,12 +298,17 @@ void keyDown(Event event) {
case SWT.ARROW_DOWN :
setRowColumn(row + 1, column, true);
break;
- case SWT.ARROW_LEFT :
- setRowColumn(row, column - 1, true);
- break;
- case SWT.ARROW_RIGHT :
- setRowColumn(row, column + 1, true);
- break;
+ case SWT.ARROW_LEFT :
+ case SWT.ARROW_RIGHT :
+ {
+ int leadKey = (getStyle() & SWT.RIGHT_TO_LEFT) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT;
+ if (event.keyCode == leadKey) {
+ setRowColumn(row, column - 1, true);
+ } else {
+ setRowColumn(row, column + 1, true);
+ }
+ break;
+ }
case SWT.HOME :
setRowColumn(0, column, true);
break;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTree.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTree.java
index 4c8f74cd0f..f118229914 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTree.java
@@ -91,7 +91,7 @@ public class TableTree extends Composite {
* @see #getStyle
*/
public TableTree(Composite parent, int style) {
- super(parent, SWT.NONE);
+ super(parent, checkStyle (style));
table = new Table(this, style);
Listener tableListener = new Listener() {
public void handleEvent(Event e) {
@@ -196,7 +196,12 @@ public void addTreeListener(TreeListener listener) {
TypedListener typedListener = new TypedListener (listener);
addListener (SWT.Expand, typedListener);
addListener (SWT.Collapse, typedListener);
-}
+}
+private static int checkStyle (int style) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ style = style & mask;
+ return style;
+}
public Point computeSize (int wHint, int hHint, boolean changed) {
checkWidget();
return table.computeSize (wHint, hHint, changed);
@@ -502,7 +507,8 @@ void onKeyDown (Event e) {
TableTreeItem item = selection[0];
int type = 0;
if (e.keyCode == SWT.ARROW_RIGHT || e.keyCode == SWT.ARROW_LEFT) {
- if (e.keyCode == SWT.ARROW_RIGHT) {
+ int trailKey = (getStyle() & SWT.MIRRORED) != 0 ? SWT.ARROW_LEFT : SWT.ARROW_RIGHT;
+ if (e.keyCode == trailKey) {
if (item.getItemCount() == 0) return;
if (item.getExpanded()) {
TableTreeItem newSelection = item.getItems()[0];
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ViewForm.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ViewForm.java
index 6acbd1cb1a..b9583196cb 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ViewForm.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ViewForm.java
@@ -147,7 +147,7 @@ public ViewForm(Composite parent, int style) {
* @private
*/
private static int checkStyle (int style) {
- int mask = SWT.FLAT;
+ int mask = SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
return style & mask | SWT.NO_REDRAW_RESIZE;
}
public Point computeSize(int wHint, int hHint, boolean changed) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/swt.c b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/swt.c
index b3f796eb33..81f10b0a56 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/swt.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/swt.c
@@ -74,6 +74,7 @@
#define NO_GetKeyNameTextA
#define NO_GetKeyNameTextW
#define NO_GetLastActivePopup
+#define NO_GetLayout
#define NO_GetLocaleInfoA
#define NO_GetMenu
#define NO_GetMenuDefaultItem
@@ -2288,6 +2289,32 @@ JNIEXPORT jint JNICALL OS_NATIVE(GetLastActivePopup)
}
#endif /* NO_GetLastActivePopup */
+#ifndef NO_GetLayout
+JNIEXPORT jint JNICALL OS_NATIVE(GetLayout)
+ (JNIEnv *env, jclass that, jint arg0)
+{
+ jint rc;
+
+ DEBUG_CALL("GetLayout\n")
+
+ //rc = (jint)GetLayout((HDC)arg0);
+ {
+ /*
+ * GetLayout is a Win2000 and Win98 specific call
+ * If you link it into swt.dll a system modal entry point not found dialog will
+ * appear as soon as swt.dll is loaded. Here we check for the entry point and
+ * only do the call if it exists.
+ */
+ HMODULE hm;
+ FARPROC fp;
+ if ((hm=GetModuleHandle("gdi32.dll")) && (fp=GetProcAddress(hm, "GetLayout"))) {
+ rc = (jint)(fp)((HDC)arg0);
+ }
+ }
+ return rc;
+}
+#endif
+
#ifndef NO_GetLastError
JNIEXPORT jint JNICALL OS_NATIVE(GetLastError)
(JNIEnv *env, jclass that)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
index 150032ca0d..5680bcedcd 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
@@ -333,6 +333,8 @@ public class OS {
public static final int EM_SETREADONLY = 0xcf;
public static final int EM_SETSEL = 0xb1;
public static final int EM_SETTABSTOPS = 0xcb;
+ public static final int EN_ALIGN_LTR_EC = 0x0700;
+ public static final int EN_ALIGN_RTL_EC = 0x0701;
public static final int EN_CHANGE = 0x300;
public static final int ERROR_NO_MORE_ITEMS = 0x103;
public static final int ESB_DISABLE_BOTH = 0x3;
@@ -454,6 +456,7 @@ public class OS {
public static final int KEY_NOTIFY = 0x10;
public static final int KEY_QUERY_VALUE = 0x1;
public static final int KEY_READ = 0x20019;
+ public static final int LAYOUT_RTL = 0x1;
public static final int LBN_DBLCLK = 0x2;
public static final int LBN_SELCHANGE = 0x1;
public static final int LBS_EXTENDEDSEL = 0x800;
@@ -962,6 +965,7 @@ public class OS {
public static final int TRANSPARENT = 0x1;
public static final int TTF_IDISHWND = 0x1;
public static final int TTF_SUBCLASS = 0x10;
+ public static final int TTF_RTLREADING = 0x4;
public static final int TTM_ADDTOOL = IsUnicode ? 0x432 : 0x404;
public static final int TTM_DELTOOL = IsUnicode ? 0x433 : 0x405;
public static final int TTM_SETMAXTIPWIDTH = 0x418;
@@ -1126,6 +1130,7 @@ public class OS {
public static final int WM_COMMAND = 0x111;
public static final int WM_CONTEXTMENU = 0x7b;
public static final int WM_COPY = 0x301;
+ public static final int WM_CREATE = 0x0001;
public static final int WM_CTLCOLORBTN = 0x135;
public static final int WM_CTLCOLORDLG = 0x136;
public static final int WM_CTLCOLOREDIT = 0x133;
@@ -1178,6 +1183,7 @@ public class OS {
public static final int WM_NULL = 0x0;
public static final int WM_PAINT = 0xf;
public static final int WM_PALETTECHANGED = 0x311;
+ public static final int WM_PARENTNOTIFY = 0x0210;
public static final int WM_PASTE = 0x302;
public static final int WM_PRINTCLIENT = 0x0318;
public static final int WM_QUERYENDSESSION = 0x11;
@@ -1203,6 +1209,7 @@ public class OS {
public static final int WM_UNDO = 0x304;
public static final int WM_USER = 0x400;
public static final int WM_VSCROLL = 0x115;
+ public static final int WM_WINDOWPOSCHANGED = 0x47;
public static final int WM_WINDOWPOSCHANGING = 0x46;
public static final int WS_BORDER = 0x800000;
public static final int WS_CAPTION = 0xc00000;
@@ -1213,7 +1220,10 @@ public class OS {
public static final int WS_EX_CLIENTEDGE = 0x200;
public static final int WS_EX_DLGMODALFRAME = 0x1;
public static final int WS_EX_LAYOUTRTL = 0x00400000;
+ public static final int WS_EX_LEFTSCROLLBAR = 0x00004000;
public static final int WS_EX_NOINHERITLAYOUT = 0x00100000;
+ public static final int WS_EX_RIGHT = 0x00001000;
+ public static final int WS_EX_RTLREADING = 0x00002000;
public static final int WS_EX_STATICEDGE = 0x20000;
public static final int WS_EX_TOOLWINDOW = 0x80;
public static final int WS_EX_TOPMOST = 0x8;
@@ -2082,6 +2092,7 @@ public static final native int GetKeyNameTextW(int lParam, char [] lpString, int
public static final native int GetKeyNameTextA(int lParam, byte [] lpString, int nSize);
public static final native int GetLastActivePopup (int hWnd);
public static final native int GetLastError ();
+public static final native int GetLayout (int hdc);
/* returns the instance handle to the swt library */
public static final native int GetLibraryHandle ();
public static final native int GetLocaleInfoW (int Locale, int LCType, char [] lpLCData, int cchData);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Printing/motif/org/eclipse/swt/printing/Printer.java b/bundles/org.eclipse.swt/Eclipse SWT Printing/motif/org/eclipse/swt/printing/Printer.java
index c5c894141d..de6b5a52eb 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Printing/motif/org/eclipse/swt/printing/Printer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Printing/motif/org/eclipse/swt/printing/Printer.java
@@ -365,6 +365,10 @@ public int internal_new_GC(GCData data) {
int xGC = OS.XCreateGC(xDisplay, xDrawable, 0, null);
if (xGC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ }
data.device = this;
data.display = xDisplay;
data.drawable = xDrawable;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Printing/win32/org/eclipse/swt/printing/Printer.java b/bundles/org.eclipse.swt/Eclipse SWT Printing/win32/org/eclipse/swt/printing/Printer.java
index dbc99a5ebc..62df71cda6 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Printing/win32/org/eclipse/swt/printing/Printer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Printing/win32/org/eclipse/swt/printing/Printer.java
@@ -228,6 +228,11 @@ public int internal_new_GC(GCData data) {
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
if (data != null) {
if (isGCCreated) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ data.layout = -1;
+ }
data.device = this;
data.hFont = OS.GetCurrentObject(handle, OS.OBJ_FONT);
isGCCreated = true;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GC.java
index 4eaa19098c..9b46ee4aea 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GC.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GC.java
@@ -66,8 +66,7 @@ public GC(Drawable drawable) {
this(drawable, 0);
}
-//3.0 API
-GC(Drawable drawable, int style) {
+public GC(Drawable drawable, int style) {
if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
GCData data = new GCData();
data.style = checkStyle(style);
@@ -1418,11 +1417,10 @@ public int getLineWidth() {
return data.lineWidth;
}
-//3.0 API
-//public int getStyle () {
-// if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
-// return data.style;
-//}
+public int getStyle () {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ return data.style;
+}
/**
* Returns <code>true</code> if this GC is drawing in the mode
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Display.java
index 9ef44f6b00..e3a1ac4581 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Display.java
@@ -1636,41 +1636,211 @@ void postEvent (Event event) {
eventQueue [index] = event;
}
-//3.0 API
-//public Rectangle map (Control from, Control to, Rectangle rectangle) {
-// checkDevice ();
-// if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
-// return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
-//}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param point to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, Point point) {
+ checkDevice ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, point.x, point.y);
+}
-//3.0 API
-//public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
-// checkDevice ();
-// if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
-// if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
-// Rectangle rectangle = new Rectangle (x, y, width, height);
-// if (from != null) {
-// Rect rect = new Rect ();
-// OS.GetControlBounds (from.handle, rect);
-// rectangle.x += rect.left;
-// rectangle.y += rect.top;
-// int window = OS.GetControlOwner (from.handle);
-// OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
-// rectangle.x += rect.left;
-// rectangle.y += rect.top;
-// }
-// if (to != null) {
-// Rect rect = new Rect ();
-// OS.GetControlBounds (to.handle, rect);
-// rectangle.x -= rect.left;
-// rectangle.y -= rect.top;
-// int window = OS.GetControlOwner (to.handle);
-// OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
-// rectangle.x -= rect.left;
-// rectangle.y -= rect.top;
-// }
-// return rectangle;
-//}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, int x, int y) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Point point = new Point (x, y);
+ if (from != null) {
+ Rect rect = new Rect ();
+ OS.GetControlBounds (from.handle, rect);
+ point.x += rect.left;
+ point.y += rect.top;
+ int window = OS.GetControlOwner (from.handle);
+ OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
+ point.x += rect.left;
+ point.y += rect.top;
+ }
+ if (to != null) {
+ Rect rect = new Rect ();
+ OS.GetControlBounds (to.handle, rect);
+ point.x -= rect.left;
+ point.y -= rect.top;
+ int window = OS.GetControlOwner (to.handle);
+ OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
+ point.x -= rect.left;
+ point.y -= rect.top;
+ }
+ return point;
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param rectangle to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, Rectangle rectangle) {
+ checkDevice ();
+ if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @param int width coordinates to be mapped
+ * @param int heigth coordinates to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Rectangle rectangle = new Rectangle (x, y, width, height);
+ if (from != null) {
+ Rect rect = new Rect ();
+ OS.GetControlBounds (from.handle, rect);
+ rectangle.x += rect.left;
+ rectangle.y += rect.top;
+ int window = OS.GetControlOwner (from.handle);
+ OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
+ rectangle.x += rect.left;
+ rectangle.y += rect.top;
+ }
+ if (to != null) {
+ Rect rect = new Rect ();
+ OS.GetControlBounds (to.handle, rect);
+ rectangle.x -= rect.left;
+ rectangle.y -= rect.top;
+ int window = OS.GetControlOwner (to.handle);
+ OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
+ rectangle.x -= rect.left;
+ rectangle.y -= rect.top;
+ }
+ return rectangle;
+}
int menuProc (int nextHandler, int theEvent, int userData) {
if (userData != 0) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
index e997c3c417..e9f6986ef7 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
@@ -732,17 +732,10 @@ public class SWT {
* <p><b>Used By:</b><ul>
* <li><code>Control</code></li>
* <li><code>Menu</code></li>
+ * <li><code>GC</code></li>
* </ul></p>
*
- * <p>
- * <b>NOTE:</b> This API element is part of an interim API that is still under
- * development and is expected to change significantly before reaching stability.
- * It is being made available at this early stage to solicit feedback from
- * pioneering adopters on the understanding that any code that uses this API
- * will almost certainly be broken (repeatedly) as the API evolves.
- * </p>
- *
- * @since 2.1
+ * @since 2.1.2
*/
public static final int LEFT_TO_RIGHT = 1 << 25;
@@ -758,17 +751,10 @@ public class SWT {
* <p><b>Used By:</b><ul>
* <li><code>Control</code></li>
* <li><code>Menu</code></li>
+ * <li><code>GC</code></li>
* </ul></p>
*
- * <p>
- * <b>NOTE:</b> This API element is part of an interim API that is still under
- * development and is expected to change significantly before reaching stability.
- * It is being made available at this early stage to solicit feedback from
- * pioneering adopters on the understanding that any code that uses this API
- * will almost certainly be broken (repeatedly) as the API evolves.
- * </p>
- *
- * @since 2.1
+ * @since 2.1.2
*/
public static final int RIGHT_TO_LEFT = 1 << 26;
@@ -779,15 +765,7 @@ public class SWT {
* <li><code>Menu</code></li>
* </ul></p>
*
- * <p>
- * <b>NOTE:</b> This API element is part of an interim API that is still under
- * development and is expected to change significantly before reaching stability.
- * It is being made available at this early stage to solicit feedback from
- * pioneering adopters on the understanding that any code that uses this API
- * will almost certainly be broken (repeatedly) as the API evolves.
- * </p>
- *
- * @since 2.1
+ * @since 2.1.2
*/
public static final int MIRRORED = 1 << 27;
@@ -830,7 +808,7 @@ public class SWT {
public static final int BOTTOM = DOWN;
/**
- * Style constant for align left behavior (value is 1&lt;&lt;14).
+ * Style constant for leading alignment (value is 1&lt;&lt;14).
* <p><b>Used By:</b><ul>
* <li><code>Button</code></li>
* <li><code>Label</code></li>
@@ -838,11 +816,21 @@ public class SWT {
* <li><code>Tracker</code></li>
* <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
* </ul></p>
+ *
+ * @since 2.1.2
+ */
+ public static final int LEAD = 1 << 14;
+
+ /**
+ * Style constant for align left behavior (value is 1&lt;&lt;14).
+ * This is a synonym for LEAD (value is 1&lt;&lt;14). Newer
+ * applications should use LEAD instead of LEFT to make code more
+ * understandable on right-to-left platforms.
*/
- public static final int LEFT = 1 << 14;
+ public static final int LEFT = LEAD;
/**
- * Style constant for align right behavior (value is 1&lt;&lt;17).
+ * Style constant for trailiing alignment (value is 1&lt;&lt;17).
* <p><b>Used By:</b><ul>
* <li><code>Button</code></li>
* <li><code>Label</code></li>
@@ -850,8 +838,18 @@ public class SWT {
* <li><code>Tracker</code></li>
* <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
* </ul></p>
+ *
+ * @since 2.1.2
+ */
+ public static final int TRAIL = 1 << 17;
+
+ /**
+ * Style constant for align right behavior (value is 1&lt;&lt;17).
+ * This is a synonym for TRAIL (value is 1&lt;&lt;14). Newer
+ * applications should use TRAIL instead of RIGHT to make code more
+ * understandable on right-to-left platforms.
*/
- public static final int RIGHT = 1 << 17;
+ public static final int RIGHT = TRAIL;
/**
* Style constant for align center behavior (value is 1&lt;&lt;24).
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java
index e8bed578a0..33b3c120a1 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java
@@ -33,6 +33,7 @@ public class BidiUtil {
public static final int CLASS_HEBREW = 2;
public static final int CLASS_ARABIC = 2;
public static final int CLASS_LOCALNUMBER = 4;
+ public static final int CLASS_LATINNUMBER = 5;
public static final int REORDER = 0;
public static final int LIGATE = 0;
public static final int GLYPHSHAPE = 0;
@@ -96,5 +97,10 @@ public static void removeLanguageListener(int hwnd) {
*/
public static void setKeyboardLanguage(int language) {
}
-
+/*
+ * Not implemented.
+ */
+public static boolean setOrientation(int hwnd, int orientation) {
+ return false;
+}
}
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 84ee0edb5c..9ed3efbdd3 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
@@ -64,8 +64,13 @@ GC() {
* </ul>
*/
public GC(Drawable drawable) {
+ this(drawable, 0);
+}
+
+public GC(Drawable drawable, int style) {
if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
GCData data = new GCData();
+ data.style = checkStyle(style);
int gdkGC = drawable.internal_new_GC(data);
Device device = data.device;
if (device == null) device = Device.getDevice();
@@ -75,6 +80,11 @@ public GC(Drawable drawable) {
if (device.tracking) device.new_Object(this);
}
+static int checkStyle (int style) {
+ if ((style & SWT.LEFT_TO_RIGHT) != 0) style &= ~SWT.RIGHT_TO_LEFT;
+ return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+}
+
/**
* Copies a rectangular area of the receiver at the specified
* position into the image, which must be of type <code>SWT.BITMAP</code>.
@@ -1394,6 +1404,11 @@ public int getLineWidth() {
return values.line_width;
}
+public int getStyle () {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ return data.style;
+}
+
/**
* Returns <code>true</code> if this GC is drawing in the mode
* where the resulting color in the destination is the
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
index b062e97b16..0530d9f927 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
@@ -26,6 +26,7 @@ import org.eclipse.swt.*;
*/
public final class GCData {
public Device device;
+ public int style;
public Image image;
public int drawable;
public GdkColor foreground;
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 8e7dc955a0..9387833cd8 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
@@ -862,6 +862,10 @@ public int internal_new_GC (GCData data) {
}
int gdkGC = OS.gdk_gc_new(pixmap);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ }
data.device = device;
data.drawable = pixmap;
data.font = device.systemFont.handle;
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 2bbf3d66d1..1dae79e5d6 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
@@ -1847,6 +1847,10 @@ public int internal_new_GC (GCData data) {
int gdkGC = OS.gdk_gc_new (window);
if (gdkGC == 0) error (SWT.ERROR_NO_HANDLES);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= style & (mask | SWT.MIRRORED);
+ }
int fontHandle = fontHandle ();
GtkStyle style = new GtkStyle ();
OS.memmove(style, OS.gtk_widget_get_style (fontHandle));
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 0b0d8b64ab..688f3558b5 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
@@ -1363,6 +1363,10 @@ public int internal_new_GC (GCData data) {
int gdkGC = OS.gdk_gc_new (root);
if (gdkGC == 0) SWT.error (SWT.ERROR_NO_HANDLES);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ }
data.device = this;
data.drawable = root;
data.font = defaultFont;
@@ -1374,6 +1378,208 @@ boolean isValidThread () {
return thread == Thread.currentThread ();
}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param point to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, Point point) {
+ checkDevice ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, point.x, point.y);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, int x, int y) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Point point = new Point (x, y);
+ if (from != null) {
+ int eventHandle = from.eventHandle ();
+ OS.gtk_widget_realize (eventHandle);
+ int window = OS.GTK_WIDGET_WINDOW (eventHandle);
+ int [] origin_x = new int [1], origin_y = new int [1];
+ OS.gdk_window_get_origin (window, origin_x, origin_y);
+ point.x += origin_x [0];
+ point.y += origin_y [0];
+ }
+ if (to != null) {
+ int eventHandle = to.eventHandle ();
+ OS.gtk_widget_realize (eventHandle);
+ int window = OS.GTK_WIDGET_WINDOW (eventHandle);
+ int [] origin_x = new int [1], origin_y = new int [1];
+ OS.gdk_window_get_origin (window, origin_x, origin_y);
+ point.x -= origin_x [0];
+ point.y -= origin_y [0];
+ }
+ return point;
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param rectangle to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, Rectangle rectangle) {
+ checkDevice();
+ if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @param int width coordinates to be mapped
+ * @param int heigth coordinates to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
+ checkDevice();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Rectangle rect = new Rectangle (x, y, width, height);
+ if (from != null) {
+ int eventHandle = from.eventHandle ();
+ OS.gtk_widget_realize (eventHandle);
+ int window = OS.GTK_WIDGET_WINDOW (eventHandle);
+ int [] origin_x = new int [1], origin_y = new int [1];
+ OS.gdk_window_get_origin (window, origin_x, origin_y);
+ rect.x += origin_x [0];
+ rect.y += origin_y [0];
+ }
+ if (to != null) {
+ int eventHandle = to.eventHandle ();
+ OS.gtk_widget_realize (eventHandle);
+ int window = OS.GTK_WIDGET_WINDOW (eventHandle);
+ int [] origin_x = new int [1], origin_y = new int [1];
+ OS.gdk_window_get_origin (window, origin_x, origin_y);
+ rect.x -= origin_x [0];
+ rect.y -= origin_y [0];
+ }
+ return rect;
+}
+
int mouseHoverProc (int handle) {
Widget widget = WidgetTable.get (handle);
if (widget == null) return 0;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GC.java
index c21fdc387b..709fd8f4a1 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GC.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GC.java
@@ -62,9 +62,13 @@ GC() {
* <li>ERROR_NO_HANDLES if a handle could not be obtained for gc creation</li>
* </ul>
*/
-public GC (Drawable drawable) {
+public GC(Drawable drawable) {
+ this(drawable, 0);
+}
+public GC(Drawable drawable, int style) {
if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
GCData data = new GCData();
+ data.style = checkStyle(style);
int xGC = drawable.internal_new_GC(data);
Device device = data.device;
if (device == null) device = Device.getDevice();
@@ -73,7 +77,10 @@ public GC (Drawable drawable) {
init(drawable, data, xGC);
if (device.tracking) device.new_Object(this);
}
-
+static int checkStyle (int style) {
+ if ((style & SWT.LEFT_TO_RIGHT) != 0) style &= ~SWT.RIGHT_TO_LEFT;
+ return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+}
/**
* Copies a rectangular area of the receiver at the source
* position onto the receiver at the destination position.
@@ -2048,6 +2055,10 @@ public int getLineWidth() {
OS.XGetGCValues(data.display, handle, OS.GCLineWidth, values);
return values.line_width;
}
+public int getStyle () {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ return data.style;
+}
/**
* Returns <code>true</code> if this GC is drawing in the mode
* where the resulting color in the destination is the
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GCData.java
index 08a2b3e969..f1e18d875b 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GCData.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/GCData.java
@@ -25,6 +25,7 @@ import org.eclipse.swt.*;
*/
public final class GCData {
public Device device;
+ public int style;
public Image image;
public int display;
public int drawable;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/Image.java
index 916eb85d1b..6b96c0feb1 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/graphics/Image.java
@@ -1050,6 +1050,10 @@ public int internal_new_GC (GCData data) {
int xGC = OS.XCreateGC (xDisplay, pixmap, 0, null);
if (xGC == 0) SWT.error (SWT.ERROR_NO_HANDLES);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ }
data.device = device;
data.display = xDisplay;
data.drawable = pixmap;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Control.java
index c6d1b00c6e..d6d2bb9534 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Control.java
@@ -1061,6 +1061,10 @@ public int internal_new_GC (GCData data) {
int [] argList = {OS.XmNforeground, 0, OS.XmNbackground, 0, OS.XmNcolormap, 0};
OS.XtGetValues (handle, argList, argList.length / 2);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= style & (mask | SWT.MIRRORED);
+ }
data.device = getDisplay ();
data.display = xDisplay;
data.drawable = xWindow;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Display.java
index d4890b73aa..6f18f0fa22 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Display.java
@@ -1618,6 +1618,10 @@ public int internal_new_GC (GCData data) {
if (xGC == 0) SWT.error (SWT.ERROR_NO_HANDLES);
OS.XSetSubwindowMode (xDisplay, xGC, OS.IncludeInferiors);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ }
data.device = this;
data.display = xDisplay;
data.drawable = xDrawable;
@@ -1651,6 +1655,192 @@ static boolean isValidClass (Class clazz) {
int index = name.lastIndexOf ('.');
return name.substring (0, index + 1).equals (PACKAGE_PREFIX);
}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param point to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, Point point) {
+ checkDevice ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, point.x, point.y);
+}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, int x, int y) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Point point = new Point (x, y);
+ if (from != null) {
+ short [] root_x = new short [1], root_y = new short [1];
+ OS.XtTranslateCoords (from.handle, (short) x, (short) y, root_x, root_y);
+ point.x = root_x [0];
+ point.y = root_y [0];
+ }
+ if (to != null) {
+ short [] root_x = new short [1], root_y = new short [1];
+ OS.XtTranslateCoords (to.handle, (short) 0, (short) 0, root_x, root_y);
+ point.x -= root_x [0];
+ point.y -= root_y [0];
+ }
+ return point;
+}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param rectangle to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, Rectangle rectangle) {
+ checkDevice();
+ if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @param int width coordinates to be mapped
+ * @param int heigth coordinates to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
+ checkDevice();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Rectangle rect = new Rectangle (x, y, width, height);
+ if (from != null) {
+ short [] root_x = new short [1], root_y = new short [1];
+ OS.XtTranslateCoords (from.handle, (short) x, (short) y, root_x, root_y);
+ rect.x = root_x [0];
+ rect.y = root_y [0];
+ }
+ if (to != null) {
+ short [] root_x = new short [1], root_y = new short [1];
+ OS.XtTranslateCoords (to.handle, (short) 0, (short) 0, root_x, root_y);
+ rect.x -= root_x [0];
+ rect.y -= root_y [0];
+ }
+ return rect;
+}
int mouseHoverProc (int handle, int id) {
mouseHoverID = mouseHoverHandle = 0;
Widget widget = WidgetTable.get (handle);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GC.java
index 62ba90b439..ccc9393c2d 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GC.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GC.java
@@ -86,10 +86,15 @@ GC() {
* </ul>
*/
public GC(Drawable drawable) {
+ this(drawable, 0);
+}
+
+public GC(Drawable drawable, int style) {
int flags = OS.PtEnter(0);
try {
if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
GCData data = new GCData ();
+ data.style = checkStyle(style);
int hDC = drawable.internal_new_GC (data);
Device device = data.device;
if (device == null) device = Device.getDevice();
@@ -102,6 +107,11 @@ public GC(Drawable drawable) {
}
}
+static int checkStyle (int style) {
+ if ((style & SWT.LEFT_TO_RIGHT) != 0) style &= ~SWT.RIGHT_TO_LEFT;
+ return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+}
+
/**
* Copies a rectangular area of the receiver at the specified
* position into the image, which must be of type <code>SWT.BITMAP</code>.
@@ -1906,6 +1916,11 @@ public int getLineWidth() {
return data.lineWidth;
}
+public int getStyle () {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ return data.style;
+}
+
/**
* Returns <code>true</code> if this GC is drawing in the mode
* where the resulting color in the destination is the
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GCData.java
index c35f694a66..741a6f67c7 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GCData.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/GCData.java
@@ -25,6 +25,7 @@ import org.eclipse.swt.*;
*/
public final class GCData {
public Device device;
+ public int style;
public Image image;
public int rid;
public int widget, topWidget;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/Image.java
index 710017cf01..37a1de443e 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/graphics/Image.java
@@ -910,6 +910,10 @@ public int internal_new_GC (GCData data) {
PhPoint_t trans = new PhPoint_t();
int pmMC = OS.PmMemCreateMC(handle, dim, trans);
if (pmMC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ }
data.device = device;
data.image = this;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java
index a37a23ae3c..ded8670da7 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java
@@ -939,6 +939,10 @@ public int internal_new_GC (GCData data) {
int phGC = OS.PgCreateGC(0); // NOTE: PgCreateGC ignores the parameter
if (phGC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= style & (mask | SWT.MIRRORED);
+ }
int [] args = {OS.Pt_ARG_COLOR, 0, 0, OS.Pt_ARG_FILL_COLOR, 0, 0};
OS.PtGetResources (handle, args.length / 3, args);
data.device = getDisplay ();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Display.java
index a1b4c2c06b..08de9111b1 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Display.java
@@ -1267,6 +1267,10 @@ public int internal_new_GC (GCData data) {
if (isDisposed()) SWT.error(SWT.ERROR_DEVICE_DISPOSED);
int phGC = OS.PgCreateGC(0); // NOTE: PgCreateGC ignores the parameter
if (phGC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ }
data.device = this;
data.rid = OS.Ph_DEV_RID;
@@ -1362,6 +1366,196 @@ static boolean isValidClass (Class clazz) {
return name.substring (0, index + 1).equals (PACKAGE_NAME);
}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param point to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, Point point) {
+ checkDevice ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, point.x, point.y);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, int x, int y) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Point point = new Point (x, y);
+ if (from != null) {
+ short [] position_x = new short [1], position_y = new short [1];
+ OS.PtGetAbsPosition (from.handle, position_x, position_y);
+ point.x += position_x [0];
+ point.y += position_y [0];
+ }
+ if (to != null) {
+ short [] position_x = new short [1], position_y = new short [1];
+ OS.PtGetAbsPosition (to.handle, position_x, position_y);
+ point.x -= position_x [0];
+ point.y -= position_y [0];
+ }
+ return point;
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param rectangle to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, Rectangle rectangle) {
+ checkDevice ();
+ if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @param int width coordinates to be mapped
+ * @param int heigth coordinates to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Rectangle rect = new Rectangle (x, y, width, height);
+ if (from != null) {
+ short [] position_x = new short [1], position_y = new short [1];
+ OS.PtGetAbsPosition (from.handle, position_x, position_y);
+ rect.x += position_x [0];
+ rect.y += position_y [0];
+ }
+ if (to != null) {
+ short [] position_x = new short [1], position_y = new short [1];
+ OS.PtGetAbsPosition (to.handle, position_x, position_y);
+ rect.x -= position_x [0];
+ rect.y -= position_y [0];
+ }
+ return rect;
+}
+
void postEvent (Event event) {
/*
* Place the event at the end of the event queue.
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
index ef192b8c66..55a276753e 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
@@ -19,6 +19,11 @@ import org.eclipse.swt.*;
* Class <code>GC</code> is where all of the drawing capabilities that are
* supported by SWT are located. Instances are used to draw on either an
* <code>Image</code>, a <code>Control</code>, or directly on a <code>Display</code>.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
+ * </dl>
+ *
* <p>
* Application code must explicitly invoke the <code>GC.dispose()</code>
* method to release the operating system resources managed by each instance
@@ -26,6 +31,10 @@ import org.eclipse.swt.*;
* important on Windows95 and Windows98 where the operating system has a limited
* number of device contexts available.
* </p>
+ *
+ * <p>
+ * Note: Only one of LEFT_TO_RIGHT and RIGHT_TO_LEFT may be specified.
+ * </p>
*
* @see org.eclipse.swt.events.PaintEvent
*/
@@ -69,9 +78,40 @@ GC() {
* </ul>
*/
public GC(Drawable drawable) {
+ this(drawable, SWT.NONE);
+}
+
+/**
+ * Constructs a new instance of this class which has been
+ * configured to draw on the specified drawable. Sets the
+ * foreground and background color in the GC to match those
+ * in the drawable.
+ * <p>
+ * You must dispose the graphics context when it is no longer required.
+ * </p>
+ *
+ * @param drawable the drawable to draw on
+ * @param style the style of GC to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the drawable is null</li>
+ * <li>ERROR_NULL_ARGUMENT - if there is no current device</li>
+ * <li>ERROR_INVALID_ARGUMENT
+ * - if the drawable is an image that is not a bitmap or an icon
+ * - if the drawable is an image or printer that is already selected
+ * into another graphics context</li>
+ * </ul>
+ * @exception SWTError <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for gc creation</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public GC(Drawable drawable, int style) {
if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
GCData data = new GCData ();
- int hDC = drawable.internal_new_GC (data);
+ data.style = checkStyle(style);
+ int hDC = drawable.internal_new_GC(data);
Device device = data.device;
if (device == null) device = Device.getDevice();
if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
@@ -80,6 +120,11 @@ public GC(Drawable drawable) {
if (device.tracking) device.new_Object(this);
}
+static int checkStyle(int style) {
+ if ((style & SWT.LEFT_TO_RIGHT) != 0) style &= ~SWT.RIGHT_TO_LEFT;
+ return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+}
+
/**
* Copies a rectangular area of the receiver at the specified
* position into the image, which must be of type <code>SWT.BITMAP</code>.
@@ -535,15 +580,24 @@ void drawIcon(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, i
newIconInfo.hbmColor = OS.CreateCompatibleBitmap(srcHdc, destWidth, destHeight);
if (newIconInfo.hbmColor == 0) SWT.error(SWT.ERROR_NO_HANDLES);
int oldDestBitmap = OS.SelectObject(dstHdc, newIconInfo.hbmColor);
- if (!OS.IsWinCE) OS.SetStretchBltMode(dstHdc, OS.COLORONCOLOR);
- OS.StretchBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcColorY, srcWidth, srcHeight, OS.SRCCOPY);
-
+ boolean stretch = !simple && (srcWidth != destWidth || srcHeight != destHeight);
+ if (stretch) {
+ if (!OS.IsWinCE) OS.SetStretchBltMode(dstHdc, OS.COLORONCOLOR);
+ OS.StretchBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcColorY, srcWidth, srcHeight, OS.SRCCOPY);
+ } else {
+ OS.BitBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcColorY, OS.SRCCOPY);
+ }
+
/* Blt the mask bitmap */
OS.SelectObject(srcHdc, srcIconInfo.hbmMask);
newIconInfo.hbmMask = OS.CreateBitmap(destWidth, destHeight, 1, 1, null);
if (newIconInfo.hbmMask == 0) SWT.error(SWT.ERROR_NO_HANDLES);
OS.SelectObject(dstHdc, newIconInfo.hbmMask);
- OS.StretchBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCCOPY);
+ if (stretch) {
+ OS.StretchBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCCOPY);
+ } else {
+ OS.BitBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCCOPY);
+ }
/* Select old bitmaps before creating the icon */
OS.SelectObject(srcHdc, oldSrcBitmap);
@@ -686,7 +740,6 @@ void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe
}
/* Scale the foreground pixels with alpha */
- if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc, OS.COLORONCOLOR);
OS.MoveMemory(dibBM.bmBits, srcData, sizeInBytes);
/*
* Bug in WinCE and Win98. StretchBlt does not correctly stretch when
@@ -699,13 +752,23 @@ void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe
int tempHdc = OS.CreateCompatibleDC(handle);
int tempDib = createDIB(destWidth, destHeight);
int oldTempBitmap = OS.SelectObject(tempHdc, tempDib);
- OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY);
+ if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) {
+ if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc, OS.COLORONCOLOR);
+ OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY);
+ } else {
+ OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, OS.SRCCOPY);
+ }
OS.BitBlt(memHdc, 0, 0, destWidth, destHeight, tempHdc, 0, 0, OS.SRCCOPY);
OS.SelectObject(tempHdc, oldTempBitmap);
OS.DeleteObject(tempDib);
OS.DeleteDC(tempHdc);
} else {
- OS.StretchBlt(memHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY);
+ if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) {
+ if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc, OS.COLORONCOLOR);
+ OS.StretchBlt(memHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY);
+ } else {
+ OS.BitBlt(memHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, OS.SRCCOPY);
+ }
}
OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes);
@@ -839,10 +902,16 @@ void drawBitmapTransparent(Image srcImage, int srcX, int srcY, int srcWidth, int
int tempBitmap = OS.CreateCompatibleBitmap(hDC, destWidth, destHeight);
int oldTempBitmap = OS.SelectObject(tempHdc, tempBitmap);
OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, handle, destX, destY, OS.SRCCOPY);
- if (!OS.IsWinCE) OS.SetStretchBltMode(tempHdc, OS.COLORONCOLOR);
- OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCINVERT);
- OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, maskHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCAND);
- OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCINVERT);
+ if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) {
+ if (!OS.IsWinCE) OS.SetStretchBltMode(tempHdc, OS.COLORONCOLOR);
+ OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCINVERT);
+ OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, maskHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCAND);
+ OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCINVERT);
+ } else {
+ OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCINVERT);
+ OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, maskHdc, srcX, srcY, OS.SRCAND);
+ OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCINVERT);
+ }
OS.BitBlt(handle, destX, destY, destWidth, destHeight, tempHdc, 0, 0, OS.SRCCOPY);
/* Release resources */
@@ -864,18 +933,21 @@ void drawBitmapTransparent(Image srcImage, int srcX, int srcY, int srcWidth, int
void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, BITMAP bm, int imgWidth, int imgHeight) {
int srcHdc = OS.CreateCompatibleDC(handle);
int oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle);
- int mode = 0, rop2 = 0;
+ int rop2 = 0;
if (!OS.IsWinCE) {
rop2 = OS.GetROP2(handle);
- mode = OS.SetStretchBltMode(handle, OS.COLORONCOLOR);
} else {
rop2 = OS.SetROP2 (handle, OS.R2_COPYPEN);
OS.SetROP2 (handle, rop2);
}
int dwRop = rop2 == OS.R2_XORPEN ? OS.SRCINVERT : OS.SRCCOPY;
- OS.StretchBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, dwRop);
- if (!OS.IsWinCE) {
- OS.SetStretchBltMode(handle, mode);
+ if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) {
+ int mode = 0;
+ if (!OS.IsWinCE) mode = OS.SetStretchBltMode(handle, OS.COLORONCOLOR);
+ OS.StretchBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, dwRop);
+ if (!OS.IsWinCE) OS.SetStretchBltMode(handle, mode);
+ } else {
+ OS.BitBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, dwRop);
}
OS.SelectObject(srcHdc, oldSrcBitmap);
OS.DeleteDC(srcHdc);
@@ -1835,6 +1907,29 @@ public int getLineWidth() {
return logPen.x;
}
+/**
+ * Returns the receiver's style information.
+ * <p>
+ * Note that the value which is returned by this method <em>may
+ * not match</em> the value which was provided to the constructor
+ * when the receiver was created. This can occur when the underlying
+ * operating system does not support a particular combination of
+ * requested styles.
+ * </p>
+ *
+ * @return the style bits
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public int getStyle () {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ return data.style;
+}
+
/**
* Returns <code>true</code> if this GC is drawing in the mode
* where the resulting color in the destination is the
@@ -1886,6 +1981,20 @@ void init(Drawable drawable, GCData data, int hDC) {
data.hNullBitmap = OS.SelectObject(hDC, image.handle);
image.memGC = this;
}
+ int layout = data.layout;
+ if (layout != -1) {
+ if ((OS.WIN32_MAJOR << 16 | OS.WIN32_MINOR) >= (4 << 16 | 10)) {
+ if ((data.style & SWT.RIGHT_TO_LEFT) != 0) {
+ data.style |= SWT.MIRRORED;
+ layout = OS.LAYOUT_RTL;
+ }
+ int flags = OS.GetLayout(hDC);
+ if ((flags & OS.LAYOUT_RTL) != layout) {
+ flags &= ~OS.LAYOUT_RTL;
+ OS.SetLayout(hDC, flags | layout);
+ }
+ }
+ }
this.drawable = drawable;
this.data = data;
handle = hDC;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java
index 18fd50b75e..27647a127d 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java
@@ -26,6 +26,7 @@ import org.eclipse.swt.internal.win32.*;
public final class GCData {
public Device device;
+ public int style;
public Image image;
public int foreground = -1;
public int background = -1;
@@ -33,4 +34,5 @@ public final class GCData {
public int hNullBitmap;
public int hwnd;
public PAINTSTRUCT ps;
+ public int layout;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
index 8f1f09d8bc..37406a3398 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
@@ -1757,6 +1757,11 @@ public int internal_new_GC (GCData data) {
if (data != null) {
/* Set the GCData fields */
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ data.layout = -1;
+ }
data.device = device;
data.image = this;
data.hFont = device.systemFont;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java
index d63eccc844..3de536dd9a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java
@@ -37,7 +37,8 @@ public class BidiUtil {
// variables used for providing a listener mechanism for keyboard language
// switching
- static Hashtable map = new Hashtable ();
+ static Hashtable languageMap = new Hashtable ();
+ static Hashtable keyMap = new Hashtable ();
static Hashtable oldProcMap = new Hashtable ();
/*
* This code is intentionally commented. In order
@@ -62,6 +63,7 @@ public class BidiUtil {
static final byte GCPCLASS_ARABIC = 2;
static final byte GCPCLASS_HEBREW = 2;
static final byte GCPCLASS_LOCALNUMBER = 4;
+ static final byte GCPCLASS_LATINNUMBER = 5;
static final int GCPGLYPH_LINKBEFORE = 0x8000;
static final int GCPGLYPH_LINKAFTER = 0x4000;
// ExtTextOut constants
@@ -85,6 +87,7 @@ public class BidiUtil {
public static final int CLASS_HEBREW = GCPCLASS_ARABIC;
public static final int CLASS_ARABIC = GCPCLASS_HEBREW;
public static final int CLASS_LOCALNUMBER = GCPCLASS_LOCALNUMBER;
+ public static final int CLASS_LATINNUMBER = GCPCLASS_LATINNUMBER;
public static final int REORDER = GCP_REORDER;
public static final int LIGATE = GCP_LIGATE;
public static final int GLYPHSHAPE = GCP_GLYPHSHAPE;
@@ -96,16 +99,14 @@ public class BidiUtil {
* monitored.
* <p>
*
- * @param int the handle of the Control that is listening for keyboard language
+ * @param hwnd the handle of the Control that is listening for keyboard language
* changes
* @param runnable the code that should be executed when a keyboard language change
* occurs
*/
-public static void addLanguageListener (int hwnd, Runnable runnable) {
- map.put (new Integer (hwnd), runnable);
- int oldProc = OS.GetWindowLong (hwnd, OS.GWL_WNDPROC);
- oldProcMap.put (new Integer(hwnd), new Integer(oldProc));
- OS.SetWindowLong (hwnd, OS.GWL_WNDPROC, callback.getAddress ());
+public static void addLanguageListener(int hwnd, Runnable runnable) {
+ languageMap.put(new Integer(hwnd), runnable);
+ subclass(hwnd);
}
/**
* Proc used for OS.EnumSystemLanguageGroups call during isBidiPlatform test.
@@ -133,6 +134,10 @@ static int EnumSystemLanguageGroupsProc(int lpLangGrpId, int lpLangGrpIdString,
*/
public static void drawGlyphs(GC gc, char[] renderBuffer, int[] renderDx, int x, int y) {
RECT rect = null;
+ if (OS.GetLayout (gc.handle) != 0) {
+ reverse(renderDx);
+ reverse(renderBuffer);
+ }
OS.ExtTextOutW(gc.handle, x, y, ETO_GLYPH_INDEX, rect, renderBuffer, renderBuffer.length, renderDx);
}
/**
@@ -158,6 +163,7 @@ public static char[] getRenderInfo(GC gc, String text, int[] order, byte[] class
int hHeap = OS.GetProcessHeap();
int[] lpCs = new int[8];
int cs = OS.GetTextCharset(gc.handle);
+ boolean isRightOriented = OS.GetLayout(gc.handle) != 0;
OS.TranslateCharsetInfo(cs, lpCs, OS.TCI_SRCCHARSET);
TCHAR textBuffer = new TCHAR(lpCs[1], text, false);
int byteCount = textBuffer.length();
@@ -223,14 +229,15 @@ public static char[] getRenderInfo(GC gc, String text, int[] order, byte[] class
if (dx != null) {
int [] dx2 = new int [result.nGlyphs];
OS.MoveMemory(dx2, result.lpDx, dx2.length * 4);
+ if (isRightOriented) {
+ reverse(dx2);
+ }
System.arraycopy (dx2, 0, dx, glyphCount, dx2.length);
}
if (order != null) {
int [] order2 = new int [length];
OS.MoveMemory(order2, result.lpOrder, order2.length * 4);
- for (int j=0; j<length; j++) {
- order2 [j] += glyphCount;
- }
+ translateOrder(order2, glyphCount, isRightOriented);
System.arraycopy (order2, 0, order, offset, length);
}
if (classBuffer != null) {
@@ -240,6 +247,9 @@ public static char[] getRenderInfo(GC gc, String text, int[] order, byte[] class
}
char[] glyphBuffer2 = new char[result.nGlyphs];
OS.MoveMemory(glyphBuffer2, result.lpGlyphs, glyphBuffer2.length * 2);
+ if (isRightOriented) {
+ reverse(glyphBuffer2);
+ }
System.arraycopy (glyphBuffer2, 0, glyphBuffer, glyphCount, glyphBuffer2.length);
glyphCount += glyphBuffer2.length;
@@ -286,6 +296,7 @@ public static void getOrderInfo(GC gc, String text, int[] order, byte[] classBuf
OS.TranslateCharsetInfo(cs, lpCs, OS.TCI_SRCCHARSET);
TCHAR textBuffer = new TCHAR(lpCs[1], text, false);
int byteCount = textBuffer.length();
+ boolean isRightOriented = (OS.GetLayout(gc.handle) != 0);
GCP_RESULTS result = new GCP_RESULTS();
result.lStructSize = GCP_RESULTS.sizeof;
@@ -325,9 +336,7 @@ public static void getOrderInfo(GC gc, String text, int[] order, byte[] classBuf
if (order != null) {
int [] order2 = new int [length];
OS.MoveMemory(order2, result.lpOrder, order2.length * 4);
- for (int j=0; j<length; j++) {
- order2 [j] += glyphCount;
- }
+ translateOrder(order2, glyphCount, isRightOriented);
System.arraycopy (order2, 0, order, offset, length);
}
if (classBuffer != null) {
@@ -395,7 +404,7 @@ public static int getKeyboardLanguage() {
*
* @return integer array with an entry for each installed language
*/
-public static int[] getKeyboardLanguageList() {
+static int[] getKeyboardLanguageList() {
int maxSize = 10;
int[] tempList = new int[maxSize];
int size = OS.GetKeyboardLayoutList(maxSize, tempList);
@@ -469,11 +478,9 @@ public static boolean isKeyboardBidi() {
*
* @param hwnd the handle of the Control that is listening for keyboard language changes
*/
-public static void removeLanguageListener (int hwnd) {
- map.remove (new Integer (hwnd));
- Integer proc = (Integer)oldProcMap.remove (new Integer (hwnd));
- if (proc == null) return;
- OS.SetWindowLong (hwnd, OS.GWL_WNDPROC, proc.intValue());
+public static void removeLanguageListener(int hwnd) {
+ languageMap.remove(new Integer(hwnd));
+ unsubclass(hwnd);
}
/**
* Switch the keyboard language to the specified language type. We do
@@ -512,10 +519,104 @@ public static void setKeyboardLanguage(int language) {
}
}
}
-
}
/**
- * Window proc to intercept keyboard language switch event (WS_INPUTLANGCHANGE).
+ * Sets the orientation (writing order) of the specified control. Text will
+ * be right aligned for right to left writing order.
+ * <p>
+ *
+ * @param hwnd the handle of the Control to change the orientation of
+ * @param orientation one of SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
+ * @return true if the orientation was changed, false if the orientation
+ * could not be changed
+ */
+public static boolean setOrientation (int hwnd, int orientation) {
+ if ((OS.WIN32_MAJOR << 16 | OS.WIN32_MINOR) < (4 << 16 | 10)) return false;
+ int bits = OS.GetWindowLong (hwnd, OS.GWL_EXSTYLE);
+ if ((orientation & SWT.RIGHT_TO_LEFT) != 0) {
+ bits |= OS.WS_EX_LAYOUTRTL;
+ } else {
+ bits &= ~OS.WS_EX_LAYOUTRTL;
+ }
+ OS.SetWindowLong (hwnd, OS.GWL_EXSTYLE, bits);
+ return true;
+}
+/**
+ * Override the window proc.
+ *
+ * @param hwnd control to override the window proc of
+ */
+static void subclass(int hwnd) {
+ Integer key = new Integer(hwnd);
+ if (oldProcMap.get(key) == null) {
+ int oldProc = OS.GetWindowLong(hwnd, OS.GWL_WNDPROC);
+ oldProcMap.put(key, new Integer(oldProc));
+ OS.SetWindowLong(hwnd, OS.GWL_WNDPROC, callback.getAddress());
+ }
+}
+/**
+ * Reverse the character array. Used for right orientation.
+ *
+ * @param charArray character array to reverse
+ */
+static void reverse(char[] charArray) {
+ int length = charArray.length;
+ for (int i = 0; i <= (length - 1) / 2; i++) {
+ char tmp = charArray[i];
+ charArray[i] = charArray[length - 1 - i];
+ charArray[length - 1 - i] = tmp;
+ }
+}
+/**
+ * Reverse the integer array. Used for right orientation.
+ *
+ * @param intArray integer array to reverse
+ */
+static void reverse(int[] intArray) {
+ int length = intArray.length;
+ for (int i = 0; i <= (length - 1) / 2; i++) {
+ int tmp = intArray[i];
+ intArray[i] = intArray[length - 1 - i];
+ intArray[length - 1 - i] = tmp;
+ }
+}
+/**
+ * Adjust the order array so that it is relative to the start of the line. Also reverse the order array if the orientation
+ * is to the right.
+ *
+ * @param orderArray integer array of order values to translate
+ * @param glyphCount number of glyphs that have been processed for the current line
+ * @param isRightOriented flag indicating whether or not current orientation is to the right
+*/
+static void translateOrder(int[] orderArray, int glyphCount, boolean isRightOriented) {
+ int maxOrder = 0;
+ int length = orderArray.length;
+ if (isRightOriented) {
+ for (int i=0; i<length; i++) {
+ maxOrder = Math.max(maxOrder, orderArray[i]);
+ }
+ }
+ for (int i=0; i<length; i++) {
+ if (isRightOriented) orderArray[i] = maxOrder - orderArray[i];
+ orderArray [i] += glyphCount;
+ }
+}
+/**
+ * Remove the overridden the window proc.
+ *
+ * @param hwnd control to remove the window proc override for
+ */
+static void unsubclass(int hwnd) {
+ Integer key = new Integer(hwnd);
+ if (languageMap.get(key) == null && keyMap.get(key) == null) {
+ Integer proc = (Integer) oldProcMap.remove(key);
+ if (proc == null) return;
+ OS.SetWindowLong(hwnd, OS.GWL_WNDPROC, proc.intValue());
+ }
+}
+/**
+ * Window proc to intercept keyboard language switch event (WS_INPUTLANGCHANGE)
+ * and widget orientation changes.
* Run the Control's registered runnable when the keyboard language is switched.
*
* @param hwnd handle of the control that is listening for the keyboard language
@@ -523,13 +624,14 @@ public static void setKeyboardLanguage(int language) {
* @param msg window message
*/
static int windowProc (int hwnd, int msg, int wParam, int lParam) {
+ Integer key = new Integer (hwnd);
switch (msg) {
case 0x51 /*OS.WM_INPUTLANGCHANGE*/:
- Runnable runnable = (Runnable) map.get (new Integer (hwnd));
+ Runnable runnable = (Runnable) languageMap.get (key);
if (runnable != null) runnable.run ();
break;
- }
- Integer oldProc = (Integer)oldProcMap.get(new Integer(hwnd));
+ }
+ Integer oldProc = (Integer)oldProcMap.get(key);
return OS.CallWindowProc (oldProc.intValue(), hwnd, msg, wParam, lParam);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java
index 02753c349f..59f710bb99 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java
@@ -217,4 +217,34 @@ LRESULT WM_SETFOCUS (int wParam, int lParam) {
return result;
}
+LRESULT WM_WINDOWPOSCHANGED (int wParam, int lParam) {
+ LRESULT result = super.WM_WINDOWPOSCHANGED (wParam, lParam);
+ if (result != null) return result;
+ /*
+ * Bug in Windows. When a window with style WS_EX_LAYOUTRTL
+ * that contains a caret is resized, Windows does not move the
+ * caret in relation to the mirrored origin in the top right.
+ * The fix is to hide the caret in WM_WINDOWPOSCHANGING and
+ * show the caret in WM_WINDOWPOSCHANGED.
+ */
+ boolean isFocus = (style & SWT.RIGHT_TO_LEFT) != 0 && caret != null && caret.isFocusCaret ();
+ if (isFocus) caret.setFocus ();
+ return result;
}
+
+LRESULT WM_WINDOWPOSCHANGING (int wParam, int lParam) {
+ LRESULT result = super.WM_WINDOWPOSCHANGING (wParam, lParam);
+ if (result != null) return result;
+ /*
+ * Bug in Windows. When a window with style WS_EX_LAYOUTRTL
+ * that contains a caret is resized, Windows does not move the
+ * caret in relation to the mirrored origin in the top right.
+ * The fix is to hide the caret in WM_WINDOWPOSCHANGING and
+ * show the caret in WM_WINDOWPOSCHANGED.
+ */
+ boolean isFocus = (style & SWT.RIGHT_TO_LEFT) != 0 && caret != null && caret.isFocusCaret ();
+ if (isFocus) caret.killFocus ();
+ return result;
+}
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java
index f4eb31435d..905126bf38 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java
@@ -623,7 +623,24 @@ LRESULT WM_NOTIFY (int wParam, int lParam) {
string = Display.withCrLf (string);
int length = string.length ();
char [] chars = new char [length + 1];
- string.getChars (0, length, chars, 0);
+ string.getChars (0, length, chars, 0);
+
+ /*
+ * Ensure that the orientation of the tool tip matches
+ * the orientation of the control.
+ */
+ int hwnd = hdr.idFrom;
+ if (hwnd != 0 && ((lpnmtdi.uFlags & OS.TTF_IDISHWND) != 0)) {
+ Control control = WidgetTable.get (hwnd);
+ if (control != null) {
+ if ((control.getStyle () & SWT.RIGHT_TO_LEFT) != 0) {
+ lpnmtdi.uFlags |= OS.TTF_RTLREADING;
+ } else {
+ lpnmtdi.uFlags &= ~OS.TTF_RTLREADING;
+ }
+ }
+ }
+
if (hdr.code == OS.TTN_GETDISPINFOA) {
byte [] bytes = new byte [chars.length * 2];
OS.WideCharToMultiByte (OS.CP_ACP, 0, chars, chars.length, bytes, bytes.length, null, null);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java
index 5e0b4fa839..bbd4a9ddbd 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java
@@ -338,9 +338,11 @@ public void addTraverseListener (TraverseListener listener) {
abstract int callWindowProc (int msg, int wParam, int lParam);
-void checkOrientation (Widget parent) {
- super.checkOrientation (parent);
- if ((style & SWT.RIGHT_TO_LEFT) != 0) style |= SWT.MIRRORED;
+void checkMirrored () {
+ if ((style & SWT.RIGHT_TO_LEFT) != 0) {
+ int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
+ if ((bits & OS.WS_EX_LAYOUTRTL) != 0) style |= SWT.MIRRORED;
+ }
}
/**
@@ -485,6 +487,7 @@ void createWidget () {
register ();
subclass ();
setDefaultFont ();
+ checkMirrored ();
}
int defaultBackground () {
@@ -1013,6 +1016,16 @@ public int internal_new_GC (GCData data) {
}
if (hDC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
+ if ((bits & OS.WS_EX_LAYOUTRTL) != 0) {
+ data.style |= SWT.RIGHT_TO_LEFT | SWT.MIRRORED;
+ } else {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ }
+ data.layout = -1;
+ }
data.device = getDisplay ();
data.foreground = getForegroundPixel ();
data.background = getBackgroundPixel ();
@@ -2472,6 +2485,9 @@ boolean translateTraversal (MSG msg) {
if ((code & (OS.DLGC_WANTTAB | OS.DLGC_WANTALLKEYS)) != 0) {
if (next && OS.GetKeyState (OS.VK_CONTROL) >= 0) doit = false;
}
+ if (parent != null && (parent.style & SWT.MIRRORED) != 0) {
+ if (key == OS.VK_LEFT || key == OS.VK_RIGHT) next = !next;
+ }
detail = next ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS;
break;
}
@@ -2816,6 +2832,7 @@ int windowProc (int msg, int wParam, int lParam) {
case OS.WM_NOTIFY: result = WM_NOTIFY (wParam, lParam); break;
case OS.WM_PAINT: result = WM_PAINT (wParam, lParam); break;
case OS.WM_PALETTECHANGED: result = WM_PALETTECHANGED (wParam, lParam); break;
+ case OS.WM_PARENTNOTIFY: result = WM_PARENTNOTIFY (wParam, lParam); break;
case OS.WM_PASTE: result = WM_PASTE (wParam, lParam); break;
case OS.WM_PRINTCLIENT: result = WM_PRINTCLIENT (wParam, lParam); break;
case OS.WM_QUERYENDSESSION: result = WM_QUERYENDSESSION (wParam, lParam); break;
@@ -2839,6 +2856,7 @@ int windowProc (int msg, int wParam, int lParam) {
case OS.WM_TIMER: result = WM_TIMER (wParam, lParam); break;
case OS.WM_UNDO: result = WM_UNDO (wParam, lParam); break;
case OS.WM_VSCROLL: result = WM_VSCROLL (wParam, lParam); break;
+ case OS.WM_WINDOWPOSCHANGED: result = WM_WINDOWPOSCHANGED (wParam, lParam); break;
case OS.WM_WINDOWPOSCHANGING: result = WM_WINDOWPOSCHANGING (wParam, lParam); break;
}
if (result != null) return result.value;
@@ -3872,6 +3890,10 @@ LRESULT WM_PALETTECHANGED (int wParam, int lParam) {
return null;
}
+LRESULT WM_PARENTNOTIFY (int wParam, int lParam) {
+ return null;
+}
+
LRESULT WM_PASTE (int wParam, int lParam) {
return null;
}
@@ -4192,6 +4214,10 @@ LRESULT WM_VSCROLL (int wParam, int lParam) {
return control.wmScrollChild (wParam, lParam);
}
+LRESULT WM_WINDOWPOSCHANGED (int wParam, int lParam) {
+ return null;
+}
+
LRESULT WM_WINDOWPOSCHANGING (int wParam, int lParam) {
return null;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
index 535f731885..e44cfffa02 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
@@ -1291,6 +1291,11 @@ public int internal_new_GC (GCData data) {
int hDC = OS.GetDC (0);
if (hDC == 0) SWT.error (SWT.ERROR_NO_HANDLES);
if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= SWT.LEFT_TO_RIGHT;
+ data.layout = -1;
+ }
data.device = this;
data.hFont = systemFont ();
}
@@ -1412,6 +1417,184 @@ boolean isVirtualKey (int key) {
return false;
}
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param point to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, Point point) {
+ checkDevice ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, point.x, point.y);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, int x, int y) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ int hwndFrom = from != null ? from.handle : 0;
+ int hwndTo = to != null ? to.handle : 0;
+ POINT point = new POINT ();
+ point.x = x;
+ point.y = y;
+ OS.MapWindowPoints (hwndFrom, hwndTo, point, 1);
+ return new Point (point.x, point.y);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param rectangle to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, Rectangle rectangle) {
+ checkDevice ();
+ if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param int x coordinates to be mapped
+ * @param int y coordinates to be mapped
+ * @param int width coordinates to be mapped
+ * @param int heigth coordinates to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ int hwndFrom = from != null ? from.handle : 0;
+ int hwndTo = to != null ? to.handle : 0;
+ RECT rect = new RECT ();
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + width;
+ rect.bottom = y + height;
+ OS.MapWindowPoints (hwndFrom, hwndTo, rect, 2);
+ return new Rectangle (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+}
+
int messageProc (int hwnd, int msg, int wParam, int lParam) {
switch (msg) {
case OS.WM_ACTIVATEAPP:
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MessageBox.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MessageBox.java
index 48a651e64e..5c2207bab6 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MessageBox.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MessageBox.java
@@ -165,8 +165,10 @@ public int open () {
int bits = buttonBits | iconBits | modalBits;
if ((style & SWT.RIGHT_TO_LEFT) != 0) bits |= OS.MB_RTLREADING;
- if (parent != null && (parent.style & SWT.RIGHT_TO_LEFT) != 0) {
- bits |= OS.MB_RTLREADING;
+ if ((style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT)) == 0) {
+ if (parent != null && (parent.style & SWT.MIRRORED) != 0) {
+ bits |= OS.MB_RTLREADING;
+ }
}
/*
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Slider.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Slider.java
index bfa780a997..700ca9d90f 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Slider.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Slider.java
@@ -679,6 +679,33 @@ int windowProc () {
return ScrollBarProc;
}
+LRESULT WM_KEYDOWN (int wParam, int lParam) {
+ LRESULT result = super.WM_KEYDOWN (wParam, lParam);
+ if (result != null) return result;
+ if ((style & SWT.VERTICAL) != 0) return result;
+
+ /*
+ * Bug in Windows. When a horizontal scroll bar is mirrored,
+ * the native control does not correctly swap the arrow keys.
+ * The fix is to swap them before calling the scroll bar window
+ * proc.
+ *
+ * NOTE: This fix is not ideal. It breaks when the bug is fixed
+ * in the operating system.
+ */
+ if ((style & SWT.MIRRORED) != 0) {
+ switch (wParam) {
+ case OS.VK_LEFT:
+ case OS.VK_RIGHT: {
+ int key = wParam == OS.VK_LEFT ? OS.VK_RIGHT : OS.VK_LEFT;
+ int code = callWindowProc (OS.WM_KEYDOWN, key, lParam);
+ return new LRESULT (code);
+ }
+ }
+ }
+ return result;
+}
+
LRESULT WM_LBUTTONDBLCLK (int wParam, int lParam) {
/*
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java
index 33e574c464..4cd240de0f 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java
@@ -44,6 +44,14 @@ public class TabFolder extends Composite {
ImageList imageList;
static final int TabFolderProc;
static final TCHAR TabFolderClass = new TCHAR (0, "SWT_" + OS.WC_TABCONTROL, true);
+
+ /*
+ * These are the undocumented control id's for the children of
+ * a tab control. Since there are no constants for these values,
+ * they may change with different versions of Windows.
+ */
+ static final int ID_UPDOWN = 1;
+
static {
/*
* Feature in Windows. The tab control window class
@@ -700,6 +708,36 @@ LRESULT WM_NOTIFY (int wParam, int lParam) {
return LRESULT.ZERO;
}
+LRESULT WM_PARENTNOTIFY (int wParam, int lParam) {
+ LRESULT result = super.WM_PARENTNOTIFY (wParam, lParam);
+ if (result != null) return result;
+ /*
+ * Feature in Windows. Windows does not explicitly set the orientation of
+ * the buddy control. Instead, the orientation is inherited when WS_EX_LAYOUTRTL
+ * is specified for the tab folder. This means that when both WS_EX_LAYOUTRTL
+ * and WS_EX_NOINHERITLAYOUT are specified for the tab folder, the buddy control
+ * will not be oriented correctly. The fix is to explicitly set the orientation
+ * for the buddy control.
+ *
+ * NOTE: WS_EX_LAYOUTRTL is not supported on Windows NT.
+ */
+ if ((OS.WIN32_MAJOR << 16 | OS.WIN32_MINOR) < (4 << 16 | 10)) return result;
+ if ((style & SWT.RIGHT_TO_LEFT) != 0) {
+ int code = wParam & 0xFFFF;
+ switch (code) {
+ case OS.WM_CREATE: {
+ int id = (wParam >> 16), hwnd = lParam;
+ if (id == ID_UPDOWN) {
+ int bits = OS.GetWindowLong (hwnd, OS.GWL_EXSTYLE);
+ OS.SetWindowLong (hwnd, OS.GWL_EXSTYLE, bits | OS.WS_EX_LAYOUTRTL);
+ }
+ break;
+ }
+ }
+ }
+ return result;
+}
+
LRESULT WM_SIZE (int wParam, int lParam) {
LRESULT result = super.WM_SIZE (wParam, lParam);
/*
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
index dbdae6a55b..e60bcfa09b 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
@@ -333,6 +333,7 @@ void createWidget () {
super.createWidget ();
doubleClick = true;
setTabStops (tabs = 8);
+ fixAlignment ();
}
/**
@@ -359,6 +360,42 @@ int defaultBackground () {
return OS.GetSysColor (OS.COLOR_WINDOW);
}
+void fixAlignment () {
+ /*
+ * Feature in Windows. When the edit control is not
+ * mirrored, it uses WS_EX_RIGHT, WS_EX_RTLREADING and
+ * WS_EX_LEFTSCROLLBAR to give the control a right to
+ * left appearance. This causes the control to be lead
+ * aligned no matter what alignment was specified by
+ * the programmer. For example, setting ES_RIGHT and
+ * WS_EX_LAYOUTRTL should cause the contents of the
+ * control to be left (trail) aligned in a mirrored world.
+ * When the orientation is changed by the user or
+ * specified by the programmer, WS_EX_RIGHT conflicts
+ * with the mirrored alignment. The fix is to clear
+ * or set WS_EX_RIGHT to achieve the correct alignment
+ * according to the orientation and mirroring.
+ */
+ if ((style & SWT.MIRRORED) != 0) return;
+ int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
+ if ((style & SWT.LEFT_TO_RIGHT) != 0) {
+ if ((style & SWT.RIGHT) != 0) {
+ bits |= OS.WS_EX_RIGHT;
+ }
+ if ((style & SWT.LEFT) != 0) {
+ bits &=~ OS.WS_EX_RIGHT;
+ }
+ } else {
+ if ((style & SWT.RIGHT) != 0) {
+ bits &=~ OS.WS_EX_RIGHT;
+ }
+ if ((style & SWT.LEFT) != 0) {
+ bits |= OS.WS_EX_RIGHT;
+ }
+ }
+ OS.SetWindowLong (handle, OS.GWL_EXSTYLE, bits);
+}
+
/**
* Gets the line number of the caret.
* <p>
@@ -1755,6 +1792,16 @@ LRESULT wmCommandChild (int wParam, int lParam) {
sendEvent (SWT.Modify);
if (isDisposed ()) return LRESULT.ZERO;
break;
+ case OS.EN_ALIGN_LTR_EC:
+ style &= ~SWT.RIGHT_TO_LEFT;
+ style |= SWT.LEFT_TO_RIGHT;
+ fixAlignment ();
+ break;
+ case OS.EN_ALIGN_RTL_EC:
+ style &= ~SWT.LEFT_TO_RIGHT;
+ style |= SWT.RIGHT_TO_LEFT;
+ fixAlignment ();
+ break;
}
return super.wmCommandChild (wParam, lParam);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tracker.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tracker.java
index 5c4c114efb..b327305563 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tracker.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tracker.java
@@ -406,6 +406,8 @@ public boolean open () {
tracking = true;
Event event = new Event ();
MSG msg = new MSG ();
+ boolean isMirrored = parent != null && (parent.style & SWT.MIRRORED) != 0;
+
/*
* If this tracker is being created without a mouse drag then
* we need to create a transparent window that fills the screen
@@ -495,13 +497,21 @@ public boolean open () {
event.x = newX;
event.y = newY;
if ((style & SWT.RESIZE) != 0) {
- resizeRectangles (newX - oldX, newY - oldY);
+ if (isMirrored) {
+ resizeRectangles (oldX - newX, newY - oldY);
+ } else {
+ resizeRectangles (newX - oldX, newY - oldY);
+ }
cursorPos = adjustResizeCursor ();
newX = cursorPos.x; newY = cursorPos.y;
inEvent = true;
sendEvent (SWT.Resize, event);
} else {
- moveRectangles (newX - oldX, newY - oldY);
+ if (isMirrored) {
+ moveRectangles (oldX - newX, newY - oldY);
+ } else {
+ moveRectangles (newX - oldX, newY - oldY);
+ }
inEvent = true;
sendEvent (SWT.Move, event);
}
@@ -534,10 +544,10 @@ public boolean open () {
tracking = false;
break;
case OS.VK_LEFT:
- xChange = -stepSize;
+ xChange = isMirrored ? stepSize : -stepSize;
break;
case OS.VK_RIGHT:
- xChange = stepSize;
+ xChange = isMirrored ? -stepSize : stepSize;
break;
case OS.VK_UP:
yChange = -stepSize;

Back to the top