Search in sources :

Example 1 with TextNode

use of org.apache.pivot.wtk.text.TextNode in project pivot by apache.

the class TextPane method addToText.

/**
 * Add the text from the given element (and its children) to the given buffer,
 * respecting the range of characters to be included.
 *
 * @param text The buffer we're building.
 * @param element The current element in the document.
 * @param includeSpan The range of text to be included (in document-relative
 * coordinates).
 */
private void addToText(StringBuilder text, Element element, Span includeSpan) {
    Span elementSpan = element.getDocumentSpan();
    Span elementIntersection = elementSpan.intersect(includeSpan);
    if (elementIntersection != null) {
        for (Node node : element) {
            if (node instanceof Element) {
                addToText(text, (Element) node, includeSpan);
            } else {
                Span nodeSpan = node.getDocumentSpan();
                Span nodeIntersection = nodeSpan.intersect(includeSpan);
                if (nodeIntersection != null) {
                    Span currentSpan = nodeIntersection.offset(-nodeSpan.start);
                    if (node instanceof TextNode) {
                        text.append(((TextNode) node).getCharacters(currentSpan));
                    } else if (node instanceof ComponentNode) {
                        text.append(((ComponentNode) node).getCharacters(currentSpan));
                    }
                // TODO: anything more that could/should be handled?
                // lists for instance???
                }
            }
        }
        if (element instanceof Paragraph && elementIntersection.end == elementSpan.end) {
            // TODO: unclear if this is included in the character count for a paragraph or not
            // or what that means for the intersection range above
            text.append('\n');
        }
    }
}
Also used : ImageNode(org.apache.pivot.wtk.text.ImageNode) ComponentNode(org.apache.pivot.wtk.text.ComponentNode) Node(org.apache.pivot.wtk.text.Node) TextNode(org.apache.pivot.wtk.text.TextNode) Element(org.apache.pivot.wtk.text.Element) TextNode(org.apache.pivot.wtk.text.TextNode) CharSpan(org.apache.pivot.text.CharSpan) TextSpan(org.apache.pivot.wtk.text.TextSpan) ComponentNode(org.apache.pivot.wtk.text.ComponentNode) Paragraph(org.apache.pivot.wtk.text.Paragraph)

Example 2 with TextNode

use of org.apache.pivot.wtk.text.TextNode in project pivot by apache.

the class TextPaneSkinTextNodeView method getPreferredSize.

@Override
public Dimensions getPreferredSize(int breakWidth) {
    TextNode textNode = (TextNode) getNode();
    Font effectiveFont = getEffectiveFont();
    // For now, just get the committed text
    if (textNode.getCharacterCount() == 0) /* && composedText == null || composedText doesn't impinge on this node */
    {
        Dimensions charSize = GraphicsUtilities.getAverageCharacterSize(effectiveFont);
        return new Dimensions(0, charSize.height);
    } else {
        FontRenderContext fontRenderContext = Platform.getFontRenderContext();
        // TODO: deal with composed text here
        AttributedCharacterIterator text = new AttributedStringCharacterIterator(textNode.getCharacters(), start, effectiveFont);
        // Note: we don't add the underline/strikethrough attributes here because
        // they shouldn't affect the sizing...
        TextLayout currentTextLayout;
        if (getTextPaneSkin().getWrapText()) {
            LineBreakMeasurer measurer = new LineBreakMeasurer(text, fontRenderContext);
            float wrappingWidth = (float) breakWidth;
            currentTextLayout = measurer.nextLayout(wrappingWidth);
        } else {
            // Not wrapping the text, then the width is of the whole thing
            currentTextLayout = new TextLayout(text, fontRenderContext);
        }
        return getTextSize(currentTextLayout);
    }
}
Also used : LineBreakMeasurer(java.awt.font.LineBreakMeasurer) Dimensions(org.apache.pivot.wtk.Dimensions) TextNode(org.apache.pivot.wtk.text.TextNode) FontRenderContext(java.awt.font.FontRenderContext) Font(java.awt.Font) AttributedCharacterIterator(java.text.AttributedCharacterIterator) AttributedStringCharacterIterator(org.apache.pivot.text.AttributedStringCharacterIterator) TextLayout(java.awt.font.TextLayout)

Example 3 with TextNode

use of org.apache.pivot.wtk.text.TextNode in project pivot by apache.

the class TextPaneSkinTextNodeView method childLayout.

@Override
protected void childLayout(int breakWidth) {
    TextNode textNode = (TextNode) getNode();
    textLayout = null;
    Font effectiveFont = getEffectiveFont();
    FontRenderContext fontRenderContext = Platform.getFontRenderContext();
    TextPane textPane = (TextPane) getTextPaneSkin().getComponent();
    AttributedStringCharacterIterator composedText = textPane.getComposedText();
    Element parent = textNode.getParent();
    // The calculations below really need to know if we're at the end of the paragraph
    // when composing text, so make sure we ignore intervening span or other nodes, but
    // also update the offset relative to the paragraph in the process.
    int relStart = start;
    if (parent != null && !(parent instanceof Paragraph)) {
        relStart += parent.getOffset();
        parent = parent.getParent();
    }
    int parentCount = parent == null ? 0 : parent.getCharacterCount();
    int selectionStart = textPane.getSelectionStart();
    int selectionLength = textPane.getSelectionLength();
    int documentOffset = textNode.getDocumentOffset();
    int charCount = textNode.getCharacterCount();
    boolean composedIntersects = false;
    if (composedText != null) {
        int composedTextBegin = composedText.getBeginIndex();
        int composedTextEnd = composedText.getEndIndex();
        int composedTextLength = composedTextEnd - composedTextBegin;
        /* exclusive - inclusive, so no +1 needed */
        // If this text node is at the end of a paragraph, increase the span by 1 for the newline
        Span ourSpan;
        if (parent instanceof Paragraph && charCount + relStart == parentCount - 1) {
            ourSpan = new Span(documentOffset + start, documentOffset + charCount);
        } else {
            ourSpan = new Span(documentOffset + start, documentOffset + charCount - 1);
        }
        // The "composed span" just encompasses the start position, because this is "phantom" text, so it exists between any two other "real" text positions.
        Span composedSpan = new Span(selectionStart + composedTextBegin);
        composedIntersects = composedSpan.intersects(ourSpan);
    }
    if (charCount == 0 && !composedIntersects) {
        Dimensions charSize = GraphicsUtilities.getAverageCharacterSize(effectiveFont);
        setSize(0, charSize.height);
        length = 0;
        next = null;
    } else {
        AttributedCharacterIterator text = null;
        boolean underlined = getEffectiveUnderline();
        boolean struckthrough = getEffectiveStrikethrough();
        if (composedText != null && composedIntersects) {
            int composedPos = selectionStart - documentOffset;
            if (composedPos == 0) {
                if (charCount - start == 0) {
                    text = composedText;
                } else {
                    AttributedStringCharacterIterator fullText = getCharIterator(textNode, start, charCount, effectiveFont);
                    // Note: only apply the underline and strikethrough to our text, not the composed text
                    fullText.addUnderlineAttribute(underlined);
                    fullText.addStrikethroughAttribute(struckthrough);
                    text = new CompositeIterator(composedText, fullText);
                }
            } else if (composedPos == charCount) {
                // Composed text is at the end
                AttributedStringCharacterIterator fullText = getCharIterator(textNode, start, charCount, effectiveFont);
                // Note: only apply the underline and strikethrough to our text, not the composed text
                fullText.addUnderlineAttribute(underlined);
                fullText.addStrikethroughAttribute(struckthrough);
                text = new CompositeIterator(fullText, composedText);
            } else {
                // Composed text is somewhere in the middle
                AttributedStringCharacterIterator leadingText = getCharIterator(textNode, start, composedPos, effectiveFont);
                leadingText.addUnderlineAttribute(underlined);
                leadingText.addStrikethroughAttribute(struckthrough);
                AttributedStringCharacterIterator trailingText = getCharIterator(textNode, composedPos, charCount, effectiveFont);
                trailingText.addUnderlineAttribute(underlined);
                trailingText.addStrikethroughAttribute(struckthrough);
                text = new CompositeIterator(leadingText, composedText, trailingText);
            }
        } else {
            AttributedStringCharacterIterator fullText = getCharIterator(textNode, start, charCount, effectiveFont);
            fullText.addUnderlineAttribute(underlined);
            fullText.addStrikethroughAttribute(struckthrough);
            text = fullText;
        }
        if (getTextPaneSkin().getWrapText()) {
            LineBreakMeasurer measurer = new LineBreakMeasurer(text, fontRenderContext);
            float wrappingWidth = (float) breakWidth;
            textLayout = measurer.nextLayout(wrappingWidth);
            length = textLayout.getCharacterCount();
            Dimensions size = getTextSize(textLayout);
            float advance = textLayout.getAdvance();
            setSize(size);
            if (start + measurer.getPosition() < textNode.getCharacterCount()) {
                next = new TextPaneSkinTextNodeView(getTextPaneSkin(), textNode, start + measurer.getPosition());
                next.setParent(getParent());
            } else {
                next = null;
            }
        } else {
            // Not wrapping the text, then the width is of the whole thing
            textLayout = new TextLayout(text, fontRenderContext);
            length = textLayout.getCharacterCount();
            Dimensions size = getTextSize(textLayout);
            float advance = textLayout.getAdvance();
            setSize(size);
            // set to null in case this node used to be broken across multiple,
            // but is no longer
            next = null;
        }
    }
}
Also used : CompositeIterator(org.apache.pivot.text.CompositeIterator) Element(org.apache.pivot.wtk.text.Element) LineBreakMeasurer(java.awt.font.LineBreakMeasurer) Dimensions(org.apache.pivot.wtk.Dimensions) TextNode(org.apache.pivot.wtk.text.TextNode) Span(org.apache.pivot.wtk.Span) TextSpan(org.apache.pivot.wtk.text.TextSpan) Font(java.awt.Font) AttributedStringCharacterIterator(org.apache.pivot.text.AttributedStringCharacterIterator) Paragraph(org.apache.pivot.wtk.text.Paragraph) AttributedCharacterIterator(java.text.AttributedCharacterIterator) TextLayout(java.awt.font.TextLayout) TextPane(org.apache.pivot.wtk.TextPane) FontRenderContext(java.awt.font.FontRenderContext)

Example 4 with TextNode

use of org.apache.pivot.wtk.text.TextNode in project pivot by apache.

the class TextPaneDemo method applyStyle.

private void applyStyle(Document document, Span selectionSpan, StyleApplicator styleApplicator) {
    // I can't apply the styles while iterating over the tree, because I
    // need to update the tree.
    // So first collect a list of all the nodes in the tree.
    List<Node> nodeList = new ArrayList<>();
    collectNodes(document, nodeList);
    final int selectionStart = textPane.getSelectionStart();
    final int selectionLength = textPane.getSelectionLength();
    for (Node node : nodeList) {
        if (node instanceof TextSpan) {
            TextSpan span = (TextSpan) node;
            int documentOffset = node.getDocumentOffset();
            int characterCount = node.getCharacterCount();
            Span textSpan = new Span(documentOffset, documentOffset + characterCount - 1);
            if (selectionSpan.intersects(textSpan)) {
                applyStyleToSpanNode(selectionSpan, styleApplicator, span, characterCount, textSpan);
            }
        }
        if (node instanceof org.apache.pivot.wtk.text.TextNode) {
            org.apache.pivot.wtk.text.TextNode textNode = (org.apache.pivot.wtk.text.TextNode) node;
            int documentOffset = node.getDocumentOffset();
            int characterCount = node.getCharacterCount();
            Span textSpan = new Span(documentOffset, documentOffset + characterCount - 1);
            if (selectionSpan.intersects(textSpan)) {
                applyStyleToTextNode(selectionSpan, styleApplicator, textNode, characterCount, textSpan);
            }
        }
    }
    // maintain the selected range
    textPane.setSelection(selectionStart, selectionLength);
}
Also used : TextNode(org.apache.pivot.wtk.text.TextNode) Node(org.apache.pivot.wtk.text.Node) TextNode(org.apache.pivot.wtk.text.TextNode) ArrayList(org.apache.pivot.collections.ArrayList) TextNode(org.apache.pivot.wtk.text.TextNode) Span(org.apache.pivot.wtk.Span) TextSpan(org.apache.pivot.wtk.text.TextSpan) TextSpan(org.apache.pivot.wtk.text.TextSpan) DesktopApplicationContext(org.apache.pivot.wtk.DesktopApplicationContext) ApplicationContext(org.apache.pivot.wtk.ApplicationContext)

Example 5 with TextNode

use of org.apache.pivot.wtk.text.TextNode in project pivot by apache.

the class HyperlinkButtonTest method startup.

@Override
public void startup(Display display, Map<String, String> properties) throws Exception {
    frame = new Frame();
    frame.setTitle("Hyperlink Button Test");
    frame.setPreferredSize(480, 360);
    HyperlinkButton button1 = new HyperlinkButton("http://pivot.apache.org");
    HyperlinkButton button2 = new HyperlinkButton("Apache website", "http://apache.org");
    TextPane textPane = new TextPane();
    Document document = new Document();
    TextNode text1 = new TextNode("Link to the Apache Pivot site: ");
    TextNode text2 = new TextNode("Main Apache Software Foundation website: ");
    ComponentNode compNode1 = new ComponentNode(button1);
    ComponentNode compNode2 = new ComponentNode(button2);
    Paragraph para1 = new Paragraph();
    para1.add(text1);
    document.add(para1);
    document.add(compNode1);
    Paragraph para2 = new Paragraph();
    para2.add(text2);
    document.add(para2);
    document.add(compNode2);
    ImageNode image1 = new ImageNode("/org/apache/pivot/tests/house.png");
    document.add(image1);
    textPane.setDocument(document);
    frame.setContent(textPane);
    frame.open(display);
}
Also used : Frame(org.apache.pivot.wtk.Frame) HyperlinkButton(org.apache.pivot.wtk.HyperlinkButton) TextPane(org.apache.pivot.wtk.TextPane) TextNode(org.apache.pivot.wtk.text.TextNode) ImageNode(org.apache.pivot.wtk.text.ImageNode) Document(org.apache.pivot.wtk.text.Document) ComponentNode(org.apache.pivot.wtk.text.ComponentNode) Paragraph(org.apache.pivot.wtk.text.Paragraph)

Aggregations

TextNode (org.apache.pivot.wtk.text.TextNode)11 Element (org.apache.pivot.wtk.text.Element)5 Node (org.apache.pivot.wtk.text.Node)4 Paragraph (org.apache.pivot.wtk.text.Paragraph)4 TextSpan (org.apache.pivot.wtk.text.TextSpan)4 ComponentNode (org.apache.pivot.wtk.text.ComponentNode)3 ImageNode (org.apache.pivot.wtk.text.ImageNode)3 Font (java.awt.Font)2 FontRenderContext (java.awt.font.FontRenderContext)2 LineBreakMeasurer (java.awt.font.LineBreakMeasurer)2 TextLayout (java.awt.font.TextLayout)2 AttributedCharacterIterator (java.text.AttributedCharacterIterator)2 AttributedStringCharacterIterator (org.apache.pivot.text.AttributedStringCharacterIterator)2 Dimensions (org.apache.pivot.wtk.Dimensions)2 Span (org.apache.pivot.wtk.Span)2 TextPane (org.apache.pivot.wtk.TextPane)2 ArrayList (org.apache.pivot.collections.ArrayList)1 CharSpan (org.apache.pivot.text.CharSpan)1 CompositeIterator (org.apache.pivot.text.CompositeIterator)1 ApplicationContext (org.apache.pivot.wtk.ApplicationContext)1