LRESULT WM_MOUSEMOVE(int /*long*/ wParam, int /*long*/ lParam) { LRESULT result = super.WM_MOUSEMOVE(wParam, lParam); if (OS.COMCTL32_MAJOR < 6) { int x = OS.GET_X_LPARAM(lParam); int y = OS.GET_Y_LPARAM(lParam); if (OS.GetKeyState(OS.VK_LBUTTON) < 0) { int oldSelection = selection.y; selection.y = layout.getOffset(x, y, null); if (selection.y != oldSelection) { int newSelection = selection.y; if (oldSelection > newSelection) { int temp = oldSelection; oldSelection = newSelection; newSelection = temp; } Rectangle rect = layout.getBounds(oldSelection, newSelection); redraw(rect.x, rect.y, rect.width, rect.height, false); } } else { for (int j = 0; j < offsets.length; j++) { Rectangle[] rects = getRectangles(j); for (int i = 0; i < rects.length; i++) { Rectangle rect = rects[i]; if (rect.contains(x, y)) { setCursor(display.getSystemCursor(SWT.CURSOR_HAND)); return result; } } } setCursor(null); } } return result; }
@Override long /*int*/ gtk_button_press_event(long /*int*/ widget, long /*int*/ event) { long /*int*/ result = super.gtk_button_press_event(widget, event); if (result != 0) return result; GdkEventButton gdkEvent = new GdkEventButton(); OS.memmove(gdkEvent, event, GdkEventButton.sizeof); if (gdkEvent.button == 1 && gdkEvent.type == OS.GDK_BUTTON_PRESS) { if (focusIndex != -1) setFocus(); int x = (int) gdkEvent.x; int y = (int) gdkEvent.y; if ((style & SWT.MIRRORED) != 0) x = getClientWidth() - x; int offset = layout.getOffset(x, y, null); int oldSelectionX = selection.x; int oldSelectionY = selection.y; selection.x = offset; selection.y = -1; if (oldSelectionX != -1 && oldSelectionY != -1) { if (oldSelectionX > oldSelectionY) { int temp = oldSelectionX; oldSelectionX = oldSelectionY; oldSelectionY = temp; } Rectangle rect = layout.getBounds(oldSelectionX, oldSelectionY); redraw(rect.x, rect.y, rect.width, rect.height, false); } for (int j = 0; j < offsets.length; j++) { Rectangle[] rects = getRectangles(j); for (int i = 0; i < rects.length; i++) { Rectangle rect = rects[i]; if (rect.contains(x, y)) { focusIndex = j; redraw(); return result; } } } } return result; }
LRESULT WM_LBUTTONDOWN(int /*long*/ wParam, int /*long*/ lParam) { LRESULT result = super.WM_LBUTTONDOWN(wParam, lParam); if (result == LRESULT.ZERO) return result; if (OS.COMCTL32_MAJOR < 6) { if (focusIndex != -1) setFocus(); int x = OS.GET_X_LPARAM(lParam); int y = OS.GET_Y_LPARAM(lParam); int offset = layout.getOffset(x, y, null); int oldSelectionX = selection.x; int oldSelectionY = selection.y; selection.x = offset; selection.y = -1; if (oldSelectionX != -1 && oldSelectionY != -1) { if (oldSelectionX > oldSelectionY) { int temp = oldSelectionX; oldSelectionX = oldSelectionY; oldSelectionY = temp; } Rectangle rect = layout.getBounds(oldSelectionX, oldSelectionY); redraw(rect.x, rect.y, rect.width, rect.height, false); } for (int j = 0; j < offsets.length; j++) { Rectangle[] rects = getRectangles(j); for (int i = 0; i < rects.length; i++) { Rectangle rect = rects[i]; if (rect.contains(x, y)) { if (j != focusIndex) { redraw(); } focusIndex = mouseDownIndex = j; return result; } } } } return result; }
@Override long /*int*/ gtk_motion_notify_event(long /*int*/ widget, long /*int*/ event) { long /*int*/ result = super.gtk_motion_notify_event(widget, event); if (result != 0) return result; GdkEventMotion gdkEvent = new GdkEventMotion(); OS.memmove(gdkEvent, event, GdkEventMotion.sizeof); int x = (int) gdkEvent.x; int y = (int) gdkEvent.y; if ((style & SWT.MIRRORED) != 0) x = getClientWidth() - x; if ((gdkEvent.state & OS.GDK_BUTTON1_MASK) != 0) { int oldSelection = selection.y; selection.y = layout.getOffset(x, y, null); if (selection.y != oldSelection) { int newSelection = selection.y; if (oldSelection > newSelection) { int temp = oldSelection; oldSelection = newSelection; newSelection = temp; } Rectangle rect = layout.getBounds(oldSelection, newSelection); redraw(rect.x, rect.y, rect.width, rect.height, false); } } else { for (int j = 0; j < offsets.length; j++) { Rectangle[] rects = getRectangles(j); for (int i = 0; i < rects.length; i++) { Rectangle rect = rects[i]; if (rect.contains(x, y)) { setCursor(display.getSystemCursor(SWT.CURSOR_HAND)); return result; } } } setCursor(null); } return result; }
@Test public void test_getOffset() { boolean isCocoa = SwtTestUtil.isCocoa; if (isCocoa) { // TODO Fix Cocoa failure. if (SwtTestUtil.verbose) { System.out.println( "Partially excluded test_getOffset(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout)."); } } TextLayout layout = new TextLayout(display); String text = "AB \u05E9\u05E0 CD\nHello"; layout.setText(text); int[] trailing = new int[1]; assertEquals(0, layout.getOffset(0, 0, trailing)); assertEquals(0, trailing[0]); Point point = layout.getLocation(0, true); assertEquals(1, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(0, trailing[0]); point = layout.getLocation(1, false); assertEquals(0, layout.getOffset(point.x - 1, 0, trailing)); assertEquals(1, trailing[0]); point = layout.getLocation(2, true); assertEquals(4, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(1, trailing[0]); point = layout.getLocation(4, true); assertEquals(2, layout.getOffset(point.x - 1, 0, trailing)); assertEquals(1, trailing[0]); point = layout.getLocation(4, false); assertEquals(3, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(1, trailing[0]); Rectangle bounds = layout.getBounds(); layout.setWidth(bounds.width + 100); layout.setAlignment(SWT.CENTER); assertEquals(0, layout.getOffset(0, 0, trailing)); assertEquals(0, trailing[0]); point = layout.getLocation(0, true); assertEquals(1, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(0, trailing[0]); point = layout.getLocation(1, false); assertEquals(0, layout.getOffset(point.x - 1, 0, trailing)); assertEquals(1, trailing[0]); point = layout.getLocation(2, true); assertEquals(4, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(1, trailing[0]); point = layout.getLocation(4, true); assertEquals(2, layout.getOffset(point.x - 1, 0, trailing)); assertEquals(1, trailing[0]); point = layout.getLocation(4, false); assertEquals(3, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(1, trailing[0]); layout.setAlignment(SWT.RIGHT); assertEquals(0, layout.getOffset(0, 0, trailing)); assertEquals(0, trailing[0]); point = layout.getLocation(0, true); assertEquals(1, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(0, trailing[0]); point = layout.getLocation(1, false); assertEquals(0, layout.getOffset(point.x - 1, 0, trailing)); assertEquals(1, trailing[0]); point = layout.getLocation(2, true); assertEquals(4, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(1, trailing[0]); point = layout.getLocation(4, true); assertEquals(2, layout.getOffset(point.x - 1, 0, trailing)); if (!isCocoa) assertEquals(1, trailing[0]); point = layout.getLocation(4, false); assertEquals(3, layout.getOffset(point.x + 1, 0, trailing)); assertEquals(1, trailing[0]); text = "Text"; layout.setText(text); int width = layout.getBounds().width; layout.setAlignment(SWT.LEFT); assertEquals(0, layout.getOffset(1, 0, null)); assertEquals(text.length() - 1, layout.getOffset(width - 1, 0, null)); layout.setWidth(width + 100); layout.setAlignment(SWT.CENTER); assertEquals(0, layout.getOffset(1 + 50, 0, null)); assertEquals(text.length() - 1, layout.getOffset(width - 1 + 50, 0, null)); layout.setAlignment(SWT.RIGHT); assertEquals(0, layout.getOffset(1 + 100, 0, null)); assertEquals(text.length() - 1, layout.getOffset(width - 1 + 100, 0, null)); layout.dispose(); }
@Test public void test_getSegments() { TextLayout layout = new TextLayout(display); layout.setText("AB"); String[] messages = { "no segments", "segments", "segments (duplicate at 0)", "segments (duplicate at 1)", "segments (duplicate at 2)" }; int[][] segments = {null, {0, 1, 2}, {0, 0, 1, 2}, {0, 1, 1, 2}, {0, 1, 2, 2}}; for (int i = 0; i < segments.length; i++) { String m = messages[i]; layout.setSegments(segments[i]); assertEquals(m, 1, layout.getNextOffset(0, SWT.MOVEMENT_CLUSTER)); assertEquals(m, 2, layout.getNextOffset(1, SWT.MOVEMENT_CLUSTER)); assertEquals(m, 2, layout.getNextOffset(2, SWT.MOVEMENT_CLUSTER)); assertEquals(m, 1, layout.getPreviousOffset(2, SWT.MOVEMENT_CLUSTER)); assertEquals(m, 0, layout.getPreviousOffset(1, SWT.MOVEMENT_CLUSTER)); assertEquals(m, 0, layout.getPreviousOffset(0, SWT.MOVEMENT_CLUSTER)); } // Bug 295513 layout.setText("Line"); layout.setAscent(20); layout.setDescent(6); layout.setSegments(new int[] {0, layout.getText().length()}); layout.getBounds(); layout.dispose(); layout = new TextLayout(display); // Bug 241482 comment 74 layout.setText("word word word"); layout.setSegments(new int[] {0, 5, 10}); int offset = 0; offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START); assertEquals(5, offset); offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START); assertEquals(10, offset); offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START); assertEquals(14, offset); layout.setWidth(layout.getBounds().width / 2); layout.setAscent(20); layout.setDescent(6); offset = 0; offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START); assertEquals(5, offset); offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START); assertEquals(10, offset); offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START); assertEquals(14, offset); layout.dispose(); layout = new TextLayout(display); // Bug 241482 comment 64 layout.setText("\nAB"); layout.setSegments(new int[] {0, 1, 3}); int[] expected = new int[] {0, 1, 3}; int[] offsets = layout.getLineOffsets(); for (int i = 0; i < offsets.length; i++) { assertEquals(" i = " + i, expected[i], offsets[i]); } layout.dispose(); layout = new TextLayout(display); // Bug 241482 comment 80 layout.setText("MNMNMN"); layout.setSegments(new int[] {0, 1, 6}); layout.getBounds(); assertEquals( layout.getText().length() - 1, layout.getOffset(layout.getBounds().width, 0, null)); layout.setAscent(9); assertEquals( layout.getText().length() - 1, layout.getOffset(layout.getBounds().width, 0, null)); layout.dispose(); layout = new TextLayout(display); // Bug 486600 comment 2 layout.setText("Abcdef\nGhij\nKl"); Rectangle bounds1 = layout.getBounds(0, 6 - 1); int[] trailing = new int[1]; offset = layout.getOffset(bounds1.width, bounds1.height + 2, trailing); assertEquals(10, offset); assertEquals(1, trailing[0]); layout.dispose(); layout = new TextLayout(display); layout.setText("AbcdefGhijKl"); layout.setSegments(new int[] {6, 10}); layout.setSegmentsChars(new char[] {'\n', '\n'}); bounds1 = layout.getBounds(0, 6 - 1); trailing = new int[1]; offset = layout.getOffset(bounds1.width, bounds1.height + 2, trailing); assertEquals(9, offset); assertEquals(1, trailing[0]); layout.dispose(); layout = new TextLayout(display); // Lina's bug (bug 241482, comment 37) boolean doit = false; // known to be broken if (doit) { int length = layout.getText().length(); layout.setSegments(new int[] {length}); trailing = new int[1]; int width = layout.getBounds().width + 20; assertEquals("hit test to the left", 0, layout.getOffset(0, 0, trailing)); assertEquals("hit test to the left (trailing)", 0, trailing[0]); assertEquals("hit test to the right", length - 1, layout.getOffset(width, 0, trailing)); assertEquals("hit test to the right (trailing)", 1, trailing[0]); layout.setSegmentsChars(new char[] {'*'}); assertEquals("hit test to the left", 0, layout.getOffset(0, 0, trailing)); assertEquals("hit test to the left (trailing)", 0, trailing[0]); assertEquals("hit test to the right", length - 1, layout.getOffset(width, 0, trailing)); assertEquals("hit test to the right (trailing)", 1, trailing[0]); } /* wrong: internal testing */ // String text = "AB"; // int textLength = text.length(); // layout.setText(text); // messages = new String [] { // "no segments", // "segments", // "segments (duplicate at 0)", // "segments (duplicate at 1)", // "segments (duplicate at 2)" }; // segments = new int [][] { // null, // { 0, 1, 2 }, // { 0, 0, 1, 2 }, // { 0, 1, 1, 2 }, // { 0, 1, 2, 2 } }; // int[][] translatedOffsets = { // { 0, 1, 2 }, // { 1, 3, 5 }, // { 2, 4, 6 }, // { 1, 4, 6 }, // { 1, 3, 6 } }; // int[][] untranslatedOffsets = { // { 0, 1, 2 }, // { 0, 0, 1, 1, 2, 2 }, // { 0, 0, 0, 1, 1, 2, 2 }, // { 0, 0, 1, 1, 1, 2, 2 }, // { 0, 0, 1, 1, 2, 2, 2 } }; // for (int i = 0; i < segments.length; i++) { // layout.setSegments(segments[i]); // layout.getBounds(); // for (int j = 0; j <= textLength; j++) { // assertEquals(messages[i] + " j = " + j, translatedOffsets[i][j], // layout.translateOffset(j)); // } // for (int j = 0, n = layout.getSegments() == null ? 0 : textLength + // layout.getSegments().length; j < n; j++) { // assertEquals(messages[i] + " j = " + j, untranslatedOffsets[i][j], // layout.untranslateOffset(j)); // } // } layout.dispose(); }