void pairDraw(GC gc, StyledRegion sr, int start, int end) { if (start > text.getCharCount() || end > text.getCharCount()) return; if (gc != null) { Point left = text.getLocationAtOffset(start); Point right = text.getLocationAtOffset(end); if (sr != null) { if (highlightStyle == HLS_XOR) { int resultColor = sr.fore ^ cm.getColor(text.getBackground()); if (text.getLineAtOffset(text.getCaretOffset()) == text.getLineAtOffset(start) && horzCross && horzCrossColor != null && ((StyledRegion) horzCrossColor).bback) resultColor = sr.fore ^ ((StyledRegion) horzCrossColor).back; Color color = cm.getColor(sr.bfore, resultColor); gc.setBackground(color); gc.setXORMode(true); gc.fillRectangle(left.x, left.y, right.x - left.x, gc.getFontMetrics().getHeight()); } else if (highlightStyle == HLS_OUTLINE) { Color color = cm.getColor(sr.bfore, sr.fore); gc.setForeground(color); gc.drawRectangle( left.x, left.y, right.x - left.x - 1, gc.getFontMetrics().getHeight() - 1); } else if (highlightStyle == HLS_OUTLINE2) { Color color = cm.getColor(sr.bfore, sr.fore); gc.setForeground(color); gc.setLineWidth(2); gc.drawRectangle( left.x + 1, left.y + 1, right.x - left.x - 2, gc.getFontMetrics().getHeight() - 2); } } } else { text.redrawRange(start, end - start, true); } }
void drawLine(int lno) { if (lno < 0 || lno >= text.getLineCount()) return; int y = text.getLocationAtOffset(text.getOffsetAtLine(lno)).y; int height = 0; if (text.getLineCount() > lno + 1) height = text.getLocationAtOffset(text.getOffsetAtLine(lno + 1)).y - y; else height = text.getLocationAtOffset(text.getCharCount()).y + text.getLineHeight(); int width = text.getClientArea().width + text.getHorizontalPixel(); text.redraw(0, y, width, height, false); }
void redrawFrom(int lno) { if (lno < 0 || lno >= text.getLineCount()) return; int y = text.getLocationAtOffset(text.getOffsetAtLine(lno)).y; int height = text.getClientArea().height - y; int width = text.getClientArea().width + text.getHorizontalPixel(); text.redraw(0, y, width, height, false); }
/** * Scrolls the containing editor to the given offset of the contained editor * * @param editor * @param scrollTo text offset in the embedded editor that should be revealed */ public void revealSelection(ContainedEditorManager editor, int scrollTo) { StyledText containedStyledText = (StyledText) editor.getAdapter(StyledText.class); // this progression determines the location of the offset in the coordinate system // of the containing styledText Point containedLoc = containedStyledText.getLocationAtOffset(scrollTo); Point displayLoc = containedStyledText.toDisplay(containedLoc); Point containingLoc = styledText.toControl(displayLoc); // next, we determine if this location is in the visible area. Point containingSize = styledText.getSize(); Rectangle containingBounds = new Rectangle(0, 0, containingSize.x, containingSize.y); if (!containingBounds.contains(containingLoc)) { // pad a little to the left and a little bit down containingLoc.x -= 50; containingLoc.y += 100; // if not, then perform a scroll. styledText.setTopPixel(styledText.getTopPixel() + containingLoc.y - containingSize.y); // do the same for horizontal styledText.setHorizontalPixel(styledText.getHorizontalPixel() + containingLoc.x); } paint(ContainingEditor.EMBEDDED_REPAINT); }
/** * Hook to compute the menu location if the focus widget is a styled text widget. * * @param text the styled text widget that has the focus * @return a widget relative position of the menu to pop up or <code>null</code> if now position * inside the widget can be computed */ protected Point computeMenuLocation(StyledText text) { int offset = text.getCaretOffset(); Point result = text.getLocationAtOffset(offset); result.y += text.getLineHeight(offset); if (!text.getClientArea().contains(result)) return null; return result; }
/** * Convert mouse screen coordinates to a <code>StyledText</code> offset. * * @param x screen X-coordinate * @param y screen Y-coordinate * @param absolute if <code>true</code>, coordinates are expected to be absolute screen * coordinates * @return text offset * @see StyledText#getOffsetAtLocation() */ private int getOffsetAtLocation(int x, int y, boolean absolute) { StyledText textWidget = fViewer.getTextWidget(); StyledTextContent content = textWidget.getContent(); Point location; if (absolute) { location = textWidget.toControl(x, y); } else { location = new Point(x, y); } int line = (textWidget.getTopPixel() + location.y) / textWidget.getLineHeight(); if (line >= content.getLineCount()) { return content.getCharCount(); } int lineOffset = content.getOffsetAtLine(line); String lineText = content.getLine(line); Point endOfLine = textWidget.getLocationAtOffset(lineOffset + lineText.length()); if (location.x >= endOfLine.x) { return lineOffset + lineText.length(); } try { return textWidget.getOffsetAtLocation(location); } catch (IllegalArgumentException iae) { // we are expecting this return -1; } }
protected void refreshCaret(StyledText text, int newOffset) { if (newOffset != -1) { Point newPos = text.getLocationAtOffset(newOffset); int newHeight = text.getLineHeight(newOffset); text.redraw(newPos.x, newPos.y, CARET_WIDTH, newHeight, false); } }
/** * triggers a repaint of the styled text of the containing editor whenever the text has changed. * * <p>The repaint will update the positions of all of the embedded controls. * * <p>XXX this method is being called too many times. It is being called more than once after each * cursor change. I need to take a good look at this and determine exactly when and where it * should be called */ public void paint(int reason) { if (reason != TEXT_CHANGE && reason != ContainingEditor.EMBEDDED_REPAINT) { return; } List<ContainedEditorManager> toRemove = new LinkedList<ContainedEditorManager>(); for (final ContainedEditorManager c : editorPositionMap.keySet()) { Position model = editorPositionMap.get(c); if (!model.isDeleted()) { // map from the model to the actual display (takes into account folding) Position projected = modelToProjected(model); if (projected == null) { // position is hidden behind folding c.getControl().setVisible(false); } else { try { Point location = styledText.getLocationAtOffset(projected.offset); location.x += ContainingEditor.MARGIN; location.y += ContainingEditor.MARGIN; c.getControl().setVisible(true); c.getControl().setLocation(location); } catch (IllegalArgumentException e) { EmbeddedCALPlugin.logError("Error repainting", e); } } } else { toRemove.add(c); } } for (final ContainedEditorManager c : toRemove) { removeControl(c, true); } styledText.getParent().getParent().redraw(); }
/** * Draw the given line range. * * @param gc * @param startLine first line number * @param endLine last line number (inclusive) * @param x the X-coordinate of the drawing range * @param w the width of the drawing range */ private void drawLineRange(GC gc, int startLine, int endLine, int x, int w) { final int viewPortWidth = fTextWidget.getClientArea().width; for (int line = startLine; line <= endLine; line++) { int lineOffset = fTextWidget.getOffsetAtLine(line); // line end offset including line delimiter int lineEndOffset; if (line < fTextWidget.getLineCount() - 1) { lineEndOffset = fTextWidget.getOffsetAtLine(line + 1); } else { lineEndOffset = fTextWidget.getCharCount(); } // line length excluding line delimiter int lineLength = lineEndOffset - lineOffset; while (lineLength > 0) { char c = fTextWidget.getTextRange(lineOffset + lineLength - 1, 1).charAt(0); if (c != '\r' && c != '\n') { break; } --lineLength; } // compute coordinates of last character on line Point endOfLine = fTextWidget.getLocationAtOffset(lineOffset + lineLength); if (x - endOfLine.x > viewPortWidth) { // line is not visible continue; } // Y-coordinate of line int y = fTextWidget.getLinePixel(line); // compute first visible char offset int startOffset; try { startOffset = fTextWidget.getOffsetAtLocation(new Point(x, y)) - 1; if (startOffset - 2 <= lineOffset) { startOffset = lineOffset; } } catch (IllegalArgumentException iae) { startOffset = lineOffset; } // compute last visible char offset int endOffset; if (x + w >= endOfLine.x) { // line end is visible endOffset = lineEndOffset; } else { try { endOffset = fTextWidget.getOffsetAtLocation(new Point(x + w - 1, y)) + 1; if (endOffset + 2 >= lineEndOffset) { endOffset = lineEndOffset; } } catch (IllegalArgumentException iae) { endOffset = lineEndOffset; } } // draw character range if (endOffset > startOffset) { drawCharRange(gc, startOffset, endOffset); } } }
protected void setLastRulerMouseLocation(ISourceViewer viewer, int line) { // set last mouse activity in order to get the correct context menu if (fCompositeRuler != null) { StyledText st = viewer.getTextWidget(); if (st != null && !st.isDisposed()) { if (viewer instanceof ITextViewerExtension5) { int widgetLine = ((ITextViewerExtension5) viewer).modelLine2WidgetLine(line); Point loc = st.getLocationAtOffset(st.getOffsetAtLine(widgetLine)); fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y); } else if (viewer instanceof TextViewer) { // TODO remove once TextViewer implements the extension int widgetLine = ((TextViewer) viewer).modelLine2WidgetLine(line); Point loc = st.getLocationAtOffset(st.getOffsetAtLine(widgetLine)); fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y); } } } }
/* * (non-Javadoc) * * @see * org.eclipse.jface.fieldassist.IControlContentAdapter#getInsertionBounds(org.eclipse * .swt.widgets.Control) */ @Override public Rectangle getInsertionBounds(Control control) { StyledText text = (StyledText) control; Point caretOrigin = text.getLocationAtOffset(text.getCaretOffset()); return new Rectangle( caretOrigin.x + text.getClientArea().x, caretOrigin.y + text.getClientArea().y + 3, 1, text.getLineHeight()); }
/** * Draw string at widget offset. * * @param gc * @param offset the widget offset * @param s the string to be drawn * @param fg the foreground color */ private void draw(GC gc, int offset, String s, Color fg) { // Compute baseline delta (see // https://bugs.eclipse.org/bugs/show_bug.cgi?id=165640) int baseline = fTextWidget.getBaseline(offset); FontMetrics fontMetrics = gc.getFontMetrics(); int fontBaseline = fontMetrics.getAscent() + fontMetrics.getLeading(); int baslineDelta = baseline - fontBaseline; Point pos = fTextWidget.getLocationAtOffset(offset); gc.setForeground(fg); gc.drawString(s, pos.x, pos.y + baslineDelta, true); }
private final void draw(final GC gc, final int offset, final int length) { if (gc != null) { Point left = mTextWidget.getLocationAtOffset(offset); Point right = mTextWidget.getLocationAtOffset(offset + length); Color color = mMismatch ? mMismatchColor : mColor; if (mBox) { gc.setForeground(color); int x = left.x; int y = left.y; int w = right.x - left.x - 1; int h = gc.getFontMetrics().getHeight(); gc.drawRectangle(x, y, w, h); } else { gc.setForeground(mDefaultColor); gc.setBackground(color); gc.drawString(mTextWidget.getTextRange(offset, 1), left.x, left.y, false); } } else { mTextWidget.redrawRange(offset, length, true); } }
/* * @see org.eclipse.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(org.eclipse.swt.graphics.GC, org.eclipse.swt.custom.StyledText, int, int, org.eclipse.swt.graphics.Color) */ public void draw( Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { if (annotation instanceof ProjectionAnnotation) { ProjectionAnnotation projectionAnnotation = (ProjectionAnnotation) annotation; if (projectionAnnotation.isCollapsed()) { if (gc != null) { StyledTextContent content = textWidget.getContent(); int line = content.getLineAtOffset(offset); int lineStart = content.getOffsetAtLine(line); String text = content.getLine(line); int lineLength = text == null ? 0 : text.length(); int lineEnd = lineStart + lineLength; Point p = textWidget.getLocationAtOffset(lineEnd); Color c = gc.getForeground(); gc.setForeground(color); FontMetrics metrics = gc.getFontMetrics(); // baseline: where the dots are drawn int baseline = textWidget.getBaseline(offset); // descent: number of pixels that the box extends over baseline int descent = Math.min(2, textWidget.getLineHeight(offset) - baseline); // ascent: so much does the box stand up from baseline int ascent = metrics.getAscent(); // leading: free space from line top to box upper line int leading = baseline - ascent; // height: height of the box int height = ascent + descent; int width = metrics.getAverageCharWidth(); gc.drawRectangle(p.x, p.y + leading, width, height); int third = width / 3; int dotsVertical = p.y + baseline - 1; gc.drawPoint(p.x + third, dotsVertical); gc.drawPoint(p.x + width - third, dotsVertical); gc.setForeground(c); } else { textWidget.redrawRange(offset, length, true); } } } }
private Point computeWordStart() { ITextSelection selection = (ITextSelection) fEditor.getSelectionProvider().getSelection(); IRegion textRegion = CWordFinder.findWord(fEditor.getViewer().getDocument(), selection.getOffset()); if (textRegion == null) return null; IRegion widgetRegion = modelRange2WidgetRange(textRegion); if (widgetRegion == null) return null; int start = widgetRegion.getOffset(); StyledText styledText = fEditor.getViewer().getTextWidget(); Point result = styledText.getLocationAtOffset(start); result.y += styledText.getLineHeight(start); if (!styledText.getClientArea().contains(result)) return null; return result; }
private Rectangle getLineRectangle(Position position) { if (position == null) { return null; } // if the position that is about to be drawn was deleted then we can't if (position.isDeleted()) { return null; } int widgetOffset = 0; if (fViewer instanceof ITextViewerExtension5) { ITextViewerExtension5 extension = (ITextViewerExtension5) fViewer; widgetOffset = extension.modelOffset2WidgetOffset(position.getOffset()); if (widgetOffset == -1) { return null; } } else { IRegion visible = fViewer.getVisibleRegion(); widgetOffset = position.getOffset() - visible.getOffset(); if (widgetOffset < 0 || visible.getLength() < widgetOffset) { return null; } } StyledText textWidget = fViewer.getTextWidget(); // check for https://bugs.eclipse.org/bugs/show_bug.cgi?id=64898 // this is a guard against the symptoms but not the actual solution if (0 <= widgetOffset && widgetOffset <= textWidget.getCharCount()) { Point upperLeft = textWidget.getLocationAtOffset(widgetOffset); int width = textWidget.getClientArea().width + textWidget.getHorizontalPixel(); int height = textWidget.getLineHeight(widgetOffset); return new Rectangle(0, upperLeft.y, width, height); } return null; }
// modified version from TextViewer private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) { StyledText styledText = textViewer.getTextWidget(); IDocument document = textViewer.getDocument(); if (document == null) return -1; try { int widgetOffset = styledText.getOffsetAtLocation(new Point(x, y)); Point p = styledText.getLocationAtOffset(widgetOffset); if (p.x > x) widgetOffset--; if (textViewer instanceof ITextViewerExtension5) { ITextViewerExtension5 extension = (ITextViewerExtension5) textViewer; return extension.widgetOffset2ModelOffset(widgetOffset); } else { IRegion visibleRegion = textViewer.getVisibleRegion(); return widgetOffset + visibleRegion.getOffset(); } } catch (IllegalArgumentException e) { return -1; } }
/* * Adds a control at the given position */ private ContainedEditorManager addControl(int offset, int length) { // create the control propoerties ContainedEditorProperties props; try { // get the contents by reading from the editor at the given position ASTNode editorExpression = ContainedEditorProperties.toASTNode(doc.get(offset, length)); props = EditorManagerFactory.createProperties(editorExpression); } catch (BadLocationException e) { // something about the contents was bad, create an empty editor instead EmbeddedCALPlugin.logError( "Error trying to create ContainedEditorProperties: offset: " + offset + " length: " + length, e); props = new CALExpressionEditorProperties(); } ContainedEditorManager contained = EditorManagerFactory.createManager(props); if (contained.editorKind() == CALModuleEditorManager.EDITOR_KIND) { replaceModuleEditor((CALModuleEditorManager) contained); } contained.createControl(styledText, containingEditor); contained.initializeEditorContents(containingEditor); // determine the location of the contained editor Position projected = modelToProjected(new Position(offset, 0)); Point location = styledText.getLocationAtOffset(projected.offset); location.x += ContainingEditor.MARGIN; location.y += ContainingEditor.MARGIN; contained.setLocation(location); return contained; }