From 4bd3b889dc1246086d2b470b1dd7eb924bef96bf Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sun, 3 May 2020 18:21:00 +0200 Subject: [PATCH] FlatSVGIcon: support color filtering --- .../com/formdev/flatlaf/FlatIconColors.java | 89 +++++++++++++++++++ .../java/com/formdev/flatlaf/FlatLaf.java | 28 ++---- .../com/formdev/flatlaf/IntelliJTheme.java | 2 +- .../formdev/flatlaf/demo/icons/back_dark.svg | 9 -- .../formdev/flatlaf/demo/icons/copy_dark.svg | 6 -- .../flatlaf/demo/icons/download_dark.svg | 6 -- .../flatlaf/demo/icons/forward_dark.svg | 9 -- .../flatlaf/demo/icons/menu-cut_dark.svg | 3 - .../formdev/flatlaf/demo/icons/menu-paste.svg | 2 +- .../flatlaf/demo/icons/menu-paste_dark.svg | 3 - .../formdev/flatlaf/demo/icons/redo_dark.svg | 3 - .../flatlaf/demo/icons/refresh_dark.svg | 3 - .../formdev/flatlaf/demo/icons/show_dark.svg | 3 - .../formdev/flatlaf/demo/icons/undo_dark.svg | 3 - .../formdev/flatlaf/extras/FlatSVGIcon.java | 70 ++++++++++++--- 15 files changed, 154 insertions(+), 85 deletions(-) create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/FlatIconColors.java delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/back_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/copy_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/download_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/forward_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-cut_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-paste_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/redo_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/refresh_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/show_dark.svg delete mode 100644 flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/undo_dark.svg diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatIconColors.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatIconColors.java new file mode 100644 index 00000000..5cda400c --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatIconColors.java @@ -0,0 +1,89 @@ +/* + * Copyright 2020 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf; + +/** + * Default color palette for action icons and object icons. + *

+ * The idea is to use only this well defined set of colors in SVG icons and + * then they are replaced at runtime to dark variants or to other theme colors. + * Then a single SVG icon (light variant) can be used for dark themes too. + * IntelliJ Platform uses this mechanism to allow themes to change IntelliJ Platform icons. + *

+ * Use the {@code *_DARK} colors only in {@code *_dark.svg} files. + *

+ * The colors are based on IntelliJ Platform + * Action icons + * and + * Noun icons + *

+ * These colors may be changed by IntelliJ Platform themes. + *

+ * You may use these colors also in your application (outside of SVG icons), but do + * not use the RGB values defined in this enum.
+ * Instead use {@code UIManager.getColor( FlatIconColors.ACTIONS_GREY.key )}. + * + * @author Karl Tauber + */ +public enum FlatIconColors +{ + // colors for action icons + // see https://jetbrains.design/intellij/principles/icons/#action-icons + ACTIONS_RED ( 0xDB5860, "Actions.Red", true, false ), + ACTIONS_RED_DARK ( 0xC75450, "Actions.Red", false, true ), + ACTIONS_YELLOW ( 0xEDA200, "Actions.Yellow", true, false ), + ACTIONS_YELLOW_DARK ( 0xF0A732, "Actions.Yellow", false, true ), + ACTIONS_GREEN ( 0x59A869, "Actions.Green", true, false ), + ACTIONS_GREEN_DARK ( 0x499C54, "Actions.Green", false, true ), + ACTIONS_BLUE ( 0x389FD6, "Actions.Blue", true, false ), + ACTIONS_BLUE_DARK ( 0x3592C4, "Actions.Blue", false, true ), + ACTIONS_GREY ( 0x6E6E6E, "Actions.Grey", true, false ), + ACTIONS_GREY_DARK ( 0xAFB1B3, "Actions.Grey", false, true ), + ACTIONS_GREYINLINE ( 0x7F8B91, "Actions.GreyInline", true, false ), + ACTIONS_GREYINLINE_DARK ( 0x7F8B91, "Actions.GreyInline", false, true ), + + // colors for object icons + // see https://jetbrains.design/intellij/principles/icons/#noun-icons + OBJECTS_GREY ( 0x9AA7B0, "Objects.Grey" ), + OBJECTS_BLUE ( 0x40B6E0, "Objects.Blue" ), + OBJECTS_GREEN ( 0x62B543, "Objects.Green" ), + OBJECTS_YELLOW ( 0xF4AF3D, "Objects.Yellow" ), + OBJECTS_YELLOW_DARK ( 0xD9A343, "Objects.YellowDark" ), + OBJECTS_PURPLE ( 0xB99BF8, "Objects.Purple" ), + OBJECTS_PINK ( 0xF98B9E, "Objects.Pink" ), + OBJECTS_RED ( 0xF26522, "Objects.Red" ), + OBJECTS_RED_STATUS ( 0xE05555, "Objects.RedStatus" ), + OBJECTS_GREEN_ANDROID ( 0xA4C639, "Objects.GreenAndroid" ), + OBJECTS_BLACK_TEXT ( 0x231F20, "Objects.BlackText" ); + + public final int rgb; + public final String key; + + public final boolean light; + public final boolean dark; + + FlatIconColors( int rgb, String key ) { + this( rgb, key, true, true ); + } + + FlatIconColors( int rgb, String key, boolean light, boolean dark ) { + this.rgb = rgb; + this.key = key; + this.light = light; + this.dark = dark; + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index af8a97b0..3ec42a7a 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -409,30 +409,14 @@ public abstract class FlatLaf * Action icons * and * Noun icons + *

+ * These colors may be changed by IntelliJ Platform themes. */ public static void initIconColors( UIDefaults defaults, boolean dark ) { - // colors for action icons - // see https://jetbrains.design/intellij/principles/icons/#action-icons - defaults.put( "Actions.Red", new ColorUIResource( !dark ? 0xDB5860 : 0xC75450 ) ); - defaults.put( "Actions.Yellow", new ColorUIResource( !dark ? 0xEDA200 : 0xF0A732 ) ); - defaults.put( "Actions.Green", new ColorUIResource( !dark ? 0x59A869 : 0x499C54 ) ); - defaults.put( "Actions.Blue", new ColorUIResource( !dark ? 0x389FD6 : 0x3592C4 ) ); - defaults.put( "Actions.Grey", new ColorUIResource( !dark ? 0x6E6E6E : 0xAFB1B3 ) ); - defaults.put( "Actions.GreyInline", new ColorUIResource( !dark ? 0x7F8B91 : 0x7F8B91 ) ); - - // colors for object icons - // see https://jetbrains.design/intellij/principles/icons/#noun-icons - defaults.put( "Objects.Grey", new ColorUIResource( 0x9AA7B0 ) ); - defaults.put( "Objects.Blue", new ColorUIResource( 0x40B6E0 ) ); - defaults.put( "Objects.Green", new ColorUIResource( 0x62B543 ) ); - defaults.put( "Objects.Yellow", new ColorUIResource( 0xF4AF3D ) ); - defaults.put( "Objects.YellowDark", new ColorUIResource( 0xD9A343 ) ); - defaults.put( "Objects.Purple", new ColorUIResource( 0xB99BF8 ) ); - defaults.put( "Objects.Pink", new ColorUIResource( 0xF98B9E ) ); - defaults.put( "Objects.Red", new ColorUIResource( 0xF26522 ) ); - defaults.put( "Objects.RedStatus", new ColorUIResource( 0xE05555 ) ); - defaults.put( "Objects.GreenAndroid", new ColorUIResource( 0xA4C639 ) ); - defaults.put( "Objects.BlackText", new ColorUIResource( 0x231F20 ) ); + for( FlatIconColors c : FlatIconColors.values() ) { + if( c.light == !dark || c.dark == dark ) + defaults.put( c.key, new ColorUIResource( c.rgb ) ); + } } private void putAATextInfo( UIDefaults defaults ) { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java index ce866526..e10aa8a5 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -240,7 +240,7 @@ public class IntelliJTheme if( color != null ) { String key = e.getKey(); namedColors.put( key, color ); - defaults.put( "ColorPalette." + e.getKey(), color ); + defaults.put( "ColorPalette." + key, color ); } } } diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/back_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/back_dark.svg deleted file mode 100644 index 88abaa73..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/back_dark.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/copy_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/copy_dark.svg deleted file mode 100644 index 4ff18263..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/copy_dark.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/download_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/download_dark.svg deleted file mode 100644 index 3e58c7d6..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/download_dark.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/forward_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/forward_dark.svg deleted file mode 100644 index d031c78f..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/forward_dark.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-cut_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-cut_dark.svg deleted file mode 100644 index 6bae57d8..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-cut_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-paste.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-paste.svg index 1debae89..0e88bad0 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-paste.svg +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-paste.svg @@ -1,3 +1,3 @@ - + diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-paste_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-paste_dark.svg deleted file mode 100644 index 10ca357f..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/menu-paste_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/redo_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/redo_dark.svg deleted file mode 100644 index 63b1a69d..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/redo_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/refresh_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/refresh_dark.svg deleted file mode 100644 index 0b0f5440..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/refresh_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/show_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/show_dark.svg deleted file mode 100644 index 24255733..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/show_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/undo_dark.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/undo_dark.svg deleted file mode 100644 index 1ab3b7f3..00000000 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/undo_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java index 60ca1627..f343b51a 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java @@ -26,9 +26,12 @@ import java.awt.RenderingHints; import java.awt.image.RGBImageFilter; import java.net.URISyntaxException; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import javax.swing.Icon; import javax.swing.LookAndFeel; import javax.swing.UIManager; +import com.formdev.flatlaf.FlatIconColors; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.util.Graphics2DProxy; @@ -100,17 +103,17 @@ public class FlatSVGIcon if( clipBounds != null && !clipBounds.intersects( new Rectangle( x, y, getIconWidth(), getIconHeight() ) ) ) return; - Graphics2D g2 = (Graphics2D) g.create(); - + // get gray filter + RGBImageFilter grayFilter = null; if( c != null && !c.isEnabled() ) { - Object grayFilter = UIManager.get( "Component.grayFilter" ); - RGBImageFilter filter = (grayFilter instanceof RGBImageFilter) - ? (RGBImageFilter) grayFilter + Object grayFilterObj = UIManager.get( "Component.grayFilter" ); + grayFilter = (grayFilterObj instanceof RGBImageFilter) + ? (RGBImageFilter) grayFilterObj : GrayFilter.createDisabledIconFilter( dark ); - - g2 = new GraphicsFilter( g2, filter ); } + Graphics2D g2 = new GraphicsFilter( (Graphics2D) g.create(), ColorFilter.getInstance(), grayFilter ); + try { FlatUIUtils.setRenderingHints( g2 ); g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR ); @@ -165,16 +168,52 @@ public class FlatSVGIcon darkLaf = (lookAndFeel instanceof FlatLaf && ((FlatLaf)lookAndFeel).isDark()); } + //---- class ColorFilter -------------------------------------------------- + + public static class ColorFilter + { + private static ColorFilter instance; + + private final Map rgb2keyMap = new HashMap<>(); + + public static ColorFilter getInstance() { + if( instance == null ) + instance = new ColorFilter(); + return instance; + } + + public ColorFilter() { + for( FlatIconColors c : FlatIconColors.values() ) + rgb2keyMap.put( c.rgb, c.key ); + } + + public Color filter( Color color ) { + String colorKey = rgb2keyMap.get( color.getRGB() & 0xffffff ); + if( colorKey == null ) + return color; + + Color newColor = UIManager.getColor( colorKey ); + if( newColor == null ) + return color; + + return (newColor.getAlpha() != color.getAlpha()) + ? new Color( (newColor.getRGB() & 0x00ffffff) | (color.getRGB() & 0xff000000) ) + : newColor; + }; + } + //---- class GraphicsFilter ----------------------------------------------- private static class GraphicsFilter extends Graphics2DProxy { - private final RGBImageFilter filter; + private final ColorFilter colorFilter; + private final RGBImageFilter grayFilter; - public GraphicsFilter( Graphics2D delegate, RGBImageFilter filter ) { + public GraphicsFilter( Graphics2D delegate, ColorFilter colorFilter, RGBImageFilter grayFilter ) { super( delegate ); - this.filter = filter; + this.colorFilter = colorFilter; + this.grayFilter = grayFilter; } @Override @@ -190,9 +229,14 @@ public class FlatSVGIcon } private Color filterColor( Color color ) { - int oldRGB = color.getRGB(); - int newRGB = filter.filterRGB( 0, 0, oldRGB ); - return (newRGB != oldRGB) ? new Color( newRGB, true ) : color; + if( colorFilter != null ) + color = colorFilter.filter( color ); + if( grayFilter != null ) { + int oldRGB = color.getRGB(); + int newRGB = grayFilter.filterRGB( 0, 0, oldRGB ); + color = (newRGB != oldRGB) ? new Color( newRGB, true ) : color; + } + return color; } } }