You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2010/09/09 21:53:19 UTC
svn commit: r995559 -
/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin2.java
Author: gbrown
Date: Thu Sep 9 19:53:19 2010
New Revision: 995559
URL: http://svn.apache.org/viewvc?rev=995559&view=rev
Log:
TextAreaSkin2 updates.
Modified:
pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin2.java
Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin2.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin2.java?rev=995559&r1=995558&r2=995559&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin2.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin2.java Thu Sep 9 19:53:19 2010
@@ -57,6 +57,19 @@ import org.apache.pivot.wtk.Visual;
public class TextAreaSkin2 extends ComponentSkin implements TextArea2.Skin,
TextAreaListener2, TextAreaContentListener2, TextAreaSelectionListener2 {
/**
+ * Class representing a row of text within a paragraph.
+ */
+ public static class Row {
+ public final GlyphVector glyphVector;
+ public final int offset;
+
+ public Row(GlyphVector glyphVector, int offset) {
+ this.glyphVector = glyphVector;
+ this.offset = offset;
+ }
+ }
+
+ /**
* Paragraph view.
*/
public class ParagraphView implements Visual, TextArea2.ParagraphListener {
@@ -70,7 +83,7 @@ public class TextAreaSkin2 extends Compo
private int breakWidth = Integer.MAX_VALUE;
private boolean valid = false;
- private ArrayList<GlyphVector> glyphVectors = new ArrayList<GlyphVector>();
+ private ArrayList<Row> rows = new ArrayList<Row>();
public ParagraphView(TextArea2.Paragraph paragraph) {
this.paragraph = paragraph;
@@ -119,7 +132,7 @@ public class TextAreaSkin2 extends Compo
// TODO Paint text using selection color when appropriate
- int n = glyphVectors.getLength();
+ int n = rows.getLength();
if (n > 0) {
FontRenderContext fontRenderContext = Platform.getFontRenderContext();
@@ -128,9 +141,9 @@ public class TextAreaSkin2 extends Compo
float y = 0;
for (int i = 0; i < n; i++) {
- GlyphVector glyphVector = glyphVectors.get(i);
+ Row row = rows.get(i);
- Rectangle2D textBounds = glyphVector.getLogicalBounds();
+ Rectangle2D textBounds = row.glyphVector.getLogicalBounds();
float lineWidth = (float)textBounds.getWidth();
float x = 0;
@@ -151,7 +164,7 @@ public class TextAreaSkin2 extends Compo
}
}
- graphics.drawGlyphVector(glyphVector, x, y + ascent);
+ graphics.drawGlyphVector(row.glyphVector, x, y + ascent);
y += textBounds.getHeight();
}
@@ -166,7 +179,7 @@ public class TextAreaSkin2 extends Compo
// TODO Validate from invalid offset rather than 0
if (!valid) {
- glyphVectors = new ArrayList<GlyphVector>();
+ rows = new ArrayList<Row>();
width = 0;
height = 0;
@@ -228,39 +241,117 @@ public class TextAreaSkin2 extends Compo
CharSequenceCharacterIterator line =
new CharSequenceCharacterIterator(characters, start, end, start);
GlyphVector glyphVector = font.createGlyphVector(fontRenderContext, line);
- glyphVectors.add(glyphVector);
+ rows.add(new Row(glyphVector, start));
Rectangle2D textBounds = glyphVector.getLogicalBounds();
width = Math.max(width, (float)textBounds.getWidth());
height += textBounds.getHeight();
}
+ public int getInsertionPoint(int x, int y) {
+ FontRenderContext fontRenderContext = Platform.getFontRenderContext();
+ LineMetrics lm = font.getLineMetrics("", fontRenderContext);
+ float lineHeight = lm.getAscent() + lm.getDescent();
+
+ int i = (int)Math.floor((float)y / lineHeight);
+
+ return getRowInsertionPoint(i, x);
+ }
+
+ public int getNextInsertionPoint(int x, int from, TextArea2.ScrollDirection direction) {
+ // Identify the row that contains the from index
+ int n = rows.getLength();
+ int i;
+ if (from == -1) {
+ i = (direction == TextArea2.ScrollDirection.DOWN) ? -1 : n;
+ } else {
+ i = getRowIndex(from);
+ }
+
+ // Move to the next or previous row
+ if (direction == TextArea2.ScrollDirection.DOWN) {
+ i++;
+ } else {
+ i--;
+ }
+
+ return getRowInsertionPoint(i, x);
+ }
+
+ private int getRowInsertionPoint(int rowIndex, float x) {
+ Row row = rows.get(rowIndex);
+
+ Rectangle2D glyphVectorBounds = row.glyphVector.getLogicalBounds();
+ float rowWidth = (float)glyphVectorBounds.getWidth();
+
+ // Translate x to glyph vector coordinates
+ x -= (width - rowWidth);
+
+ int index;
+ if (x < 0) {
+ index = 0;
+ } else if (x > rowWidth) {
+ index = row.glyphVector.getNumGlyphs();
+ } else {
+ index = 0;
+ int n = row.glyphVector.getNumGlyphs();
+
+ while (index < n) {
+ Shape glyphBounds = row.glyphVector.getGlyphLogicalBounds(index);
+ Rectangle2D glyphBounds2D = glyphBounds.getBounds2D();
+ System.out.println(glyphBounds2D);
+
+ if (glyphBounds2D.contains(x, glyphBounds2D.getY())) {
+ // Determine the bias; if the user clicks on the right half of the
+ // character; select the next character
+ if (x - glyphBounds2D.getX() > glyphBounds2D.getWidth() / 2
+ && index < n - 1) {
+ index++;
+ }
+
+ break;
+ }
+
+ index++;
+ }
+ }
+
+ return index + row.offset;
+ }
+
+ public int getRowIndex(int index) {
+ int rowIndex = rows.getLength() - 1;
+ Row row = rows.get(rowIndex);
+
+ while (row.offset > index) {
+ row = rows.get(--rowIndex);
+ }
+
+ return rowIndex;
+ }
+
+ public int getRowCount() {
+ return rows.getLength();
+ }
+
public Bounds getCharacterBounds(int index) {
Bounds characterBounds = null;
CharSequence characters = paragraph.getCharacters();
int characterCount = characters.length();
- int lineIndex = glyphVectors.getLength() - 1;
- GlyphVector glyphVector = glyphVectors.get(lineIndex);
+ int rowIndex = rows.getLength() - 1;
+ Row row = rows.get(rowIndex);
int x, width;
if (index == characterCount) {
// This is the terminator character
- Rectangle2D glyphVectorBounds = glyphVector.getLogicalBounds();
+ Rectangle2D glyphVectorBounds = row.glyphVector.getLogicalBounds();
x = (int)Math.floor(glyphVectorBounds.getWidth());
width = PARAGRAPH_TERMINATOR_WIDTH;
-
} else {
// This is a visible character
- int lineOffset = characterCount - glyphVector.getNumGlyphs();
-
- while (lineOffset > index) {
- glyphVector = glyphVectors.get(--lineIndex);
- lineOffset -= glyphVector.getNumGlyphs();
- }
-
- Shape glyphBounds = glyphVector.getGlyphLogicalBounds(index - lineOffset);
+ Shape glyphBounds = row.glyphVector.getGlyphLogicalBounds(index - row.offset);
Rectangle2D glyphBounds2D = glyphBounds.getBounds2D();
x = (int)Math.floor(glyphBounds2D.getX());
@@ -271,7 +362,7 @@ public class TextAreaSkin2 extends Compo
LineMetrics lm = font.getLineMetrics("", fontRenderContext);
float lineHeight = lm.getAscent() + lm.getDescent();
- characterBounds = new Bounds(x, (int)Math.floor(lineIndex * lineHeight),
+ characterBounds = new Bounds(x, (int)Math.floor(rowIndex * lineHeight),
width, (int)Math.ceil(lineHeight));
return characterBounds;
@@ -552,32 +643,92 @@ public class TextAreaSkin2 extends Compo
&& backgroundColor.getTransparency() == Transparency.OPAQUE);
}
+ @Override
public int getInsertionPoint(int x, int y) {
- // TODO
- return -1;
+ int index = -1;
+
+ for (int i = 0, n = paragraphViews.getLength(); i < n; i++) {
+ ParagraphView paragraphView = paragraphViews.get(i);
+ Bounds paragraphViewBounds = new Bounds(paragraphView.x, paragraphView.y,
+ paragraphView.getWidth(), paragraphView.getHeight());
+
+ if (y >= paragraphViewBounds.y
+ && y < paragraphViewBounds.y + paragraphViewBounds.height) {
+ index = paragraphView.getInsertionPoint(x - paragraphView.x, y - paragraphView.y)
+ + paragraphView.paragraph.getOffset();
+ break;
+ }
+ }
+
+ return index;
}
+ @Override
public int getNextInsertionPoint(int x, int from, TextArea2.ScrollDirection direction) {
- // TODO
- return -1;
+ int index = -1;
+
+ if (from == -1) {
+ int i = (direction == TextArea2.ScrollDirection.DOWN) ?
+ 0 : paragraphViews.getLength() - 1;
+ ParagraphView paragraphView = paragraphViews.get(i);
+ index = paragraphView.getNextInsertionPoint(x - paragraphView.x, -1, direction);
+
+ if (index != -1) {
+ index += paragraphView.paragraph.getOffset();
+ }
+ } else {
+ TextArea2 textArea = (TextArea2)getComponent();
+ int i = textArea.getParagraphAt(index);
+
+ ParagraphView paragraphView = paragraphViews.get(i);
+ index = paragraphView.getNextInsertionPoint(x - paragraphView.x,
+ from - paragraphView.paragraph.getOffset(), direction);
+
+ if (index == -1) {
+ // Move to the next or previous paragraph view
+ if (direction == TextArea2.ScrollDirection.DOWN) {
+ paragraphView = (i < paragraphViews.getLength() - 1) ? paragraphViews.get(i + 1) : null;
+ } else {
+ paragraphView = (i > 0) ? paragraphViews.get(i - 1) : null;
+ }
+
+ if (paragraphView != null) {
+ index = paragraphView.getNextInsertionPoint(x - paragraphView.x, -1, direction);
+ }
+ }
+
+ if (index != -1) {
+ index += paragraphView.paragraph.getOffset();
+ }
+ }
+
+ return index;
}
+ @Override
public int getRowIndex(int index) {
- // TODO
- return -1;
+ TextArea2 textArea = (TextArea2)getComponent();
+ ParagraphView paragraphView = paragraphViews.get(textArea.getParagraphAt(index));
+
+ return paragraphView.getRowIndex(index - paragraphView.paragraph.getOffset());
}
+ @Override
public int getRowCount() {
- // TODO
- return 0;
+ int rowCount = 0;
+
+ for (ParagraphView paragraphView : paragraphViews) {
+ rowCount += paragraphView.getRowCount();
+ }
+
+ return rowCount;
}
public Bounds getCharacterBounds(int index) {
TextArea2 textArea = (TextArea2)getComponent();
- int paragraphIndex = textArea.getParagraphAt(index);
- ParagraphView paragraphView = paragraphViews.get(paragraphIndex);
- Bounds characterBounds = paragraphView.getCharacterBounds(index -
- paragraphView.paragraph.getOffset());
+ ParagraphView paragraphView = paragraphViews.get(textArea.getParagraphAt(index));
+ Bounds characterBounds = paragraphView.getCharacterBounds(index
+ - paragraphView.paragraph.getOffset());
return new Bounds(characterBounds.x + paragraphView.x,
characterBounds.y + paragraphView.y,