changeset 10909:8861b4dd6376

8177380: Add standard colors in ColorPicker color palette Reviewed-by: nlisker, kcr
author aghaisas
date Fri, 20 Apr 2018 11:26:59 +0530
parents 6f724f7a84e6
children 091e448a0417
files modules/javafx.controls/src/main/java/javafx/scene/control/skin/ColorPalette.java modules/javafx.controls/src/main/java/javafx/scene/control/skin/ColorPickerSkin.java modules/javafx.controls/src/main/resources/com/sun/javafx/scene/control/skin/resources/controls.properties modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/ColorPickerSkinTest.java
diffstat 4 files changed, 108 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ColorPalette.java	Thu Apr 19 16:57:28 2018 +0200
+++ b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ColorPalette.java	Fri Apr 20 11:26:59 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,6 +79,7 @@
     CustomColorDialog customColorDialog = null;
 
     private ColorPicker colorPicker;
+    private final GridPane standardColorGrid = new GridPane();
     private final GridPane customColorGrid = new GridPane();
     private final Separator separator = new Separator();
     private final Label customColorLabel = new Label(getColorPickerString("customColorLabel"));
@@ -137,6 +138,10 @@
         });
 
         initNavigation();
+
+        buildStandardColors();
+        standardColorGrid.getStyleClass().add("color-picker-grid");
+        standardColorGrid.setVisible(true);
         customColorGrid.getStyleClass().add("color-picker-grid");
         customColorGrid.setVisible(false);
         buildCustomColors();
@@ -148,7 +153,7 @@
 
         VBox paletteBox = new VBox();
         paletteBox.getStyleClass().add("color-palette");
-        paletteBox.getChildren().addAll(colorPickerGrid, customColorLabel, customColorGrid, separator, customColorLink);
+        paletteBox.getChildren().addAll(standardColorGrid, colorPickerGrid, customColorLabel, customColorGrid, separator, customColorLink);
 
         hoverSquare.setMouseTransparent(true);
         hoverSquare.getStyleClass().addAll("hover-square");
@@ -193,6 +198,35 @@
         hoverSquare.setLayoutY(snapPositionY(y) - focusedSquare.getHeight() / 2.0 + (hoverSquare.getScaleY() == 1.0 ? 0 : focusedSquare.getHeight() / 4.0));
     }
 
+    private void buildStandardColors() {
+        // WARNING:
+        // Make sure that the number of standard colors is equal to NUM_OF_COLUMNS
+        // Currently, 12 standard colors are supported in a single row
+        // Note : Creation & access logic of standardColorGrid needs to be updated
+        // in case more colors are added as separate row(s) in future.
+
+        final Color[] STANDARD_COLORS = {
+            Color.AQUA,
+            Color.TEAL,
+            Color.BLUE,
+            Color.NAVY,
+            Color.FUCHSIA,
+            Color.PURPLE,
+            Color.RED,
+            Color.MAROON,
+            Color.YELLOW,
+            Color.OLIVE,
+            Color.GREEN,
+            Color.LIME
+        };
+
+        standardColorGrid.getChildren().clear();
+
+        for (int i = 0; i < NUM_OF_COLUMNS; i++) {
+            standardColorGrid.add(new ColorSquare(STANDARD_COLORS[i], i, ColorType.STANDARD), i, 0);
+        }
+    }
+
     private void buildCustomColors() {
         final ObservableList<Color> customColors = colorPicker.getCustomColors();
         customColorNumber = customColors.size();
@@ -228,7 +262,7 @@
 
         for (int i = 0; i < customColors.size(); i++) {
             Color c = customColors.get(i);
-            ColorSquare square = new ColorSquare(c, i, true);
+            ColorSquare square = new ColorSquare(c, i, ColorType.CUSTOM);
             square.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
                 if (e.getCode() == KeyCode.DELETE) {
                     customColors.remove(square.rectangle.getFill());
@@ -293,24 +327,37 @@
             }
 
             private Node processArrow(ColorSquare owner, Direction dir) {
-                final int row = owner.index / NUM_OF_COLUMNS;
-                final int column = owner.index % NUM_OF_COLUMNS;
+                int row = 0;
+                int column = 0;
+
+                if (owner.colorType == ColorType.STANDARD) {
+                    row = 0;
+                    column = owner.index;
+                } else {
+                    row = owner.index / NUM_OF_COLUMNS;
+                    column = owner.index % NUM_OF_COLUMNS;
+                }
 
                 // Adjust the direction according to color picker orientation
                 dir = dir.getDirectionForNodeOrientation(colorPicker.getEffectiveNodeOrientation());
                 // This returns true for all the cases which we need to override
-                if (isAtBorder(dir, row, column, owner.isCustom)) {
+                if (isAtBorder(dir, row, column, (owner.colorType == ColorType.CUSTOM))) {
                     // There's no other node in the direction from the square, so we need to continue on some other row
                     // or cycle
                     int subsequentRow = row;
                     int subsequentColumn = column;
-                    boolean subSequentSquareCustom = owner.isCustom;
+                    boolean subSequentSquareCustom = (owner.colorType == ColorType.CUSTOM);
+                    boolean subSequentSquareStandard = (owner.colorType == ColorType.STANDARD);
                     switch (dir) {
                         case LEFT:
                         case RIGHT:
                             // The next row is either the first or the last, except when cycling in custom colors, the last row
                             // might have different number of columns
-                            if (owner.isCustom) {
+                            if (owner.colorType == ColorType.STANDARD) {
+                                subsequentRow = 0;
+                                subsequentColumn = (dir == Direction.LEFT)? NUM_OF_COLUMNS - 1 : 0;
+                            }
+                            else if (owner.colorType == ColorType.CUSTOM) {
                                 subsequentRow = Math.floorMod(dir == Direction.LEFT ? row - 1 : row + 1, customColorRows);
                                 subsequentColumn = dir == Direction.LEFT ? subsequentRow == customColorRows - 1 ?
                                         customColorLastRowLength - 1 : NUM_OF_COLUMNS - 1 : 0;
@@ -320,7 +367,9 @@
                             }
                             break;
                         case UP: // custom color are not handled here
-                            subsequentRow = NUM_OF_ROWS - 1;
+                            if (owner.colorType == ColorType.NORMAL && row == 0) {
+                                subSequentSquareStandard = true;
+                            }
                             break;
                         case DOWN: // custom color are not handled here
                             if (customColorNumber > 0) {
@@ -329,12 +378,14 @@
                                 subsequentColumn = customColorRows > 1 ? column : Math.min(customColorLastRowLength - 1, column);
                                 break;
                             } else {
-                                return null; // Let the default algorith handle this
+                                return null; // Let the default algorithm handle this
                             }
 
                     }
                     if (subSequentSquareCustom) {
                         return customColorGrid.getChildren().get(subsequentRow * NUM_OF_COLUMNS + subsequentColumn);
+                    } else if (subSequentSquareStandard) {
+                        return standardColorGrid.getChildren().get(subsequentColumn);
                     } else {
                         return colorPickerGrid.getChildren().get(subsequentRow * NUM_OF_COLUMNS + subsequentColumn);
                     }
@@ -359,7 +410,7 @@
 
             @Override
             public Node selectFirst(TraversalContext context) {
-                return colorPickerGrid.getChildren().get(0);
+                return standardColorGrid.getChildren().get(0);
             }
 
             @Override
@@ -386,21 +437,28 @@
         return false;
     }
 
+
+    enum ColorType {
+        NORMAL,
+        STANDARD,
+        CUSTOM
+    };
+
     class ColorSquare extends StackPane {
         Rectangle rectangle;
         int index;
         boolean isEmpty;
-        boolean isCustom;
+        ColorType colorType = ColorType.NORMAL;
 
         public ColorSquare() {
-            this(null, -1, false);
+            this(null, -1, ColorType.NORMAL);
         }
 
         public ColorSquare(Color color, int index) {
-            this(color, index, false);
+            this(color, index, ColorType.NORMAL);
         }
 
-        public ColorSquare(Color color, int index, boolean isCustom) {
+        public ColorSquare(Color color, int index, ColorType type) {
             // Add style class to handle selected color square
             getStyleClass().add("color-square");
             if (color != null) {
@@ -429,7 +487,7 @@
                         colorPicker.hide();
                     } else if (event.getButton() == MouseButton.SECONDARY ||
                             event.getButton() == MouseButton.MIDDLE) {
-                        if (isCustom && contextMenu != null) {
+                        if ((colorType == ColorType.CUSTOM) && contextMenu != null) {
                             if (!contextMenu.isShowing()) {
                                 contextMenu.show(ColorSquare.this, Side.RIGHT, 0, 0);
                                 Utils.addMnemonics(contextMenu, ColorSquare.this.getScene(), NodeHelper.isShowMnemonics(colorPicker));
@@ -442,7 +500,7 @@
                 });
             }
             this.index = index;
-            this.isCustom = isCustom;
+            this.colorType = type;
             rectangle = new Rectangle(SQUARE_SIZE, SQUARE_SIZE);
             if (color == null) {
                 rectangle.setFill(Color.WHITE);
@@ -477,20 +535,29 @@
     public void updateSelection(Color color) {
         setFocusedSquare(null);
 
-        for (ColorSquare c : colorPickerGrid.getSquares()) {
-            if (c.rectangle.getFill().equals(color)) {
-                setFocusedSquare(c);
+        // Check all color grids to find ColorSquare that matches color
+        // if found, set focus to it
+
+        List<GridPane> gridList = List.of(standardColorGrid, colorPickerGrid,
+                                          customColorGrid);
+
+        for (GridPane grid : gridList) {
+            ColorSquare sq = findColorSquare(grid, color);
+            if (sq != null) {
+                setFocusedSquare(sq);
                 return;
             }
         }
-        // check custom colors
-        for (Node n : customColorGrid.getChildren()) {
+    }
+
+    private ColorSquare findColorSquare(GridPane colorGrid, Color color) {
+        for (Node n : colorGrid.getChildren()) {
             ColorSquare c = (ColorSquare) n;
             if (c.rectangle.getFill().equals(color)) {
-                setFocusedSquare(c);
-                return;
+                return c;
             }
         }
+        return null;
     }
 
     class ColorPickerGrid extends GridPane {
--- a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ColorPickerSkin.java	Thu Apr 19 16:57:28 2018 +0200
+++ b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ColorPickerSkin.java	Fri Apr 20 11:26:59 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -343,7 +343,7 @@
         }
     }
 
-    private static final Map<Color, String> colorNameMap = new HashMap<>(24);
+    private static final Map<Color, String> colorNameMap = new HashMap<>(30);
     private static final Map<Color, String> cssNameMap = new HashMap<>(139);
     static {
         // Translatable display names for the most common colors
@@ -364,11 +364,17 @@
         colorNameMap.put(LIGHTGRAY,   Properties.getColorPickerString("colorName.lightgray"));
         colorNameMap.put(LIGHTGREEN,  Properties.getColorPickerString("colorName.lightgreen"));
         colorNameMap.put(LIGHTYELLOW, Properties.getColorPickerString("colorName.lightyellow"));
+        colorNameMap.put(LIME,        Properties.getColorPickerString("colorName.lime"));
         colorNameMap.put(MAGENTA,     Properties.getColorPickerString("colorName.magenta"));
+        colorNameMap.put(MAROON,      Properties.getColorPickerString("colorName.maroon"));
         colorNameMap.put(MEDIUMBLUE,  Properties.getColorPickerString("colorName.mediumblue"));
+        colorNameMap.put(NAVY,        Properties.getColorPickerString("colorName.navy"));
+        colorNameMap.put(OLIVE,       Properties.getColorPickerString("colorName.olive"));
         colorNameMap.put(ORANGE,      Properties.getColorPickerString("colorName.orange"));
         colorNameMap.put(PINK,        Properties.getColorPickerString("colorName.pink"));
+        colorNameMap.put(PURPLE,      Properties.getColorPickerString("colorName.purple"));
         colorNameMap.put(RED,         Properties.getColorPickerString("colorName.red"));
+        colorNameMap.put(TEAL,        Properties.getColorPickerString("colorName.teal"));
         colorNameMap.put(WHITE,       Properties.getColorPickerString("colorName.white"));
         colorNameMap.put(YELLOW,      Properties.getColorPickerString("colorName.yellow"));
 
--- a/modules/javafx.controls/src/main/resources/com/sun/javafx/scene/control/skin/resources/controls.properties	Thu Apr 19 16:57:28 2018 +0200
+++ b/modules/javafx.controls/src/main/resources/com/sun/javafx/scene/control/skin/resources/controls.properties	Fri Apr 20 11:26:59 2018 +0530
@@ -70,11 +70,17 @@
 ColorPicker.colorName.lightgray=Light Gray
 ColorPicker.colorName.lightgreen=Light Green
 ColorPicker.colorName.lightyellow=Light Yellow
+ColorPicker.colorName.lime=Lime
 ColorPicker.colorName.magenta=Magenta
+ColorPicker.colorName.maroon=Maroon
 ColorPicker.colorName.mediumblue=Medium Blue
+ColorPicker.colorName.navy=Navy
+ColorPicker.colorName.olive=Olive
 ColorPicker.colorName.orange=Orange
 ColorPicker.colorName.pink=Pink
+ColorPicker.colorName.purple=Purple
 ColorPicker.colorName.red=Red
+ColorPicker.colorName.teal=Teal
 ColorPicker.colorName.white=White
 ColorPicker.colorName.yellow=Yellow
 
--- a/modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/ColorPickerSkinTest.java	Thu Apr 19 16:57:28 2018 +0200
+++ b/modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/ColorPickerSkinTest.java	Fri Apr 20 11:26:59 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -80,10 +80,10 @@
         paletteScene.getWindow().requestFocus();
 
         SceneHelper.processMouseEvent(paletteScene,
-                generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+85, yval+40));
+                generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+85, yval+65));
 
         SceneHelper.processMouseEvent(paletteScene,
-                generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+85, yval+40));
+                generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+85, yval+65));
         tk.firePulse();
 
         assertEquals(colorPicker.getValue().toString(), "0x330033ff");