IDEA-201950 Use error underline style in UI

GitOrigin-RevId: 80cb9d9f36160646af0adafc18102e7f6b7025e6
This commit is contained in:
Kirill Kirichenko
2020-12-17 16:35:20 +00:00
committed by intellij-monorepo-bot
parent b0b3a81022
commit 2d2f729f4d
11 changed files with 132 additions and 39 deletions
@@ -22,7 +22,7 @@ public final class SimpleTextAttributes {
@MagicConstant(flags = {
STYLE_PLAIN, STYLE_BOLD, STYLE_ITALIC, STYLE_STRIKEOUT, STYLE_WAVED, STYLE_UNDERLINE,
STYLE_BOLD_DOTTED_LINE, STYLE_SEARCH_MATCH, STYLE_SMALLER, STYLE_OPAQUE,
STYLE_CLICKABLE, STYLE_HOVERED, STYLE_NO_BORDER})
STYLE_CLICKABLE, STYLE_HOVERED, STYLE_NO_BORDER, STYLE_BOLD_UNDERLINE, STYLE_USE_EFFECT_COLOR})
public @interface StyleAttributeConstant { }
public static final int STYLE_PLAIN = Font.PLAIN;
@@ -39,6 +39,8 @@ public final class SimpleTextAttributes {
public static final int STYLE_CLICKABLE = STYLE_OPAQUE << 1;
public static final int STYLE_HOVERED = STYLE_CLICKABLE << 1;
public static final int STYLE_NO_BORDER = STYLE_HOVERED << 1;
public static final int STYLE_BOLD_UNDERLINE = STYLE_NO_BORDER << 1;
public static final int STYLE_USE_EFFECT_COLOR = STYLE_BOLD_UNDERLINE << 1;
public static final SimpleTextAttributes REGULAR_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, null);
public static final SimpleTextAttributes REGULAR_BOLD_ATTRIBUTES = new SimpleTextAttributes(STYLE_BOLD, null);
@@ -99,7 +101,9 @@ public final class SimpleTextAttributes {
STYLE_OPAQUE |
STYLE_CLICKABLE |
STYLE_HOVERED |
STYLE_NO_BORDER) & style) != 0) {
STYLE_NO_BORDER |
STYLE_BOLD_UNDERLINE |
STYLE_USE_EFFECT_COLOR) & style) != 0) {
throw new IllegalArgumentException("Wrong style: " + style);
}
@@ -185,6 +189,14 @@ public final class SimpleTextAttributes {
return BitUtil.isSet(myStyle, STYLE_NO_BORDER);
}
public boolean isBoldUnderline() {
return BitUtil.isSet(myStyle, STYLE_BOLD_UNDERLINE);
}
public boolean useEffectColor() {
return BitUtil.isSet(myStyle, STYLE_USE_EFFECT_COLOR);
}
@NotNull
public static SimpleTextAttributes fromTextAttributes(TextAttributes attributes) {
if (attributes == null) return REGULAR_ATTRIBUTES;
@@ -202,11 +214,15 @@ public final class SimpleTextAttributes {
else if (effectType == EffectType.WAVE_UNDERSCORE) {
style |= STYLE_WAVED;
}
else if (effectType == EffectType.LINE_UNDERSCORE ||
effectType == EffectType.BOLD_LINE_UNDERSCORE ||
effectType == EffectType.BOLD_DOTTED_LINE) {
else if (effectType == EffectType.LINE_UNDERSCORE) {
style |= STYLE_UNDERLINE;
}
else if (effectType == EffectType.BOLD_DOTTED_LINE) {
style |= STYLE_BOLD_DOTTED_LINE;
}
else if (effectType == EffectType.BOLD_LINE_UNDERSCORE) {
style |= STYLE_BOLD_UNDERLINE;
}
else if (effectType == EffectType.SEARCH_MATCH) {
style |= STYLE_SEARCH_MATCH;
}
@@ -242,6 +258,10 @@ public final class SimpleTextAttributes {
effectColor = myWaveColor;
effectType = EffectType.BOLD_DOTTED_LINE;
}
else if (isBoldUnderline()) {
effectColor = myWaveColor;
effectType = EffectType.BOLD_LINE_UNDERSCORE;
}
else if (isSearchMatch()) {
effectColor = myWaveColor;
effectType = EffectType.SEARCH_MATCH;
@@ -1,10 +1,16 @@
// Copyright 2000-2019 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.actions;
import com.intellij.ide.ui.LafManagerListener;
import com.intellij.ide.util.PlatformModuleRendererFactory;
import com.intellij.ide.util.PsiElementListCellRenderer;
import com.intellij.ide.util.gotoByName.GotoFileCellRenderer;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.SystemInfo;
@@ -20,7 +26,10 @@ import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ObjectUtils;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -33,8 +42,9 @@ import java.util.Optional;
* @author Konstantin Bulenkov
*/
public class SearchEverywherePsiRenderer extends PsiElementListCellRenderer<PsiElement> {
private EditorColorsScheme scheme = EditorColorsManager.getInstance().getSchemeForCurrentUITheme();
public SearchEverywherePsiRenderer() {
public SearchEverywherePsiRenderer(Disposable parent) {
setFocusBorderEnabled(false);
setLayout(new BorderLayout() {
@Override
@@ -51,6 +61,17 @@ public class SearchEverywherePsiRenderer extends PsiElementListCellRenderer<PsiE
}
}
});
ApplicationManager.getApplication().getMessageBus().connect(parent).subscribe(LafManagerListener.TOPIC, __ -> {
scheme = EditorColorsManager.getInstance().getSchemeForCurrentUITheme();
});
}
@Override
protected @NotNull SimpleTextAttributes getErrorAttributes() {
SimpleTextAttributes schemeAttributes = SimpleTextAttributes.fromTextAttributes(scheme.getAttributes(CodeInsightColors.ERRORS_ATTRIBUTES));
return new SimpleTextAttributes(schemeAttributes.getBgColor(), UIUtil.getInactiveTextColor(), schemeAttributes.getWaveColor(),
schemeAttributes.getStyle() | SimpleTextAttributes.STYLE_USE_EFFECT_COLOR);
}
@Override
@@ -454,7 +454,7 @@ public abstract class AbstractGotoSEContributor implements WeightedSearchEverywh
@NotNull
@Override
public ListCellRenderer<Object> getElementsRenderer() {
return new SearchEverywherePsiRenderer();
return new SearchEverywherePsiRenderer(this);
}
@Override
@@ -7,7 +7,9 @@ import com.intellij.ide.util.gotoByName.FileTypeRef;
import com.intellij.ide.util.gotoByName.FilteringGotoByModel;
import com.intellij.ide.util.gotoByName.GotoFileConfiguration;
import com.intellij.ide.util.gotoByName.GotoFileModel;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsContexts;
@@ -24,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
import static com.intellij.ide.actions.searcheverywhere.SearchEverywhereFiltersStatisticsCollector.*;
import static com.intellij.ide.actions.searcheverywhere.SearchEverywhereFiltersStatisticsCollector.FileTypeFilterCollector;
/**
* @author Konstantin Bulenkov
@@ -86,7 +88,7 @@ public class FileSearchEverywhereContributor extends AbstractGotoSEContributor {
@NotNull
@Override
public ListCellRenderer<Object> getElementsRenderer() {
return new SearchEverywherePsiRenderer() {
return new SearchEverywherePsiRenderer(this) {
@NotNull
@Override
protected ItemMatchers getItemMatchers(@NotNull JList list, @NotNull Object value) {
@@ -4,7 +4,12 @@ package com.intellij.ide.navigationToolbar;
import com.intellij.icons.AllIcons;
import com.intellij.ide.projectView.impl.ProjectRootsUtil;
import com.intellij.ide.structureView.StructureViewBundle;
import com.intellij.ide.ui.LafManagerListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
@@ -25,7 +30,6 @@ import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiDirectoryContainer;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.IconUtil;
import org.jetbrains.annotations.Nls;
@@ -38,12 +42,24 @@ import javax.swing.*;
* @author Konstantin Bulenkov
*/
public class NavBarPresentation {
private static final SimpleTextAttributes WOLFED = new SimpleTextAttributes(null, null, JBColor.red, SimpleTextAttributes.STYLE_WAVED);
private final Project myProject;
private EditorColorsScheme scheme;
public NavBarPresentation(Project project) {
myProject = project;
updateScheme();
ApplicationManager.getApplication().getMessageBus().connect(myProject).subscribe(LafManagerListener.TOPIC, laf -> updateScheme());
}
private void updateScheme() {
scheme = EditorColorsManager.getInstance().getSchemeForCurrentUITheme();
}
private SimpleTextAttributes getErrorAttributes() {
SimpleTextAttributes schemeAttributes = SimpleTextAttributes.fromTextAttributes(scheme.getAttributes(CodeInsightColors.ERRORS_ATTRIBUTES));
return SimpleTextAttributes.merge(new SimpleTextAttributes(SimpleTextAttributes.STYLE_USE_EFFECT_COLOR, schemeAttributes.getFgColor()),
schemeAttributes);
}
@Nullable
@@ -113,11 +129,11 @@ public class NavBarPresentation {
}
PsiFile psiFile = ((PsiElement)object).getContainingFile();
if (psiFile != null) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
VirtualFile virtualFile = psiFile.getVirtualFile();
return new SimpleTextAttributes(null, selected ? null : FileStatusManager.getInstance(myProject).getStatus(virtualFile).getColor(),
JBColor.red, virtualFile != null && WolfTheProblemSolver.getInstance(myProject).isProblemFile(virtualFile)
? SimpleTextAttributes.STYLE_WAVED
: SimpleTextAttributes.STYLE_PLAIN);
getErrorAttributes().getWaveColor(),
virtualFile != null && WolfTheProblemSolver.getInstance(myProject).isProblemFile(virtualFile)
? getErrorAttributes().getStyle() : SimpleTextAttributes.STYLE_PLAIN);
}
else {
if (object instanceof PsiDirectory) {
@@ -128,13 +144,13 @@ public class NavBarPresentation {
}
if (wolfHasProblemFilesBeneath((PsiElement)object)) {
return WOLFED;
return getErrorAttributes();
}
}
}
else if (object instanceof Module) {
if (WolfTheProblemSolver.getInstance(myProject).hasProblemFilesBeneath((Module)object)) {
return WOLFED;
return getErrorAttributes();
}
}
@@ -143,7 +159,7 @@ public class NavBarPresentation {
final Module[] modules = ReadAction.compute(() -> ModuleManager.getInstance(project).getModules());
for (Module module : modules) {
if (WolfTheProblemSolver.getInstance(project).hasProblemFilesBeneath(module)) {
return WOLFED;
return getErrorAttributes();
}
}
}
@@ -54,6 +54,8 @@ public abstract class PsiElementListCellRenderer<T extends PsiElement> extends J
private static final Logger LOG = Logger.getInstance(PsiElementListCellRenderer.class);
private static final String LEFT = BorderLayout.WEST;
private static final Pattern CONTAINER_PATTERN = Pattern.compile("(\\(in |\\()?([^)]*)(\\))?");
private static final SimpleTextAttributes DEFAULT_ERROR_ATTRIBUTES =
new SimpleTextAttributes(SimpleTextAttributes.STYLE_WAVED, UIUtil.getInactiveTextColor(), JBColor.RED);
private boolean myFocusBorderEnabled = Registry.is("psi.element.list.cell.renderer.focus.border.enabled");
protected int myRightComponentWidth;
@@ -167,7 +169,7 @@ public abstract class PsiElementListCellRenderer<T extends PsiElement> extends J
private void appendLocationText(boolean selected, Color bgColor, boolean isProblemFile, @Nls String containerText) {
SimpleTextAttributes locationAttrs = SimpleTextAttributes.GRAYED_ATTRIBUTES;
if (isProblemFile) {
SimpleTextAttributes wavedAttributes = SimpleTextAttributes.merge(new SimpleTextAttributes(SimpleTextAttributes.STYLE_WAVED, UIUtil.getInactiveTextColor(), JBColor.RED), locationAttrs);
SimpleTextAttributes wavedAttributes = SimpleTextAttributes.merge(getErrorAttributes(), locationAttrs);
java.util.regex.Matcher matcher = CONTAINER_PATTERN.matcher(containerText);
if (matcher.matches()) {
String prefix = matcher.group(1);
@@ -235,6 +237,11 @@ public abstract class PsiElementListCellRenderer<T extends PsiElement> extends J
return this;
}
@NotNull
protected SimpleTextAttributes getErrorAttributes() {
return DEFAULT_ERROR_ATTRIBUTES;
}
@NotNull
protected ItemMatchers getItemMatchers(@NotNull JList list, @NotNull Object value) {
return new ItemMatchers(MatcherHolder.getAssociatedMatcher(list), null);
@@ -991,6 +991,9 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
}
if (attributes.isUnderline()) {
if (attributes.useEffectColor() && attributes.getWaveColor() != null) {
g.setColor(attributes.getWaveColor());
}
EffectPainter.LINE_UNDERSCORE.paint(g, offset, textBaseline, fragmentWidth, metrics.getDescent(), font);
}
@@ -999,6 +1002,13 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
final Color lineColor = attributes.getWaveColor();
UIUtil.drawBoldDottedLine(g, offset, offset + fragmentWidth, dottedAt, attributes.getBgColor(), lineColor, isOpaque());
}
if (attributes.isBoldUnderline()) {
if (attributes.useEffectColor() && attributes.getWaveColor() != null) {
g.setColor(attributes.getWaveColor());
}
EffectPainter.BOLD_LINE_UNDERSCORE.paint(g, offset, textBaseline, fragmentWidth, metrics.getDescent(), font);
}
}
private static int getCharHeight(Graphics g) {
@@ -73,8 +73,7 @@ public final class TabInfo implements Queryable, PlaceProvider {
private int myDefaultStyle = -1;
private Color myDefaultForeground;
private Color myDefaultWaveColor;
private TextAttributes editorAttributes;
private SimpleTextAttributes myDefaultAttributes;
private static final AlertIcon DEFAULT_ALERT_ICON = new AlertIcon(AllIcons.Nodes.TabAlert);
@@ -104,23 +103,29 @@ public final class TabInfo implements Queryable, PlaceProvider {
public TabInfo setText(@NlsContexts.TabTitle @NotNull String text) {
List<SimpleTextAttributes> attributes = myText.getAttributes();
TextAttributes textAttributes = attributes.size() == 1 ? attributes.get(0).toTextAttributes() : null;
TextAttributes defaultAttributes = getDefaultAttributes().toTextAttributes();
if (!myText.toString().equals(text) || !Comparing.equal(textAttributes, defaultAttributes)) {
SimpleTextAttributes defaultAttributes = getDefaultAttributes();
if (!myText.toString().equals(text) || !Comparing.equal(textAttributes, defaultAttributes.toTextAttributes())) {
clearText(false);
append(text, getDefaultAttributes());
append(text, defaultAttributes);
}
return this;
}
@NotNull
private SimpleTextAttributes getDefaultAttributes() {
SimpleTextAttributes attributes = myDefaultAttributes;
if (attributes == null) {
int style = myDefaultStyle != -1 ? myDefaultStyle : SimpleTextAttributes.STYLE_PLAIN;
style = myDefaultWaveColor == null ? style : style | SimpleTextAttributes.STYLE_WAVED;
myDefaultAttributes = attributes = new SimpleTextAttributes(style, myDefaultForeground, myDefaultWaveColor);
if (myDefaultAttributes == null) {
if (editorAttributes != null) {
SimpleTextAttributes attr = SimpleTextAttributes.fromTextAttributes(editorAttributes);
attr = SimpleTextAttributes.merge(new SimpleTextAttributes(SimpleTextAttributes.STYLE_USE_EFFECT_COLOR, attr.getFgColor()), attr);
myDefaultAttributes = (myDefaultStyle != -1) ?
new SimpleTextAttributes(attr.getBgColor(), attr.getFgColor(), attr.getWaveColor(), myDefaultStyle) : attr;
}
else {
int style = myDefaultStyle != -1 ? myDefaultStyle : SimpleTextAttributes.STYLE_PLAIN;
myDefaultAttributes = new SimpleTextAttributes(style, myDefaultForeground);
}
}
return attributes;
return myDefaultAttributes;
}
@NotNull
@@ -352,8 +357,8 @@ public final class TabInfo implements Queryable, PlaceProvider {
}
@NotNull
public TabInfo setDefaultWaveColor(final Color waveColor) {
myDefaultWaveColor = waveColor;
public TabInfo setDefaultAttributes(@Nullable TextAttributes attributes) {
editorAttributes = attributes;
myDefaultAttributes = null;
update();
return this;
@@ -12,6 +12,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
@@ -185,9 +186,9 @@ public final class EditorTabbedContainer implements CloseAction.CloseTarget {
myTabs.getTabAt(index).setDefaultStyle(style);
}
void setWaveColor(int index, @Nullable Color color) {
void setTextAttributes(int index, @Nullable TextAttributes attributes) {
TabInfo tab = myTabs.getTabAt(index);
tab.setDefaultWaveColor(color);
tab.setDefaultAttributes(attributes);
}
void setIconAt(int index, Icon icon) {
@@ -16,6 +16,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.ScrollingModel;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.fileEditor.TextEditor;
@@ -324,8 +325,8 @@ public final class EditorWindow {
myTabbedPane.setStyleAt(index, style);
}
void setWaveColor(int index, @Nullable Color color) {
myTabbedPane.setWaveColor(index, color);
void setTextAttributes(int index, @Nullable TextAttributes attributes) {
myTabbedPane.setTextAttributes(index, attributes);
}
private void setTitleAt(int index, @NlsContexts.TabTitle @NotNull String text) {
@@ -5,6 +5,7 @@ import com.intellij.diagnostic.Activity;
import com.intellij.diagnostic.ActivityCategory;
import com.intellij.diagnostic.StartUpMeasurer;
import com.intellij.diagnostic.StartUpMeasurer.Activities;
import com.intellij.ide.ui.LafManagerListener;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.Disposable;
@@ -13,6 +14,9 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
@@ -89,6 +93,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
private final Alarm myIconUpdaterAlarm;
final Disposable parentDisposable;
private final UIBuilder myUIBuilder = new UIBuilder();
private EditorColorsScheme colorScheme;
EditorsSplitters(@NotNull FileEditorManagerImpl manager, boolean createOwnDockableContainer, @NotNull Disposable parentDisposable) {
super(new BorderLayout());
@@ -128,6 +133,11 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
repaint();
}
});
colorScheme = EditorColorsManager.getInstance().getSchemeForCurrentUITheme();
ApplicationManager.getApplication().getMessageBus().connect(myManager).subscribe(LafManagerListener.TOPIC, laf -> {
colorScheme = EditorColorsManager.getInstance().getSchemeForCurrentUITheme();
});
}
@NotNull
@@ -411,7 +421,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
int index = window.findEditorIndex(window.findFileComposite(file));
LOG.assertTrue(index != -1);
window.setForegroundAt(index, getManager().getFileColor(file));
window.setWaveColor(index, getManager().isProblem(file) ? JBColor.red : null);
window.setTextAttributes(index, getManager().isProblem(file) ? colorScheme.getAttributes(CodeInsightColors.ERRORS_ATTRIBUTES) : null);
}
}