/** * Called on editor settings change. Current model is expected to drop all cached information * about the settings if any. */ public void reinitSettings() { boolean softWrapsUsedBefore = myUseSoftWraps; myUseSoftWraps = areSoftWrapsEnabledInEditor(); int tabWidthBefore = myTabWidth; myTabWidth = EditorUtil.getTabSize(myEditor); boolean fontsChanged = false; if (!myFontPreferences.equals(myEditor.getColorsScheme().getFontPreferences()) && myEditorTextRepresentationHelper instanceof DefaultEditorTextRepresentationHelper) { fontsChanged = true; myEditor.getColorsScheme().getFontPreferences().copyTo(myFontPreferences); ((DefaultEditorTextRepresentationHelper) myEditorTextRepresentationHelper) .clearSymbolWidthCache(); myPainter.reinit(); } if ((myUseSoftWraps ^ softWrapsUsedBefore) || (tabWidthBefore >= 0 && myTabWidth != tabWidthBefore) || fontsChanged) { myApplianceManager.reset(); myDeferredFoldRegions.clear(); myStorage.removeAll(); myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); } }
private void paintSelectionOnFirstSoftWrapLineIfNecessary( Graphics2D g, int columnStart, float xStart, float xEnd, int y) { VisualPosition selectionStartPosition = myEditor.getSelectionModel().getSelectionStartPosition(); VisualPosition selectionEndPosition = myEditor.getSelectionModel().getSelectionEndPosition(); int visualLine = myView.yToVisualLine(y); if (selectionStartPosition.equals(selectionEndPosition) || visualLine < selectionStartPosition.line || visualLine > selectionEndPosition.line || visualLine == selectionEndPosition.line && selectionEndPosition.column <= columnStart) { return; } float startX = selectionStartPosition.line == visualLine && selectionStartPosition.column > columnStart ? myView.visualPositionToXY(selectionStartPosition).x : xStart; float endX = selectionEndPosition.line == visualLine ? myView.visualPositionToXY(selectionEndPosition).x : xEnd; paintBackground( g, myEditor.getColorsScheme().getColor(EditorColors.SELECTION_BACKGROUND_COLOR), startX, y, endX - startX); }
private void paintVirtualSelectionIfNecessary( Graphics2D g, Map<Integer, Couple<Integer>> virtualSelectionMap, int columnStart, float xStart, float xEnd, int y) { int visualLine = myView.yToVisualLine(y); Couple<Integer> selectionRange = virtualSelectionMap.get(visualLine); if (selectionRange == null || selectionRange.second <= columnStart) return; float startX = selectionRange.first <= columnStart ? xStart : myView.visualPositionToXY(new VisualPosition(visualLine, selectionRange.first)).x; float endX = Math.min( xEnd, myView.visualPositionToXY(new VisualPosition(visualLine, selectionRange.second)).x); paintBackground( g, myEditor.getColorsScheme().getColor(EditorColors.SELECTION_BACKGROUND_COLOR), startX, y, endX - startX); }
private boolean paintPlaceholderText(Graphics2D g) { CharSequence hintText = myEditor.getPlaceholder(); EditorComponentImpl editorComponent = myEditor.getContentComponent(); if (myDocument.getTextLength() > 0 || hintText == null || hintText.length() == 0 || KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == editorComponent && !myEditor.getShowPlaceholderWhenFocused()) { return false; } hintText = SwingUtilities.layoutCompoundLabel( g.getFontMetrics(), hintText.toString(), null, 0, 0, 0, 0, editorComponent.getBounds(), new Rectangle(), new Rectangle(), 0); g.setColor(myEditor.getFoldingModel().getPlaceholderAttributes().getForegroundColor()); g.setFont(myEditor.getColorsScheme().getFont(EditorFontType.PLAIN)); g.drawString(hintText.toString(), 0, myView.getAscent()); return true; }
public SoftWrapModelImpl(@NotNull EditorImpl editor) { myEditor = editor; myStorage = new SoftWrapsStorage(); myPainter = new CompositeSoftWrapPainter(editor); myEditorTextRepresentationHelper = new DefaultEditorTextRepresentationHelper(editor); myDataMapper = new CachingSoftWrapDataMapper(editor, myStorage); myApplianceManager = new SoftWrapApplianceManager(myStorage, editor, myPainter, myDataMapper); myVisualSizeManager = new SoftWrapAwareVisualSizeManager(myPainter); myApplianceManager.addListener(myVisualSizeManager); myApplianceManager.addListener( new SoftWrapAwareDocumentParsingListenerAdapter() { @Override public void recalculationEnds() { for (SoftWrapChangeListener listener : mySoftWrapListeners) { listener.recalculationEnds(); } } }); myUseSoftWraps = areSoftWrapsEnabledInEditor(); myEditor.getColorsScheme().getFontPreferences().copyTo(myFontPreferences); editor.addPropertyChangeListener(this, this); myApplianceManager.addListener(myDataMapper); }
private void paintBackground(Graphics2D g, Color color, float x, int y, float width) { if (width <= 0 || color == null || color.equals(myEditor.getColorsScheme().getDefaultBackground()) || color.equals(myEditor.getBackgroundColor())) return; g.setColor(color); g.fillRect((int) x, y, (int) width, myView.getLineHeight()); }
private void paintCaret(Graphics2D g_) { EditorImpl.CaretRectangle[] locations = myEditor.getCaretLocations(true); if (locations == null) return; Graphics2D g = IdeBackgroundUtil.getOriginalGraphics(g_); int lineHeight = myView.getLineHeight(); EditorSettings settings = myEditor.getSettings(); Color caretColor = myEditor.getColorsScheme().getColor(EditorColors.CARET_COLOR); if (caretColor == null) caretColor = new JBColor(CARET_DARK, CARET_LIGHT); g.setColor(caretColor); for (EditorImpl.CaretRectangle location : locations) { int x = location.myPoint.x; int y = location.myPoint.y; Caret caret = location.myCaret; boolean isRtl = location.myIsRtl; if (myEditor.isInsertMode() != settings.isBlockCursor()) { int lineWidth = JBUI.scale(settings.getLineCursorWidth()); g.fillRect(x, y, lineWidth, lineHeight); if (myDocument.getTextLength() > 0 && caret != null && !myView.getLineLayout(caret.getLogicalPosition().line).isLtr()) { g.fillPolygon( new int[] { isRtl ? x + lineWidth : x, isRtl ? x + lineWidth - CARET_DIRECTION_MARK_SIZE : x + CARET_DIRECTION_MARK_SIZE, isRtl ? x + lineWidth : x }, new int[] {y, y, y + CARET_DIRECTION_MARK_SIZE}, 3); } } else { int width = location.myWidth; int startX = Math.max(0, isRtl ? x - width : x); g.fillRect(startX, y, width, lineHeight - 1); if (myDocument.getTextLength() > 0 && caret != null) { int targetVisualColumn = caret.getVisualPosition().column; for (VisualLineFragmentsIterator.Fragment fragment : VisualLineFragmentsIterator.create(myView, caret.getVisualLineStart(), false)) { int startVisualColumn = fragment.getStartVisualColumn(); int endVisualColumn = fragment.getEndVisualColumn(); if (startVisualColumn < targetVisualColumn && endVisualColumn > targetVisualColumn || startVisualColumn == targetVisualColumn && !isRtl || endVisualColumn == targetVisualColumn && isRtl) { g.setColor(ColorUtil.isDark(caretColor) ? CARET_LIGHT : CARET_DARK); fragment.draw( g, startX, y + myView.getAscent(), targetVisualColumn - startVisualColumn - (isRtl ? 1 : 0), targetVisualColumn - startVisualColumn + (isRtl ? 0 : 1)); break; } } } } } }
private void paintRightMargin(Graphics g, Rectangle clip) { EditorSettings settings = myEditor.getSettings(); Color rightMargin = myEditor.getColorsScheme().getColor(EditorColors.RIGHT_MARGIN_COLOR); if (!settings.isRightMarginShown() || rightMargin == null) return; int x = settings.getRightMargin(myEditor.getProject()) * myView.getPlainSpaceWidth(); g.setColor(rightMargin); UIUtil.drawLine(g, x, clip.y, x, clip.y + clip.height); }
public TextAttributes getTextAttributes() { if (myTextAttributes == null) { myTextAttributes = new TextAttributes(); myTextAttributes.setBackgroundColor( myEditor.getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR)); } return myTextAttributes; }
private void paintWhitespace( Graphics2D g, CharSequence text, float x, int y, int start, int end, EditorImpl.LineWhitespacePaintingStrategy whitespacePaintingStrategy, VisualLineFragmentsIterator.Fragment fragment) { g.setColor(myEditor.getColorsScheme().getColor(EditorColors.WHITESPACES_COLOR)); boolean isRtl = fragment.isRtl(); int baseStartOffset = fragment.getStartOffset(); int startOffset = isRtl ? baseStartOffset - start : baseStartOffset + start; for (int i = start; i < end; i++) { int charOffset = isRtl ? baseStartOffset - i - 1 : baseStartOffset + i; char c = text.charAt(charOffset); if (" \t\u3000".indexOf(c) >= 0 && whitespacePaintingStrategy.showWhitespaceAtOffset(charOffset)) { int startX = (int) fragment.offsetToX( x, startOffset, isRtl ? baseStartOffset - i : baseStartOffset + i); int endX = (int) fragment.offsetToX( x, startOffset, isRtl ? baseStartOffset - i - 1 : baseStartOffset + i + 1); if (c == ' ') { g.fillRect((startX + endX) / 2, y, 1, 1); } else if (c == '\t') { endX -= myView.getPlainSpaceWidth() / 4; int height = myView.getCharHeight(); int halfHeight = height / 2; int mid = y - halfHeight; int top = y - height; UIUtil.drawLine(g, startX, mid, endX, mid); UIUtil.drawLine(g, endX, y, endX, top); g.fillPolygon( new int[] {endX - halfHeight, endX - halfHeight, endX}, new int[] {y, y - height, y - halfHeight}, 3); } else if (c == '\u3000') { // ideographic space final int charHeight = myView.getCharHeight(); g.drawRect(startX + 2, y - charHeight, endX - startX - 4, charHeight); } } } }
private void paintComposedTextDecoration(Graphics2D g) { TextRange composedTextRange = myEditor.getComposedTextRange(); if (composedTextRange != null) { Point p1 = myView.offsetToXY( Math.min(composedTextRange.getStartOffset(), myDocument.getTextLength()), true, false); Point p2 = myView.offsetToXY( Math.min(composedTextRange.getEndOffset(), myDocument.getTextLength()), false, true); int y = p1.y + myView.getAscent() + 1; g.setStroke(IME_COMPOSED_TEXT_UNDERLINE_STROKE); g.setColor(myEditor.getColorsScheme().getDefaultForeground()); UIUtil.drawLine(g, p1.x, y, p2.x, y); } }
private void paintLineMarkerSeparator(RangeHighlighter marker, Rectangle clip, Graphics g) { Color separatorColor = marker.getLineSeparatorColor(); LineSeparatorRenderer lineSeparatorRenderer = marker.getLineSeparatorRenderer(); if (separatorColor == null && lineSeparatorRenderer == null) { return; } int line = myDocument.getLineNumber( marker.getLineSeparatorPlacement() == SeparatorPlacement.TOP ? marker.getStartOffset() : marker.getEndOffset()); int visualLine = myView.logicalToVisualPosition( new LogicalPosition( line + (marker.getLineSeparatorPlacement() == SeparatorPlacement.TOP ? 0 : 1), 0), false) .line; int y = myView.visualLineToY(visualLine) - 1; int endShift = clip.x + clip.width; EditorSettings settings = myEditor.getSettings(); if (settings.isRightMarginShown() && myEditor.getColorsScheme().getColor(EditorColors.RIGHT_MARGIN_COLOR) != null) { endShift = Math.min( endShift, settings.getRightMargin(myEditor.getProject()) * myView.getPlainSpaceWidth()); } g.setColor(separatorColor); if (lineSeparatorRenderer != null) { lineSeparatorRenderer.drawLine(g, 0, endShift, y); } else { UIUtil.drawLine(g, 0, y, endShift, y); } }
public void refreshSettings() { myFoldTextAttributes = myEditor.getColorsScheme().getAttributes(EditorColors.FOLDED_TEXT_ATTRIBUTES); }