/** * Calls layout() on the rootBox until the y-coordinate of a caret at the given offset converges, * i.e. is less than LAYOUT_TOLERANCE pixels from the last call. * * @param offset Offset around which we should lay out boxes. */ private void iterateLayout(int offset) { int repaintStart = Integer.MAX_VALUE; int repaintEnd = 0; Graphics g = this.hostComponent.createDefaultGraphics(); LayoutContext context = this.createLayoutContext(g); int layoutY = this.rootBox.getCaret(context, offset).getY(); while (true) { int oldLayoutY = layoutY; IntRange repaintRange = this.rootBox.layout(context, layoutY - LAYOUT_WINDOW / 2, layoutY + LAYOUT_WINDOW / 2); if (repaintRange != null) { repaintStart = Math.min(repaintStart, repaintRange.getStart()); repaintEnd = Math.max(repaintEnd, repaintRange.getEnd()); } layoutY = this.rootBox.getCaret(context, offset).getY(); if (Math.abs(layoutY - oldLayoutY) < LAYOUT_TOLERANCE) { break; } } g.dispose(); if (repaintStart < repaintEnd) { Rectangle viewport = this.hostComponent.getViewport(); if (repaintStart < viewport.getY() + viewport.getHeight() && repaintEnd > viewport.getY()) { int start = Math.max(repaintStart, viewport.getY()); int end = Math.min(repaintEnd, viewport.getY() + viewport.getHeight()); this.hostComponent.repaint(viewport.getX(), start, viewport.getWidth(), end - start); } } }
/** * Returns true if the given element or range is at least partially selected. * * @param vexWidget IVexWidget being tested. * @param elementOrRange Element or IntRange being tested. */ public static boolean elementOrRangeIsPartiallySelected( IVexWidget vexWidget, Object elementOrRange) { IntRange range = getInnerRange(elementOrRange); return range.getEnd() >= vexWidget.getSelectionStart() && range.getStart() <= vexWidget.getSelectionEnd(); }