Search in sources :

Example 6 with Paragraph

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

the class TextPaneSkinParagraphView method getPreferredSize.

@Override
public Dimensions getPreferredSize(int breakWidth) {
    // Break the views into multiple rows
    Paragraph paragraph = (Paragraph) getNode();
    ArrayList<Row> rowsLocal = new ArrayList<>();
    int offset = 0;
    ParagraphChildLayouter layouter = new ParagraphChildLayouter();
    Row row = new Row();
    for (TextPaneSkinNodeView nodeView : this) {
        nodeView.layout(Math.max(breakWidth - (row.width + PARAGRAPH_TERMINATOR_WIDTH), 0));
        int nodeViewWidth = nodeView.getWidth();
        if (row.width + nodeViewWidth > breakWidth && row.width > 0) {
            // The view is too big to fit in the remaining space,
            // and it is not the only view in this row
            rowsLocal.add(row);
            layouter.endRow(row);
            row = new Row();
            row.width = 0;
        }
        // Add the view to the row
        RowSegment segment = new RowSegment(nodeView, offset);
        row.rowSegments.add(segment);
        layouter.startSegment(segment);
        offset += nodeView.getCharacterCount();
        row.width += nodeViewWidth;
        // If the view was split into multiple views, add them to their own rows
        nodeView = getNext(nodeView);
        while (nodeView != null) {
            rowsLocal.add(row);
            layouter.endRow(row);
            row = new Row();
            nodeView.layout(breakWidth);
            segment = new RowSegment(nodeView, offset);
            row.rowSegments.add(segment);
            layouter.startSegment(segment);
            offset += nodeView.getCharacterCount();
            row.width = nodeView.getWidth();
            nodeView = getNext(nodeView);
        }
    }
    // Add the last row
    if (row.rowSegments.getLength() > 0) {
        rowsLocal.add(row);
        layouter.endRow(row);
    }
    // calculate paragraph width and adjust for alignment
    layouter.end(paragraph, rowsLocal);
    // Recalculate terminator bounds
    FontRenderContext fontRenderContext = Platform.getFontRenderContext();
    LineMetrics lm = getTextPaneSkin().getFont().getLineMetrics("", 0, 0, fontRenderContext);
    int terminatorHeight = (int) Math.ceil(lm.getHeight());
    int terminatorY;
    if (getCharacterCount() == 1) {
        // The terminator is the only character in this paragraph
        terminatorY = 0;
    } else {
        terminatorY = layouter.rowY - terminatorHeight;
    }
    Bounds terminatorBoundsLocal = new Bounds(layouter.x, terminatorY, PARAGRAPH_TERMINATOR_WIDTH, terminatorHeight);
    // Ensure that the paragraph is visible even when empty
    layouter.paragraphWidth += terminatorBoundsLocal.width;
    int height = Math.max(layouter.rowY, terminatorBoundsLocal.height);
    return new Dimensions(layouter.paragraphWidth, height);
}
Also used : Bounds(org.apache.pivot.wtk.Bounds) ArrayList(org.apache.pivot.collections.ArrayList) Dimensions(org.apache.pivot.wtk.Dimensions) FontRenderContext(java.awt.font.FontRenderContext) LineMetrics(java.awt.font.LineMetrics) Paragraph(org.apache.pivot.wtk.text.Paragraph)

Example 7 with Paragraph

use of org.apache.pivot.wtk.text.Paragraph 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 8 with Paragraph

use of org.apache.pivot.wtk.text.Paragraph 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)

Example 9 with Paragraph

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

the class TextPaneDemo method applyAlignmentStyle.

private void applyAlignmentStyle(HorizontalAlignment horizontalAlignment) {
    Node node = textPane.getDocument().getDescendantAt(textPane.getSelectionStart());
    while (node != null && !(node instanceof Paragraph)) {
        node = node.getParent();
    }
    if (node != null) {
        Paragraph paragraph = (Paragraph) node;
        paragraph.setHorizontalAlignment(horizontalAlignment);
    }
}
Also used : Node(org.apache.pivot.wtk.text.Node) TextNode(org.apache.pivot.wtk.text.TextNode) Paragraph(org.apache.pivot.wtk.text.Paragraph)

Example 10 with Paragraph

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

the class TextPane method insertText.

public void insertText(String text, int index) {
    Utils.checkNull(text, "text");
    checkDocumentNull();
    if (selectionLength > 0) {
        delete(false);
    }
    if (document.getCharacterCount() == 0) {
        // the document is currently empty
        document.insert(new Paragraph(text), 0);
    } else {
        Node descendant = document.getDescendantAt(index);
        int offset = index - descendant.getDocumentOffset();
        if (descendant instanceof TextNode) {
            // The caret is positioned within an existing text node
            TextNode textNode = (TextNode) descendant;
            textNode.insertText(text, offset);
        } else if (descendant instanceof Paragraph) {
            // The caret is positioned on the paragraph terminator
            // so get to the bottom rightmost descendant and add there
            Paragraph paragraph = (Paragraph) descendant;
            Node node = getRightmostDescendant(paragraph);
            if (node instanceof TextNode) {
                // Insert the text into the existing node
                TextNode textNode = (TextNode) node;
                textNode.insertText(text, index - textNode.getDocumentOffset());
            } else if (node instanceof Element) {
                // Append a new text node
                Element element = (Element) node;
                element.add(new TextNode(text));
            } else {
                // The paragraph is currently empty
                paragraph.add(new TextNode(text));
            }
        } else {
            // The caret is positioned on a non-text character node; insert
            // the text into the descendant's parent
            Element parent = descendant.getParent();
            int elemIndex = parent.indexOf(descendant);
            parent.insert(new TextNode(text), elemIndex);
        }
    }
    // Set the selection start to the character following the insertion
    setSelection(index + text.length(), 0);
}
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) Paragraph(org.apache.pivot.wtk.text.Paragraph)

Aggregations

Paragraph (org.apache.pivot.wtk.text.Paragraph)11 TextNode (org.apache.pivot.wtk.text.TextNode)8 ComponentNode (org.apache.pivot.wtk.text.ComponentNode)6 ImageNode (org.apache.pivot.wtk.text.ImageNode)6 Node (org.apache.pivot.wtk.text.Node)6 Element (org.apache.pivot.wtk.text.Element)5 FontRenderContext (java.awt.font.FontRenderContext)3 Document (org.apache.pivot.wtk.text.Document)3 LineMetrics (java.awt.font.LineMetrics)2 Bounds (org.apache.pivot.wtk.Bounds)2 Dimensions (org.apache.pivot.wtk.Dimensions)2 TextPane (org.apache.pivot.wtk.TextPane)2 TextSpan (org.apache.pivot.wtk.text.TextSpan)2 Font (java.awt.Font)1 LineBreakMeasurer (java.awt.font.LineBreakMeasurer)1 TextLayout (java.awt.font.TextLayout)1 IOException (java.io.IOException)1 AttributedCharacterIterator (java.text.AttributedCharacterIterator)1 ArrayList (org.apache.pivot.collections.ArrayList)1 AttributedStringCharacterIterator (org.apache.pivot.text.AttributedStringCharacterIterator)1