Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void drawProblemLabel(InlineProblem problem) {
problem,
drawDetails.getTextColor(),
drawDetails.getBackgroundColor(),
drawDetails.getTextColor().brighter(),
settings
);

Expand Down
100 changes: 87 additions & 13 deletions src/main/java/org/overengineer/inlineproblems/InlineProblemLabel.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
package org.overengineer.inlineproblems;

import com.intellij.codeInsight.hints.presentation.InputHandler;
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
import com.intellij.ide.ui.AntialiasingType;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorCustomElementRenderer;
import com.intellij.openapi.editor.Inlay;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.impl.FontInfo;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.paint.EffectPainter;
import lombok.Getter;
import lombok.Setter;
import org.jdesktop.swingx.action.ActionManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.overengineer.inlineproblems.entities.InlineProblem;
import org.overengineer.inlineproblems.settings.SettingsState;
import org.overengineer.inlineproblems.utils.FontUtil;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.font.FontRenderContext;


@Getter
public class InlineProblemLabel implements EditorCustomElementRenderer {

public class InlineProblemLabel implements EditorCustomElementRenderer, InputHandler {
private final String text;
private final Color textColor;
private final Color backgroundColor;
private final Color hoverColor;
private final boolean isDrawBox;
private final boolean isRoundedCorners;
private final boolean isFillBackground;
private boolean hovered;
private final boolean hoveredEnabled;
private Inlay<?> inlay;
private final int actualStartOffset;

@Setter
private boolean isBlockElement;
Expand All @@ -47,10 +63,12 @@ public InlineProblemLabel(
final InlineProblem problem,
final Color textColor,
final Color backgroundColor,
final Color hoverColor,
final SettingsState settings
) {
this.textColor = textColor;
this.backgroundColor = backgroundColor;
this.hoverColor = hoverColor;
this.isDrawBox = settings.isDrawBoxesAroundErrorLabels();
this.isRoundedCorners = settings.isRoundedCornerBoxes();
this.text = problem.getText();
Expand All @@ -59,6 +77,9 @@ public InlineProblemLabel(

this.isUseEditorFont = settings.isUseEditorFont();
this.inlayFontSizeDelta = settings.getInlayFontSizeDelta();
this.hovered = false;
this.actualStartOffset = problem.getActualStartffset();
hoveredEnabled = settings.isHovering();
}

@Override
Expand All @@ -80,7 +101,7 @@ public int calcWidthInPixels(@NotNull Editor editor) {
@Override
public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rectangle targetRegion, @NotNull TextAttributes textAttributes) {
Editor editor = inlay.getEditor();

this.inlay = inlay;
// These offsets are applied here and not in the calc functions itself because we use it to shrink the drawn stuff a little bit
int width = calcWidthInPixels(inlay) + DRAW_BOX_WIDTH_OFFSET;
int height = calcHeightInPixels(inlay) + DRAW_BOX_HEIGHT_OFFSET;
Expand All @@ -92,7 +113,7 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
// Apply delta on the boxes
if (inlayFontSizeDelta != 0 && editorFontSize > inlayFontSizeDelta) {
height -= inlayFontSizeDelta;
targetRegionY += (int)(inlayFontSizeDelta / 1.5);
targetRegionY += (int) (inlayFontSizeDelta / 1.5);
}

if (isDrawBox) {
Expand All @@ -118,14 +139,13 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
5
);
}
}
else {
graphics.drawRect(
targetRegion.x,
targetRegionY,
width,
height
);
} else {
graphics.drawRect(
targetRegion.x,
targetRegionY,
width,
height
);

if (isFillBackground) {
graphics.fillRect(
Expand All @@ -138,7 +158,7 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
}
}

graphics.setColor(textColor);
graphics.setColor(hovered ? hoverColor : textColor);

graphics.setFont(FontUtil.getActiveFont(editor));

Expand All @@ -147,10 +167,64 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
targetRegion.x + DRAW_STRING_LINE_PLACEMENT_OFFSET_X,
targetRegion.y + DRAW_STRING_LINE_PLACEMENT_OFFSET_Y + editor.getAscent()
);
if (hovered)
EffectPainter.LINE_UNDERSCORE.paint(
(Graphics2D) graphics,
targetRegion.x - DRAW_BOX_WIDTH_OFFSET,
targetRegion.y + editor.getAscent() ,
width + (DRAW_BOX_WIDTH_OFFSET * 2),
editor.getAscent(),
FontUtil.getActiveFont(editor));
}

private void setHovered(boolean hovered) {
if (!this.hoveredEnabled || this.hovered == hovered) {
return;
}
this.hovered = hovered;
if (inlay != null)
inlay.repaint();
}

@Override
public @Nullable GutterIconRenderer calcGutterIconRenderer(@NotNull Inlay inlay) {
return EditorCustomElementRenderer.super.calcGutterIconRenderer(inlay);
}

@Override
public void mouseClicked(@NotNull MouseEvent mouseEvent, @NotNull Point point) {
if (!hoveredEnabled) {
return;
}
if (mouseEvent.getButton() == MouseEvent.BUTTON1) {
mouseEvent.consume();

var editor = inlay.getEditor();
editor.getCaretModel().moveToOffset(actualStartOffset);
editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);

var action = ActionManager.getInstance().getAction(IdeActions.ACTION_SHOW_INTENTION_ACTIONS);
if (action == null) {
Project project = editor.getProject();
if (project == null) return;
PsiFile psiFileInEditor = PsiUtilBase.getPsiFileInEditor(editor, project);
if (psiFileInEditor == null) return;
new ShowIntentionActionsHandler().invoke(project, editor, psiFileInEditor, false);
} else {
ActionUtil.invokeAction((AnAction) action, editor.getComponent(), "EditorInlay", null, null);

}
}
}

@Override
public void mouseMoved(@NotNull MouseEvent mouseEvent, @NotNull Point point) {
setHovered(true);
}

@Override
public void mouseExited() {
setHovered(false);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class InlineProblem {
private DrawDetails drawDetails;

private int actualEndOffset;
private int actualStartffset;

private boolean isBlockElement = false;

Expand Down Expand Up @@ -73,6 +74,7 @@ public InlineProblem(
this.actualEndOffset = highlightInfo.getActualEndOffset();
else
this.actualEndOffset = highlightInfo.getActualEndOffset() -1;
this.actualStartffset = highlightInfo.getStartOffset();
}

private String getTextWithHtmlStrippingAndXmlUnescaping(String text, SettingsState settingsState) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public class SettingsComponent {
private final JBCheckBox fillProblemLabels = new JBCheckBox(SettingsBundle.message("settings.fillProblemLabels"));
private final JBCheckBox boldProblemLabels = new JBCheckBox(SettingsBundle.message("settings.boldProblemLabels"));
private final JBCheckBox italicProblemLabels = new JBCheckBox(SettingsBundle.message("settings.italicProblemLabels"));
private final JBCheckBox enableHovering = new JBCheckBox(SettingsBundle.message("settings.enableHovering"));

private final JBTextField problemFilterList = new JBTextField();
private final JBTextField fileExtensionBlacklist = new JBTextField();

Expand Down Expand Up @@ -133,6 +135,7 @@ public SettingsComponent() {
fillProblemLabels.setSelected(settingsState.isFillProblemLabels());
boldProblemLabels.setSelected(settingsState.isBoldProblemLabels());
italicProblemLabels.setSelected(settingsState.isItalicProblemLabels());
enableHovering.setSelected(settingsState.isHovering());

additionalInfoSeverities.setText(settingsState.getAdditionalInfoSeveritiesAsString());
additionalWeakWarningSeverities.setText(settingsState.getAdditionalWeakWarningSeveritiesAsString());
Expand All @@ -154,6 +157,7 @@ public SettingsComponent() {
.addComponent(fillProblemLabels, 0)
.addComponent(boldProblemLabels, 0)
.addComponent(italicProblemLabels, 0)
.addComponent(enableHovering, 0)
.addSeparator()
.addComponent(new JBLabel(SettingsBundle.message("settings.submenu.general")))
.addLabeledComponent(new JBLabel(SettingsBundle.message("settings.activeProblemListener")), enabledListener)
Expand Down Expand Up @@ -317,6 +321,13 @@ public void setItalicProblemLabels(boolean isSelected) {
italicProblemLabels.setSelected(isSelected);
}

public boolean isHovering() {
return enableHovering.isSelected();
}
public void setHovering(boolean isSelected) {
enableHovering.setSelected(isSelected);
}

public boolean isShowErrors() {
return showErrors.isSelected();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public boolean isModified() {
state.isFillProblemLabels() == settingsComponent.isFillProblemLabels() &&
state.isBoldProblemLabels() == settingsComponent.isBoldProblemLabels() &&
state.isItalicProblemLabels() == settingsComponent.isItalicProblemLabels() &&
state.isHovering() == settingsComponent.isHovering() &&

state.getErrorTextColor().equals(settingsComponent.getErrorTextColor()) &&
state.getErrorBackgroundColor().equals(settingsComponent.getErrorLabelBackgroundColor()) &&
Expand Down Expand Up @@ -143,6 +144,7 @@ public void apply() {
state.setFillProblemLabels(settingsComponent.isFillProblemLabels());
state.setBoldProblemLabels(settingsComponent.isBoldProblemLabels());
state.setItalicProblemLabels(settingsComponent.isItalicProblemLabels());
state.setHovering(settingsComponent.isHovering());

state.setEnabledListener(settingsComponent.getEnabledListener());
state.setManualScannerDelay(settingsComponent.getManualScannerDelay());
Expand Down Expand Up @@ -213,6 +215,7 @@ public void reset() {
settingsComponent.setFillProblemLabels(state.isFillProblemLabels());
settingsComponent.setBoldProblemLabels(state.isBoldProblemLabels());
settingsComponent.setItalicProblemLabels(state.isItalicProblemLabels());
settingsComponent.setHovering(state.isHovering());

settingsComponent.setEnabledListener(state.getEnabledListener());
settingsComponent.setManualScannerDelay(state.getManualScannerDelay());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class SettingsState implements PersistentStateComponent<SettingsState> {
private boolean showInfos = false;
private boolean highlightInfos = false;
private boolean showInfosInGutter = false;
private boolean hovering = false;

/**
* Colors renamed from '<NAME>Color' to '<NAME>Col' to solve
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/messages/SettingsBundle_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ settings.forceProblemsInOneLine=Force problems in the same line even if they are
settings.useEditorFont=Use editor font instead of tooltip font
settings.showOnlyHighestPerLine=Show only the problem with the highest severity per line
settings.enableHtmlStripping=Enable stripping of HTML in the messages
settings.enableXmlUnescaping=Enable unescaping of XML in the messages
settings.enableXmlUnescaping=Enable unescaping of XML in the messages
settings.enableHovering=Enable hovering
Loading