differently-colored tail text fragments

This commit is contained in:
peter
2012-09-28 11:39:19 +02:00
parent 506ee8b312
commit 2390fe7ecc
4 changed files with 130 additions and 43 deletions
@@ -66,10 +66,12 @@ public class MemberLookupHelper {
PsiFormatUtil.SHOW_PARAMETERS,
PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE)
: "";
presentation.clearTail();
presentation.appendTailText(params, false);
if (myShouldImport && StringUtil.isNotEmpty(className)) {
presentation.setTailText(params + " in " + className + location);
presentation.appendTailText(" in " + className + location, true);
} else {
presentation.setTailText(params + location, !(myMember instanceof PsiMethod));
presentation.appendTailText(location, true);
}
final PsiType type = myMember instanceof PsiMethod ? ((PsiMethod)myMember).getReturnType() : ((PsiField) myMember).getType();
@@ -67,8 +67,7 @@ public class Foo {
""")
myFixture.configureByText "a.java", "class Bar {{ abcf<caret> }}"
def element = complete()[0]
def presentation = new LookupElementPresentation()
element.renderElement(presentation)
def presentation = LookupElementPresentation.renderElement(element)
assert 'Foo.abcfield' == presentation.itemText
assert ' (foo)' == presentation.tailText
assert 'int' == presentation.typeText
@@ -162,7 +161,14 @@ class Bar {{ abcmethod1()<caret> }}"""
""")
myFixture.configureByText("a.java", "class Bar {{ abcm<caret> }}")
complete()
def element = complete()[0]
def tail = LookupElementPresentation.renderElement(element).tailFragments
assert tail[0].text == '(...)'
assert !tail[0].grayed
assert tail[1].text == ' (foo)'
assert tail[1].grayed
assertOrderedEquals myFixture.lookupElementStrings, "abcmethod", "abcmethod1"
}
@@ -177,8 +183,7 @@ class A {
}
""")
def element = complete()[0]
def presentation = new LookupElementPresentation()
element.renderElement(presentation)
def presentation = LookupElementPresentation.renderElement(element)
assert 'foo' == presentation.itemText
myFixture.type '\n'
myFixture.checkResult '''
@@ -15,11 +15,16 @@
*/
package com.intellij.codeInsight.lookup;
import org.jetbrains.annotations.Nullable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Collections;
import java.util.List;
/**
* @author peter
@@ -28,15 +33,13 @@ public class LookupElementPresentation {
private Icon myIcon;
private Icon myTypeIcon;
private String myItemText;
private String myTailText;
private String myTypeText;
private boolean myStrikeout;
private boolean myTailGrayed;
private Color myTailForeground;
private Color myItemTextForeground = Color.black;
private boolean myItemTextBold;
private boolean myItemTextUnderlined;
private boolean myTypeGrayed;
@Nullable private List<TextFragment> myTail;
public void setIcon(@Nullable Icon icon) {
myIcon = icon;
@@ -58,14 +61,33 @@ public class LookupElementPresentation {
setTailText(text, false);
}
public void clearTail() {
myTail = null;
}
public void appendTailText(@NotNull String text, boolean grayed) {
appendTailText(new TextFragment(text, grayed, null));
}
private void appendTailText(@NotNull TextFragment fragment) {
if (myTail == null) {
myTail = new SmartList<TextFragment>();
}
myTail.add(fragment);
}
public void setTailText(@Nullable String text, boolean grayed) {
myTailText = text;
myTailGrayed = grayed;
clearTail();
if (text != null) {
appendTailText(new TextFragment(text, grayed, null));
}
}
public void setTailText(@Nullable String text, @Nullable Color foreground) {
myTailText = text;
myTailForeground = foreground;
clearTail();
if (text != null) {
appendTailText(new TextFragment(text, false, foreground));
}
}
public void setTypeText(@Nullable String text) {
@@ -102,9 +124,21 @@ public class LookupElementPresentation {
return myItemText;
}
@NotNull
public List<TextFragment> getTailFragments() {
return myTail == null ? Collections.<TextFragment>emptyList() : Collections.unmodifiableList(myTail);
}
@Nullable
@Deprecated
public String getTailText() {
return myTailText;
if (myTail == null) return null;
return StringUtil.join(myTail, new Function<TextFragment, String>() {
@Override
public String fun(TextFragment fragment) {
return fragment.text;
}
}, "");
}
@Nullable
@@ -116,13 +150,15 @@ public class LookupElementPresentation {
return myStrikeout;
}
@Deprecated
public boolean isTailGrayed() {
return myTailGrayed;
return myTail != null && myTail.get(0).grayed;
}
@Nullable
@Deprecated
public Color getTailForeground() {
return myTailForeground;
return myTail != null ? myTail.get(0).fgColor : null;
}
public boolean isItemTextBold() {
@@ -149,11 +185,12 @@ public class LookupElementPresentation {
myIcon = presentation.myIcon;
myTypeIcon = presentation.myTypeIcon;
myItemText = presentation.myItemText;
myTailText = presentation.myTailText;
List<TextFragment> thatTail = presentation.myTail;
myTail = thatTail == null ? null : new SmartList<TextFragment>(thatTail);
myTypeText = presentation.myTypeText;
myStrikeout = presentation.myStrikeout;
myTailGrayed = presentation.myTailGrayed;
myTailForeground = presentation.myTailForeground;
myItemTextBold = presentation.myItemTextBold;
myTypeGrayed = presentation.myTypeGrayed;
myItemTextUnderlined = presentation.myItemTextUnderlined;
@@ -173,4 +210,43 @@ public class LookupElementPresentation {
element.renderElement(presentation);
return presentation;
}
@Override
public String toString() {
return "LookupElementPresentation{" +
", itemText='" + myItemText + '\'' +
", tail=" + myTail +
", typeText='" + myTypeText + '\'' +
'}';
}
public static class TextFragment {
public final String text;
private final boolean grayed;
@Nullable private final Color fgColor;
public TextFragment(String text, boolean grayed, @Nullable Color fgColor) {
this.text = text;
this.grayed = grayed;
this.fgColor = fgColor;
}
@Override
public String toString() {
return "TextFragment{" +
"text='" + text + '\'' +
", grayed=" + grayed +
", fgColor=" + fgColor +
'}';
}
public boolean isGrayed() {
return grayed;
}
@Nullable
public Color getForegroundColor() {
return fgColor;
}
}
}
@@ -193,21 +193,17 @@ public class LookupCellRenderer implements ListCellRenderer {
}
private void setTailTextLabel(boolean isSelected, LookupElementPresentation presentation, Color foreground, int allowedWidth) {
final Color fg = getTailTextColor(isSelected, presentation, foreground);
int style = getStyle(false, presentation.isStrikeout(), false);
final String tailText = StringUtil.notNullize(presentation.getTailText());
for (LookupElementPresentation.TextFragment fragment : presentation.getTailFragments()) {
if (allowedWidth < 0) {
return;
}
int style = SimpleTextAttributes.STYLE_PLAIN;
if (presentation.isStrikeout()) {
style |= SimpleTextAttributes.STYLE_STRIKEOUT;
String trimmed = trimLabelText(fragment.text, allowedWidth, myNormalMetrics);
myTailComponent.append(trimmed, new SimpleTextAttributes(style, getTailTextColor(isSelected, fragment, foreground)));
allowedWidth -= RealLookupElementPresentation.getStringWidth(trimmed, myNormalMetrics);
}
SimpleTextAttributes attributes = new SimpleTextAttributes(style, fg);
if (allowedWidth < 0) {
return;
}
myTailComponent.append(trimLabelText(tailText, allowedWidth, myNormalMetrics), attributes);
}
private String trimLabelText(@Nullable String text, int maxWidth, FontMetrics metrics) {
@@ -240,13 +236,13 @@ public class LookupCellRenderer implements ListCellRenderer {
return text.substring(0, i) + ELLIPSIS;
}
public static Color getTailTextColor(boolean isSelected, LookupElementPresentation presentation, Color defaultForeground) {
if (presentation.isTailGrayed()) {
public static Color getTailTextColor(boolean isSelected, LookupElementPresentation.TextFragment fragment, Color defaultForeground) {
if (fragment.isGrayed()) {
return getGrayedForeground(isSelected);
}
if (!isSelected) {
final Color tailForeground = presentation.getTailForeground();
final Color tailForeground = fragment.getForegroundColor();
if (tailForeground != null) {
return tailForeground;
}
@@ -264,13 +260,7 @@ public class LookupCellRenderer implements ListCellRenderer {
myNameComponent.setFont(bold ? myBoldFont : myNormalFont);
int style = bold ? SimpleTextAttributes.STYLE_BOLD : SimpleTextAttributes.STYLE_PLAIN;
if (presentation.isStrikeout()) {
style |= SimpleTextAttributes.STYLE_STRIKEOUT;
}
if (presentation.isItemTextUnderlined()) {
style |= SimpleTextAttributes.STYLE_UNDERLINE;
}
int style = getStyle(bold, presentation.isStrikeout(), presentation.isItemTextUnderlined());
final FontMetrics metrics = bold ? myBoldMetrics : myNormalMetrics;
final String name = trimLabelText(presentation.getItemText(), allowedWidth, metrics);
@@ -280,6 +270,18 @@ public class LookupCellRenderer implements ListCellRenderer {
return used;
}
@SimpleTextAttributes.StyleAttributeConstant
private static int getStyle(boolean bold, boolean strikeout, boolean underlined) {
int style = bold ? SimpleTextAttributes.STYLE_BOLD : SimpleTextAttributes.STYLE_PLAIN;
if (strikeout) {
style |= SimpleTextAttributes.STYLE_STRIKEOUT;
}
if (underlined) {
style |= SimpleTextAttributes.STYLE_UNDERLINE;
}
return style;
}
private void renderItemName(LookupElement item,
Color foreground,
boolean selected,
@@ -321,7 +323,9 @@ public class LookupCellRenderer implements ListCellRenderer {
Color sampleBackground = background;
Object o = item.getObject();
//noinspection deprecation
if (o instanceof LookupValueWithUIHint && StringUtil.isEmpty(labelText)) {
//noinspection deprecation
Color proposedBackground = ((LookupValueWithUIHint)o).getColorHint();
if (proposedBackground != null) {
sampleBackground = proposedBackground;