private void getNearestHighlighters( MarkupModelEx markupModel, MouseEvent e, final double width, final Collection<RangeHighlighter> nearest) { if (0 > e.getX() || e.getX() >= width) return; int startOffset = yPositionToOffset(e.getY() - getMinHeight(), true); int endOffset = yPositionToOffset(e.getY() + getMinHeight(), false); markupModel.processHighlightsOverlappingWith( startOffset, endOffset, new Processor<RangeHighlighterEx>() { public boolean process(RangeHighlighterEx highlighter) { if (highlighter.getErrorStripeMarkColor() != null) nearest.add(highlighter); return true; } }); }
private void drawMarkup( final Graphics g, final int width, int startOffset, int endOffset, MarkupModelEx markup) { final Queue<PositionedStripe> thinEnds = new PriorityQueue<PositionedStripe>( 5, new Comparator<PositionedStripe>() { public int compare(PositionedStripe o1, PositionedStripe o2) { return o1.yEnd - o2.yEnd; } }); final Queue<PositionedStripe> wideEnds = new PriorityQueue<PositionedStripe>( 5, new Comparator<PositionedStripe>() { public int compare(PositionedStripe o1, PositionedStripe o2) { return o1.yEnd - o2.yEnd; } }); // sorted by layer final List<PositionedStripe> thinStripes = new ArrayList<PositionedStripe>(); final List<PositionedStripe> wideStripes = new ArrayList<PositionedStripe>(); final int[] thinYStart = new int[1]; // in range 0..yStart all spots are drawn final int[] wideYStart = new int[1]; // in range 0..yStart all spots are drawn markup.processHighlightsOverlappingWith( startOffset, endOffset, new Processor<RangeHighlighterEx>() { public boolean process(RangeHighlighterEx highlighter) { Color color = highlighter.getErrorStripeMarkColor(); if (color == null) return true; boolean isThin = highlighter.isThinErrorStripeMark(); int[] yStart = isThin ? thinYStart : wideYStart; List<PositionedStripe> stripes = isThin ? thinStripes : wideStripes; Queue<PositionedStripe> ends = isThin ? thinEnds : wideEnds; ProperTextRange range = offsetToYPosition(highlighter.getStartOffset(), highlighter.getEndOffset()); final int ys = range.getStartOffset(); int ye = range.getEndOffset(); if (ye - ys < getMinHeight()) ye = ys + getMinHeight(); yStart[0] = drawStripesEndingBefore(ys, ends, stripes, g, width, yStart[0]); final int layer = highlighter.getLayer(); PositionedStripe stripe = null; int i; for (i = 0; i < stripes.size(); i++) { PositionedStripe s = stripes.get(i); if (s.layer == layer) { stripe = s; break; } if (s.layer < layer) { break; } } if (stripe == null) { // started new stripe, draw previous above if (yStart[0] != ys) { if (!stripes.isEmpty()) { PositionedStripe top = stripes.get(0); drawSpot(g, width, top.thin, yStart[0], ys, top.color, true, true); } yStart[0] = ys; } stripe = new PositionedStripe(color, ys, ye, isThin, layer); stripes.add(i, stripe); ends.offer(stripe); } else { // key changed, reinsert into queue if (stripe.yEnd != ye) { ends.remove(stripe); stripe.yEnd = ye; ends.offer(stripe); } } return true; } }); drawStripesEndingBefore(Integer.MAX_VALUE, thinEnds, thinStripes, g, width, thinYStart[0]); drawStripesEndingBefore(Integer.MAX_VALUE, wideEnds, wideStripes, g, width, wideYStart[0]); }