Skip to content

Commit b4fb738

Browse files
Refactor cursor handle creation using CursorHandleProvider abstraction
Replaces ad-hoc handle creation logic in win32_getHandle() with a new CursorHandleProvider abstract class. This class has three concrete implementations to cover the different input sources used to create a cursor: - StyleCursorHandleProvider: uses predefined cursor style ints. - ImageDataProviderCursorHandleProvider: uses ImageDataProvider for source. - ImageDataCursorHandleProvider: uses ImageData and mask directly. This eliminates the need for checking which cursor fields are set, and removes the problem of having multiple unused fields in Cursor. The abstract class defines a final helper method to create handles from scaled image data, centralizing logic and reducing duplication.
1 parent 7e6f2aa commit b4fb738

File tree

1 file changed

+173
-91
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+173
-91
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java

Lines changed: 173 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -68,24 +68,8 @@ public final class Cursor extends Resource {
6868

6969
private HashMap<Integer, Long> zoomLevelToHandle = new HashMap<>();
7070

71+
private final CursorHandleProvider cursorHandleProvider;
7172
boolean isIcon;
72-
private final ImageDataProvider imageDataProvider;
73-
private final ImageData source;
74-
private final ImageData mask;
75-
private final int hotspotX;
76-
private final int hotspotY;
77-
/**
78-
* Prevents uninitialized instances from being created outside the package.
79-
*/
80-
Cursor(Device device) {
81-
super(device);
82-
this.source = null;
83-
this.imageDataProvider = null;
84-
this.mask = null;
85-
this.hotspotX = -1;
86-
this.hotspotY = -1;
87-
this.device.registerResourceWithZoomSupport(this);
88-
}
8973

9074
/**
9175
* Constructs a new cursor given a device and a style
@@ -134,42 +118,11 @@ public final class Cursor extends Resource {
134118
* @see #dispose()
135119
*/
136120
public Cursor(Device device, int style) {
137-
this(device);
138-
this.handle = setupCursorFromStyle(style);
121+
super(device);
122+
this.cursorHandleProvider = new StyleCursorHandleProvider(style);
123+
this.handle = this.cursorHandleProvider.createHandle(this, DEFAULT_ZOOM);
139124
init();
140-
}
141-
142-
private static long setupCursorFromStyle(int style) {
143-
long lpCursorName = 0;
144-
switch (style) {
145-
case SWT.CURSOR_HAND: lpCursorName = OS.IDC_HAND; break;
146-
case SWT.CURSOR_ARROW: lpCursorName = OS.IDC_ARROW; break;
147-
case SWT.CURSOR_WAIT: lpCursorName = OS.IDC_WAIT; break;
148-
case SWT.CURSOR_CROSS: lpCursorName = OS.IDC_CROSS; break;
149-
case SWT.CURSOR_APPSTARTING: lpCursorName = OS.IDC_APPSTARTING; break;
150-
case SWT.CURSOR_HELP: lpCursorName = OS.IDC_HELP; break;
151-
case SWT.CURSOR_SIZEALL: lpCursorName = OS.IDC_SIZEALL; break;
152-
case SWT.CURSOR_SIZENESW: lpCursorName = OS.IDC_SIZENESW; break;
153-
case SWT.CURSOR_SIZENS: lpCursorName = OS.IDC_SIZENS; break;
154-
case SWT.CURSOR_SIZENWSE: lpCursorName = OS.IDC_SIZENWSE; break;
155-
case SWT.CURSOR_SIZEWE: lpCursorName = OS.IDC_SIZEWE; break;
156-
case SWT.CURSOR_SIZEN: lpCursorName = OS.IDC_SIZENS; break;
157-
case SWT.CURSOR_SIZES: lpCursorName = OS.IDC_SIZENS; break;
158-
case SWT.CURSOR_SIZEE: lpCursorName = OS.IDC_SIZEWE; break;
159-
case SWT.CURSOR_SIZEW: lpCursorName = OS.IDC_SIZEWE; break;
160-
case SWT.CURSOR_SIZENE: lpCursorName = OS.IDC_SIZENESW; break;
161-
case SWT.CURSOR_SIZESE: lpCursorName = OS.IDC_SIZENWSE; break;
162-
case SWT.CURSOR_SIZESW: lpCursorName = OS.IDC_SIZENESW; break;
163-
case SWT.CURSOR_SIZENW: lpCursorName = OS.IDC_SIZENWSE; break;
164-
case SWT.CURSOR_UPARROW: lpCursorName = OS.IDC_UPARROW; break;
165-
case SWT.CURSOR_IBEAM: lpCursorName = OS.IDC_IBEAM; break;
166-
case SWT.CURSOR_NO: lpCursorName = OS.IDC_NO; break;
167-
default:
168-
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
169-
}
170-
long handle = OS.LoadCursor(0, lpCursorName);
171-
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
172-
return handle;
125+
this.device.registerResourceWithZoomSupport(this);
173126
}
174127

175128
/**
@@ -207,12 +160,8 @@ private static long setupCursorFromStyle(int style) {
207160
*/
208161
public Cursor(Device device, ImageData source, ImageData mask, int hotspotX, int hotspotY) {
209162
super(device);
210-
this.source = source;
211-
this.mask = mask;
212-
this.hotspotX = hotspotX;
213-
this.hotspotY = hotspotY;
214-
this.imageDataProvider = null;
215-
this.handle = setupCursorFromImageData(source, mask, hotspotX, hotspotY);
163+
this.cursorHandleProvider = new ImageDataCursorHandleProvider(source, mask, hotspotX, hotspotY);
164+
this.handle = this.cursorHandleProvider.createHandle(this, DEFAULT_ZOOM);
216165
init();
217166
this.device.registerResourceWithZoomSupport(this);
218167
}
@@ -280,13 +229,9 @@ private static long setupCursorFromImageData(ImageData source, ImageData mask, i
280229
*/
281230
public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
282231
super(device);
283-
this.source = source;
284-
this.mask = null;
285-
this.hotspotX = hotspotX;
286-
this.hotspotY = hotspotY;
287-
this.imageDataProvider = null;
288-
this.handle = setupCursorFromImageData(device, source, hotspotX, hotspotY);
232+
this.cursorHandleProvider = new ImageDataCursorHandleProvider(source, null, hotspotX, hotspotY);
289233
isIcon = true;
234+
this.handle = this.cursorHandleProvider.createHandle(this, DEFAULT_ZOOM);
290235
init();
291236
this.device.registerResourceWithZoomSupport(this);
292237
}
@@ -397,13 +342,9 @@ private static long setupCursorFromImageData(Device device, ImageData source, in
397342
public Cursor(Device device, ImageDataProvider imageDataProvider, int hotspotX, int hotspotY) {
398343
super(device);
399344
if (imageDataProvider == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
400-
this.imageDataProvider = imageDataProvider;
401-
this.source = imageDataProvider.getImageData(100);
402-
this.mask = null;
403-
this.hotspotX = hotspotX;
404-
this.hotspotY = hotspotY;
405-
this.handle = setupCursorFromImageData(device, this.source, hotspotX, hotspotY);
345+
this.cursorHandleProvider = new ImageDataProviderCursorHandleProvider(imageDataProvider, hotspotX, hotspotY);
406346
isIcon = true;
347+
this.handle = this.cursorHandleProvider.createHandle(this, DEFAULT_ZOOM);
407348
init();
408349
this.device.registerResourceWithZoomSupport(this);
409350
}
@@ -431,27 +372,9 @@ public static Long win32_getHandle (Cursor cursor, int zoom) {
431372
return cursor.zoomLevelToHandle.get(zoom);
432373
}
433374

434-
if (cursor.source == null) {
435-
cursor.setHandleForZoomLevel(cursor.handle, zoom);
436-
} else {
437-
ImageData source;
438-
if (cursor.imageDataProvider != null) {
439-
Image tempImage = new Image(cursor.getDevice(), cursor.imageDataProvider);
440-
source = tempImage.getImageData(zoom);
441-
tempImage.dispose();
442-
}
443-
else {
444-
source = DPIUtil.scaleImageData(cursor.device, cursor.source, zoom, DEFAULT_ZOOM);
445-
}
446-
if (cursor.isIcon) {
447-
long handle = setupCursorFromImageData(cursor.getDevice(), source, Win32DPIUtils.pointToPixel(cursor.hotspotX, zoom), Win32DPIUtils.pointToPixel(cursor.hotspotY, zoom));
448-
cursor.setHandleForZoomLevel(handle, zoom);
449-
} else {
450-
ImageData mask = DPIUtil.scaleImageData(cursor.getDevice(), cursor.mask, zoom, DEFAULT_ZOOM);
451-
long handle = setupCursorFromImageData(source, mask, Win32DPIUtils.pointToPixel(cursor.hotspotX, zoom), Win32DPIUtils.pointToPixel(cursor.hotspotY, zoom));
452-
cursor.setHandleForZoomLevel(handle, zoom);
453-
}
454-
}
375+
long handle = cursor.cursorHandleProvider.createHandle(cursor, zoom);
376+
cursor.setHandleForZoomLevel(handle, zoom);
377+
455378
return cursor.zoomLevelToHandle.get(zoom);
456379
}
457380

@@ -578,4 +501,163 @@ void destroyHandlesExcept(Set<Integer> zoomLevels) {
578501
});
579502
}
580503

504+
private static final long createHandleFromImageData(Cursor cursor, int zoom, ImageData source, ImageData mask,
505+
int hotspotX, int hotspotY) {
506+
return cursor.isIcon ? setupCursorFromImageData(cursor.device, source, hotspotX, hotspotY)
507+
: setupCursorFromImageData(source, mask, hotspotX, hotspotY);
508+
}
509+
510+
private static interface CursorHandleProvider {
511+
long createHandle(Cursor cursor, int zoom);
512+
}
513+
514+
private static class StyleCursorHandleProvider implements CursorHandleProvider {
515+
private final int style;
516+
517+
public StyleCursorHandleProvider(int style) {
518+
this.style = style;
519+
}
520+
521+
@Override
522+
public long createHandle(Cursor cursor, int zoom) {
523+
// zoom ignored, LoadCursor handles scaling internally
524+
return setupCursorFromStyle(this.style);
525+
}
526+
527+
private static final long setupCursorFromStyle(int style) {
528+
long lpCursorName = 0;
529+
switch (style) {
530+
case SWT.CURSOR_HAND:
531+
lpCursorName = OS.IDC_HAND;
532+
break;
533+
case SWT.CURSOR_ARROW:
534+
lpCursorName = OS.IDC_ARROW;
535+
break;
536+
case SWT.CURSOR_WAIT:
537+
lpCursorName = OS.IDC_WAIT;
538+
break;
539+
case SWT.CURSOR_CROSS:
540+
lpCursorName = OS.IDC_CROSS;
541+
break;
542+
case SWT.CURSOR_APPSTARTING:
543+
lpCursorName = OS.IDC_APPSTARTING;
544+
break;
545+
case SWT.CURSOR_HELP:
546+
lpCursorName = OS.IDC_HELP;
547+
break;
548+
case SWT.CURSOR_SIZEALL:
549+
lpCursorName = OS.IDC_SIZEALL;
550+
break;
551+
case SWT.CURSOR_SIZENESW:
552+
lpCursorName = OS.IDC_SIZENESW;
553+
break;
554+
case SWT.CURSOR_SIZENS:
555+
lpCursorName = OS.IDC_SIZENS;
556+
break;
557+
case SWT.CURSOR_SIZENWSE:
558+
lpCursorName = OS.IDC_SIZENWSE;
559+
break;
560+
case SWT.CURSOR_SIZEWE:
561+
lpCursorName = OS.IDC_SIZEWE;
562+
break;
563+
case SWT.CURSOR_SIZEN:
564+
lpCursorName = OS.IDC_SIZENS;
565+
break;
566+
case SWT.CURSOR_SIZES:
567+
lpCursorName = OS.IDC_SIZENS;
568+
break;
569+
case SWT.CURSOR_SIZEE:
570+
lpCursorName = OS.IDC_SIZEWE;
571+
break;
572+
case SWT.CURSOR_SIZEW:
573+
lpCursorName = OS.IDC_SIZEWE;
574+
break;
575+
case SWT.CURSOR_SIZENE:
576+
lpCursorName = OS.IDC_SIZENESW;
577+
break;
578+
case SWT.CURSOR_SIZESE:
579+
lpCursorName = OS.IDC_SIZENWSE;
580+
break;
581+
case SWT.CURSOR_SIZESW:
582+
lpCursorName = OS.IDC_SIZENESW;
583+
break;
584+
case SWT.CURSOR_SIZENW:
585+
lpCursorName = OS.IDC_SIZENWSE;
586+
break;
587+
case SWT.CURSOR_UPARROW:
588+
lpCursorName = OS.IDC_UPARROW;
589+
break;
590+
case SWT.CURSOR_IBEAM:
591+
lpCursorName = OS.IDC_IBEAM;
592+
break;
593+
case SWT.CURSOR_NO:
594+
lpCursorName = OS.IDC_NO;
595+
break;
596+
default:
597+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
598+
}
599+
long handle = OS.LoadCursor(0, lpCursorName);
600+
if (handle == 0) {
601+
SWT.error(SWT.ERROR_NO_HANDLES);
602+
}
603+
return handle;
604+
}
605+
}
606+
607+
private static class ImageDataProviderCursorHandleProvider implements CursorHandleProvider {
608+
private final ImageDataProvider provider;
609+
private final int hotspotX;
610+
private final int hotspotY;
611+
612+
public ImageDataProviderCursorHandleProvider(ImageDataProvider provider, int hotspotX, int hotspotY) {
613+
this.provider = provider;
614+
this.hotspotX = hotspotX;
615+
this.hotspotY = hotspotY;
616+
}
617+
618+
@Override
619+
public long createHandle(Cursor cursor, int zoom) {
620+
ImageData source;
621+
if (zoom == DEFAULT_ZOOM) {
622+
source = this.provider.getImageData(DEFAULT_ZOOM);
623+
} else {
624+
Image tempImage = new Image(cursor.device, this.provider);
625+
source = tempImage.getImageData(zoom);
626+
tempImage.dispose();
627+
}
628+
int hotspotXInPixels = Win32DPIUtils.pointToPixel(hotspotX, zoom);
629+
int hotspotYInPixels = Win32DPIUtils.pointToPixel(hotspotY, zoom);
630+
long handle = createHandleFromImageData(cursor, zoom, source, null, hotspotXInPixels, hotspotYInPixels);
631+
632+
return handle;
633+
}
634+
}
635+
636+
private static class ImageDataCursorHandleProvider implements CursorHandleProvider {
637+
private final ImageData source;
638+
private final ImageData mask;
639+
private final int hotspotX;
640+
private final int hotspotY;
641+
642+
public ImageDataCursorHandleProvider(ImageData source, ImageData mask, int hotspotX, int hotspotY) {
643+
this.source = source;
644+
this.mask = mask;
645+
this.hotspotX = hotspotX;
646+
this.hotspotY = hotspotY;
647+
}
648+
649+
@Override
650+
public long createHandle(Cursor cursor, int zoom) {
651+
ImageData scaledSource = DPIUtil.scaleImageData(cursor.device, this.source, zoom, DEFAULT_ZOOM);
652+
ImageData scaledMask = this.mask != null ? DPIUtil.scaleImageData(cursor.device, mask, zoom, DEFAULT_ZOOM)
653+
: null;
654+
int hotspotXInPixels = Win32DPIUtils.pointToPixel(hotspotX, zoom);
655+
int hotspotYInPixels = Win32DPIUtils.pointToPixel(hotspotY, zoom);
656+
long handle = createHandleFromImageData(cursor, zoom, scaledSource, scaledMask, hotspotXInPixels,
657+
hotspotYInPixels);
658+
659+
return handle;
660+
}
661+
}
662+
581663
}

0 commit comments

Comments
 (0)