changed highlighter layer for placeholders
[idea/community.git] / python / educational-core / src / com / jetbrains / edu / EduAnswerPlaceholderPainter.java
1 package com.jetbrains.edu;
2
3 import com.intellij.openapi.editor.Document;
4 import com.intellij.openapi.editor.Editor;
5 import com.intellij.openapi.editor.RangeMarker;
6 import com.intellij.openapi.editor.colors.EditorColorsManager;
7 import com.intellij.openapi.editor.colors.EditorColorsScheme;
8 import com.intellij.openapi.editor.impl.DocumentImpl;
9 import com.intellij.openapi.editor.markup.*;
10 import com.intellij.openapi.project.Project;
11 import com.intellij.ui.JBColor;
12 import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
13 import com.jetbrains.edu.courseFormat.TaskFile;
14 import org.jetbrains.annotations.NotNull;
15
16 import java.awt.*;
17 import java.util.List;
18
19 public class EduAnswerPlaceholderPainter {
20
21   //it should be the lowest highlighting layer, otherwise selection and other effects are not visible
22   public static final int PLACEHOLDERS_LAYER = 0;
23
24   private EduAnswerPlaceholderPainter() {
25
26   }
27
28   public static void drawAnswerPlaceholder(@NotNull final Editor editor, @NotNull final AnswerPlaceholder placeholder,
29                                            boolean useLength, @NotNull final JBColor color) {
30     final Document document = editor.getDocument();
31     if (useLength && !placeholder.isValid(document)) {
32       return;
33     }
34     EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
35     final TextAttributes textAttributes = new TextAttributes(scheme.getDefaultForeground(), scheme.getDefaultBackground(), null,
36                                                                     EffectType.BOXED, Font.PLAIN);
37     final Project project = editor.getProject();
38     assert project != null;
39     final int startOffset = placeholder.getRealStartOffset(document);
40     final int length = placeholder.getLength();
41     final int replacementLength = placeholder.getPossibleAnswerLength();
42     int highlighterLength = useLength ? length : replacementLength;
43     final int endOffset = startOffset + highlighterLength;
44     textAttributes.setEffectColor(color);
45     RangeHighlighter
46       highlighter = editor.getMarkupModel().addRangeHighlighter(startOffset, endOffset, PLACEHOLDERS_LAYER,
47                                                                 textAttributes, HighlighterTargetArea.EXACT_RANGE);
48     highlighter.setGreedyToLeft(true);
49     highlighter.setGreedyToRight(true);
50   }
51
52   public static void createGuardedBlock(Editor editor, List<RangeMarker> blocks, int start, int end) {
53     RangeHighlighter rh = editor.getMarkupModel()
54       .addRangeHighlighter(start, end, PLACEHOLDERS_LAYER, null, HighlighterTargetArea.EXACT_RANGE);
55     blocks.add(rh);
56   }
57
58
59   public static void createGuardedBlocks(@NotNull final Editor editor, TaskFile taskFile, boolean useLength) {
60     for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
61       createGuardedBlocks(editor, answerPlaceholder, useLength);
62     }
63   }
64
65   public static void createGuardedBlocks(@NotNull final Editor editor, AnswerPlaceholder placeholder, boolean useLength) {
66     Document document = editor.getDocument();
67     if (document instanceof DocumentImpl) {
68       DocumentImpl documentImpl = (DocumentImpl)document;
69       List<RangeMarker> blocks = documentImpl.getGuardedBlocks();
70       if (useLength && !placeholder.isValid(document)) return;
71       int start = placeholder.getRealStartOffset(document);
72       final int length = useLength ? placeholder.getLength() : placeholder.getPossibleAnswerLength();
73       int end = start + length;
74       if (start != 0) {
75         createGuardedBlock(editor, blocks, start - 1, start);
76       }
77       if (end != document.getTextLength()) {
78         createGuardedBlock(editor, blocks, end, end + 1);
79       }
80     }
81   }
82
83 }