@Override
 protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
   int shift = isMirrored() ? -9 : 9;
   g.translate(shift, 0);
   super.paintThumb(g, c, thumbBounds);
   g.translate(-shift, 0);
 }
 @Override
 public void drawChars(
     @NotNull Graphics g,
     @NotNull char[] data,
     int start,
     int end,
     int x,
     int y,
     Color color,
     FontInfo fontInfo) {
   g.setFont(fontInfo.getFont());
   g.setColor(color);
   g.drawChars(data, start, end - start, x, y);
 }
  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);
  }
    @Override
    protected void paintTrack(Graphics g, JComponent c, Rectangle bounds) {
      g.setColor(TRACK_BACKGROUND);
      g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);

      g.setColor(TRACK_BORDER);
      int border = isMirrored() ? bounds.x + bounds.width - 1 : bounds.x;
      g.drawLine(border, bounds.y, border, bounds.y + bounds.height);

      ((ApplicationImpl) ApplicationManager.getApplication()).editorPaintStart();

      try {
        Rectangle clipBounds = g.getClipBounds();
        repaint(g, ERROR_ICON_WIDTH - 1, clipBounds);
      } finally {
        ((ApplicationImpl) ApplicationManager.getApplication()).editorPaintFinish();
      }
    }
    private void drawSpot(
        Graphics g,
        int width,
        boolean thinErrorStripeMark,
        int yStart,
        int yEnd,
        Color color,
        boolean drawTopDecoration,
        boolean drawBottomDecoration) {
      int x = isMirrored() ? 3 : 5;
      int paintWidth = width;
      if (thinErrorStripeMark) {
        paintWidth /= 2;
        paintWidth += 1;
        x = isMirrored() ? width + 2 : 0;
      }
      if (color == null) return;
      g.setColor(color);
      g.fillRect(x + 1, yStart, paintWidth - 2, yEnd - yStart + 1);

      Color brighter = color.brighter();
      g.setColor(brighter);
      // left decoration
      UIUtil.drawLine(g, x, yStart, x, yEnd /* - 1*/);
      if (drawTopDecoration) {
        // top decoration
        UIUtil.drawLine(g, x + 1, yStart, x + paintWidth - 2, yStart);
      }
      Color darker = ColorUtil.shift(color, 0.75);

      g.setColor(darker);
      if (drawBottomDecoration) {
        // bottom decoration
        UIUtil.drawLine(
            g,
            x + 1,
            yEnd /* - 1*/,
            x + paintWidth - 2,
            yEnd /* - 1*/); // large bottom to let overwrite by hl below
      }
      // right decoration
      UIUtil.drawLine(g, x + paintWidth - 2, yStart, x + paintWidth - 2, yEnd /* - 1*/);
    }
    @Override
    public void paint(Graphics g) {
      ((ApplicationImpl) ApplicationManager.getApplication()).editorPaintStart();

      final Rectangle bounds = getBounds();

      g.setColor(ButtonlessScrollBarUI.TRACK_BACKGROUND);
      g.fillRect(0, 0, bounds.width, bounds.height);

      g.setColor(ButtonlessScrollBarUI.TRACK_BORDER);
      g.drawLine(0, 0, 0, bounds.height);

      try {
        if (myErrorStripeRenderer != null) {
          myErrorStripeRenderer.paint(
              this, g, new Rectangle(5, 2, ERROR_ICON_WIDTH, ERROR_ICON_HEIGHT));
        }
      } finally {
        ((ApplicationImpl) ApplicationManager.getApplication()).editorPaintFinish();
      }
    }
  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);
    }
  }
Exemple #8
0
        @Override
        @SuppressWarnings({"AssignmentToForLoopParameter"})
        public void paint(
            @NotNull Editor editor, @NotNull RangeHighlighter highlighter, @NotNull Graphics g) {
          int startOffset = highlighter.getStartOffset();
          final Document doc = highlighter.getDocument();
          if (startOffset >= doc.getTextLength()) return;

          final int endOffset = highlighter.getEndOffset();
          final int endLine = doc.getLineNumber(endOffset);

          int off;
          int startLine = doc.getLineNumber(startOffset);
          IndentGuideDescriptor descriptor =
              editor.getIndentsModel().getDescriptor(startLine, endLine);

          final CharSequence chars = doc.getCharsSequence();
          do {
            int start = doc.getLineStartOffset(startLine);
            int end = doc.getLineEndOffset(startLine);
            off = CharArrayUtil.shiftForward(chars, start, end, " \t");
            startLine--;
          } while (startLine > 1 && off < doc.getTextLength() && chars.charAt(off) == '\n');

          final VisualPosition startPosition = editor.offsetToVisualPosition(off);
          int indentColumn = startPosition.column;

          // It's considered that indent guide can cross not only white space but comments, javadocs
          // etc. Hence, there is a possible
          // case that the first indent guide line is, say, single-line comment where comment
          // symbols ('//') are located at the first
          // visual column. We need to calculate correct indent guide column then.
          int lineShift = 1;
          if (indentColumn <= 0 && descriptor != null) {
            indentColumn = descriptor.indentLevel;
            lineShift = 0;
          }
          if (indentColumn <= 0) return;

          final FoldingModel foldingModel = editor.getFoldingModel();
          if (foldingModel.isOffsetCollapsed(off)) return;

          final FoldRegion headerRegion =
              foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(doc.getLineNumber(off)));
          final FoldRegion tailRegion =
              foldingModel.getCollapsedRegionAtOffset(
                  doc.getLineStartOffset(doc.getLineNumber(endOffset)));

          if (tailRegion != null && tailRegion == headerRegion) return;

          final boolean selected;
          final IndentGuideDescriptor guide = editor.getIndentsModel().getCaretIndentGuide();
          if (guide != null) {
            final CaretModel caretModel = editor.getCaretModel();
            final int caretOffset = caretModel.getOffset();
            selected =
                caretOffset >= off
                    && caretOffset < endOffset
                    && caretModel.getLogicalPosition().column == indentColumn;
          } else {
            selected = false;
          }

          Point start =
              editor.visualPositionToXY(
                  new VisualPosition(startPosition.line + lineShift, indentColumn));
          final VisualPosition endPosition = editor.offsetToVisualPosition(endOffset);
          Point end =
              editor.visualPositionToXY(new VisualPosition(endPosition.line, endPosition.column));
          int maxY = end.y;
          if (endPosition.line == editor.offsetToVisualPosition(doc.getTextLength()).line) {
            maxY += editor.getLineHeight();
          }

          Rectangle clip = g.getClipBounds();
          if (clip != null) {
            if (clip.y >= maxY || clip.y + clip.height <= start.y) {
              return;
            }
            maxY = Math.min(maxY, clip.y + clip.height);
          }

          final EditorColorsScheme scheme = editor.getColorsScheme();
          g.setColor(
              selected
                  ? scheme.getColor(EditorColors.SELECTED_INDENT_GUIDE_COLOR)
                  : scheme.getColor(EditorColors.INDENT_GUIDE_COLOR));

          // There is a possible case that indent line intersects soft wrap-introduced text.
          // Example:
          //     this is a long line <soft-wrap>
          // that| is soft-wrapped
          //     |
          //     | <- vertical indent
          //
          // Also it's possible that no additional intersections are added because of soft wrap:
          //     this is a long line <soft-wrap>
          //     |   that is soft-wrapped
          //     |
          //     | <- vertical indent
          // We want to use the following approach then:
          //     1. Show only active indent if it crosses soft wrap-introduced text;
          //     2. Show indent as is if it doesn't intersect with soft wrap-introduced text;
          if (selected) {
            g.drawLine(start.x + 2, start.y, start.x + 2, maxY);
          } else {
            int y = start.y;
            int newY = start.y;
            SoftWrapModel softWrapModel = editor.getSoftWrapModel();
            int lineHeight = editor.getLineHeight();
            for (int i = Math.max(0, startLine + lineShift); i < endLine && newY < maxY; i++) {
              List<? extends SoftWrap> softWraps = softWrapModel.getSoftWrapsForLine(i);
              int logicalLineHeight = softWraps.size() * lineHeight;
              if (i > startLine + lineShift) {
                logicalLineHeight +=
                    lineHeight; // We assume that initial 'y' value points just below the target
                // line.
              }
              if (!softWraps.isEmpty() && softWraps.get(0).getIndentInColumns() < indentColumn) {
                if (y < newY
                    || i
                        > startLine
                            + lineShift) { // There is a possible case that soft wrap is located on
                  // indent start line.
                  g.drawLine(start.x + 2, y, start.x + 2, newY + lineHeight);
                }
                newY += logicalLineHeight;
                y = newY;
              } else {
                newY += logicalLineHeight;
              }

              FoldRegion foldRegion =
                  foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(i));
              if (foldRegion != null && foldRegion.getEndOffset() < doc.getTextLength()) {
                i = doc.getLineNumber(foldRegion.getEndOffset());
              }
            }

            if (y < maxY) {
              g.drawLine(start.x + 2, y, start.x + 2, maxY);
            }
          }
        }