[duplicates] enable duplicates analysis in PyCharm/WebStorm/PhpStorm/RubyMine
[idea/community.git] / platform / core-api / src / com / intellij / ui / SimpleTextAttributes.java
1 // Copyright 2000-2018 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.
2 package com.intellij.ui;
3
4 import com.intellij.openapi.editor.markup.EffectType;
5 import com.intellij.openapi.editor.markup.TextAttributes;
6 import com.intellij.openapi.util.Comparing;
7 import com.intellij.util.BitUtil;
8 import com.intellij.util.ui.JBUI;
9 import com.intellij.util.ui.UIUtil;
10 import org.intellij.lang.annotations.JdkConstants;
11 import org.intellij.lang.annotations.MagicConstant;
12 import org.jetbrains.annotations.NotNull;
13 import org.jetbrains.annotations.Nullable;
14
15 import java.awt.*;
16
17 /**
18  * @author Vladimir Kondratyev
19  */
20 public final class SimpleTextAttributes {
21
22   @MagicConstant(flags = {
23     STYLE_PLAIN, STYLE_BOLD, STYLE_ITALIC, STYLE_STRIKEOUT, STYLE_WAVED, STYLE_UNDERLINE,
24     STYLE_BOLD_DOTTED_LINE, STYLE_SEARCH_MATCH, STYLE_SMALLER, STYLE_OPAQUE,
25     STYLE_CLICKABLE, STYLE_HOVERED})
26   public @interface StyleAttributeConstant { }
27
28   public static final int STYLE_PLAIN = Font.PLAIN;
29   public static final int STYLE_BOLD = Font.BOLD;
30   public static final int STYLE_ITALIC = Font.ITALIC;
31   public static final int FONT_MASK = STYLE_PLAIN | STYLE_BOLD | STYLE_ITALIC;
32   public static final int STYLE_STRIKEOUT = STYLE_ITALIC << 1;
33   public static final int STYLE_WAVED = STYLE_STRIKEOUT << 1;
34   public static final int STYLE_UNDERLINE = STYLE_WAVED << 1;
35   public static final int STYLE_BOLD_DOTTED_LINE = STYLE_UNDERLINE << 1;
36   public static final int STYLE_SEARCH_MATCH = STYLE_BOLD_DOTTED_LINE << 1;
37   public static final int STYLE_SMALLER = STYLE_SEARCH_MATCH << 1;
38   public static final int STYLE_OPAQUE = STYLE_SMALLER << 1;
39   public static final int STYLE_CLICKABLE = STYLE_OPAQUE << 1;
40   public static final int STYLE_HOVERED = STYLE_CLICKABLE << 1;
41
42   public static final SimpleTextAttributes REGULAR_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, null);
43   public static final SimpleTextAttributes REGULAR_BOLD_ATTRIBUTES = new SimpleTextAttributes(STYLE_BOLD, null);
44   public static final SimpleTextAttributes REGULAR_ITALIC_ATTRIBUTES = new SimpleTextAttributes(STYLE_ITALIC, null);
45   public static final SimpleTextAttributes ERROR_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, JBColor.red);
46
47   public static final SimpleTextAttributes GRAYED_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, UIUtil.getInactiveTextColor());
48   public static final SimpleTextAttributes GRAYED_BOLD_ATTRIBUTES = new SimpleTextAttributes(STYLE_BOLD, UIUtil.getInactiveTextColor());
49   public static final SimpleTextAttributes GRAYED_ITALIC_ATTRIBUTES = new SimpleTextAttributes(STYLE_ITALIC, UIUtil.getInactiveTextColor());
50   public static final SimpleTextAttributes GRAYED_SMALL_ATTRIBUTES = new SimpleTextAttributes(STYLE_SMALLER, UIUtil.getInactiveTextColor());
51
52   public static final SimpleTextAttributes SYNTHETIC_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, JBColor.blue);
53
54   public static final SimpleTextAttributes GRAY_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, Color.GRAY);
55   public static final SimpleTextAttributes GRAY_ITALIC_ATTRIBUTES = new SimpleTextAttributes(STYLE_ITALIC, Color.GRAY);
56   public static final SimpleTextAttributes GRAY_SMALL_ATTRIBUTES = new SimpleTextAttributes(STYLE_SMALLER, Color.GRAY);
57
58   public static final SimpleTextAttributes DARK_TEXT = new SimpleTextAttributes(STYLE_PLAIN, new Color(112, 112, 164));
59   public static final SimpleTextAttributes SIMPLE_CELL_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, new JBColor(Gray._0, Gray._187));
60   public static final SimpleTextAttributes SELECTED_SIMPLE_CELL_ATTRIBUTES =
61     new SimpleTextAttributes(STYLE_PLAIN, UIUtil.getListSelectionForeground());
62   public static final SimpleTextAttributes EXCLUDED_ATTRIBUTES = new SimpleTextAttributes(STYLE_ITALIC, Color.GRAY);
63
64   public static final SimpleTextAttributes LINK_PLAIN_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, JBUI.CurrentTheme.Link.linkColor());
65   public static final SimpleTextAttributes LINK_ATTRIBUTES = new SimpleTextAttributes(STYLE_UNDERLINE, JBUI.CurrentTheme.Link.linkColor());
66   public static final SimpleTextAttributes LINK_BOLD_ATTRIBUTES = new SimpleTextAttributes(STYLE_UNDERLINE | STYLE_BOLD, JBUI.CurrentTheme.Link.linkColor());
67
68   private final Color myBgColor;
69   private final Color myFgColor;
70   private final Color myWaveColor;
71   @StyleAttributeConstant
72   private final int myStyle;
73
74   /**
75    * @param style   style of the text fragment.
76    * @param fgColor color of the text fragment. {@code color} can be
77    *                {@code null}. In that case {@code SimpleColoredComponent} will
78    *                use its foreground to paint the text fragment.
79    */
80   public SimpleTextAttributes(@StyleAttributeConstant int style, Color fgColor) {
81     this(style, fgColor, null);
82   }
83
84   public SimpleTextAttributes(@StyleAttributeConstant int style, Color fgColor, @Nullable Color waveColor) {
85     this(null, fgColor, waveColor, style);
86   }
87
88   public SimpleTextAttributes(@Nullable Color bgColor, Color fgColor, @Nullable Color waveColor, @StyleAttributeConstant int style) {
89     if ((~(STYLE_PLAIN |
90            STYLE_BOLD |
91            STYLE_ITALIC |
92            STYLE_STRIKEOUT |
93            STYLE_WAVED |
94            STYLE_UNDERLINE |
95            STYLE_BOLD_DOTTED_LINE |
96            STYLE_SEARCH_MATCH |
97            STYLE_SMALLER |
98            STYLE_OPAQUE |
99            STYLE_CLICKABLE |
100            STYLE_HOVERED) & style) != 0) {
101       throw new IllegalArgumentException("Wrong style: " + style);
102     }
103
104     myBgColor = bgColor;
105     myFgColor = fgColor;
106     myWaveColor = waveColor;
107     myStyle = style;
108   }
109
110   /**
111    * @return foreground color
112    */
113   public Color getFgColor() {
114     return myFgColor;
115   }
116
117
118   /**
119    * @return background color
120    */
121   @Nullable
122   public Color getBgColor() {
123     return myBgColor;
124   }
125
126   /**
127    * @return wave color. The method can return {@code null}. {@code null}
128    *         means that color of wave is the same as foreground color.
129    */
130   @Nullable
131   public Color getWaveColor() {
132     return myWaveColor;
133   }
134
135   @StyleAttributeConstant
136   public int getStyle() {
137     return myStyle;
138   }
139
140   /**
141    * @return whether text is struck out or not
142    */
143   public boolean isStrikeout() {
144     return BitUtil.isSet(myStyle, STYLE_STRIKEOUT);
145   }
146
147   /**
148    * @return whether text is waved or not
149    */
150   public boolean isWaved() {
151     return BitUtil.isSet(myStyle, STYLE_WAVED);
152   }
153
154   public boolean isUnderline() {
155     return BitUtil.isSet(myStyle, STYLE_UNDERLINE);
156   }
157
158   public boolean isBoldDottedLine() {
159     return BitUtil.isSet(myStyle, STYLE_BOLD_DOTTED_LINE);
160   }
161
162   public boolean isSearchMatch() {
163     return BitUtil.isSet(myStyle, STYLE_SEARCH_MATCH);
164   }
165   
166   public boolean isSmaller() {
167     return BitUtil.isSet(myStyle, STYLE_SMALLER);
168   }
169
170   public boolean isOpaque() {
171     return BitUtil.isSet(myStyle, STYLE_OPAQUE);
172   }
173
174   public boolean isClickable() {
175     return BitUtil.isSet(myStyle, STYLE_CLICKABLE);
176   }
177
178   public boolean isHovered() {
179     return BitUtil.isSet(myStyle, STYLE_HOVERED);
180   }
181
182   @NotNull
183   public static SimpleTextAttributes fromTextAttributes(TextAttributes attributes) {
184     if (attributes == null) return REGULAR_ATTRIBUTES;
185
186     Color fgColor = attributes.getForegroundColor();
187     if (fgColor == null) fgColor = REGULAR_ATTRIBUTES.getFgColor();
188     Color bgColor = attributes.getBackgroundColor();
189
190     int style = attributes.getFontType();
191     if (attributes.getEffectColor() != null) {
192       EffectType effectType = attributes.getEffectType();
193       if (effectType == EffectType.STRIKEOUT) {
194         style |= STYLE_STRIKEOUT;
195       }
196       else if (effectType == EffectType.WAVE_UNDERSCORE) {
197         style |= STYLE_WAVED;
198       }
199       else if (effectType == EffectType.LINE_UNDERSCORE ||
200                effectType == EffectType.BOLD_LINE_UNDERSCORE ||
201                effectType == EffectType.BOLD_DOTTED_LINE) {
202         style |= STYLE_UNDERLINE;
203       }
204       else if (effectType == EffectType.SEARCH_MATCH) {
205         style |= STYLE_SEARCH_MATCH;
206       }
207       else {
208         // not supported
209       }
210     }
211     //noinspection MagicConstant
212     return new SimpleTextAttributes(bgColor, fgColor, attributes.getEffectColor(), style);
213   }
214
215   @JdkConstants.FontStyle
216   public int getFontStyle() {
217     return myStyle & FONT_MASK;
218   }
219
220   public TextAttributes toTextAttributes() {
221     Color effectColor;
222     EffectType effectType;
223     if (isWaved()) {
224       effectColor = myWaveColor;
225       effectType = EffectType.WAVE_UNDERSCORE;
226     }
227     else if (isStrikeout()) {
228       effectColor = myWaveColor;
229       effectType = EffectType.STRIKEOUT;
230     }
231     else if (isUnderline()) {
232       effectColor = myWaveColor;
233       effectType = EffectType.LINE_UNDERSCORE;
234     }
235     else if (isBoldDottedLine()) {
236       effectColor = myWaveColor;
237       effectType = EffectType.BOLD_DOTTED_LINE;
238     }
239     else if (isSearchMatch()) {
240       effectColor = myWaveColor;
241       effectType = EffectType.SEARCH_MATCH;
242     }
243     else {
244       effectColor = null;
245       effectType = null;
246     }
247     return new TextAttributes(myFgColor, null, effectColor, effectType, myStyle & FONT_MASK);
248   }
249
250   public SimpleTextAttributes derive(@StyleAttributeConstant int style, @Nullable Color fg, @Nullable Color bg, @Nullable Color wave) {
251     return new SimpleTextAttributes(bg != null ? bg : getBgColor(), fg != null ? fg : getFgColor(), wave != null ? wave : getWaveColor(),
252                                     style == -1 ? getStyle() : style);
253   }
254
255   // take what differs from REGULAR
256   public static SimpleTextAttributes merge(final SimpleTextAttributes weak, final SimpleTextAttributes strong) {
257     final int style = strong.getStyle() | weak.getStyle();
258
259     final Color wave;
260     if (!Comparing.equal(strong.getWaveColor(), REGULAR_ATTRIBUTES.getWaveColor())) {
261       wave = strong.getWaveColor();
262     }
263     else {
264       wave = weak.getWaveColor();
265     }
266     final Color fg;
267     if (!Comparing.equal(strong.getFgColor(), REGULAR_ATTRIBUTES.getFgColor())) {
268       fg = strong.getFgColor();
269     }
270     else {
271       fg = weak.getFgColor();
272     }
273     final Color bg;
274     if (!Comparing.equal(strong.getBgColor(), REGULAR_ATTRIBUTES.getBgColor())) {
275       bg = strong.getBgColor();
276     }
277     else {
278       bg = weak.getBgColor();
279     }
280
281     return new SimpleTextAttributes(bg, fg, wave, style);
282   }
283 }