Search in sources :

Example 1 with EditorMouseMotionAdapter

use of com.intellij.openapi.editor.event.EditorMouseMotionAdapter 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));
}
Also used : MouseEvent(java.awt.event.MouseEvent) EditorMouseEvent(com.intellij.openapi.editor.event.EditorMouseEvent) HintManager(com.intellij.codeInsight.hint.HintManager) EditorMouseMotionAdapter(com.intellij.openapi.editor.event.EditorMouseMotionAdapter) LightweightHint(com.intellij.ui.LightweightHint) LightweightHint(com.intellij.ui.LightweightHint) EditorMouseEvent(com.intellij.openapi.editor.event.EditorMouseEvent)

Aggregations

HintManager (com.intellij.codeInsight.hint.HintManager)1 EditorMouseEvent (com.intellij.openapi.editor.event.EditorMouseEvent)1 EditorMouseMotionAdapter (com.intellij.openapi.editor.event.EditorMouseMotionAdapter)1 LightweightHint (com.intellij.ui.LightweightHint)1 MouseEvent (java.awt.event.MouseEvent)1