use of org.apache.pivot.wtk.Bounds 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);
}
use of org.apache.pivot.wtk.Bounds in project pivot by apache.
the class TextPaneSkinParagraphView method getNextInsertionPoint.
@Override
public int getNextInsertionPoint(int x, int from, TextPane.ScrollDirection direction) {
int offset = -1;
int n = rows.getLength();
if (n == 0 && from == -1) {
// There are no rows; select the terminator character
offset = 0;
} else {
int i;
if (from == -1) {
i = (direction == TextPane.ScrollDirection.DOWN) ? -1 : rows.getLength();
} else {
// Find the row that contains offset
if (from == getCharacterCount() - 1) {
i = rows.getLength() - 1;
} else {
i = 0;
while (i < n) {
Row row = rows.get(i);
RowSegment firstNodeSegment = row.rowSegments.get(0);
RowSegment lastNodeSegment = row.rowSegments.get(row.rowSegments.getLength() - 1);
if (from >= firstNodeSegment.offset && from < lastNodeSegment.offset + lastNodeSegment.nodeView.getCharacterCount()) {
break;
}
i++;
}
}
}
// Move to the next or previous row
if (direction == TextPane.ScrollDirection.DOWN) {
i++;
} else {
i--;
}
if (i >= 0 && i < n) {
// Find the node view that contains x and get the insertion point from it
Row row = rows.get(i);
for (RowSegment segment : row.rowSegments) {
Bounds bounds = segment.nodeView.getBounds();
if (x >= bounds.x && x < bounds.x + bounds.width) {
offset = segment.nodeView.getNextInsertionPoint(x - segment.nodeView.getX(), -1, direction) + segment.offset;
break;
}
}
if (offset == -1) {
// No node view contained the x position; move to the end of the row
RowSegment lastNodeSegment = row.rowSegments.get(row.rowSegments.getLength() - 1);
offset = lastNodeSegment.offset + lastNodeSegment.nodeView.getCharacterCount();
if (offset < getCharacterCount() - 1) {
offset--;
}
}
}
}
return offset;
}
use of org.apache.pivot.wtk.Bounds in project pivot by apache.
the class GridPaneSkin method getRowBounds.
@Override
public Bounds getRowBounds(int row) {
GridPane gridPane = (GridPane) getComponent();
GridPane.RowSequence rows = gridPane.getRows();
int rowCount = rows.getLength();
if (row < 0 || row >= rowCount) {
throw new IndexOutOfBoundsException(String.valueOf(row));
}
int rowY = padding.top;
for (int i = 0; i < row; i++) {
rowY += cellHeight + verticalSpacing;
}
return new Bounds(0, rowY, getWidth(), cellHeight);
}
use of org.apache.pivot.wtk.Bounds in project pivot by apache.
the class GridPaneSkin method getColumnBounds.
@Override
public Bounds getColumnBounds(int column) {
GridPane gridPane = (GridPane) getComponent();
int columnCount = gridPane.getColumnCount();
if (column < 0 || column >= columnCount) {
throw new IndexOutOfBoundsException(String.valueOf(column));
}
int columnX = padding.left;
for (int j = 0; j < column; j++) {
columnX += cellWidth + horizontalSpacing;
}
return new Bounds(columnX, 0, cellWidth, getHeight());
}
use of org.apache.pivot.wtk.Bounds in project pivot by apache.
the class TextPaneSkinTextNodeView method paint.
@Override
public void paint(Graphics2D graphics) {
if (textLayout != null) {
TextPane textPane = (TextPane) getTextPaneSkin().getComponent();
FontRenderContext fontRenderContext = Platform.getFontRenderContext();
Font effectiveFont = getEffectiveFont();
LineMetrics lm = effectiveFont.getLineMetrics("", fontRenderContext);
float ascent = lm.getAscent() + lm.getLeading();
graphics.setFont(effectiveFont);
int selectionStart = textPane.getSelectionStart();
int selectionLength = textPane.getSelectionLength();
Span selectionRange = new Span(selectionStart, selectionStart + selectionLength - 1);
int documentOffset = getDocumentOffset();
Span characterRange = new Span(documentOffset, documentOffset + getCharacterCount() - 1);
int width = getWidth();
int height = getHeight();
if (selectionLength > 0 && characterRange.intersects(selectionRange)) {
// Determine the selection bounds
int x0;
if (selectionRange.start > characterRange.start) {
Bounds leadingSelectionBounds = getCharacterBounds(selectionRange.start - documentOffset);
x0 = leadingSelectionBounds.x;
} else {
x0 = 0;
}
int x1;
if (selectionRange.end < characterRange.end) {
Bounds trailingSelectionBounds = getCharacterBounds(selectionRange.end - documentOffset);
x1 = trailingSelectionBounds.x + trailingSelectionBounds.width;
} else {
x1 = width;
}
int selectionWidth = x1 - x0;
Rectangle selection = new Rectangle(x0, 0, selectionWidth, height);
// Paint the unselected text
Area unselectedArea = new Area();
unselectedArea.add(new Area(new Rectangle(0, 0, width, height)));
unselectedArea.subtract(new Area(selection));
Graphics2D textGraphics = (Graphics2D) graphics.create();
textGraphics.setColor(getEffectiveForegroundColor());
textGraphics.clip(unselectedArea);
textLayout.draw(textGraphics, 0, ascent);
textGraphics.dispose();
// Paint the selection
Color selectionColor;
if (textPane.isFocused()) {
selectionColor = getTextPaneSkin().getSelectionColor();
} else {
selectionColor = getTextPaneSkin().getInactiveSelectionColor();
}
Graphics2D selectedTextGraphics = (Graphics2D) graphics.create();
selectedTextGraphics.setColor(textPane.isFocused() && textPane.isEditable() ? selectionColor : getTextPaneSkin().getInactiveSelectionColor());
selectedTextGraphics.clip(selection.getBounds());
textLayout.draw(selectedTextGraphics, 0, ascent);
selectedTextGraphics.dispose();
} else {
// Draw the text
graphics.setColor(getEffectiveForegroundColor());
textLayout.draw(graphics, 0, ascent);
}
}
}
Aggregations