From a9aabaf37b92697e60ebabd01f2810d76784742e Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 16 Jul 2010 16:32:10 +0400 Subject: [PATCH] allowed to add text before and after link in HyperlinkLabel --- .../intellij/ui/HighlightableComponent.java | 58 ++++++++++++++----- .../src/com/intellij/ui/HyperlinkLabel.java | 36 ++++++++---- 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/HighlightableComponent.java b/platform/platform-api/src/com/intellij/ui/HighlightableComponent.java index 704be5062416..8fd4b8b47bc3 100644 --- a/platform/platform-api/src/com/intellij/ui/HighlightableComponent.java +++ b/platform/platform-api/src/com/intellij/ui/HighlightableComponent.java @@ -20,6 +20,7 @@ import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.util.ui.UIUtil; import gnu.trove.TIntObjectHashMap; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -347,6 +348,29 @@ public class HighlightableComponent extends JComponent { return myIcon.getIconWidth() + myIconTextGap; } + @Nullable + public HighlightedRegion findRegionByX(int x) { + FontMetrics defFontMetrics = getFontMetrics(getFont()); + + int width = getTextOffset(); + if (width > x) return null; + + if (myText.length() != 0 && myHighlightedRegions.size() != 0) { + int endIndex = 0; + for (HighlightedRegion hRegion : myHighlightedRegions) { + width += defFontMetrics.stringWidth(myText.substring(endIndex, hRegion.startOffset)); + endIndex = hRegion.endOffset; + if (width > x) return null; + + String text = getRegionText(hRegion); + FontMetrics fontMetrics = myFontMetrics.get(hRegion.textAttributes.getFontType()); + width += fontMetrics.stringWidth(text); + if (width > x) return hRegion; + } + } + return null; + } + public Dimension getPreferredSize() { FontMetrics defFontMetrics = getFontMetrics(getFont()); @@ -359,24 +383,10 @@ public class HighlightableComponent extends JComponent { else{ int endIndex = 0; for (HighlightedRegion hRegion : myHighlightedRegions) { - - String text = myText.substring(endIndex, hRegion.startOffset); + width += defFontMetrics.stringWidth(myText.substring(endIndex, hRegion.startOffset)); endIndex = hRegion.endOffset; - width += defFontMetrics.stringWidth(text); - - if (hRegion.endOffset > myText.length()) { - if (hRegion.startOffset < myText.length()) { - text = myText.substring(hRegion.startOffset); - } - else { - text = ""; - } - } - else { - text = myText.substring(hRegion.startOffset, hRegion.endOffset); - } - + String text = getRegionText(hRegion); FontMetrics fontMetrics = myFontMetrics.get(hRegion.textAttributes.getFontType()); width += fontMetrics.stringWidth(text); } @@ -392,4 +402,20 @@ public class HighlightableComponent extends JComponent { return new Dimension(width + 2, height); } + + private String getRegionText(HighlightedRegion hRegion) { + String text; + if (hRegion.endOffset > myText.length()) { + if (hRegion.startOffset < myText.length()) { + text = myText.substring(hRegion.startOffset); + } + else { + text = ""; + } + } + else { + text = myText.substring(hRegion.startOffset, hRegion.endOffset); + } + return text; + } } diff --git a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java index 7370ec885bee..93c9dc5e301d 100644 --- a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java +++ b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java @@ -51,7 +51,7 @@ public class HyperlinkLabel extends HighlightableComponent { myTextEffectColor = textEffectColor; enforceBackgroundOutsideText(textBackgroundColor); setHyperlinkText(text); - enableEvents(AWTEvent.MOUSE_EVENT_MASK); + enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); } public void addNotify() { @@ -60,7 +60,11 @@ public class HyperlinkLabel extends HighlightableComponent { } public void setHyperlinkText(String text) { - prepareText(text, myTextForegroundColor, myTextBackgroundColor, myTextEffectColor); + setHyperlinkText("", text, ""); + } + + public void setHyperlinkText(String beforeLinkText, String linkText, String afterLinkText) { + prepareText(beforeLinkText, linkText, afterLinkText); revalidate(); adjustSize(); } @@ -72,24 +76,34 @@ public class HyperlinkLabel extends HighlightableComponent { protected void processMouseEvent(MouseEvent e) { - if (e.getID() == MouseEvent.MOUSE_ENTERED) { - setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - else if (e.getID() == MouseEvent.MOUSE_EXITED) { + if (e.getID() == MouseEvent.MOUSE_EXITED) { setCursor(Cursor.getDefaultCursor()); } - else if (UIUtil.isActionClick(e, MouseEvent.MOUSE_PRESSED)) { + else if (UIUtil.isActionClick(e, MouseEvent.MOUSE_PRESSED) && isOnLink(e.getX())) { fireHyperlinkEvent(); } super.processMouseEvent(e); } - private void prepareText(String text, final Color textForegroundColor, final Color textBackgroundColor, final Color textEffectColor) { + @Override + protected void processMouseMotionEvent(MouseEvent e) { + if (e.getID() == MouseEvent.MOUSE_MOVED) { + setCursor(isOnLink(e.getX()) ? Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) : Cursor.getDefaultCursor()); + } + super.processMouseMotionEvent(e); + } + + private boolean isOnLink(int x) { + return findRegionByX(x) != null; + } + + private void prepareText(String beforeLinkText, String linkText, String afterLinkText) { setFont(UIUtil.getLabelFont()); myHighlightedText = new HighlightedText(); - myHighlightedText.appendText(text, new TextAttributes( - textForegroundColor, textBackgroundColor, textEffectColor, EffectType.LINE_UNDERSCORE, Font.PLAIN - )); + myHighlightedText.appendText(beforeLinkText, null); + myHighlightedText.appendText(linkText, new TextAttributes(myTextForegroundColor, myTextBackgroundColor, myTextEffectColor, + EffectType.LINE_UNDERSCORE, Font.PLAIN)); + myHighlightedText.appendText(afterLinkText, null); myHighlightedText.applyToComponent(this); adjustSize(); }