Example usage for com.intellij.openapi.editor.event EditorMouseMotionAdapter EditorMouseMotionAdapter

List of usage examples for com.intellij.openapi.editor.event EditorMouseMotionAdapter EditorMouseMotionAdapter

Introduction

In this page you can find the example usage for com.intellij.openapi.editor.event EditorMouseMotionAdapter EditorMouseMotionAdapter.

Prototype

EditorMouseMotionAdapter

Source Link

Usage

From source file:com.intellij.codeInsight.folding.impl.CodeFoldingManagerImpl.java

License:Apache License

@Override
public void projectOpened() {
    final EditorMouseMotionAdapter myMouseMotionListener = new EditorMouseMotionAdapter() {
        LightweightHint myCurrentHint = null;
        FoldRegion myCurrentFold = null;

        @Override/* w w w  .  j av a 2 s.  com*/
        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(new DumbAwareRunnable() {
        @Override
        public void run() {
            EditorFactory.getInstance().getEventMulticaster()
                    .addEditorMouseMotionListener(myMouseMotionListener, myProject);
        }
    });
}