1 /*
   2  * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene;
  27 
  28 import static javafx.scene.image.TestImages.TEST_IMAGE_0x100;
  29 import static javafx.scene.image.TestImages.TEST_IMAGE_100x0;
  30 import static javafx.scene.image.TestImages.TEST_IMAGE_100x200;
  31 import static javafx.scene.image.TestImages.TEST_IMAGE_200x100;
  32 import static javafx.scene.image.TestImages.TEST_IMAGE_32x32;
  33 import static org.junit.Assert.assertEquals;
  34 import static org.junit.Assert.assertSame;
  35 
  36 import javafx.beans.InvalidationListener;
  37 import javafx.beans.Observable;
  38 import javafx.geometry.Dimension2D;
  39 import javafx.scene.image.Image;
  40 import javafx.scene.image.TestImages;
  41 
  42 import org.junit.AfterClass;
  43 import org.junit.BeforeClass;
  44 import org.junit.Test;
  45 
  46 import com.sun.javafx.pgstub.CursorSizeConverter;
  47 import com.sun.javafx.pgstub.StubAsyncImageLoader;
  48 import com.sun.javafx.pgstub.StubImageLoaderFactory;
  49 import com.sun.javafx.pgstub.StubPlatformImageInfo;
  50 import com.sun.javafx.pgstub.StubToolkit;
  51 import com.sun.javafx.test.PropertyInvalidationCounter;
  52 import com.sun.javafx.tk.Toolkit;
  53 
  54 public final class ImageCursorTest {
  55     private static StubToolkit toolkit;
  56 
  57     private static CursorSizeConverter oldCursorSizeConverter;
  58     private static int oldMaximumCursorColors;
  59 
  60     @BeforeClass
  61     public static void setUpClass() {
  62         toolkit = (StubToolkit) Toolkit.getToolkit();
  63 
  64         oldCursorSizeConverter = toolkit.getCursorSizeConverter();
  65         oldMaximumCursorColors = toolkit.getMaximumCursorColors();
  66     }
  67 
  68     @AfterClass
  69     public static void tearDownClass() {
  70         toolkit.setCursorSizeConverter(oldCursorSizeConverter);
  71         toolkit.setMaximumCursorColors(oldMaximumCursorColors);
  72     }
  73 
  74     @Test
  75     public void constructionTest() {
  76         assertCursorEquals(new ImageCursor(), null, 0, 0);
  77         assertCursorEquals(new ImageCursor(null), null, 0, 0);
  78         assertCursorEquals(new ImageCursor(null, 100, 200), null, 0, 0);
  79         assertCursorEquals(new ImageCursor(TEST_IMAGE_0x100, 100, 200),
  80                            TestImages.TEST_IMAGE_0x100, 0, 0);
  81         assertCursorEquals(new ImageCursor(TEST_IMAGE_100x0, 200, 100),
  82                            TestImages.TEST_IMAGE_100x0, 0, 0);
  83         assertCursorEquals(new ImageCursor(TEST_IMAGE_100x200, 20, 10),
  84                            TestImages.TEST_IMAGE_100x200, 20, 10);
  85         assertCursorEquals(new ImageCursor(TEST_IMAGE_200x100, 10, 20),
  86                            TestImages.TEST_IMAGE_200x100, 10, 20);
  87         assertCursorEquals(new ImageCursor(TEST_IMAGE_100x200, -50, -100),
  88                            TestImages.TEST_IMAGE_100x200, 0, 0);
  89         assertCursorEquals(new ImageCursor(TEST_IMAGE_200x100, 300, 150),
  90                            TestImages.TEST_IMAGE_200x100, 199, 99);
  91     }
  92 
  93     @Test
  94     public void constructionAsyncImageTest() {
  95         final StubImageLoaderFactory imageLoaderFactory =
  96                 toolkit.getImageLoaderFactory();
  97 
  98         final String url = "file:test.png";
  99         imageLoaderFactory.registerImage(
 100                 url, new StubPlatformImageInfo(48, 48));
 101 
 102         final Image testImage = new Image(url, true);
 103         final StubAsyncImageLoader asyncImageLoader =
 104                 imageLoaderFactory.getLastAsyncImageLoader();
 105         final ImageCursor testCursor = new ImageCursor(testImage, 100, 24);
 106 
 107         asyncImageLoader.finish();
 108 
 109         assertCursorEquals(testCursor, testImage, 47, 24);
 110     }
 111     
 112     @Test
 113     public void getBestSizeTest() {
 114         toolkit.setCursorSizeConverter(CursorSizeConverter.IDENTITY_CONVERTER);
 115 
 116         assertEquals(new Dimension2D(10, 20), ImageCursor.getBestSize(10, 20));
 117         assertEquals(new Dimension2D(20, 10), ImageCursor.getBestSize(20, 10));
 118 
 119         toolkit.setCursorSizeConverter(
 120                 CursorSizeConverter.createConstantConverter(32, 24));
 121         assertEquals(new Dimension2D(32, 24), ImageCursor.getBestSize(10, 20));
 122 
 123         toolkit.setCursorSizeConverter(
 124                 CursorSizeConverter.createConstantConverter(24, 32));
 125         assertEquals(new Dimension2D(24, 32), ImageCursor.getBestSize(20, 10));
 126     }
 127 
 128     @Test
 129     public void getMaximumColorsTest() {
 130         toolkit.setMaximumCursorColors(16);
 131         assertEquals(16, ImageCursor.getMaximumColors());
 132 
 133         toolkit.setMaximumCursorColors(256);
 134         assertEquals(256, ImageCursor.getMaximumColors());
 135     }
 136 
 137     @Test
 138     public void findBestImageSpecialCasesTest() {
 139         toolkit.setCursorSizeConverter(
 140                 CursorSizeConverter.createConstantConverter(16, 16));
 141         assertCursorEquals(ImageCursor.chooseBestCursor(new Image[0], 10, 20),
 142                            null, 0, 0);
 143 
 144         final Image[] deformedImages = { TEST_IMAGE_0x100, TEST_IMAGE_100x0 };
 145         assertCursorEquals(ImageCursor.chooseBestCursor(deformedImages, 0, 0),
 146                            TEST_IMAGE_0x100, 0, 0);
 147 
 148         final Image[] singleImage = { TEST_IMAGE_200x100 };
 149         assertCursorEquals(ImageCursor.chooseBestCursor(singleImage, 10, 20),
 150                            TEST_IMAGE_200x100, 10, 20);
 151 
 152         toolkit.setCursorSizeConverter(
 153                 CursorSizeConverter.createConstantConverter(0, 16));
 154         assertCursorEquals(ImageCursor.chooseBestCursor(singleImage, 10, 20),
 155                            null, 0, 0);
 156 
 157         toolkit.setCursorSizeConverter(
 158                 CursorSizeConverter.createConstantConverter(16, 0));
 159         assertCursorEquals(ImageCursor.chooseBestCursor(singleImage, 10, 20),
 160                            null, 0, 0);
 161 
 162         toolkit.setCursorSizeConverter(
 163                 new CursorSizeConverter() {
 164                     @Override
 165                     public Dimension2D getBestCursorSize(
 166                             final int preferredWidth,
 167                             final int preferredHeight) {
 168                         if (preferredWidth < preferredHeight) {
 169                             return new Dimension2D(preferredWidth, 0);
 170                         } else if (preferredWidth > preferredHeight) {
 171                             return new Dimension2D(0, preferredHeight);
 172                         }
 173 
 174                         return new Dimension2D(16, 16);
 175                     }
 176                 });
 177         final Image[] twoImages = { TEST_IMAGE_100x200, TEST_IMAGE_200x100 };
 178         assertCursorEquals(ImageCursor.chooseBestCursor(twoImages, 0, 0),
 179                            TEST_IMAGE_100x200, 0, 0);
 180     }
 181 
 182     @Test
 183     public void findBestImageFromAsyncImagesTest() {
 184         final StubImageLoaderFactory imageLoaderFactory =
 185                 toolkit.getImageLoaderFactory();
 186 
 187         final String url32x48 = "file:image_32x48.png";
 188         imageLoaderFactory.registerImage(
 189                 url32x48, new StubPlatformImageInfo(32, 48));
 190 
 191         final String url48x48 = "file:image_48x48.png";
 192         imageLoaderFactory.registerImage(
 193                 url48x48, new StubPlatformImageInfo(48, 48));
 194 
 195         final Image asyncImage32x48 = new Image(url32x48, true);
 196         final StubAsyncImageLoader asyncImage32x48loader =
 197                 imageLoaderFactory.getLastAsyncImageLoader();
 198         
 199         final Image asyncImage48x48 = new Image(url48x48, true);
 200         final StubAsyncImageLoader asyncImage48x48loader =
 201                 imageLoaderFactory.getLastAsyncImageLoader();
 202 
 203         final Image[] cursorImages = {
 204                 TEST_IMAGE_32x32,
 205                 asyncImage32x48,
 206                 asyncImage48x48
 207         };
 208 
 209         toolkit.setCursorSizeConverter(
 210                 CursorSizeConverter.createConstantConverter(48, 48));
 211         final ImageCursor selectedCursor =
 212                 ImageCursor.chooseBestCursor(cursorImages, 32, 32);
 213 
 214         asyncImage32x48loader.setProgress(50, 100);
 215         asyncImage32x48loader.finish();
 216         asyncImage48x48loader.finish();
 217 
 218         assertCursorEquals(selectedCursor,
 219                            asyncImage48x48, 47, 47);
 220     }
 221 
 222     @Test
 223     public void imageCursorPropertyListenersCalledOnceTest() {
 224         final StubImageLoaderFactory imageLoaderFactory =
 225                 toolkit.getImageLoaderFactory();
 226 
 227         final String url = "file:test.png";
 228         imageLoaderFactory.registerImage(
 229                 url, new StubPlatformImageInfo(32, 32));
 230 
 231         final Image testImage = new Image(url, true);
 232         final StubAsyncImageLoader asyncImageLoader =
 233                 imageLoaderFactory.getLastAsyncImageLoader();
 234         final ImageCursor testCursor = new ImageCursor(testImage, 16, 16);
 235 
 236         final PropertyInvalidationCounter<Number> hotspotXInvalidationCounter =
 237                 new PropertyInvalidationCounter<Number>();
 238         final PropertyInvalidationCounter<Number> hotspotYInvalidationCounter =
 239                 new PropertyInvalidationCounter<Number>();
 240         final PropertyInvalidationCounter<Object> imageInvalidationCounter =
 241                 new PropertyInvalidationCounter<Object>();
 242 
 243         testCursor.hotspotXProperty().addListener(hotspotXInvalidationCounter);
 244         testCursor.hotspotYProperty().addListener(hotspotYInvalidationCounter);
 245         testCursor.imageProperty().addListener(imageInvalidationCounter);
 246 
 247         assertCursorEquals(testCursor, null, 0, 0);
 248 
 249         asyncImageLoader.finish();
 250 
 251         assertEquals(1, hotspotXInvalidationCounter.getCounter());
 252         assertEquals(1, hotspotYInvalidationCounter.getCounter());
 253         assertEquals(1, imageInvalidationCounter.getCounter());
 254     }
 255 
 256     @Test
 257     public void imageCursorPropertiesChangedAtomicallyTest() {
 258         final StubImageLoaderFactory imageLoaderFactory =
 259                 toolkit.getImageLoaderFactory();
 260 
 261         final String url = "file:test.png";
 262         imageLoaderFactory.registerImage(
 263                 url, new StubPlatformImageInfo(32, 32));
 264 
 265         final Image testImage = new Image(url, true);
 266         final StubAsyncImageLoader asyncImageLoader =
 267                 imageLoaderFactory.getLastAsyncImageLoader();
 268         final ImageCursor testCursor = new ImageCursor(testImage, 16, 16);
 269 
 270         final InvalidationListener imageCursorChecker =
 271                 observable -> assertCursorEquals(testCursor, testImage, 16, 16);
 272 
 273         testCursor.hotspotXProperty().addListener(imageCursorChecker);
 274         testCursor.hotspotYProperty().addListener(imageCursorChecker);
 275         testCursor.imageProperty().addListener(imageCursorChecker);
 276 
 277         asyncImageLoader.finish();
 278     }
 279 
 280     public static void assertCursorEquals(final ImageCursor cursor,
 281                                           final Image image,
 282                                           final float hotspotX,
 283                                           final float hotspotY) {
 284         assertSame(image, cursor.getImage());
 285         assertEquals(hotspotX, cursor.getHotspotX(), 0);
 286         assertEquals(hotspotY, cursor.getHotspotY(), 0);
 287     }
 288 }