11package org .overengineer .inlineproblems ;
22
3+ import com .intellij .codeInsight .hints .presentation .InputHandler ;
4+ import com .intellij .codeInsight .intention .impl .ShowIntentionActionsHandler ;
35import com .intellij .ide .ui .AntialiasingType ;
46import com .intellij .ide .ui .UISettings ;
7+ import com .intellij .openapi .actionSystem .AnAction ;
8+ import com .intellij .openapi .actionSystem .IdeActions ;
9+ import com .intellij .openapi .actionSystem .ex .ActionUtil ;
510import com .intellij .openapi .editor .Editor ;
611import com .intellij .openapi .editor .EditorCustomElementRenderer ;
712import com .intellij .openapi .editor .Inlay ;
13+ import com .intellij .openapi .editor .ScrollType ;
814import com .intellij .openapi .editor .impl .FontInfo ;
915import com .intellij .openapi .editor .markup .GutterIconRenderer ;
1016import com .intellij .openapi .editor .markup .TextAttributes ;
17+ import com .intellij .openapi .project .Project ;
18+ import com .intellij .psi .PsiFile ;
19+ import com .intellij .psi .util .PsiUtilBase ;
20+ import com .intellij .ui .paint .EffectPainter ;
1121import lombok .Getter ;
1222import lombok .Setter ;
23+ import org .jdesktop .swingx .action .ActionManager ;
1324import org .jetbrains .annotations .NotNull ;
1425import org .jetbrains .annotations .Nullable ;
1526import org .overengineer .inlineproblems .entities .InlineProblem ;
1627import org .overengineer .inlineproblems .settings .SettingsState ;
1728import org .overengineer .inlineproblems .utils .FontUtil ;
1829
1930import java .awt .*;
31+ import java .awt .event .MouseEvent ;
2032import java .awt .font .FontRenderContext ;
2133
2234
2335@ Getter
24- public class InlineProblemLabel implements EditorCustomElementRenderer {
25-
36+ public class InlineProblemLabel implements EditorCustomElementRenderer , InputHandler {
2637 private final String text ;
2738 private final Color textColor ;
2839 private final Color backgroundColor ;
2940 private final boolean isDrawBox ;
3041 private final boolean isRoundedCorners ;
3142 private final boolean isFillBackground ;
43+ private boolean hovered ;
44+ private final boolean hoveredEnabled ;
45+ private Inlay <?> inlay ;
46+ private final int actualStartOffset ;
3247
3348 @ Setter
3449 private boolean isBlockElement ;
@@ -59,6 +74,9 @@ public InlineProblemLabel(
5974
6075 this .isUseEditorFont = settings .isUseEditorFont ();
6176 this .inlayFontSizeDelta = settings .getInlayFontSizeDelta ();
77+ this .hovered = false ;
78+ this .actualStartOffset = problem .getActualStartffset ();
79+ hoveredEnabled = settings .isHovering ();
6280 }
6381
6482 @ Override
@@ -80,7 +98,7 @@ public int calcWidthInPixels(@NotNull Editor editor) {
8098 @ Override
8199 public void paint (@ NotNull Inlay inlay , @ NotNull Graphics graphics , @ NotNull Rectangle targetRegion , @ NotNull TextAttributes textAttributes ) {
82100 Editor editor = inlay .getEditor ();
83-
101+ this . inlay = inlay ;
84102 // These offsets are applied here and not in the calc functions itself because we use it to shrink the drawn stuff a little bit
85103 int width = calcWidthInPixels (inlay ) + DRAW_BOX_WIDTH_OFFSET ;
86104 int height = calcHeightInPixels (inlay ) + DRAW_BOX_HEIGHT_OFFSET ;
@@ -92,7 +110,7 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
92110 // Apply delta on the boxes
93111 if (inlayFontSizeDelta != 0 && editorFontSize > inlayFontSizeDelta ) {
94112 height -= inlayFontSizeDelta ;
95- targetRegionY += (int )(inlayFontSizeDelta / 1.5 );
113+ targetRegionY += (int ) (inlayFontSizeDelta / 1.5 );
96114 }
97115
98116 if (isDrawBox ) {
@@ -118,14 +136,13 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
118136 5
119137 );
120138 }
121- }
122- else {
123- graphics .drawRect (
124- targetRegion .x ,
125- targetRegionY ,
126- width ,
127- height
128- );
139+ } else {
140+ graphics .drawRect (
141+ targetRegion .x ,
142+ targetRegionY ,
143+ width ,
144+ height
145+ );
129146
130147 if (isFillBackground ) {
131148 graphics .fillRect (
@@ -138,7 +155,7 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
138155 }
139156 }
140157
141- graphics .setColor (textColor );
158+ graphics .setColor (hovered ? textColor . brighter () : textColor );
142159
143160 graphics .setFont (FontUtil .getActiveFont (editor ));
144161
@@ -147,10 +164,64 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
147164 targetRegion .x + DRAW_STRING_LINE_PLACEMENT_OFFSET_X ,
148165 targetRegion .y + DRAW_STRING_LINE_PLACEMENT_OFFSET_Y + editor .getAscent ()
149166 );
167+ if (hovered )
168+ EffectPainter .LINE_UNDERSCORE .paint (
169+ (Graphics2D ) graphics ,
170+ targetRegion .x - DRAW_BOX_WIDTH_OFFSET ,
171+ targetRegion .y + DRAW_STRING_LINE_PLACEMENT_OFFSET_Y + editor .getAscent (),
172+ width + (DRAW_BOX_WIDTH_OFFSET * 2 ),
173+ editor .getAscent (),
174+ FontUtil .getActiveFont (editor ));
175+ }
176+
177+ private void setHovered (boolean hovered ) {
178+ if (!this .hoveredEnabled || this .hovered == hovered ) {
179+ return ;
180+ }
181+ this .hovered = hovered ;
182+ if (inlay != null )
183+ inlay .repaint ();
150184 }
151185
152186 @ Override
153187 public @ Nullable GutterIconRenderer calcGutterIconRenderer (@ NotNull Inlay inlay ) {
154188 return EditorCustomElementRenderer .super .calcGutterIconRenderer (inlay );
155189 }
190+
191+ @ Override
192+ public void mouseClicked (@ NotNull MouseEvent mouseEvent , @ NotNull Point point ) {
193+ if (!hoveredEnabled ) {
194+ return ;
195+ }
196+ if (mouseEvent .getButton () == MouseEvent .BUTTON1 ) {
197+ mouseEvent .consume ();
198+
199+ var editor = inlay .getEditor ();
200+ editor .getCaretModel ().moveToOffset (actualStartOffset );
201+ editor .getScrollingModel ().scrollToCaret (ScrollType .CENTER );
202+
203+ var action = ActionManager .getInstance ().getAction (IdeActions .ACTION_SHOW_INTENTION_ACTIONS );
204+ if (action == null ) {
205+ Project project = editor .getProject ();
206+ if (project == null ) return ;
207+ PsiFile psiFileInEditor = PsiUtilBase .getPsiFileInEditor (editor , project );
208+ if (psiFileInEditor == null ) return ;
209+ new ShowIntentionActionsHandler ().invoke (project , editor , psiFileInEditor , false );
210+ } else {
211+ ActionUtil .invokeAction ((AnAction ) action , editor .getComponent (), "EditorInlay" , null , null );
212+
213+ }
214+ }
215+ }
216+
217+ @ Override
218+ public void mouseMoved (@ NotNull MouseEvent mouseEvent , @ NotNull Point point ) {
219+ setHovered (true );
220+ }
221+
222+ @ Override
223+ public void mouseExited () {
224+ setHovered (false );
225+ }
226+
156227}
0 commit comments