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 test.javafx.scene;
  27 
  28 import static test.javafx.scene.image.TestImages.TEST_IMAGE_0x100;
  29 import static test.javafx.scene.image.TestImages.TEST_IMAGE_100x0;
  30 import static test.javafx.scene.image.TestImages.TEST_IMAGE_100x200;
  31 import static test.javafx.scene.image.TestImages.TEST_IMAGE_200x100;
  32 import static test.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 test.javafx.scene.image.TestImages;
  41 
  42 import org.junit.AfterClass;
  43 import org.junit.BeforeClass;
  44 import org.junit.Test;
  45 
  46 import test.com.sun.javafx.pgstub.CursorSizeConverter;
  47 import test.com.sun.javafx.pgstub.StubAsyncImageLoader;
  48 import test.com.sun.javafx.pgstub.StubImageLoaderFactory;
  49 import test.com.sun.javafx.pgstub.StubPlatformImageInfo;
  50 import test.com.sun.javafx.pgstub.StubToolkit;
  51 import test.com.sun.javafx.test.PropertyInvalidationCounter;
  52 import com.sun.javafx.tk.Toolkit;
  53 import javafx.scene.ImageCursor;
  54 
  55 public final class ImageCursorTest {
  56     private static StubToolkit toolkit;
  57 
  58     private static CursorSizeConverter oldCursorSizeConverter;
  59     private static int oldMaximumCursorColors;
  60 
  61     @BeforeClass
  62     public static void setUpClass() {
  63         toolkit = (StubToolkit) Toolkit.getToolkit();
  64 
  65         oldCursorSizeConverter = toolkit.getCursorSizeConverter();
  66         oldMaximumCursorColors = toolkit.getMaximumCursorColors();
  67     }
  68 
  69     @AfterClass
  70     public static void tearDownClass() {
  71         toolkit.setCursorSizeConverter(oldCursorSizeConverter);
  72         toolkit.setMaximumCursorColors(oldMaximumCursorColors);
  73     }
  74 
  75     @Test
  76     public void constructionTest() {
  77         assertCursorEquals(new ImageCursor(), null, 0, 0);
  78         assertCursorEquals(new ImageCursor(null), null, 0, 0);
  79         assertCursorEquals(new ImageCursor(null, 100, 200), null, 0, 0);
  80         assertCursorEquals(new ImageCursor(TEST_IMAGE_0x100, 100, 200),
  81                            TestImages.TEST_IMAGE_0x100, 0, 0);
  82         assertCursorEquals(new ImageCursor(TEST_IMAGE_100x0, 200, 100),
  83                            TestImages.TEST_IMAGE_100x0, 0, 0);
  84         assertCursorEquals(new ImageCursor(TEST_IMAGE_100x200, 20, 10),
  85                            TestImages.TEST_IMAGE_100x200, 20, 10);
  86         assertCursorEquals(new ImageCursor(TEST_IMAGE_200x100, 10, 20),
  87                            TestImages.TEST_IMAGE_200x100, 10, 20);
  88         assertCursorEquals(new ImageCursor(TEST_IMAGE_100x200, -50, -100),
  89                            TestImages.TEST_IMAGE_100x200, 0, 0);
  90         assertCursorEquals(new ImageCursor(TEST_IMAGE_200x100, 300, 150),
  91                            TestImages.TEST_IMAGE_200x100, 199, 99);
  92     }
  93 
  94     @Test
  95     public void constructionAsyncImageTest() {
  96         final StubImageLoaderFactory imageLoaderFactory =
  97                 toolkit.getImageLoaderFactory();
  98 
  99         final String url = "file:test.png";
 100         imageLoaderFactory.registerImage(
 101                 url, new StubPlatformImageInfo(48, 48));
 102 
 103         final Image testImage = new Image(url, true);
 104         final StubAsyncImageLoader asyncImageLoader =
 105                 imageLoaderFactory.getLastAsyncImageLoader();
 106         final ImageCursor testCursor = new ImageCursor(testImage, 100, 24);
 107 
 108         asyncImageLoader.finish();
 109 
 110         assertCursorEquals(testCursor, testImage, 47, 24);
 111     }
 112     
 113     @Test
 114     public void getBestSizeTest() {
 115         toolkit.setCursorSizeConverter(CursorSizeConverter.IDENTITY_CONVERTER);
 116 
 117         assertEquals(new Dimension2D(10, 20), ImageCursor.getBestSize(10, 20));
 118         assertEquals(new Dimension2D(20, 10), ImageCursor.getBestSize(20, 10));
 119 
 120         toolkit.setCursorSizeConverter(
 121                 CursorSizeConverter.createConstantConverter(32, 24));
 122         assertEquals(new Dimension2D(32, 24), ImageCursor.getBestSize(10, 20));
 123 
 124         toolkit.setCursorSizeConverter(
 125                 CursorSizeConverter.createConstantConverter(24, 32));
 126         assertEquals(new Dimension2D(24, 32), ImageCursor.getBestSize(20, 10));
 127     }
 128 
 129     @Test
 130     public void getMaximumColorsTest() {
 131         toolkit.setMaximumCursorColors(16);
 132         assertEquals(16, ImageCursor.getMaximumColors());
 133 
 134         toolkit.setMaximumCursorColors(256);
 135         assertEquals(256, ImageCursor.getMaximumColors());
 136     }
 137 
 138     @Test
 139     public void findBestImageSpecialCasesTest() {
 140         toolkit.setCursorSizeConverter(
 141                 CursorSizeConverter.createConstantConverter(16, 16));
 142         assertCursorEquals(ImageCursor.chooseBestCursor(new Image[0], 10, 20),
 143                            null, 0, 0);
 144 
 145         final Image[] deformedImages = { TEST_IMAGE_0x100, TEST_IMAGE_100x0 };
 146         assertCursorEquals(ImageCursor.chooseBestCursor(deformedImages, 0, 0),
 147                            TEST_IMAGE_0x100, 0, 0);
 148 
 149         final Image[] singleImage = { TEST_IMAGE_200x100 };
 150         assertCursorEquals(ImageCursor.chooseBestCursor(singleImage, 10, 20),
 151                            TEST_IMAGE_200x100, 10, 20);
 152 
 153         toolkit.setCursorSizeConverter(
 154                 CursorSizeConverter.createConstantConverter(0, 16));
 155         assertCursorEquals(ImageCursor.chooseBestCursor(singleImage, 10, 20),
 156                            null, 0, 0);
 157 
 158         toolkit.setCursorSizeConverter(
 159                 CursorSizeConverter.createConstantConverter(16, 0));
 160         assertCursorEquals(ImageCursor.chooseBestCursor(singleImage, 10, 20),
 161                            null, 0, 0);
 162 
 163         toolkit.setCursorSizeConverter(
 164                 new CursorSizeConverter() {
 165                     @Override
 166                     public Dimension2D getBestCursorSize(
 167                             final int preferredWidth,
 168                             final int preferredHeight) {
 169                         if (preferredWidth < preferredHeight) {
 170                             return new Dimension2D(preferredWidth, 0);
 171                         } else if (preferredWidth > preferredHeight) {
 172                             return new Dimension2D(0, preferredHeight);
 173                         }
 174 
 175                         return new Dimension2D(16, 16);
 176                     }
 177                 });
 178         final Image[] twoImages = { TEST_IMAGE_100x200, TEST_IMAGE_200x100 };
 179         assertCursorEquals(ImageCursor.chooseBestCursor(twoImages, 0, 0),
 180                            TEST_IMAGE_100x200, 0, 0);
 181     }
 182 
 183     @Test
 184     public void findBestImageFromAsyncImagesTest() {
 185         final StubImageLoaderFactory imageLoaderFactory =
 186                 toolkit.getImageLoaderFactory();
 187 
 188         final String url32x48 = "file:image_32x48.png";
 189         imageLoaderFactory.registerImage(
 190                 url32x48, new StubPlatformImageInfo(32, 48));
 191 
 192         final String url48x48 = "file:image_48x48.png";
 193         imageLoaderFactory.registerImage(
 194                 url48x48, new StubPlatformImageInfo(48, 48));
 195 
 196         final Image asyncImage32x48 = new Image(url32x48, true);
 197         final StubAsyncImageLoader asyncImage32x48loader =
 198                 imageLoaderFactory.getLastAsyncImageLoader();
 199         
 200         final Image asyncImage48x48 = new Image(url48x48, true);
 201         final StubAsyncImageLoader asyncImage48x48loader =
 202                 imageLoaderFactory.getLastAsyncImageLoader();
 203 
 204         final Image[] cursorImages = {
 205                 TEST_IMAGE_32x32,
 206                 asyncImage32x48,
 207                 asyncImage48x48
 208         };
 209 
 210         toolkit.setCursorSizeConverter(
 211                 CursorSizeConverter.createConstantConverter(48, 48));
 212         final ImageCursor selectedCursor =
 213                 ImageCursor.chooseBestCursor(cursorImages, 32, 32);
 214 
 215         asyncImage32x48loader.setProgress(50, 100);
 216         asyncImage32x48loader.finish();
 217         asyncImage48x48loader.finish();
 218 
 219         assertCursorEquals(selectedCursor,
 220                            asyncImage48x48, 47, 47);
 221     }
 222 
 223     @Test
 224     public void imageCursorPropertyListenersCalledOnceTest() {
 225         final StubImageLoaderFactory imageLoaderFactory =
 226                 toolkit.getImageLoaderFactory();
 227 
 228         final String url = "file:test.png";
 229         imageLoaderFactory.registerImage(
 230                 url, new StubPlatformImageInfo(32, 32));
 231 
 232         final Image testImage = new Image(url, true);
 233         final StubAsyncImageLoader asyncImageLoader =
 234                 imageLoaderFactory.getLastAsyncImageLoader();
 235         final ImageCursor testCursor = new ImageCursor(testImage, 16, 16);
 236 
 237         final PropertyInvalidationCounter<Number> hotspotXInvalidationCounter =
 238                 new PropertyInvalidationCounter<Number>();
 239         final PropertyInvalidationCounter<Number> hotspotYInvalidationCounter =
 240                 new PropertyInvalidationCounter<Number>();
 241         final PropertyInvalidationCounter<Object> imageInvalidationCounter =
 242                 new PropertyInvalidationCounter<Object>();
 243 
 244         testCursor.hotspotXProperty().addListener(hotspotXInvalidationCounter);
 245         testCursor.hotspotYProperty().addListener(hotspotYInvalidationCounter);
 246         testCursor.imageProperty().addListener(imageInvalidationCounter);
 247 
 248         assertCursorEquals(testCursor, null, 0, 0);
 249 
 250         asyncImageLoader.finish();
 251 
 252         assertEquals(1, hotspotXInvalidationCounter.getCounter());
 253         assertEquals(1, hotspotYInvalidationCounter.getCounter());
 254         assertEquals(1, imageInvalidationCounter.getCounter());
 255     }
 256 
 257     @Test
 258     public void imageCursorPropertiesChangedAtomicallyTest() {
 259         final StubImageLoaderFactory imageLoaderFactory =
 260                 toolkit.getImageLoaderFactory();
 261 
 262         final String url = "file:test.png";
 263         imageLoaderFactory.registerImage(
 264                 url, new StubPlatformImageInfo(32, 32));
 265 
 266         final Image testImage = new Image(url, true);
 267         final StubAsyncImageLoader asyncImageLoader =
 268                 imageLoaderFactory.getLastAsyncImageLoader();
 269         final ImageCursor testCursor = new ImageCursor(testImage, 16, 16);
 270 
 271         final InvalidationListener imageCursorChecker =
 272                 observable -> assertCursorEquals(testCursor, testImage, 16, 16);
 273 
 274         testCursor.hotspotXProperty().addListener(imageCursorChecker);
 275         testCursor.hotspotYProperty().addListener(imageCursorChecker);
 276         testCursor.imageProperty().addListener(imageCursorChecker);
 277 
 278         asyncImageLoader.finish();
 279     }
 280 
 281     public static void assertCursorEquals(final ImageCursor cursor,
 282                                           final Image image,
 283                                           final float hotspotX,
 284                                           final float hotspotY) {
 285         assertSame(image, cursor.getImage());
 286         assertEquals(hotspotX, cursor.getHotspotX(), 0);
 287         assertEquals(hotspotY, cursor.getHotspotY(), 0);
 288     }
 289 }