From 44fd4639dbc89d4c8a765abe4097cba194bac315 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 9 Jan 2014 15:08:01 +0400 Subject: [PATCH] IDEA-57553 Optimize display of multiple similar editor gutter icons (e.g. Spring autowiring) --- .../daemon/RelatedItemLineMarkerInfo.java | 39 ++++++++++++++++++- .../impl/DaemonTooltipRendererProvider.java | 14 +++---- .../daemon/impl/LineMarkersPass.java | 8 ++-- .../daemon/impl/SlowLineMarkersPass.java | 10 +++-- .../impl/SlowLineMarkersPassFactory.java | 2 +- .../codeInsight/hint/LineTooltipRenderer.java | 3 +- .../util/src/com/intellij/util/ui/UIUtil.java | 2 + 7 files changed, 59 insertions(+), 19 deletions(-) diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/RelatedItemLineMarkerInfo.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/RelatedItemLineMarkerInfo.java index 55ce601e8943..ad0f66c73c9c 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/RelatedItemLineMarkerInfo.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/RelatedItemLineMarkerInfo.java @@ -21,16 +21,20 @@ import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Collection; +import java.util.List; +import java.util.Set; /** * @author nik */ -public class RelatedItemLineMarkerInfo extends LineMarkerInfo { +public class RelatedItemLineMarkerInfo extends MergeableLineMarkerInfo { private final NotNullLazyValue> myTargets; public RelatedItemLineMarkerInfo(@NotNull T element, @NotNull TextRange range, Icon icon, int updatePass, @@ -67,6 +71,39 @@ public class RelatedItemLineMarkerInfo extends LineMarkerI return new RelatedItemLineMarkerGutterIconRenderer(this); } + @Override + public boolean canMergeWith(@NotNull MergeableLineMarkerInfo info) { + return myIcon == info.myIcon; + } + + @Override + public Icon getCommonIcon(@NotNull List infos) { + return myIcon; + } + + @Override + public Function getCommonTooltip(@NotNull final List infos) { + return new Function() { + @Override + public String fun(PsiElement element) { + Set tooltips = ContainerUtil.map2Set(infos, new Function() { + @Override + public String fun(MergeableLineMarkerInfo info) { + return info.getLineMarkerTooltip(); + } + }); + StringBuilder tooltip = new StringBuilder(); + for (String info : tooltips) { + if (tooltip.length() > 0) { + tooltip.append(UIUtil.BORDER_LINE); + } + tooltip.append(UIUtil.getHtmlBody(info)); + } + return "" + tooltip.toString() + ""; + } + }; + } + private static class RelatedItemLineMarkerGutterIconRenderer extends LineMarkerGutterIconRenderer { public RelatedItemLineMarkerGutterIconRenderer(final RelatedItemLineMarkerInfo markerInfo) { super(markerInfo); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java index 4451797b3b26..5b705e8c43ba 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java @@ -135,7 +135,7 @@ public class DaemonTooltipRendererProvider implements ErrorStripTooltipRendererP @Override protected boolean dressDescription(@NotNull final Editor editor) { - final List problems = StringUtil.split(UIUtil.getHtmlBody(myText), BORDER_LINE); + final List problems = StringUtil.split(UIUtil.getHtmlBody(myText), UIUtil.BORDER_LINE); String text = ""; for (String problem : problems) { final String ref = getLinkRef(problem); @@ -145,15 +145,15 @@ public class DaemonTooltipRendererProvider implements ErrorStripTooltipRendererP description = DefaultInspectionToolPresentation.stripUIRefsFromInspectionDescription(UIUtil.getHtmlBody(description)); text += UIUtil.getHtmlBody(problem).replace(DaemonBundle.message("inspection.extended.description"), DaemonBundle.message("inspection.collapse.description")) + - END_MARKER + "

" + description + BORDER_LINE; + END_MARKER + "

" + description + UIUtil.BORDER_LINE; } } else { - text += UIUtil.getHtmlBody(problem) + BORDER_LINE; + text += UIUtil.getHtmlBody(problem) + UIUtil.BORDER_LINE; } } if (!text.isEmpty()) { //otherwise do not change anything - myText = "" + StringUtil.trimEnd(text, BORDER_LINE) + ""; + myText = "" + StringUtil.trimEnd(text, UIUtil.BORDER_LINE) + ""; return true; } return false; @@ -175,14 +175,14 @@ public class DaemonTooltipRendererProvider implements ErrorStripTooltipRendererP @Override protected void stripDescription() { - final List problems = StringUtil.split(UIUtil.getHtmlBody(myText), BORDER_LINE); + final List problems = StringUtil.split(UIUtil.getHtmlBody(myText), UIUtil.BORDER_LINE); myText = ""; for (int i = 0, size = problems.size(); i < size; i++) { final String problem = StringUtil.split(problems.get(i), END_MARKER).get(0); myText += UIUtil.getHtmlBody(problem).replace(DaemonBundle.message("inspection.collapse.description"), - DaemonBundle.message("inspection.extended.description")) + BORDER_LINE; + DaemonBundle.message("inspection.extended.description")) + UIUtil.BORDER_LINE; } - myText = StringUtil.trimEnd(myText, BORDER_LINE) + ""; + myText = StringUtil.trimEnd(myText, UIUtil.BORDER_LINE) + ""; } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java index 9f1489c31015..19a247f4a4a1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java @@ -122,10 +122,10 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM collectLineMarkersForInjected(lineMarkers, elements, this, myFile, progress); } - myMarkers = mergeLineMarkers(lineMarkers); + myMarkers = mergeLineMarkers(lineMarkers, myEditor); } - private List mergeLineMarkers(@NotNull List markers) { + static List mergeLineMarkers(@NotNull List markers, Editor editor) { List forMerge = new ArrayList(); final Iterator iterator = markers.iterator(); while (iterator.hasNext()) { @@ -137,12 +137,12 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM } } - if (forMerge.isEmpty() || myEditor == null) return markers; + if (forMerge.isEmpty() || editor == null) return markers; final List result = new ArrayList(markers); TIntObjectHashMap> sameLineMarkers = new TIntObjectHashMap>(); for (MergeableLineMarkerInfo info : forMerge) { - final LogicalPosition position = myEditor.offsetToLogicalPosition(info.startOffset); + final LogicalPosition position = editor.offsetToLogicalPosition(info.startOffset); List infos = sameLineMarkers.get(position.line); if (infos == null) { infos = new ArrayList(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPass.java index 24ceab182546..ebc7089f89c1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPass.java @@ -21,7 +21,7 @@ import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.codeInsight.daemon.impl.analysis.HighlightingLevelManager; import com.intellij.lang.Language; -import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.DumbAware; @@ -39,14 +39,16 @@ import java.util.Set; public class SlowLineMarkersPass extends TextEditorHighlightingPass implements LineMarkersProcessor, DumbAware { private final PsiFile myFile; + @NotNull private final Editor myEditor; private final int myStartOffset; private final int myEndOffset; private volatile Collection myMarkers = Collections.emptyList(); - public SlowLineMarkersPass(@NotNull Project project, @NotNull PsiFile file, @NotNull Document document, int startOffset, int endOffset) { - super(project, document, false); + public SlowLineMarkersPass(@NotNull Project project, @NotNull PsiFile file, @NotNull Editor editor, int startOffset, int endOffset) { + super(project, editor.getDocument(), false); myFile = file; + myEditor = editor; myStartOffset = startOffset; myEndOffset = endOffset; } @@ -65,7 +67,7 @@ public class SlowLineMarkersPass extends TextEditorHighlightingPass implements L LineMarkersPass.collectLineMarkersForInjected(markers, elements, this, myFile, progress); } - myMarkers = markers; + myMarkers = LineMarkersPass.mergeLineMarkers(markers, myEditor); } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPassFactory.java index c3b415b8cbfa..416d24b3d8ca 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPassFactory.java @@ -47,7 +47,7 @@ public class SlowLineMarkersPassFactory extends AbstractProjectComponent impleme public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) { TextRange textRange = calculateRangeToProcess(editor); if (textRange == null) return null; - return new SlowLineMarkersPass(myProject, file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset()); + return new SlowLineMarkersPass(myProject, file, editor, textRange.getStartOffset(), textRange.getEndOffset()); } private static TextRange calculateRangeToProcess(Editor editor) { diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/LineTooltipRenderer.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/LineTooltipRenderer.java index f2bfbcf954ec..9bcfb8741e73 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/LineTooltipRenderer.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/LineTooltipRenderer.java @@ -45,7 +45,6 @@ import java.net.URL; * @author cdr */ public class LineTooltipRenderer extends ComparableObject.Impl implements TooltipRenderer { - @NonNls protected static final String BORDER_LINE = "


"; @NonNls protected String myText; @@ -323,7 +322,7 @@ public class LineTooltipRenderer extends ComparableObject.Impl implements Toolti else { String html1 = UIUtil.getHtmlBody(myText); String html2 = UIUtil.getHtmlBody(text); - newBody = html1 + BORDER_LINE + html2; + newBody = html1 + UIUtil.BORDER_LINE + html2; } myText = "" + newBody + ""; } diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index ed5cbe856322..3a161b6e1fb8 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -70,6 +70,8 @@ import java.util.regex.Pattern; @SuppressWarnings("StaticMethodOnlyUsedInOneClass") public class UIUtil { + @NonNls public static final String BORDER_LINE = "
"; + private static final AtomicNotNullLazyValue X_RENDER_ACTIVE = new AtomicNotNullLazyValue() { @NotNull @Override