mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Deferred class icons for project view
This commit is contained in:
@@ -27,6 +27,7 @@ public class ElementPresentationUtil {
|
||||
public static final Icon JUNIT_TEST_MARK = IconLoader.getIcon("/nodes/junitTestMark.png");
|
||||
private static final Icon RUNNABLE_MARK = IconLoader.getIcon("/nodes/runnableMark.png");
|
||||
|
||||
|
||||
private ElementPresentationUtil() {
|
||||
}
|
||||
|
||||
@@ -83,6 +84,18 @@ public class ElementPresentationUtil {
|
||||
&& CompilerConfiguration.getInstance(project).isExcludedFromCompilation(vFile);
|
||||
}
|
||||
|
||||
public static int getBasicClassKind(PsiClass aClass) {
|
||||
if (!aClass.isValid()) return CLASS_KIND_CLASS;
|
||||
|
||||
if (aClass.isAnnotationType()) return CLASS_KIND_ANNOTATION;
|
||||
if (aClass.isEnum()) return CLASS_KIND_ENUM;
|
||||
if (aClass.isInterface()) return CLASS_KIND_INTERFACE;
|
||||
if (aClass instanceof JspClass) return CLASS_KIND_JSP;
|
||||
if (aClass instanceof PsiAnonymousClass) return CLASS_KIND_ANONYMOUS;
|
||||
|
||||
return CLASS_KIND_CLASS;
|
||||
}
|
||||
|
||||
public static int getClassKind(final PsiClass aClass) {
|
||||
if (!aClass.isValid()) {
|
||||
aClass.putUserData(CLASS_KIND_KEY, null);
|
||||
@@ -162,8 +175,7 @@ public class ElementPresentationUtil {
|
||||
BASE_ICON.put(CLASS_KIND_RUNNABLE, Icons.CLASS_ICON);
|
||||
}
|
||||
|
||||
public static Icon getClassBaseIcon(final PsiClass aClass) {
|
||||
final int classKind = getClassKind(aClass);
|
||||
public static Icon getClassIconOfKind(PsiClass aClass, int classKind) {
|
||||
final boolean isAbstract = aClass.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
return BASE_ICON.get(classKind | (isAbstract ? FLAGS_ABSTRACT : 0));
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.PackageScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.ui.IconDeferrer;
|
||||
import com.intellij.ui.RowIcon;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ReflectionCache;
|
||||
import com.intellij.util.SmartList;
|
||||
@@ -267,11 +269,52 @@ public class PsiClassImplUtil {
|
||||
return (Map<String, List<Pair<T, PsiSubstitutor>>>)value.getValue().get(memberClazz);
|
||||
}
|
||||
|
||||
private static class ClassIconRequest {
|
||||
public PsiClass psiClass;
|
||||
public int flags;
|
||||
|
||||
private ClassIconRequest(PsiClass psiClass, int flags) {
|
||||
this.psiClass = psiClass;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ClassIconRequest)) return false;
|
||||
|
||||
ClassIconRequest that = (ClassIconRequest)o;
|
||||
|
||||
if (flags != that.flags) return false;
|
||||
if (psiClass != null ? !psiClass.equals(that.psiClass) : that.psiClass != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = psiClass != null ? psiClass.hashCode() : 0;
|
||||
result = 31 * result + flags;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Function<ClassIconRequest, Icon> FULL_ICON_EVALUATOR = new Function<ClassIconRequest, Icon>() {
|
||||
public Icon fun(ClassIconRequest r) {
|
||||
final boolean isLocked = (r.flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && !r.psiClass.isWritable();
|
||||
Icon symbolIcon = ElementPresentationUtil.getClassIconOfKind(r.psiClass, ElementPresentationUtil.getClassKind(r.psiClass));
|
||||
RowIcon baseIcon = ElementBase.createLayeredIcon(symbolIcon, ElementPresentationUtil.getFlags(r.psiClass, isLocked));
|
||||
return ElementPresentationUtil.addVisibilityIcon(r.psiClass, r.flags, baseIcon);
|
||||
}
|
||||
};
|
||||
|
||||
public static Icon getClassIcon(final int flags, final PsiClass aClass) {
|
||||
final boolean isLocked = (flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && !aClass.isWritable();
|
||||
Icon symbolIcon = ElementPresentationUtil.getClassBaseIcon(aClass);
|
||||
RowIcon baseIcon = ElementBase.createLayeredIcon(symbolIcon, ElementPresentationUtil.getFlags(aClass, isLocked));
|
||||
return ElementPresentationUtil.addVisibilityIcon(aClass, flags, baseIcon);
|
||||
Icon symbolIcon = ElementPresentationUtil.getClassIconOfKind(aClass, ElementPresentationUtil.getBasicClassKind(aClass));
|
||||
RowIcon baseIcon = ElementBase.createLayeredIcon(symbolIcon, 0);
|
||||
|
||||
return IconDeferrer.getInstance().defer(ElementPresentationUtil.addVisibilityIcon(aClass, flags, baseIcon),
|
||||
new ClassIconRequest(aClass, flags),
|
||||
FULL_ICON_EVALUATOR);
|
||||
}
|
||||
|
||||
public static SearchScope getClassUseScope(final PsiClass aClass) {
|
||||
|
||||
+1
-5
@@ -123,11 +123,7 @@ public abstract class AbstractPsiBasedNode<Value> extends ProjectViewNode<Value>
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
data.setPresentableText(myName);
|
||||
try {
|
||||
data.setTooltip(calcTooltip());
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
|
||||
try {
|
||||
if (isDeprecated()) {
|
||||
data.setAttributesKey(CodeInsightColors.DEPRECATED_ATTRIBUTES);
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.intellij.concurrency.Job;
|
||||
import com.intellij.concurrency.JobScheduler;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
|
||||
@@ -15,8 +16,11 @@ import javax.swing.plaf.TreeUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import java.awt.*;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
private static final RepaintScheduler ourRepaintScheduler = new RepaintScheduler();
|
||||
private volatile Icon myDelegateIcon;
|
||||
private final Function<T, Icon> myEvaluator;
|
||||
private volatile boolean myIsScheduled = false;
|
||||
@@ -96,7 +100,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
c.repaint(x, y, getIconWidth(), getIconHeight());
|
||||
}
|
||||
else {
|
||||
target.repaint();
|
||||
ourRepaintScheduler.pushDirtyComponent(target);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -171,4 +175,23 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
lastTarget.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private static class RepaintScheduler {
|
||||
private final Alarm myAlarm = new Alarm();
|
||||
private final Set<Component> myQueue = new LinkedHashSet<Component>();
|
||||
|
||||
public void pushDirtyComponent(Component c) {
|
||||
myAlarm.cancelAllRequests();
|
||||
myAlarm.addRequest(new Runnable() {
|
||||
public void run() {
|
||||
for (Component component : myQueue) {
|
||||
component.repaint();
|
||||
}
|
||||
myQueue.clear();
|
||||
}
|
||||
}, 50);
|
||||
|
||||
myQueue.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user