| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @author Yura Cangea |
| */ |
| package com.intellij.application.options.colors; |
| |
| import com.intellij.application.options.colors.highlighting.HighlightData; |
| import com.intellij.openapi.editor.Editor; |
| import com.intellij.openapi.editor.HighlighterColors; |
| import com.intellij.openapi.editor.LogicalPosition; |
| import com.intellij.openapi.editor.colors.TextAttributesKey; |
| import com.intellij.openapi.editor.event.CaretAdapter; |
| import com.intellij.openapi.editor.event.CaretEvent; |
| import com.intellij.openapi.editor.event.CaretListener; |
| import com.intellij.openapi.editor.ex.EditorEx; |
| import com.intellij.openapi.editor.ex.util.EditorUtil; |
| import com.intellij.openapi.editor.highlighter.HighlighterIterator; |
| import com.intellij.openapi.fileTypes.SyntaxHighlighter; |
| import com.intellij.psi.tree.IElementType; |
| import com.intellij.ui.ListScrollingUtil; |
| import com.intellij.util.ui.UIUtil; |
| import org.intellij.lang.annotations.JdkConstants; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.awt.event.MouseEvent; |
| import java.awt.event.MouseMotionAdapter; |
| |
| public class ClickNavigator { |
| private final JList myOptionsList; |
| |
| public ClickNavigator(JList optionsList) { |
| myOptionsList = optionsList; |
| } |
| |
| public void addClickNavigatorToGeneralView(final Editor view) { |
| view.getContentComponent().addMouseMotionListener(new MouseMotionAdapter() { |
| @Override |
| public void mouseMoved(MouseEvent e) { |
| EditorUtil.setHandCursor(view); |
| } |
| }); |
| |
| CaretListener listener = new CaretAdapter() { |
| @Override |
| public void caretPositionChanged(CaretEvent e) { |
| setSelectedItem(HighlighterColors.TEXT.getExternalName(), true); |
| } |
| }; |
| view.getCaretModel().addCaretListener(listener); |
| } |
| |
| private boolean setSelectedItem(String type, boolean select) { |
| DefaultListModel model = (DefaultListModel)myOptionsList.getModel(); |
| |
| for (int i = 0; i < model.size(); i++) { |
| Object o = model.get(i); |
| if (o instanceof EditorSchemeAttributeDescriptor) { |
| if (type.equals(((EditorSchemeAttributeDescriptor)o).getType())) { |
| if (select) { |
| ListScrollingUtil.selectItem(myOptionsList, i); |
| } |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| private static boolean isWhiteSpace(int offset, CharSequence text) { |
| return offset <= 0 || offset >= text.length() || |
| text.charAt(offset) == ' ' || text.charAt(offset) == '\t' || |
| text.charAt(offset) == '\n' || text.charAt(offset) == '\r'; |
| } |
| |
| public static boolean highlightDataContainsOffset(HighlightData data, int offset) { |
| return offset >= data.getStartOffset() && offset <= data.getEndOffset(); |
| } |
| |
| public void addClickNavigator(final Editor view, |
| final SyntaxHighlighter highlighter, |
| final HighlightData[] data, |
| final boolean isBackgroundImportant) { |
| addMouseMotionListener(view, highlighter, data, isBackgroundImportant); |
| |
| CaretListener listener = new CaretAdapter() { |
| @Override |
| public void caretPositionChanged(CaretEvent e) { |
| navigate(view, true, e.getNewPosition(), highlighter, data, isBackgroundImportant); |
| } |
| }; |
| view.getCaretModel().addCaretListener(listener); |
| } |
| |
| private boolean selectItem(boolean select, HighlighterIterator itr, SyntaxHighlighter highlighter) { |
| |
| IElementType tokenType = itr.getTokenType(); |
| if (tokenType == null) return false; |
| String type = highlightingTypeFromTokenType(tokenType, highlighter); |
| return setSelectedItem(type, select); |
| } |
| |
| public static String highlightingTypeFromTokenType(IElementType tokenType, SyntaxHighlighter highlighter) { |
| TextAttributesKey[] highlights = highlighter.getTokenHighlights(tokenType); |
| String s = null; |
| for (int i = highlights.length - 1; i >= 0; i--) { |
| if (highlights[i] != HighlighterColors.TEXT) { |
| s = highlights[i].getExternalName(); |
| break; |
| } |
| } |
| return s == null ? HighlighterColors.TEXT.getExternalName() : s; |
| } |
| |
| private void addMouseMotionListener(final Editor view, |
| final SyntaxHighlighter highlighter, |
| final HighlightData[] data, final boolean isBackgroundImportant) { |
| view.getContentComponent().addMouseMotionListener(new MouseMotionAdapter() { |
| @Override |
| public void mouseMoved(MouseEvent e) { |
| LogicalPosition pos = view.xyToLogicalPosition(new Point(e.getX(), e.getY())); |
| navigate(view, false, pos, highlighter, data, isBackgroundImportant); |
| } |
| }); |
| } |
| |
| private void navigate(final Editor editor, boolean select, |
| LogicalPosition pos, |
| final SyntaxHighlighter highlighter, |
| final HighlightData[] data, final boolean isBackgroundImportant) { |
| int offset = editor.logicalPositionToOffset(pos); |
| |
| if (!isBackgroundImportant && editor.offsetToLogicalPosition(offset).column != pos.column) { |
| if (!select) { |
| setCursor(editor, Cursor.TEXT_CURSOR); |
| return; |
| } |
| } |
| |
| if (data != null) { |
| for (HighlightData highlightData : data) { |
| if (highlightDataContainsOffset(highlightData, editor.logicalPositionToOffset(pos))) { |
| if (!select) setCursor(editor, Cursor.HAND_CURSOR); |
| setSelectedItem(highlightData.getHighlightType(), select); |
| return; |
| } |
| } |
| } |
| |
| if (highlighter != null) { |
| HighlighterIterator itr = ((EditorEx)editor).getHighlighter().createIterator(offset); |
| boolean selection = selectItem(select, itr, highlighter); |
| if (!select && selection) { |
| setCursor(editor, Cursor.HAND_CURSOR); |
| } |
| else { |
| setCursor(editor, Cursor.TEXT_CURSOR); |
| } |
| } |
| } |
| |
| public static void setCursor(final Editor view, @JdkConstants.CursorType int type) { |
| final Cursor cursor = type == Cursor.TEXT_CURSOR && view instanceof EditorEx ? |
| UIUtil.getTextCursor(((EditorEx)view).getBackgroundColor()) : Cursor.getPredefinedCursor(type); |
| view.getContentComponent().setCursor(cursor); |
| } |
| |
| } |