mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix findIcon(path, ClassLoader)
GitOrigin-RevId: fd35f17f9ecb137afa677228244693abc35e74c0
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2efd1b4175
commit
ffc64b112b
+3
-1
@@ -32,12 +32,14 @@ public final class PropertyGroup implements Group, ColoredItemPresentation, Acce
|
||||
private SmartPsiElementPointer<?> myGetterPointer;
|
||||
private SmartPsiElementPointer<?> mySetterPointer;
|
||||
private boolean myIsStatic;
|
||||
|
||||
public static final Icon PROPERTY_READ_ICON = loadIcon("/nodes/propertyRead.png");
|
||||
public static final Icon PROPERTY_READ_STATIC_ICON = loadIcon("/nodes/propertyReadStatic.png");
|
||||
public static final Icon PROPERTY_WRITE_ICON = loadIcon("/nodes/propertyWrite.png");
|
||||
public static final Icon PROPERTY_WRITE_STATIC_ICON = loadIcon("/nodes/propertyWriteStatic.png");
|
||||
public static final Icon PROPERTY_READ_WRITE_ICON = loadIcon("/nodes/propertyReadWrite.png");
|
||||
public static final Icon PROPERTY_READ_WRITE_STATIC_ICON = loadIcon("/nodes/propertyReadWriteStatic.png");
|
||||
|
||||
private final Project myProject;
|
||||
private final Collection<TreeElement> myChildren = new ArrayList<>();
|
||||
|
||||
@@ -202,7 +204,7 @@ public final class PropertyGroup implements Group, ColoredItemPresentation, Acce
|
||||
}
|
||||
|
||||
private static Icon loadIcon(@NonNls String resourceName) {
|
||||
Icon icon = IconLoader.findIcon(resourceName);
|
||||
Icon icon = IconLoader.findIcon(resourceName, PropertyGroup.class, PropertyGroup.class.getClassLoader(), null, true);
|
||||
Application application = ApplicationManager.getApplication();
|
||||
if (icon == null && application != null && application.isUnitTestMode()) {
|
||||
return new ImageIcon();
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.zip.ZipInputStream;
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class LocalArchivedTemplate extends ArchivedProjectTemplate {
|
||||
public final class LocalArchivedTemplate extends ArchivedProjectTemplate {
|
||||
public static final @NonNls String DESCRIPTION_PATH = Project.DIRECTORY_STORE_FOLDER + "/description.html";
|
||||
static final @NonNls String TEMPLATE_DESCRIPTOR = Project.DIRECTORY_STORE_FOLDER + "/project-template.xml";
|
||||
static final @NonNls String TEMPLATE_META_XML = "template-meta.xml";
|
||||
@@ -40,13 +40,12 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate {
|
||||
static final @NonNls String ROOT_FILE_NAME = "root";
|
||||
|
||||
private final URL myArchivePath;
|
||||
private final ModuleType myModuleType;
|
||||
private final ModuleType<?> myModuleType;
|
||||
@Nullable private final List<RootDescription> myModuleDescriptions;
|
||||
private boolean myEscaped = true;
|
||||
private Icon myIcon;
|
||||
|
||||
public LocalArchivedTemplate(@NotNull URL archivePath,
|
||||
@NotNull ClassLoader classLoader) {
|
||||
public LocalArchivedTemplate(@NotNull URL archivePath, @NotNull ClassLoader classLoader) {
|
||||
super(getTemplateName(archivePath), null);
|
||||
|
||||
myArchivePath = archivePath;
|
||||
@@ -135,7 +134,7 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate {
|
||||
@Nullable
|
||||
String readEntry(@NotNull final String endsWith) {
|
||||
try {
|
||||
return processStream(new StreamProcessor<String>() {
|
||||
return processStream(new StreamProcessor<>() {
|
||||
@Override
|
||||
public String consume(@NotNull ZipInputStream stream) throws IOException {
|
||||
ZipEntry entry;
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.extensions.PluginAware;
|
||||
import com.intellij.openapi.extensions.PluginDescriptor;
|
||||
import com.intellij.openapi.extensions.RequiredElement;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.NullableLazyValue;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class TypeIconEP extends AbstractExtensionPointBean {
|
||||
public static final ExtensionPointName<TypeIconEP> EP_NAME = ExtensionPointName.create("com.intellij.typeIcon");
|
||||
final class TypeIconEP implements PluginAware {
|
||||
@Transient
|
||||
private PluginDescriptor pluginDescriptor;
|
||||
|
||||
@Attribute("className")
|
||||
@RequiredElement
|
||||
@@ -24,14 +24,12 @@ public class TypeIconEP extends AbstractExtensionPointBean {
|
||||
@RequiredElement
|
||||
public String icon;
|
||||
|
||||
private final NullableLazyValue<Icon> myIcon = new NullableLazyValue<Icon>() {
|
||||
@Override
|
||||
protected Icon compute() {
|
||||
return IconLoader.findIcon(icon, getLoaderForClass());
|
||||
}
|
||||
};
|
||||
@Transient final NullableLazyValue<Icon> lazyIcon = NullableLazyValue.createValue(() -> {
|
||||
return IconLoader.findIcon(icon, pluginDescriptor == null ? getClass().getClassLoader() : pluginDescriptor.getPluginClassLoader());
|
||||
});
|
||||
|
||||
public NullableLazyValue<Icon> getIcon() {
|
||||
return myIcon;
|
||||
@Override
|
||||
public final void setPluginDescriptor(@NotNull PluginDescriptor pluginDescriptor) {
|
||||
this.pluginDescriptor = pluginDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
public final class TypePresentationServiceImpl extends TypePresentationService {
|
||||
private static final ExtensionPointName<TypeIconEP> TYPE_ICON_EP_NAME = new ExtensionPointName<>("com.intellij.typeIcon");
|
||||
|
||||
private static final ExtensionPointName<PresentationProvider<?>> PROVIDER_EP = new ExtensionPointName<>("com.intellij.presentationProvider");
|
||||
private static final ClassExtension<PresentationProvider<?>> PROVIDERS = new ClassExtension<>(PROVIDER_EP.getName());
|
||||
|
||||
@@ -45,9 +47,8 @@ public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
return findFirst(type, template -> template.getIcon(o, 0));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypePresentableName(Class type) {
|
||||
public @NotNull String getTypePresentableName(Class type) {
|
||||
String typeName = findFirst(type, template -> template.getTypeName());
|
||||
return typeName != null ? typeName : getDefaultTypeName(type);
|
||||
}
|
||||
@@ -77,13 +78,13 @@ public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
}
|
||||
|
||||
public TypePresentationServiceImpl() {
|
||||
for (TypeIconEP ep : TypeIconEP.EP_NAME.getExtensionList()) {
|
||||
myIcons.put(ep.className, ep.getIcon());
|
||||
for (TypeIconEP ep : TYPE_ICON_EP_NAME.getExtensionList()) {
|
||||
myIcons.put(ep.className, ep.lazyIcon);
|
||||
}
|
||||
TypeIconEP.EP_NAME.addExtensionPointListener(new ExtensionPointListener<TypeIconEP>() {
|
||||
TYPE_ICON_EP_NAME.addExtensionPointListener(new ExtensionPointListener<>() {
|
||||
@Override
|
||||
public void extensionAdded(@NotNull TypeIconEP extension, @NotNull PluginDescriptor pluginDescriptor) {
|
||||
myIcons.put(extension.className, extension.getIcon());
|
||||
myIcons.put(extension.className, extension.lazyIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,7 +96,7 @@ public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
for (TypeNameEP ep : TypeNameEP.EP_NAME.getExtensionList()) {
|
||||
myNames.put(ep.className, ep.getTypeName());
|
||||
}
|
||||
TypeNameEP.EP_NAME.addExtensionPointListener(new ExtensionPointListener<TypeNameEP>() {
|
||||
TypeNameEP.EP_NAME.addExtensionPointListener(new ExtensionPointListener<>() {
|
||||
@Override
|
||||
public void extensionAdded(@NotNull TypeNameEP extension, @NotNull PluginDescriptor pluginDescriptor) {
|
||||
myNames.put(extension.className, extension.getTypeName());
|
||||
@@ -115,46 +116,48 @@ public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PresentationTemplate createPresentationTemplate(Class<?> type) {
|
||||
private @Nullable PresentationTemplate createPresentationTemplate(Class<?> type) {
|
||||
Presentation presentation = type.getAnnotation(Presentation.class);
|
||||
if (presentation != null) {
|
||||
return new AnnotationBasedTemplate(presentation, type);
|
||||
}
|
||||
|
||||
PresentationProvider<?> provider = PROVIDERS.forClass(type);
|
||||
if (provider != null) {
|
||||
return new ProviderBasedTemplate(provider);
|
||||
}
|
||||
final NullableLazyValue<Icon> icon = myIcons.get(type.getName());
|
||||
final NullableLazyValue<String> typeName = myNames.get(type.getName());
|
||||
if (icon != null || typeName != null) {
|
||||
return new PresentationTemplate() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Icon getIcon(Object o, int flags) {
|
||||
return icon == null ? null : icon.getValue();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName(Object o) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeName == null ? null : typeName.getValue();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypeName(Object o) {
|
||||
return getTypeName();
|
||||
}
|
||||
};
|
||||
NullableLazyValue<Icon> icon = myIcons.get(type.getName());
|
||||
NullableLazyValue<String> typeName = myNames.get(type.getName());
|
||||
if (icon == null && typeName == null) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
return new PresentationTemplate() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Icon getIcon(Object o, int flags) {
|
||||
return icon == null ? null : icon.getValue();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName(Object o) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeName == null ? null : typeName.getValue();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypeName(Object o) {
|
||||
return getTypeName();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final Map<String, NullableLazyValue<Icon>> myIcons = new HashMap<>();
|
||||
@@ -223,7 +226,7 @@ public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static class AnnotationBasedTemplate extends PresentationProvider<Object> implements PresentationTemplate {
|
||||
private static final class AnnotationBasedTemplate extends PresentationProvider<Object> implements PresentationTemplate {
|
||||
private final Presentation myPresentation;
|
||||
private final Class<?> myClass;
|
||||
|
||||
@@ -241,7 +244,9 @@ public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
@Nullable
|
||||
@Override
|
||||
public Icon getIcon(Object o, int flags) {
|
||||
if (o == null) return myIcon.getValue();
|
||||
if (o == null) {
|
||||
return myIcon.getValue();
|
||||
}
|
||||
PresentationProvider provider = myPresentationProvider.getValue();
|
||||
if (provider == null) {
|
||||
return myIcon.getValue();
|
||||
@@ -277,7 +282,7 @@ public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
return namer == null ? null : namer.getName(o);
|
||||
}
|
||||
|
||||
private final NullableLazyValue<Icon> myIcon = new NullableLazyValue<Icon>() {
|
||||
private final NullableLazyValue<Icon> myIcon = new NullableLazyValue<>() {
|
||||
@Override
|
||||
protected Icon compute() {
|
||||
if (StringUtil.isEmpty(myPresentation.icon())) return null;
|
||||
@@ -285,12 +290,12 @@ public class TypePresentationServiceImpl extends TypePresentationService {
|
||||
}
|
||||
};
|
||||
|
||||
private final NullableLazyValue<PresentationProvider<?>> myPresentationProvider = new NullableLazyValue<PresentationProvider<?>>() {
|
||||
private final NullableLazyValue<PresentationProvider<?>> myPresentationProvider = new NullableLazyValue<>() {
|
||||
@Override
|
||||
protected PresentationProvider<?> compute() {
|
||||
Class<? extends PresentationProvider> aClass = myPresentation.provider();
|
||||
try {
|
||||
return aClass == PresentationProvider.class ? null : aClass.newInstance();
|
||||
return aClass == PresentationProvider.class ? null : aClass.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
|
||||
@@ -281,7 +281,7 @@ public final class IconLoader {
|
||||
return path.regionMatches(dotIndex - suffixLength, "Icons", 0, suffixLength);
|
||||
}
|
||||
|
||||
public static @Nullable Icon findIcon(URL url) {
|
||||
public static @Nullable Icon findIcon(@Nullable URL url) {
|
||||
return findIcon(url, true);
|
||||
}
|
||||
|
||||
@@ -324,9 +324,16 @@ public final class IconLoader {
|
||||
cachedIcon = iconCache.computeIfAbsent(key, k -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
ClassLoader classLoader1 = (ClassLoader)((Pair<String, Object>)k).getSecond();
|
||||
ImageDataResolverImpl resolver = new ImageDataResolverImpl(path, clazz, classLoader1, handleNotFound, /* useCacheOnLoad = */ true);
|
||||
if (!deferUrlResolve && resolver.getURL() == null) {
|
||||
return null;
|
||||
ImageDataLoader resolver;
|
||||
if (deferUrlResolve) {
|
||||
resolver = new ImageDataResolverImpl(path, clazz, classLoader1, handleNotFound, /* useCacheOnLoad = */ true);
|
||||
}
|
||||
else {
|
||||
URL url = doResolve(originalPath, classLoader1, null, HandleNotFound.IGNORE);
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
resolver = new ResolvedImageDataResolver(url, classLoader1);
|
||||
}
|
||||
return new CachedImageIcon(originalPath, resolver, null, null);
|
||||
});
|
||||
@@ -348,8 +355,7 @@ public final class IconLoader {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Icon findIcon(@NotNull String path, @NotNull ClassLoader classLoader) {
|
||||
public static @Nullable Icon findIcon(@NotNull String path, @NotNull ClassLoader classLoader) {
|
||||
return findIcon(path, null, classLoader, HandleNotFound.IGNORE, false);
|
||||
}
|
||||
|
||||
@@ -1003,12 +1009,69 @@ public final class IconLoader {
|
||||
|
||||
@Nullable IconLoader.ImageDataLoader patch(@NotNull String originalPath, @NotNull IconTransform transform);
|
||||
|
||||
boolean isMyClassLoader(@NotNull ClassLoader loader);
|
||||
boolean isMyClassLoader(@NotNull ClassLoader classLoader);
|
||||
}
|
||||
|
||||
private static final class ResolvedImageDataResolver implements ImageDataLoader {
|
||||
private final URL url;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
ResolvedImageDataResolver(@NotNull URL url, @Nullable ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Image loadImage(@Nullable List<ImageFilter> filters, @NotNull ScaleContext scaleContext, boolean isDark) {
|
||||
int flags = ImageLoader.USE_SVG | ImageLoader.ALLOW_FLOAT_SCALING | ImageLoader.USE_CACHE;
|
||||
if (isDark) {
|
||||
flags |= ImageLoader.USE_DARK;
|
||||
}
|
||||
|
||||
String path = url.toString();
|
||||
return ImageLoader.load(path, filters, null, null, flags, scaleContext, !path.endsWith(".svg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull URL getURL() {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @Nullable IconLoader.ImageDataLoader patch(@NotNull String originalPath, @NotNull IconTransform transform) {
|
||||
Pair<String, ClassLoader> patchedPath = transform.patchPath(originalPath, classLoader);
|
||||
if (patchedPath == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ClassLoader classLoader = patchedPath.second == null ? null : patchedPath.second;
|
||||
String path = patchedPath.first;
|
||||
// This use case for temp themes only. Here we want immediately replace existing icon to a local one
|
||||
if (path != null && path.startsWith("file:/")) {
|
||||
try {
|
||||
ImageDataResolverImpl resolver = new ImageDataResolverImpl(new URL(path), path.substring(1), classLoader, true);
|
||||
resolver.resolve();
|
||||
return resolver;
|
||||
}
|
||||
catch (MalformedURLException ignore) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isMyClassLoader(@NotNull ClassLoader classLoader) {
|
||||
return classLoader == this.classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return "ResolvedImageDataResolver{" +
|
||||
", url=" + url +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to defer URL resolve.
|
||||
*/
|
||||
private static class ImageDataResolverImpl implements ImageDataLoader {
|
||||
private static final URL UNRESOLVED_URL;
|
||||
|
||||
@@ -1092,29 +1155,6 @@ public final class IconLoader {
|
||||
getURL();
|
||||
}
|
||||
|
||||
private static @Nullable URL doResolve(@Nullable String overriddenPath,
|
||||
@Nullable ClassLoader classLoader,
|
||||
@Nullable Class<?> ownerClass,
|
||||
@NotNull HandleNotFound handleNotFound) {
|
||||
String path = overriddenPath;
|
||||
URL url = null;
|
||||
if (path != null) {
|
||||
if (classLoader != null) {
|
||||
// paths in ClassLoader getResource must not start with "/"
|
||||
path = path.charAt(0) == '/' ? path.substring(1) : path;
|
||||
url = findUrl(path, classLoader::getResource);
|
||||
}
|
||||
if (url == null && ownerClass != null) {
|
||||
// some plugins use findIcon("icon.png",IconContainer.class)
|
||||
url = findUrl(path, ownerClass::getResource);
|
||||
}
|
||||
}
|
||||
if (url == null) {
|
||||
handleNotFound.handle("Can't find icon in '" + path + "' near " + classLoader);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @Nullable URL getURL() {
|
||||
URL result = this.url;
|
||||
@@ -1159,32 +1199,9 @@ public final class IconLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicateExpressions")
|
||||
private static @Nullable URL findUrl(@NotNull String path, @NotNull Function<? super String, URL> urlProvider) {
|
||||
URL url = urlProvider.apply(path);
|
||||
if (url != null) {
|
||||
return url;
|
||||
}
|
||||
|
||||
// Find either PNG or SVG icon. The icon will then be wrapped into CachedImageIcon
|
||||
// which will load proper icon version depending on the context - UI theme, DPI.
|
||||
// SVG version, when present, has more priority than PNG.
|
||||
// See for details: com.intellij.util.ImageLoader.ImageDescList#create
|
||||
if (path.endsWith(".png")) {
|
||||
path = path.substring(0, path.length() - 4) + ".svg";
|
||||
}
|
||||
else if (path.endsWith(".svg")) {
|
||||
path = path.substring(0, path.length() - 4) + ".png";
|
||||
}
|
||||
else {
|
||||
LOG.debug("unexpected path: ", path);
|
||||
}
|
||||
return urlProvider.apply(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isMyClassLoader(@NotNull ClassLoader loader) {
|
||||
return classLoader == loader;
|
||||
public final boolean isMyClassLoader(@NotNull ClassLoader classLoader) {
|
||||
return this.classLoader == classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1199,6 +1216,52 @@ public final class IconLoader {
|
||||
}
|
||||
}
|
||||
|
||||
static @Nullable URL doResolve(@Nullable String overriddenPath,
|
||||
@Nullable ClassLoader classLoader,
|
||||
@Nullable Class<?> ownerClass,
|
||||
@NotNull HandleNotFound handleNotFound) {
|
||||
String path = overriddenPath;
|
||||
URL url = null;
|
||||
if (path != null) {
|
||||
if (classLoader != null) {
|
||||
// paths in ClassLoader getResource must not start with "/"
|
||||
path = path.charAt(0) == '/' ? path.substring(1) : path;
|
||||
url = findUrl(path, classLoader::getResource);
|
||||
}
|
||||
if (url == null && ownerClass != null) {
|
||||
// some plugins use findIcon("icon.png",IconContainer.class)
|
||||
url = findUrl(path, ownerClass::getResource);
|
||||
}
|
||||
}
|
||||
if (url == null) {
|
||||
handleNotFound.handle("Can't find icon in '" + path + "' near " + classLoader);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicateExpressions")
|
||||
private static @Nullable URL findUrl(@NotNull String path, @NotNull Function<? super String, URL> urlProvider) {
|
||||
URL url = urlProvider.apply(path);
|
||||
if (url != null) {
|
||||
return url;
|
||||
}
|
||||
|
||||
// Find either PNG or SVG icon. The icon will then be wrapped into CachedImageIcon
|
||||
// which will load proper icon version depending on the context - UI theme, DPI.
|
||||
// SVG version, when present, has more priority than PNG.
|
||||
// See for details: com.intellij.util.ImageLoader.ImageDescList#create
|
||||
if (path.endsWith(".png")) {
|
||||
path = path.substring(0, path.length() - 4) + ".svg";
|
||||
}
|
||||
else if (path.endsWith(".svg")) {
|
||||
path = path.substring(0, path.length() - 4) + ".png";
|
||||
}
|
||||
else {
|
||||
LOG.debug("unexpected path: ", path);
|
||||
}
|
||||
return urlProvider.apply(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Icon createLazy(@NotNull Supplier<? extends @NotNull Icon> producer) {
|
||||
return new LazyIcon() {
|
||||
|
||||
Reference in New Issue
Block a user