spring mergeable gutter action group

This commit is contained in:
sergey.vasiliev
2017-07-28 14:55:38 +02:00
parent ea83a9ddfd
commit 826001baba
3 changed files with 53 additions and 39 deletions
@@ -27,15 +27,15 @@ import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.util.Function;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
* @author Konstantin Bulenkov
@@ -54,13 +54,27 @@ public abstract class MergeableLineMarkerInfo<T extends PsiElement> extends Line
public abstract boolean canMergeWith(@NotNull MergeableLineMarkerInfo<?> info);
public abstract Icon getCommonIcon(@NotNull List<MergeableLineMarkerInfo> infos);
@NotNull
public abstract Function<? super PsiElement, String> getCommonTooltip(@NotNull List<MergeableLineMarkerInfo> infos);
public Function<? super PsiElement, String> getCommonTooltip(@NotNull final List<MergeableLineMarkerInfo> infos) {
return (Function<PsiElement, String>)element -> {
Set<String> tooltips = new HashSet<>(ContainerUtil.mapNotNull(infos, info -> 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 XmlStringUtil.wrapInHtml(tooltip);
};
}
public GutterIconRenderer.Alignment getCommonIconAlignment(@NotNull List<MergeableLineMarkerInfo> infos) {
return GutterIconRenderer.Alignment.LEFT;
}
public String getElementPresentation(PsiElement element) {
return element.getText();
}
@@ -133,7 +147,7 @@ public abstract class MergeableLineMarkerInfo<T extends PsiElement> extends Line
Collections.sort(infos, (o1, o2) -> o1.startOffset - o2.startOffset);
final JBList list = new JBList(infos);
list.setFixedCellHeight(UIUtil.LIST_FIXED_CELL_HEIGHT);
PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(list);
PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(list);
if (!markers.get(0).configurePopupAndRenderer(builder, list, infos)) {
list.installCellRenderer(dom -> {
if (dom instanceof LineMarkerInfo) {
@@ -83,22 +83,6 @@ public class RelatedItemLineMarkerInfo<T extends PsiElement> extends MergeableLi
return myIcon;
}
@NotNull
@Override
public Function<? super PsiElement, String> getCommonTooltip(@NotNull final List<MergeableLineMarkerInfo> infos) {
return (Function<PsiElement, String>)element -> {
Set<String> tooltips = new HashSet<>(ContainerUtil.mapNotNull(infos, info -> 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 XmlStringUtil.wrapInHtml(tooltip);
};
}
private static class RelatedItemLineMarkerGutterIconRenderer<T extends PsiElement> extends LineMarkerGutterIconRenderer<T> {
public RelatedItemLineMarkerGutterIconRenderer(final RelatedItemLineMarkerInfo<T> markerInfo) {
super(markerInfo);
@@ -57,23 +57,23 @@ import java.util.*;
*/
public class NavigationGutterIconBuilder<T> {
@NonNls private static final String PATTERN = "&nbsp;&nbsp;&nbsp;&nbsp;{0}";
private static final NotNullFunction<PsiElement,Collection<? extends PsiElement>> DEFAULT_PSI_CONVERTOR =
private static final NotNullFunction<PsiElement, Collection<? extends PsiElement>> DEFAULT_PSI_CONVERTOR =
element -> ContainerUtil.createMaybeSingletonList(element);
private final Icon myIcon;
private final NotNullFunction<T,Collection<? extends PsiElement>> myConverter;
private final NotNullFunction<T, Collection<? extends PsiElement>> myConverter;
private NotNullLazyValue<Collection<T>> myTargets;
private boolean myLazy;
protected NotNullLazyValue<Collection<T>> myTargets;
protected boolean myLazy;
private String myTooltipText;
private String myPopupTitle;
private String myEmptyText;
private String myTooltipTitle;
private GutterIconRenderer.Alignment myAlignment = GutterIconRenderer.Alignment.CENTER;
private Computable<PsiElementListCellRenderer> myCellRenderer;
private NullableFunction<T,String> myNamer = ElementPresentationManager.namer();
private final NotNullFunction<T, Collection<? extends GotoRelatedItem>> myGotoRelatedItemProvider;
public static final NotNullFunction<DomElement,Collection<? extends PsiElement>> DEFAULT_DOM_CONVERTOR =
private NullableFunction<T, String> myNamer = ElementPresentationManager.namer();
protected final NotNullFunction<T, Collection<? extends GotoRelatedItem>> myGotoRelatedItemProvider;
public static final NotNullFunction<DomElement, Collection<? extends PsiElement>> DEFAULT_DOM_CONVERTOR =
o -> ContainerUtil.createMaybeSingletonList(o.getXmlElement());
public static final NotNullFunction<DomElement, Collection<? extends GotoRelatedItem>> DOM_GOTO_RELATED_ITEM_PROVIDER = dom -> {
if (dom.getXmlElement() != null) {
@@ -157,7 +157,7 @@ public class NavigationGutterIconBuilder<T> {
return this;
}
public NavigationGutterIconBuilder<T> setNamer(@NotNull NullableFunction<T,String> namer) {
public NavigationGutterIconBuilder<T> setNamer(@NotNull NullableFunction<T, String> namer) {
myNamer = namer;
return this;
}
@@ -189,12 +189,16 @@ public class NavigationGutterIconBuilder<T> {
public RelatedItemLineMarkerInfo<PsiElement> createLineMarkerInfo(@NotNull PsiElement element) {
final MyNavigationGutterIconRenderer renderer = createGutterIconRenderer(element.getProject());
final String tooltip = renderer.getTooltipText();
NotNullLazyValue<Collection<? extends GotoRelatedItem>> gotoTargets = createGotoTargetsThunk(myLazy, myGotoRelatedItemProvider,
evaluateAndForget(myTargets));
return new RelatedItemLineMarkerInfo<PsiElement>(element, element.getTextRange(), renderer.getIcon(), Pass.LINE_MARKERS,
tooltip == null ? null : new ConstantFunction<PsiElement, String>(tooltip),
renderer.isNavigateAction() ? renderer : null, renderer.getAlignment(),
gotoTargets);
NotNullLazyValue<Collection<? extends GotoRelatedItem>> gotoTargets = getGotoTargets();
return new RelatedItemLineMarkerInfo<>(element, element.getTextRange(), renderer.getIcon(), Pass.LINE_MARKERS,
tooltip == null ? null : new ConstantFunction<>(tooltip),
renderer.isNavigateAction() ? renderer : null, renderer.getAlignment(),
gotoTargets);
}
@NotNull
protected NotNullLazyValue<Collection<? extends GotoRelatedItem>> getGotoTargets() {
return createGotoTargetsThunk(myLazy, myGotoRelatedItemProvider, evaluateAndForget(myTargets));
}
private static <T> NotNullLazyValue<Collection<? extends GotoRelatedItem>> createGotoTargetsThunk(boolean lazy,
@@ -220,8 +224,8 @@ public class NavigationGutterIconBuilder<T> {
private void checkBuilt() {
assert myTargets != null : "Must have called .setTargets() before calling create()";
}
private static <T> Factory<T> evaluateAndForget(NotNullLazyValue<T> lazyValue) {
protected static <T> Factory<T> evaluateAndForget(NotNullLazyValue<T> lazyValue) {
final Ref<NotNullLazyValue<T>> ref = Ref.create(lazyValue);
return new Factory<T>() {
volatile T result;
@@ -237,7 +241,7 @@ public class NavigationGutterIconBuilder<T> {
};
}
private MyNavigationGutterIconRenderer createGutterIconRenderer(@NotNull final Project project) {
protected MyNavigationGutterIconRenderer createGutterIconRenderer(@NotNull final Project project) {
checkBuilt();
NotNullLazyValue<List<SmartPsiElementPointer>> pointers = createPointersThunk(myLazy, project, evaluateAndForget(myTargets),
@@ -382,4 +386,16 @@ public class NavigationGutterIconBuilder<T> {
return result;
}
}
private static class MyPsiElementRelatedItemLineMarkerInfo extends RelatedItemLineMarkerInfo<PsiElement> {
public MyPsiElementRelatedItemLineMarkerInfo(PsiElement element,
NavigationGutterIconRenderer renderer,
String tooltip,
NotNullLazyValue<Collection<? extends GotoRelatedItem>> gotoTargets) {
super(element, element.getTextRange(), renderer.getIcon(), Pass.LINE_MARKERS, tooltip == null
? null
: new ConstantFunction<>(tooltip),
renderer.isNavigateAction() ? renderer : null, renderer.getAlignment(), gotoTargets);
}
}
}