@Override public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) { int offs = -1; if (!isAllocationValid()) { Rectangle alloc = a.getBounds(); setSize(alloc.width, alloc.height); } // Get the child view for the line at (x,y), and ask it for the // specific offset. Rectangle alloc = getInsideAllocation(a); View v = getViewAtPoint((int) x, (int) y, alloc); if (v != null) { offs = v.viewToModel(x, y, alloc, bias); } // Code folding may have hidden the last line. If so, return the last // visible offset instead of the last offset. if (host.isCodeFoldingEnabled() && v == getView(getViewCount() - 1) && offs == v.getEndOffset() - 1) { offs = host.getLastVisibleOffset(); } return offs; }
/** * Determines the preferred span for this view along an axis. * * @param axis may be either View.X_AXIS or View.Y_AXIS * @return the span the view would like to be rendered into >= 0. Typically the view is told to * render into the span that is returned, although there is no guarantee. The parent may * choose to resize or break the view. * @exception IllegalArgumentException for an invalid axis */ @Override public float getPreferredSpan(int axis) { updateMetrics(); switch (axis) { case View.X_AXIS: float span = longLineWidth + getRhsCorrection(); // fudge factor if (host.getEOLMarkersVisible()) { span += metrics.charWidth('\u00B6'); } return span; case View.Y_AXIS: // We update lineHeight here as when this method is first // called, lineHeight isn't initialized. If we don't do it // here, we get no vertical scrollbar (as lineHeight==0). lineHeight = host != null ? host.getLineHeight() : lineHeight; // return getElement().getElementCount() * lineHeight; int visibleLineCount = getElement().getElementCount(); if (host.isCodeFoldingEnabled()) { visibleLineCount -= host.getFoldManager().getHiddenLineCount(); } return visibleLineCount * (float) lineHeight; default: throw new IllegalArgumentException("Invalid axis: " + axis); } }
/** {@inheritDoc} */ public int yForLineContaining(Rectangle alloc, int offs) throws BadLocationException { if (isAllocationValid()) { // TODO: make cached Y_AXIS offsets valid even with folding enabled // to speed this back up! Rectangle r = (Rectangle) modelToView(offs, alloc, Bias.Forward); if (r != null) { if (host.isCodeFoldingEnabled()) { int line = host.getLineOfOffset(offs); FoldManager fm = host.getFoldManager(); if (fm.isLineHidden(line)) { return -1; } } return r.y; } } return -1; }
/** * Determine the rectangle that represents the given line. * * @param a The region allocated for the view to render into * @param line The line number to find the region of. This must be a valid line number in the * model. */ protected Rectangle lineToRect(Shape a, int line) { Rectangle r = null; updateMetrics(); if (metrics != null) { Rectangle alloc = a.getBounds(); // NOTE: lineHeight is not initially set here, leading to the // current line not being highlighted when a document is first // opened. So, we set it here just in case. lineHeight = host != null ? host.getLineHeight() : lineHeight; if (host != null && host.isCodeFoldingEnabled()) { FoldManager fm = host.getFoldManager(); int hiddenCount = fm.getHiddenLineCountAbove(line); line -= hiddenCount; } r = new Rectangle(alloc.x, alloc.y + line * lineHeight, alloc.width, lineHeight); } return r; }
/** * Returns a token list for the <i>physical</i> line below the physical line containing the * specified offset into the document. Note that for this plain (non-wrapped) view, this is simply * the token list for the logical line below the line containing <code>offset</code>, since lines * are not wrapped. * * @param offset The offset in question. * @return A token list for the physical (and in this view, logical) line after this one. If * <code>offset</code> is in the last physical line in the document, <code>null</code> is * returned. */ public Token getTokenListForPhysicalLineBelow(int offset) { RSyntaxDocument document = (RSyntaxDocument) getDocument(); Element map = document.getDefaultRootElement(); int lineCount = map.getElementCount(); int line = map.getElementIndex(offset); if (!host.isCodeFoldingEnabled()) { if (line < lineCount - 1) { return document.getTokenListForLine(line + 1); } } else { FoldManager fm = host.getFoldManager(); line = fm.getVisibleLineBelow(line); if (line >= 0 && line < lineCount) { return document.getTokenListForLine(line); } } // int line = map.getElementIndex(offset); // int lineCount = map.getElementCount(); // if (line<lineCount-1) // return document.getTokenListForLine(line+1); return null; }
/** * Determines the preferred span for this view along an axis. This is implemented to provide the * superclass behavior after first making sure that the current font metrics are cached (for the * nested lines which use the metrics to determine the height of the potentially wrapped lines). * * @param axis may be either View.X_AXIS or View.Y_AXIS * @return the span the view would like to be rendered into. Typically the view is told to render * into the span that is returned, although there is no guarantee. The parent may choose to * resize or break the view. * @see View#getPreferredSpan */ public float getPreferredSpan(int axis) { updateMetrics(); float span = 0; if (axis == View.X_AXIS) { // Add EOL marker span = super.getPreferredSpan(axis); span += metrics.charWidth('\u00b6'); // metrics set in updateMetrics } else { span = super.getPreferredSpan(axis); host = (RSyntaxTextArea) getContainer(); if (host.isCodeFoldingEnabled()) { // TODO: Cache y-offsets again to speed this up // System.out.println("y-axis baby"); int lineCount = host.getLineCount(); FoldManager fm = host.getFoldManager(); for (int i = 0; i < lineCount; i++) { if (fm.isLineHidden(i)) { span -= getSpan(View.Y_AXIS, i); } } } } return span; }