@Override protected void paintLine(int line, int y, int lineheight, GC gc, Display display) { int widgetLine = JFaceTextUtil.modelLineToWidgetLine(getParentRuler().getTextViewer(), line); // get the corresponding line number and background color for this column String text = ""; Color bgColor = null; if (line < indexedLineNumbersList.size()) { bgColor = linesToColorMapping.get(line); List<IndexedLineNumber> curLine = indexedLineNumbersList.get(line); for (IndexedLineNumber lineNumber : curLine) { if (lineNumber.getColumnIndex() == columnIndex) { text = createDisplayString(lineNumber.getNumber()); } } } // get line indentation int[] indentations = null; try { indentations = getIndentations(); } catch (Exception e) { LOGGER.error("Could not get unified column line indentation!", e); } // calculate proper positioning and draw number if (indentations != null) { int indentation = indentations[text.length()]; int baselineBias = getBaselineBias(gc, widgetLine); if (bgColor != null) { gc.setBackground(bgColor); gc.drawString(text, indentation, y + baselineBias, false); } else { gc.drawString(text, indentation, y + baselineBias, true); } } }
@Override public void paintControl(PaintEvent e) { if (inDraw || styledText == null || styledText.isDisposed()) { return; } try { inDraw = true; boolean showIndentGuide = this.indentGuide.getShowIndentGuide(); if (!showIndentGuide) { return; } int xOffset = styledText.getHorizontalPixel(); int yOffset = styledText.getTopPixel(); // Important: call all to cache the new values (instead of doing all inside the or below). boolean styledTextContentChanged = getStyledTextContentChangedAndStoreNew(); boolean clientAreaChanged = getClientAreaChangedAndStoreNew(); boolean charCountChanged = getCharCountChangedAndStoreNew(); boolean tabWidthChanged = getTabWidthChangedAndStoreNew(); boolean redrawAll = styledTextContentChanged || clientAreaChanged || charCountChanged || tabWidthChanged || xOffset != lastXOffset || yOffset != lastYOffset; StyledTextContent currentContent = this.content; if (currClientArea == null || currClientArea.width < 5 || currClientArea.height < 5 || currCharCount < 1 || currentContent == null || currTabWidth <= 0) { return; } lastXOffset = xOffset; lastYOffset = yOffset; int topIndex; try { topIndex = JFaceTextUtil.getPartialTopIndex(styledText); } catch (IllegalArgumentException e1) { // Just silence it... // java.lang.IllegalArgumentException: Index out of bounds // at org.eclipse.swt.SWT.error(SWT.java:4458) // at org.eclipse.swt.SWT.error(SWT.java:4392) // at org.eclipse.swt.SWT.error(SWT.java:4363) // at org.eclipse.swt.custom.StyledText.getOffsetAtLine(StyledText.java:4405) // at org.eclipse.jface.text.JFaceTextUtil.getPartialTopIndex(JFaceTextUtil.java:103) // at // org.python.pydev.shared_ui.editor.VerticalIndentGuidesPainter.paintControl(VerticalIndentGuidesPainter.java:93) return; } int bottomIndex = JFaceTextUtil.getPartialBottomIndex(styledText); if (redrawAll) { this.lineToVerticalLinesToDraw = this.indentGuide.computeVerticalLinesToDrawInRegion(styledText, topIndex, bottomIndex); // This is a bit unfortunate: when something changes, we may have to repaint out of the // clipping // region, but even setting the clipping region (e.gc.setClipping), the clipping region may // still // be unchanged (because the system said that it only wants to repaint some specific area // already // and we can't make it bigger -- so, what's left for us is asking for a repaint of the full // area // in this case). if (askFullRedraw) { askFullRedraw = false; if (Math.abs(currClientArea.height - e.gc.getClipping().height) > 40) { // Only do it if the difference is really high (some decorations make it usually a bit // lower than // the actual client area -- usually around 14 in my tests, but make it a bit higher as // the usual // difference when a redraw is needed is pretty high). RunInUiThread.async( new Runnable() { @Override public void run() { StyledText s = styledText; if (s != null && !s.isDisposed()) { s.redraw(); } } }); } else { } } } if (this.lineToVerticalLinesToDraw != null) { try (AutoCloseable temp = configGC(e.gc)) { Collection<List<VerticalLinesToDraw>> values = lineToVerticalLinesToDraw.values(); for (List<VerticalLinesToDraw> list : values) { for (VerticalLinesToDraw verticalLinesToDraw : list) { verticalLinesToDraw.drawLine(e.gc); } } } } } catch (Exception e1) { Log.log(e1); } finally { inDraw = false; } }