use of com.intellij.codeInsight.hint.HintManager in project intellij-community by JetBrains.
the class CodeFoldingManagerImpl method projectOpened.
@Override
public void projectOpened() {
final EditorMouseMotionAdapter myMouseMotionListener = new EditorMouseMotionAdapter() {
LightweightHint myCurrentHint;
FoldRegion myCurrentFold;
@Override
public void mouseMoved(EditorMouseEvent e) {
if (myProject.isDisposed())
return;
HintManager hintManager = HintManager.getInstance();
if (hintManager != null && hintManager.hasShownHintsThatWillHideByOtherHint(false)) {
return;
}
if (e.getArea() != EditorMouseEventArea.FOLDING_OUTLINE_AREA)
return;
LightweightHint hint = null;
try {
Editor editor = e.getEditor();
if (PsiDocumentManager.getInstance(myProject).isUncommited(editor.getDocument()))
return;
MouseEvent mouseEvent = e.getMouseEvent();
FoldRegion fold = ((EditorEx) editor).getGutterComponentEx().findFoldingAnchorAt(mouseEvent.getX(), mouseEvent.getY());
if (fold == null || !fold.isValid())
return;
if (fold == myCurrentFold && myCurrentHint != null) {
hint = myCurrentHint;
return;
}
TextRange psiElementRange = EditorFoldingInfo.get(editor).getPsiElementRange(fold);
if (psiElementRange == null)
return;
int textOffset = psiElementRange.getStartOffset();
// There is a possible case that target PSI element's offset is less than fold region offset (e.g. complete method is
// returned as PSI element for fold region that corresponds to java method code block). We don't want to show any hint
// if start of the current fold region is displayed.
Point foldStartXY = editor.visualPositionToXY(editor.offsetToVisualPosition(Math.max(textOffset, fold.getStartOffset())));
Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
if (visibleArea.y > foldStartXY.y) {
if (myCurrentHint != null) {
myCurrentHint.hide();
myCurrentHint = null;
}
// We want to show a hint with the top fold region content that is above the current viewport position.
// However, there is a possible case that complete region has a big height and only a little bottom part
// is shown at the moment. We can't just show hint with the whole top content because it would hide actual
// editor content, hence, we show max(2; available visual lines number) instead.
// P.S. '2' is used here in assumption that many java methods have javadocs which first line is just '/**'.
// So, it's not too useful to show only it even when available vertical space is not big enough.
int availableVisualLines = 2;
JComponent editorComponent = editor.getComponent();
Container editorComponentParent = editorComponent.getParent();
if (editorComponentParent != null) {
Container contentPane = editorComponent.getRootPane().getContentPane();
if (contentPane != null) {
int y = SwingUtilities.convertPoint(editorComponentParent, editorComponent.getLocation(), contentPane).y;
int visualLines = y / editor.getLineHeight();
availableVisualLines = Math.max(availableVisualLines, visualLines);
}
}
int startVisualLine = editor.offsetToVisualPosition(textOffset).line;
int desiredEndVisualLine = Math.max(0, editor.xyToVisualPosition(new Point(0, visibleArea.y)).line - 1);
int endVisualLine = startVisualLine + availableVisualLines;
if (endVisualLine > desiredEndVisualLine) {
endVisualLine = desiredEndVisualLine;
}
// Show only the non-displayed top part of the target fold region
int endOffset = editor.logicalPositionToOffset(editor.visualToLogicalPosition(new VisualPosition(endVisualLine, 0)));
TextRange textRange = new UnfairTextRange(textOffset, endOffset);
hint = EditorFragmentComponent.showEditorFragmentHint(editor, textRange, true, true);
myCurrentFold = fold;
myCurrentHint = hint;
}
} finally {
if (hint == null) {
if (myCurrentHint != null) {
myCurrentHint.hide();
myCurrentHint = null;
}
myCurrentFold = null;
}
}
}
};
StartupManager.getInstance(myProject).registerPostStartupActivity((DumbAwareRunnable) () -> EditorFactory.getInstance().getEventMulticaster().addEditorMouseMotionListener(myMouseMotionListener, myProject));
}
Aggregations