IDEA-171869 Win10 LaF LinkLabels, HyperLinkLabels fixed

This commit is contained in:
Kirill Kirichenko
2017-07-12 18:34:13 +03:00
parent b909e10a05
commit 9040dc8e80
2 changed files with 73 additions and 32 deletions
@@ -21,11 +21,9 @@ import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ui.UIUtil;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.Nullable;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.*;
@@ -40,7 +38,6 @@ public class HighlightableComponent extends JComponent implements Accessible {
protected Icon myIcon;
protected int myIconTextGap;
protected ArrayList<HighlightedRegion> myHighlightedRegions;
protected TIntObjectHashMap<FontMetrics> myFontMetrics;
protected boolean myIsSelected;
protected boolean myHasFocus;
protected boolean myPaintUnfocusedSelection = false;
@@ -48,20 +45,13 @@ public class HighlightableComponent extends JComponent implements Accessible {
public HighlightableComponent() {
myIconTextGap = 4;
myFontMetrics = new TIntObjectHashMap<>();
setText("");
fillFontMetricsMap();
setOpaque(true);
updateUI();
}
protected void fillFontMetricsMap() {
Font font = getFont();
if (font != null){
myFontMetrics.put(Font.PLAIN, getFontMetrics(font.deriveFont(Font.PLAIN)));
myFontMetrics.put(Font.BOLD, getFontMetrics(font.deriveFont(Font.BOLD)));
myFontMetrics.put(Font.ITALIC, getFontMetrics(font.deriveFont(Font.ITALIC)));
myFontMetrics.put(Font.BOLD | Font.ITALIC, getFontMetrics(font.deriveFont(Font.BOLD | Font.ITALIC)));
}
@Override public void updateUI() {
UISettings.setupComponentAntialiasing(this);
}
public void setText(String text) {
@@ -88,13 +78,6 @@ public class HighlightableComponent extends JComponent implements Accessible {
myIcon = icon;
}
public void setFont(Font font) {
if (!font.equals(getFont())){
super.setFont(font);
fillFontMetricsMap();
}
}
public void addHighlighter(int startOffset, int endOffset, TextAttributes attributes) {
addHighlighter(0, startOffset, endOffset, attributes);
}
@@ -298,7 +281,8 @@ public class HighlightableComponent extends JComponent implements Accessible {
offset += defFontMetrics.stringWidth(text);
}
FontMetrics fontMetrics = myFontMetrics.get(hRegion.textAttributes.getFontType());
Font regFont = getFont().deriveFont(hRegion.textAttributes.getFontType());
FontMetrics fontMetrics = getFontMetrics(regFont);
text = myText.substring(hRegion.startOffset, hRegion.endOffset);
@@ -313,8 +297,7 @@ public class HighlightableComponent extends JComponent implements Accessible {
if (hRegion.textAttributes.getForegroundColor() != null && paintHighlightsForeground) {
g.setColor(hRegion.textAttributes.getForegroundColor());
}
else {
} else {
g.setColor(fgColor);
}
@@ -323,7 +306,7 @@ public class HighlightableComponent extends JComponent implements Accessible {
// draw highlight underscored line
if (hRegion.textAttributes.getEffectColor() != null) {
if (hRegion.textAttributes.getEffectType() != null && hRegion.textAttributes.getEffectColor() != null) {
g.setColor(hRegion.textAttributes.getEffectColor());
int y = yOffset/*fontMetrics.getMaxAscent()*/ + 2;
UIUtil.drawLine(g, offset, y, offset + fontMetrics.stringWidth(text) - 1, y);
@@ -385,7 +368,9 @@ public class HighlightableComponent extends JComponent implements Accessible {
if (width > x) return null;
String text = getRegionText(hRegion);
FontMetrics fontMetrics = myFontMetrics.get(hRegion.textAttributes.getFontType());
Font regFont = getFont().deriveFont(hRegion.textAttributes.getFontType());
FontMetrics fontMetrics = getFontMetrics(regFont);
width += fontMetrics.stringWidth(text);
if (width > x) return hRegion;
}
@@ -409,7 +394,9 @@ public class HighlightableComponent extends JComponent implements Accessible {
endIndex = hRegion.endOffset;
String text = getRegionText(hRegion);
FontMetrics fontMetrics = myFontMetrics.get(hRegion.textAttributes.getFontType());
Font regFont = getFont().deriveFont(hRegion.textAttributes.getFontType());
FontMetrics fontMetrics = getFontMetrics(regFont);
width += fontMetrics.stringWidth(text);
}
width += defFontMetrics.stringWidth(myText.substring(endIndex, myText.length()));
@@ -59,6 +59,9 @@ public class HyperlinkLabel extends HighlightableComponent {
private final TextAttributes myAnchorAttributes;
private HyperlinkListener myHyperlinkListener = null;
private boolean myMouseHover;
private boolean myMousePressed;
public HyperlinkLabel() {
this("");
}
@@ -72,8 +75,10 @@ public class HyperlinkLabel extends HighlightableComponent {
}
public HyperlinkLabel(String text, final Color textForegroundColor, final Color textBackgroundColor, final Color textEffectColor) {
myAnchorAttributes =
myAnchorAttributes = UIUtil.isUnderWin10LookAndFeel() ?
new Win10TextAttributes(textBackgroundColor) :
new TextAttributes(textForegroundColor, textBackgroundColor, textEffectColor, EffectType.LINE_UNDERSCORE, Font.PLAIN);
enforceBackgroundOutsideText(textBackgroundColor);
setHyperlinkText(text);
enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
@@ -114,11 +119,21 @@ public class HyperlinkLabel extends HighlightableComponent {
}
protected void processMouseEvent(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_EXITED) {
if (e.getID() == MouseEvent.MOUSE_ENTERED && isOnLink(e.getX())) {
myMouseHover = true;
repaint();
} else if (e.getID() == MouseEvent.MOUSE_EXITED) {
setCursor(Cursor.getDefaultCursor());
}
else if (UIUtil.isActionClick(e, MouseEvent.MOUSE_PRESSED) && isOnLink(e.getX())) {
myMouseHover = false;
myMousePressed = false;
repaint();
} else if (UIUtil.isActionClick(e, MouseEvent.MOUSE_PRESSED) && isOnLink(e.getX())) {
fireHyperlinkEvent();
myMousePressed = true;
repaint();
} else if (e.getID() == MouseEvent.MOUSE_RELEASED) {
myMousePressed = false;
repaint();
}
super.processMouseEvent(e);
}
@@ -126,7 +141,14 @@ public class HyperlinkLabel extends HighlightableComponent {
@Override
protected void processMouseMotionEvent(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_MOVED) {
setCursor(isOnLink(e.getX()) ? Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) : Cursor.getDefaultCursor());
boolean onLink = isOnLink(e.getX());
boolean needRepaint = myMouseHover != onLink;
myMouseHover = onLink;
setCursor(myMouseHover ? Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) : Cursor.getDefaultCursor());
if (needRepaint) {
repaint();
}
}
super.processMouseMotionEvent(e);
}
@@ -240,6 +262,7 @@ public class HyperlinkLabel extends HighlightableComponent {
@Override
public void updateUI() {
super.updateUI();
setFont(UIUtil.getLabelFont());
}
@@ -253,7 +276,7 @@ public class HyperlinkLabel extends HighlightableComponent {
/**
* Hyperlink accessibility: "HYPERLINK" role and expose a "click" action.
* @see javax.swing.AbstractButton.AccessibleAbstractButton
* @see AbstractButton.AccessibleAbstractButton
*/
protected class AccessibleHyperlinkLabel extends AccessibleHighlightable implements AccessibleAction {
@Override
@@ -291,4 +314,35 @@ public class HyperlinkLabel extends HighlightableComponent {
}
}
}
private class Win10TextAttributes extends TextAttributes {
private Win10TextAttributes(Color textBackgroundColor) {
super(null, textBackgroundColor, null, null, Font.PLAIN);
}
@Override public Color getForegroundColor() {
return !isEnabled() ? UIManager.getColor("Label.disabledForeground") :
myMousePressed ? UIManager.getColor("link.pressed.foreground") :
myMouseHover ? UIManager.getColor("link.hover.foreground") :
UIManager.getColor("link.foreground");
}
@Override public Color getEffectColor() {
return getForegroundColor();
}
@Override public EffectType getEffectType() {
return !isEnabled() || myMouseHover || myMousePressed ? EffectType.LINE_UNDERSCORE : null;
}
@Override public void setForegroundColor(Color color) {
throw new UnsupportedOperationException();
}
@Override public void setEffectColor(Color color) {
throw new UnsupportedOperationException();
}
@Override public void setEffectType(EffectType effectType) {
throw new UnsupportedOperationException();
}
}
}