Skip to content

Commit 7887e1c

Browse files
ShahzaibIbrahimHeikoKlare
authored andcommitted
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 e2e8c1d commit 7887e1c

File tree

1 file changed

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

1 file changed

+166
-91
lines changed

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

Lines changed: 166 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,156 @@ void destroyHandlesExcept(Set<Integer> zoomLevels) {
578501
});
579502
}
580503

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

0 commit comments

Comments
 (0)