From 91d3d558fb7a292174206eb031c6efa41d343fa0 Mon Sep 17 00:00:00 2001 From: lemon Date: Fri, 30 Aug 2024 11:51:52 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-127437=20fix:=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=80=BB=E8=BE=91=EF=BC=8C=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E8=B7=9F=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=85=B1=E7=94=A8=20icon?= =?UTF-8?q?=20=E5=8A=A0=E8=BD=BD=E6=96=B9=E5=BC=8F=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8F=92=E4=BB=B6=20icon=20=E5=92=8C=20set=20?= =?UTF-8?q?=E7=9A=84=20id=20=E6=A0=87=E8=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fine/theme/icon/IconManager.java | 33 ++- .../theme/icon/plugin/PluginIconManager.java | 223 ------------------ .../theme/icon/plugin/PluginJsonIconSet.java | 113 +-------- .../theme/icon/plugin/PluginLazyIcon.java | 137 ----------- .../theme/icon/plugin/PluginListIconSet.java | 57 +++++ .../theme/icon/plugin/PluginMapIconSet.java | 54 ----- .../fine/theme/light/ui/laf/FineDarkLaf.java | 5 +- .../com/fine/theme/light/ui/laf/FineLaf.java | 57 ++--- .../fine/theme/light/ui/laf/FineLightLaf.java | 3 +- .../com/fr/design/fun/LazyIconProvider.java | 42 ++-- .../fun/impl/AbstractLazyIconProvider.java | 19 +- 11 files changed, 142 insertions(+), 601 deletions(-) delete mode 100644 designer-base/src/main/java/com/fine/theme/icon/plugin/PluginIconManager.java delete mode 100644 designer-base/src/main/java/com/fine/theme/icon/plugin/PluginLazyIcon.java create mode 100644 designer-base/src/main/java/com/fine/theme/icon/plugin/PluginListIconSet.java delete mode 100644 designer-base/src/main/java/com/fine/theme/icon/plugin/PluginMapIconSet.java diff --git a/designer-base/src/main/java/com/fine/theme/icon/IconManager.java b/designer-base/src/main/java/com/fine/theme/icon/IconManager.java index aa2ef8b173..86506c8475 100644 --- a/designer-base/src/main/java/com/fine/theme/icon/IconManager.java +++ b/designer-base/src/main/java/com/fine/theme/icon/IconManager.java @@ -3,6 +3,7 @@ package com.fine.theme.icon; import com.fr.base.extension.FileExtension; import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; +import com.fr.nx.app.web.out.widget.utils.CollectionUtils; import com.fr.third.errorprone.annotations.Immutable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -10,8 +11,10 @@ import org.jetbrains.annotations.Nullable; import javax.swing.Icon; import java.awt.Dimension; import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; /** * 图标管理器 @@ -29,8 +32,8 @@ public class IconManager { public static final String ICON_DISABLE_SUFFIX = "_disable"; public static final Dimension DEFAULT_DIMENSION = new Dimension(16, 16); - private static final ArrayList ICON_SETS = new ArrayList<>(2); - private static final HashMap> CACHE = new HashMap<>(64); + private static final CopyOnWriteArrayList ICON_SETS = new CopyOnWriteArrayList<>(); + private static final Map> CACHE = new ConcurrentHashMap<>(64); /** @@ -123,6 +126,28 @@ public class IconManager { return id + "_" + dimension.width + "_" + dimension.height + "_" + type; } + /** + * 批量添加图标集 + * + * @param sets 图标集 + */ + public static void addSet(@NotNull List sets) { + if (CollectionUtils.isEmpty(sets)) { + return; + } + sets.forEach(IconManager::addSet); + } + + /** + * 删除指定 id 图标集 + * + * @param id 图标集ID + */ + public static void removeSet(@NotNull String id) { + ICON_SETS.removeIf(iconSet -> id.equals(iconSet.getId())); + clearCache(); + } + /** * 是否SVG图标格式 * diff --git a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginIconManager.java b/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginIconManager.java deleted file mode 100644 index e0f6a822d2..0000000000 --- a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginIconManager.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.fine.theme.icon.plugin; - -import com.fine.theme.icon.IconException; -import com.fine.theme.icon.IconManager; -import com.fine.theme.icon.IconSet; -import com.fine.theme.icon.IconType; -import com.fine.theme.icon.LazyIcon; -import com.fr.base.extension.FileExtension; -import com.fr.general.IOUtils; -import com.fr.log.FineLoggerFactory; -import com.fr.nx.app.web.out.widget.utils.CollectionUtils; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.Icon; -import java.awt.Dimension; -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 管理插件图标集 - * - * @author lemon - * @since - * Created on 2024/08/23 - */ -public class PluginIconManager { - - public static final String ICON_DISABLE_SUFFIX = "_disable"; - public static final Dimension DEFAULT_DIMENSION = new Dimension(16, 16); - private static final Map> SOURCE_ICON_MAPS = new ConcurrentHashMap<>(2); - private static final Map>> CACHE = new ConcurrentHashMap<>(); - - - /** - * 获取图标集 - * - * @param id 图标集ID - * @return 图标集 - */ - public static IconSet getSet(String source, String id) { - List sets = SOURCE_ICON_MAPS.get(source); - - for (IconSet set : sets) { - if (set != null && set.getId().equals(id)) { - return set; - } - } - throw new IconException("[PluginIconManager] Can not find icon set by id: " + id); - } - - /** - * 添加图标集 - * - * @param source 插件 - * @param sets 图标集 - */ - public static void addSet(@NotNull String source, @NotNull List sets) { - if (SOURCE_ICON_MAPS.containsKey(source)) { - FineLoggerFactory.getLogger().warn("[PluginIconManager] plugin:{} icon set already exists: " + source); - } - SOURCE_ICON_MAPS.put(source, sets); - clearCacheBySource(source); - } - - - /** - * 更新指定插件图标集 - * - * @param source 插件 - * @param sets 图标集 - */ - public static void updateSet(@NotNull String source, @NotNull List sets) { - removeSet(source); - addSet(source, sets); - } - - /** - * 删除指定插件图标集 - * - * @param source 插件 - */ - public static void removeSet(@NotNull String source) { - SOURCE_ICON_MAPS.remove(source); - clearCacheBySource(source); - } - - /** - * 根据图标ID获取图标 - *

- * 查找路径 - * 1)查找图集图标 - * 2)路径为图片图标,从路径再查找 - * 3)提供默认svg图标 - * - * @param id 图标ID - * @param 图标类型 - * @return 图标 - */ - @NotNull - public static I getIcon(@NotNull String source, @NotNull final String id, @NotNull Dimension dimension, @NotNull IconType type) { - Icon icon = findIcon(source, id, dimension, type); - if (icon == null) { - // 只有找不到再进行其他fallback,提升效率 - if (IconManager.isImageIcon(id)) { - return (I) fallbackLegacyIcon(id); - } else { - FineLoggerFactory.getLogger().warn("[PluginIconManager] Can not find icon by id: " + id); - return (I) new LazyIcon("default"); - } - } - return (I) icon; - } - - private static Icon fallbackLegacyIcon(String id) { - return IOUtils.readIcon(id); - } - - @Nullable - private static I findIcon(String source, String id, Dimension dimension, IconType type) { - String cacheKey = genCacheKey(source, id, dimension, type); - HashMap> sourceCache = CACHE.getOrDefault(cacheKey, new HashMap<>(64)); - final WeakReference reference = sourceCache.get(cacheKey); - I icon = reference != null ? (I) reference.get() : null; - if (icon == null) { - List sets = SOURCE_ICON_MAPS.get(source); - if (CollectionUtils.isEmpty(sets)) { - return icon; - } - for (IconSet set : sets) { - Icon f = set.findIcon(id, dimension, type); - if (f != null) { - icon = (I) f; - sourceCache.put(cacheKey, new WeakReference<>(icon)); - CACHE.put(source, sourceCache); - } - } - } - return icon; - } - - - /** - * 生成缓存key - * - * @param id id - * @param dimension 尺寸 - * @param type 图标类型 - * @return 缓存key - */ - public static @NotNull String genCacheKey(String source, String id, Dimension dimension, IconType type) { - if (DEFAULT_DIMENSION.equals(dimension)) { - return source + "_" + id + "_" + type; - } - return source + "_" + id + "_" + dimension.width + "_" + dimension.height + "_" + type; - } - - /** - * 是否SVG图标格式 - * - * @param path 路径 - * @return 是否SVG图标格式 - */ - public static boolean isSvgIcon(String path) { - return FileExtension.SVG.matchExtension(path); - } - - /** - * 是否支持的图片图标格式,目前只支持png和jpg - * - * @param path 路径 - * @return 是否支持的图片图标格式 - */ - public static boolean isImageIcon(String path) { - return FileExtension.PNG.matchExtension(path) - || FileExtension.JPG.matchExtension(path); - } - - /** - * 判断是否存在指定id的icon,非io读取行为,而是从已注册的sourceMap中遍历判断 - * - * @param id id - * @return 是否存在 - */ - public static boolean existIcon(String id, String source) { - List sets = SOURCE_ICON_MAPS.get(source); - for (IconSet set : sets) { - if (set != null && set.getIds().contains(id)) { - return true; - } - } - return false; - } - - /** - * 清理所有缓存 - */ - public static void clearCache() { - CACHE.clear(); - } - - /** - * 清楚指定插件缓存 - * @param source 插件标识 - */ - public static void clearCacheBySource(String source) { - CACHE.remove(source); - } - - /** - * 查找灰化图标 - * - * @param path 原始路径 - * @return 灰化路径 - */ - public static String findDisablePath(String path) { - int i = path.lastIndexOf('.'); - return path.substring(0, i) + ICON_DISABLE_SUFFIX + path.substring(i); - } -} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginJsonIconSet.java b/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginJsonIconSet.java index 66c758f825..75a12c6a43 100644 --- a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginJsonIconSet.java +++ b/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginJsonIconSet.java @@ -1,121 +1,22 @@ package com.fine.theme.icon.plugin; -import com.fine.theme.icon.AbstractIconSet; -import com.fine.theme.icon.IconType; +import com.fine.theme.icon.JsonIconSet; import com.fine.theme.icon.UrlIconResource; -import com.fine.theme.icon.img.ImageIconSource; -import com.fine.theme.icon.svg.SvgIconSource; -import com.formdev.flatlaf.json.Json; -import com.formdev.flatlaf.json.ParseException; -import com.fr.stable.StringUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.Objects; /** * 插件 json 图标集 + * json 格式参考 fine_light.icon.json + * 为了保证 插件之间,插件与设计器 icon id 的唯一性,icons key 值规则参考 {@link PluginListIconSet} * * @author lemon * @since * Created on 2024/08/20 */ -public class PluginJsonIconSet extends AbstractIconSet { - - private String base; - - public PluginJsonIconSet(UrlIconResource resource) { - if (resource.getPath() == null) { - return; - } - Map json; - try (InputStream in = resource.getInputStream()) { - try (Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) { - json = (Map) Json.parse(reader); - } - } catch (ParseException | IOException ex) { - throw new RuntimeException(ex.getMessage(), ex); - } - - name = (String) json.get("name"); - dark = Boolean.parseBoolean((String) json.get("dark")); - base = (String) json.get("base"); - if (base == null) { - base = StringUtils.EMPTY; - } - - Map icons = (Map) json.get("icons"); - - for (Map.Entry icon : icons.entrySet()) { - applyIcon(icon.getKey(), icon.getValue()); - } - - } +public class PluginJsonIconSet extends JsonIconSet { - private void applyIcon(String key, Object value) { - if (value instanceof String) { - dealWithIconString(key, (String) value); - } else if (value instanceof Map) { - dealWithIconMap(key, (Map) value); - } + public PluginJsonIconSet(String id, UrlIconResource resource) { + super(resource); + this.name = id; } - private void dealWithIconString(String key, String value) { - if (PluginIconManager.isSvgIcon(value)) { - // 默认字符串提供正常图和灰化图 - addIcon(new SvgIconSource(key, - base + value, - PluginIconManager.findDisablePath(base + value), - null - )); - } else if (PluginIconManager.isImageIcon(value)) { - addIcon(new ImageIconSource(key, base + value)); - } - // 其他无法识别格式不处理 - } - - - /** - * 处理object形式的icon配置 - */ - private void dealWithIconMap(String key, Map value) { - String normalPath = (String) value.get(IconType.normal.name()); - String disablePath = (String) value.get(IconType.disable.name()); - String whitePath = (String) value.get(IconType.white.name()); - // 暂不支持混合格式,每个id的格式需要保持一致 - if (PluginIconManager.isSvgIcon(normalPath)) { - addIcon(new SvgIconSource(key, - base + normalPath, - StringUtils.isNotBlank(disablePath) ? base + disablePath : null, - StringUtils.isNotBlank(whitePath) ? base + whitePath : null - )); - } else if (PluginIconManager.isImageIcon(normalPath)) { - addIcon(new ImageIconSource(key, - base + normalPath, - StringUtils.isNotBlank(disablePath) ? base + disablePath : null, - StringUtils.isNotBlank(whitePath) ? base + whitePath : null - )); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PluginJsonIconSet that = (PluginJsonIconSet) o; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hashCode(name); - } } diff --git a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginLazyIcon.java b/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginLazyIcon.java deleted file mode 100644 index 8f17242505..0000000000 --- a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginLazyIcon.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.fine.theme.icon.plugin; - -import com.fine.theme.icon.DisabledIcon; -import com.fine.theme.icon.IconManager; -import com.fine.theme.icon.IconType; -import com.fine.theme.icon.Identifiable; -import com.fine.theme.icon.WhiteIcon; -import com.fr.design.fun.impl.AbstractLazyIconProvider; -import com.fr.stable.AssistUtils; -import org.jetbrains.annotations.NotNull; - -import javax.swing.Icon; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics; -import java.util.StringJoiner; - -import static com.fine.theme.utils.FineUIScale.scale; - -/** - * 插件图标加载类 - * - * @author lemon - * @since - * Created on 2024/08/23 - */ -public class PluginLazyIcon implements Identifiable, DisabledIcon, WhiteIcon, Icon { - @NotNull - private final String id; - - private final Dimension dimension; - - private final IconType type; - - private final String source; - - /** - * - * @param source {@link AbstractLazyIconProvider#pluginId()} - * @param id - */ - public PluginLazyIcon(@NotNull final String source, @NotNull final String id) { - this.id = id; - this.dimension = IconManager.DEFAULT_DIMENSION; - this.type = IconType.normal; - this.source = source; - } - - public PluginLazyIcon(@NotNull final String source, @NotNull final String id, int side) { - this.id = id; - this.dimension = new Dimension(side, side); - this.type = IconType.normal; - this.source = source; - } - - public PluginLazyIcon(@NotNull final String source, @NotNull final String id, @NotNull Dimension dimension) { - this.id = id; - this.dimension = dimension; - this.type = IconType.normal; - this.source = source; - } - - private PluginLazyIcon(@NotNull final String source, @NotNull final String id, @NotNull IconType type) { - this.id = id; - this.dimension = IconManager.DEFAULT_DIMENSION; - this.type = type; - this.source = source; - } - - public PluginLazyIcon(@NotNull final String source, @NotNull final String id, @NotNull Dimension dimension, @NotNull IconType type) { - this.id = id; - this.dimension = dimension; - this.type = type; - this.source = source; - } - - - @NotNull - @Override - public String getId() { - return id; - } - - @Override - public void paintIcon(@NotNull final Component c, @NotNull final Graphics g, final int x, final int y) { - getIcon().paintIcon(c, g, x, y); - } - - @Override - public int getIconWidth() { - return scale(dimension.width); - } - - @Override - public int getIconHeight() { - return scale(dimension.height); - } - - - @NotNull - public I getIcon() { - return PluginIconManager.getIcon(source, getId(), dimension, type); - } - - /** - * 创建一份灰化图标 - * - * @return 灰化图标 - */ - @NotNull - @Override - public Icon disabled() { - return new PluginLazyIcon(source, getId(), dimension, IconType.disable); - } - - /** - * 创建一份白化图标 - * - * @return 白化图标 - */ - @NotNull - @Override - public Icon white() { - return new PluginLazyIcon(source, getId(), dimension, IconType.white); - } - - - @Override - public String toString() { - return new StringJoiner(", ", PluginLazyIcon.class.getSimpleName() + "[", "]") - .add("source='" + source + "'") - .add("id='" + id + "'") - .add("size=" + "[w=" + scale(dimension.width) + ",h=" + scale(dimension.height) + "]") - .add("type=" + type) - .toString(); - } -} diff --git a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginListIconSet.java b/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginListIconSet.java new file mode 100644 index 0000000000..4034ef01ef --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginListIconSet.java @@ -0,0 +1,57 @@ +package com.fine.theme.icon.plugin; + +import com.fine.theme.icon.AbstractIconSet; +import com.fine.theme.icon.IconManager; +import com.fine.theme.icon.img.ImageIconSource; +import com.fine.theme.icon.svg.SvgIconSource; + +import java.util.List; +import java.util.Objects; + +/** + * 插件 map 图标集 + * 为了保证 插件之间,插件与设计器 icon id 的唯一性,以图标 path 为 id 进行注册 + * + * @author lemon + * @since + * Created on 2024/08/20 + */ +public class PluginListIconSet extends AbstractIconSet { + + public PluginListIconSet(String id, List icons) { + this.name = id; + addIconWithList(icons); + } + + + /** + * 根据 list 注册图标 + * @param icons icon path list + */ + public void addIconWithList(List icons) { + for (String path : icons) { + if (IconManager.isSvgIcon(path)) { + addIcon(new SvgIconSource(path, path)); + } else if (IconManager.isImageIcon(path)) { + addIcon(new ImageIconSource(path, path)); + } + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PluginListIconSet that = (PluginListIconSet) o; + return Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hashCode(name); + } +} diff --git a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginMapIconSet.java b/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginMapIconSet.java deleted file mode 100644 index fdc32bac63..0000000000 --- a/designer-base/src/main/java/com/fine/theme/icon/plugin/PluginMapIconSet.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.fine.theme.icon.plugin; - -import com.fine.theme.icon.AbstractIconSet; -import com.fine.theme.icon.img.ImageIconSource; -import com.fine.theme.icon.svg.SvgIconSource; - -import java.util.Map; -import java.util.Objects; - -/** - * 插件 map 图标集 - * - * @author lemon - * @since - * Created on 2024/08/20 - */ -public class PluginMapIconSet extends AbstractIconSet { - - public PluginMapIconSet(Map iconId2Path) { - addIconWithMap(iconId2Path); - } - - - /** - * 根据 map 注册图标 - * @param iconId2Path key: id, value: icon path - */ - public void addIconWithMap(Map iconId2Path) { - for (Map.Entry entry: iconId2Path.entrySet()) { - if (PluginIconManager.isSvgIcon(entry.getValue())) { - addIcon(new SvgIconSource(entry.getKey(), entry.getValue())); - } else if (PluginIconManager.isImageIcon(entry.getValue())) { - addIcon(new ImageIconSource(entry.getKey(), entry.getValue())); - } - } - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PluginMapIconSet that = (PluginMapIconSet) o; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hashCode(name); - } -} diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineDarkLaf.java b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineDarkLaf.java index f06d8ee888..df1c597d46 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineDarkLaf.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineDarkLaf.java @@ -4,7 +4,6 @@ import com.fine.swing.ui.layout.Layouts; import com.fine.theme.icon.IconManager; import com.fine.theme.light.ui.FineLightIconSet; import com.formdev.flatlaf.util.UIScale; -import com.fr.design.fun.LazyIconProvider; import com.fr.stable.StringUtils; /** @@ -27,14 +26,14 @@ public class FineDarkLaf extends FineLaf { */ public static boolean setup() { IconManager.addSet(new FineLightIconSet()); - // dark_icon 目前还没适配,先使用 light_icon - insertIconProvider(LazyIconProvider.THEME.LIGHT_ICON); Layouts.setScaleFactor(UIScale.getUserScaleFactor()); UIScale.addPropertyChangeListener(evt -> { if (StringUtils.equals(evt.getPropertyName(), USER_SCALE_FACTOR)) { Layouts.setScaleFactor((float) evt.getNewValue()); } }); + // dark_icon 目前还没适配,先使用 light_icon + listenPluginIcons(false); return setup(new FineDarkLaf()); } diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java index f28f1e11d0..a005aa1c4c 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java @@ -1,16 +1,15 @@ package com.fine.theme.light.ui.laf; +import com.fine.theme.icon.IconManager; import com.fine.theme.icon.IconSet; import com.fine.theme.icon.UrlIconResource; -import com.fine.theme.icon.plugin.PluginIconManager; import com.fine.theme.icon.plugin.PluginJsonIconSet; -import com.fine.theme.icon.plugin.PluginMapIconSet; +import com.fine.theme.icon.plugin.PluginListIconSet; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.util.SystemInfo; -import com.fr.design.ExtraDesignClassManager; import com.fr.design.fun.LazyIconProvider; -import com.fr.general.ComparatorUtils; import com.fr.general.GeneralContext; +import com.fr.nx.app.web.out.widget.utils.CollectionUtils; import com.fr.plugin.manage.PluginFilter; import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEventListener; @@ -35,27 +34,36 @@ public abstract class FineLaf extends FlatLaf { private static final String NAME = "FineLaf"; - private static void handlePluginEvent(PluginEvent event, LazyIconProvider.THEME category, + private static void handlePluginEvent(PluginEvent event, boolean isDark, BiConsumer> operation) { Set set = event.getContext().getRuntime().get(LazyIconProvider.MARK_STRING); - dealWithPluginIcon(set, category, operation); + dealWithPluginIcon(set, isDark, operation); } - private static void dealWithPluginIcon(Set set, LazyIconProvider.THEME category, + private static void dealWithPluginIcon(Set set, boolean isDark, BiConsumer> operation) { for (LazyIconProvider provider : set) { - if (!ComparatorUtils.equals(provider.themeCategory(), category)) { + if (provider.isDark() != isDark) { continue; } - List iconSets = new ArrayList<>(); - PluginJsonIconSet jsonIconSet = new PluginJsonIconSet(new UrlIconResource(provider.jsonPath())); - iconSets.add(jsonIconSet); - PluginMapIconSet mapIconSet = new PluginMapIconSet(provider.iconId2Path()); - iconSets.add(mapIconSet); + List iconSets = generatePluginIconSet(provider); operation.accept(provider, iconSets); } } + private static List generatePluginIconSet(LazyIconProvider provider) { + List iconSets = new ArrayList<>(); + if (provider.jsonPath() != null) { + PluginJsonIconSet jsonIconSet = new PluginJsonIconSet(provider.id(), new UrlIconResource(provider.jsonPath())); + iconSets.add(jsonIconSet); + } + if (CollectionUtils.isNotEmpty(provider.icons())) { + PluginListIconSet listIconSet = new PluginListIconSet(provider.id(), provider.icons()); + iconSets.add(listIconSet); + } + return iconSets; + } + @Override public String getName() { return NAME; @@ -93,43 +101,28 @@ public abstract class FineLaf extends FlatLaf { /** * 适配插件图标 Icon - * @param category 图标 Icon 分类 {@link LazyIconProvider.THEME} + * @param isDark 图标 Icon 主题,light 或者 dark */ - public static void insertIconProvider(LazyIconProvider.THEME category) { - Set set = ExtraDesignClassManager.getInstance().getArray(LazyIconProvider.MARK_STRING); - dealWithPluginIcon(set, category, (provider, iconSets) -> PluginIconManager.addSet(provider.pluginId(), iconSets)); - listenerPlugins(category); - } - - private static void listenerPlugins(LazyIconProvider.THEME category) { + public static void listenPluginIcons(boolean isDark) { //注册插件监听 PluginFilter filter = context -> context.contain(LazyIconProvider.MARK_STRING); PluginEventListener insert = new PluginEventListener() { @Override public void on(PluginEvent event) { - handlePluginEvent(event, category, (provider, iconSets) -> PluginIconManager.addSet(provider.pluginId(), iconSets)); - } - }; - - PluginEventListener update = new PluginEventListener() { - @Override - public void on(PluginEvent event) { - handlePluginEvent(event, category, (provider, iconSets) -> PluginIconManager.updateSet(provider.pluginId(), iconSets)); + handlePluginEvent(event, isDark, (provider, iconSets) -> IconManager.addSet(iconSets)); } }; PluginEventListener remove = new PluginEventListener() { @Override public void on(PluginEvent event) { - handlePluginEvent(event, category, (provider, iconSets) -> PluginIconManager.removeSet(provider.pluginId())); + handlePluginEvent(event, isDark, (provider, iconSets) -> IconManager.removeSet(provider.id())); } }; GeneralContext.listenPlugin(PluginEventType.AfterRun, insert, filter); GeneralContext.listenPlugin(PluginEventType.AfterInstall, insert, filter); - GeneralContext.listenPlugin(PluginEventType.AfterUpdate, update, filter); - GeneralContext.listenPlugin(PluginEventType.AfterActive, update, filter); GeneralContext.listenPlugin(PluginEventType.AfterForbid, remove, filter); GeneralContext.listenPlugin(PluginEventType.AfterUninstall, remove, filter); } diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLightLaf.java b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLightLaf.java index 08a0602d62..5acb9a7a04 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLightLaf.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLightLaf.java @@ -4,7 +4,6 @@ import com.fine.swing.ui.layout.Layouts; import com.fine.theme.icon.IconManager; import com.fine.theme.light.ui.FineLightIconSet; import com.formdev.flatlaf.util.UIScale; -import com.fr.design.fun.LazyIconProvider; import com.fr.stable.StringUtils; /** @@ -27,13 +26,13 @@ public class FineLightLaf extends FineLaf { */ public static boolean setup() { IconManager.addSet(new FineLightIconSet()); - insertIconProvider(LazyIconProvider.THEME.LIGHT_ICON); Layouts.setScaleFactor(UIScale.getUserScaleFactor()); UIScale.addPropertyChangeListener(evt -> { if (StringUtils.equals(evt.getPropertyName(), USER_SCALE_FACTOR)) { Layouts.setScaleFactor((float) evt.getNewValue()); } }); + listenPluginIcons(false); return setup(new FineLightLaf()); } diff --git a/designer-base/src/main/java/com/fr/design/fun/LazyIconProvider.java b/designer-base/src/main/java/com/fr/design/fun/LazyIconProvider.java index 1a9fc8095d..edde0535e6 100644 --- a/designer-base/src/main/java/com/fr/design/fun/LazyIconProvider.java +++ b/designer-base/src/main/java/com/fr/design/fun/LazyIconProvider.java @@ -2,7 +2,7 @@ package com.fr.design.fun; import com.fr.stable.fun.mark.Mutable; -import java.util.Map; +import java.util.List; /** * 插件图标适配接口 @@ -13,6 +13,8 @@ import java.util.Map; */ public interface LazyIconProvider extends Mutable { String MARK_STRING = "LazyIconProvider"; + String DARK_SUFFIX = "_dark"; + String LIGHT_SUFFIX = "_light"; int CURRENT_LEVEL = 1; @@ -30,39 +32,25 @@ public interface LazyIconProvider extends Mutable { */ String jsonPath(); - /** - * 图标所属主题分类 - * - * @return 主题类别 - */ - THEME themeCategory(); - /** * 构建需要注册的图标 key: id, value: icon path * @return map */ - Map iconId2Path(); + List icons(); /** - * 图标主题 + * 主题类别 light, dark + * @return 是否是 dark */ - enum THEME { - - /** - * light_icon - */ - LIGHT_ICON("light_icon"), + boolean isDark(); - /** - * dark_icon - */ - DARK_ICON("dark_icon") - ; - - final String category; - THEME(String category) { - this.category = category; - } + /** + * 插件注册的 iconSet id 根据主题设置为 pluginId_light 或者 pluginId_dark + * 同种主题内部的 iconSet id 不做区分 + * @return iconSet id + */ + default String id() { + String suffix = isDark() ? DARK_SUFFIX : LIGHT_SUFFIX; + return pluginId() + suffix; } - } diff --git a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractLazyIconProvider.java b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractLazyIconProvider.java index 6da1316497..187b9deecd 100644 --- a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractLazyIconProvider.java +++ b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractLazyIconProvider.java @@ -4,9 +4,7 @@ import com.fr.design.fun.LazyIconProvider; import com.fr.stable.fun.impl.AbstractProvider; import com.fr.stable.fun.mark.API; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.Map; +import java.util.List; /** @@ -49,23 +47,18 @@ public class AbstractLazyIconProvider extends AbstractProvider implements LazyIc } /** - * 图标主题 {@link THEME} + * 直接注册图标:元素是 icon path * - * @return 主题类别 + * @return list */ @Override - public THEME themeCategory() { + public List icons() { return null; } - /** - * 直接注册图标:key 是 icon id, value 是 icon path - * - * @return map - */ @Override - public Map iconId2Path() { - return null; + public boolean isDark() { + return false; } }