Skip to content

Commit 38e6552

Browse files
ptzieglerpcdavid
authored andcommitted
[90] Fix cursor initialization when using fractional scaling
Recent Eclipse version support fractional zoom level as opposed to 100% or 200% zoom. Because no icons exist for those levels, an IllegalArgumentException is thrown when trying to create the corresponding cursors. In order to solve this, one has to consider the following cases: 1) Newer SWT versions provide a Cursor constructor that accepts an ImageDataProvider. This constructor always creates image data matching the device zoom. 2) Win32: Older SWT versions automatically upscale the image data to match the device zoom. Therefore the original image data must be at 100% zoom. 3) On other operating systems, the image data should be pre-scaled, as no further scaling is done by SWT. Bug: #90
1 parent eed618d commit 38e6552

File tree

1 file changed

+23
-22
lines changed
  • bundles/org.eclipse.gmf.runtime.gef.ui/src/org/eclipse/gmf/runtime/gef/ui/internal/l10n

1 file changed

+23
-22
lines changed
Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/******************************************************************************
2-
* Copyright (c) 2002, 2003 IBM Corporation and others.
2+
* Copyright (c) 2002, 2025 IBM Corporation and others.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -12,14 +12,18 @@
1212

1313
package org.eclipse.gmf.runtime.gef.ui.internal.l10n;
1414

15-
import org.eclipse.swt.graphics.Cursor;
15+
import java.lang.reflect.Constructor;
16+
import java.lang.reflect.InvocationTargetException;
1617

18+
import org.eclipse.jface.resource.ImageDescriptor;
19+
import org.eclipse.swt.graphics.Cursor;
20+
import org.eclipse.swt.graphics.Device;
21+
import org.eclipse.swt.graphics.ImageDataProvider;
1722

1823
/**
19-
* This is class that stores a series of globally accessible cursors.
24+
* Stores a series of globally accessible cursors.
2025
*
2126
* @author sshaw
22-
*
2327
*/
2428
public class Cursors {
2529

@@ -30,30 +34,27 @@ public class Cursors {
3034
public static final Cursor CURSOR_SEG_ADD;
3135

3236
/**
33-
* Constant define for a cusor used to move an existing line segment
37+
* Constant define for a cursor used to move an existing line segment
3438
*/
3539
public static final Cursor CURSOR_SEG_MOVE;
36-
37-
private static int deviceZoom = -1;
3840

3941
static {
40-
CURSOR_SEG_ADD = new Cursor(null, GefUIPluginImages.DESC_SEG_ADD.getImageData(getDeviceZoom()), 0, 0);
41-
CURSOR_SEG_MOVE = new Cursor(null, GefUIPluginImages.DESC_SEG_MOVE.getImageData(getDeviceZoom()), 0, 0);
42+
CURSOR_SEG_ADD = createCursor(GefUIPluginImages.DESC_SEG_ADD, 0, 0);
43+
CURSOR_SEG_MOVE = createCursor(GefUIPluginImages.DESC_SEG_MOVE, 0, 0);
4244
}
4345

44-
// Taken from org.eclipse.gef.SharedCursors.java
45-
private static int getDeviceZoom() {
46-
if (deviceZoom == -1) {
47-
deviceZoom = 100; // default value
48-
String deviceZoomProperty = System.getProperty("org.eclipse.swt.internal.deviceZoom"); //$NON-NLS-1$
49-
if (deviceZoomProperty != null) {
50-
try {
51-
deviceZoom = Integer.parseInt(deviceZoomProperty);
52-
} catch (NumberFormatException ex) {
53-
// if the property can not be parsed we keep the default 100% zoom level
54-
}
55-
}
46+
// Taken from org.eclipse.gef.internal.InternalGEFPlugin.java
47+
// https://github.com/eclipse-gef/gef-classic/blob/467992a631d37b3a5268765ad87bcae8425a9d21/org.eclipse.gef/src/org/eclipse/gef/internal/InternalGEFPlugin.java#L127
48+
private static Cursor createCursor(ImageDescriptor source, int hotspotX, int hotspotY) {
49+
try {
50+
Constructor<Cursor> ctor = Cursor.class.getConstructor(Device.class, ImageDataProvider.class, int.class,
51+
int.class);
52+
return ctor.newInstance(null, (ImageDataProvider) source::getImageData, hotspotX, hotspotY);
53+
} catch (NoSuchMethodException e) {
54+
// SWT version < 3.131.0 (no ImageDataProvider-based constructor)
55+
return new Cursor(null, source.getImageData(100), hotspotX, hotspotY); // older constructor
56+
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
57+
throw new RuntimeException("Failed to instantiate Cursor", e); //$NON-NLS-1$
5658
}
57-
return deviceZoom;
5859
}
5960
}

0 commit comments

Comments
 (0)