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 2009/10/21 00:02:48 UTC
svn commit: r827814 - in /incubator/pivot/trunk:
core/src/org/apache/pivot/collections/ArrayList.java
wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java
Author: gbrown
Date: Tue Oct 20 22:02:48 2009
New Revision: 827814
URL: http://svn.apache.org/viewvc?rev=827814&view=rev
Log:
Update character hit detection in TextAreaSkin.
Modified:
incubator/pivot/trunk/core/src/org/apache/pivot/collections/ArrayList.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java
Modified: incubator/pivot/trunk/core/src/org/apache/pivot/collections/ArrayList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/collections/ArrayList.java?rev=827814&r1=827813&r2=827814&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/collections/ArrayList.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/collections/ArrayList.java Tue Oct 20 22:02:48 2009
@@ -571,8 +571,7 @@
}
@SuppressWarnings("unchecked")
- public static <T> int binarySearch(ArrayList<T> arrayList, T item,
- final Comparator<T> comparator) {
+ public static <T> int binarySearch(ArrayList<T> arrayList, T item, Comparator<T> comparator) {
if (arrayList == null
|| item == null
|| comparator == null) {
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java?rev=827814&r1=827813&r2=827814&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java Tue Oct 20 22:02:48 2009
@@ -21,13 +21,12 @@
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
+import java.awt.Shape;
import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.text.CharacterIterator;
-import java.util.Comparator;
import java.util.Iterator;
import org.apache.pivot.collections.ArrayList;
@@ -248,86 +247,10 @@
*/
public abstract class ElementView extends NodeView
implements Sequence<NodeView>, Iterable<NodeView>, ElementListener {
- /**
- * Null node view, used for binary searches.
- */
- private class NullNodeView extends NodeView {
- private int offset;
-
- public NullNodeView() {
- super(null);
- }
-
- @Override
- public int getOffset() {
- return offset;
- }
-
- protected void setOffset(int offset) {
- this.offset = offset;
- }
-
- @Override
- public NodeView getNext() {
- return null;
- }
-
- @Override
- public int getCharacterAt(int x, int y) {
- return -1;
- }
-
- @Override
- public Bounds getCharacterBounds(int offset) {
- return null;
- }
-
- @Override
- public void paint(Graphics2D graphics) {
- // No-op
- }
- }
-
- /**
- * Comparator used to perform binary searches on node views by location.
- */
- private class NodeViewLocationComparator implements Comparator<NodeView> {
- @Override
- public int compare(NodeView nodeView1, NodeView nodeView2) {
- int x1 = nodeView1.getX();
- int y1 = nodeView1.getY();
-
- int x2 = nodeView2.getX();
- int y2 = nodeView2.getY();
-
- int width = (x2 - x1);
-
- return (y1 * width + x1) - (y2 * width + x2);
- }
- }
-
- /**
- * Comparator used to perform binary searches on node views by offset.
- */
- private class NodeViewOffsetComparator implements Comparator<NodeView> {
- @Override
- public int compare(NodeView nodeView1, NodeView nodeView2) {
- int offset1 = nodeView1.getOffset();
- int offset2 = nodeView2.getOffset();
-
- return (offset1 - offset2);
- }
- }
-
private ArrayList<NodeView> nodeViews = new ArrayList<NodeView>();
- private NullNodeView nullNodeView = new NullNodeView();
- private NodeViewLocationComparator nodeViewLocationComparator = new NodeViewLocationComparator();
- private NodeViewOffsetComparator nodeViewOffsetComparator = new NodeViewOffsetComparator();
-
public ElementView(Element element) {
super(element);
-
}
@Override
@@ -453,65 +376,48 @@
@Override
public int getCharacterAt(int x, int y) {
- // Get the index of the node view at x, y
- nullNodeView.setLocation(x, y);
-
- int i = ArrayList.binarySearch(nodeViews, nullNodeView,
- nodeViewLocationComparator);
+ int offset = -1;
- if (i < 0) {
- i = -(i + 1) - 1;
- }
-
- // TODO i should never be less than 0 here? What about in getCharacterBounds()?
- int offset;
- if (i < 0) {
- offset = -1;
- } else {
- if (i < nodeViews.getLength()) {
- NodeView nodeView = nodeViews.get(i);
-
- // Adjust the x and y values
- x -= nodeView.getX();
- y -= nodeView.getY();
-
- offset = nodeView.getCharacterAt(x, y);
+ for (int i = 0, n = nodeViews.getLength(); i < n; i++) {
+ NodeView nodeView = nodeViews.get(i);
+ Bounds nodeViewBounds = nodeView.getBounds();
- // Adjust the offset
+ if (nodeViewBounds.contains(x, y)) {
Node node = nodeView.getNode();
- offset += node.getOffset();
- } else {
- // Return the character count of this node
- Node node = getNode();
- offset = node.getCharacterCount();
+ offset = nodeView.getCharacterAt(x - nodeView.getX(), y - nodeView.getY())
+ + node.getOffset();
+ break;
}
}
+ // TODO Return the node view length (not node character count), so we can
+ // append to the node?
+
return offset;
}
@Override
public Bounds getCharacterBounds(int offset) {
- // Get the index of the node view at offset
- nullNodeView.setOffset(offset);
-
- int i = ArrayList.binarySearch(nodeViews, nullNodeView,
- nodeViewOffsetComparator);
+ Bounds characterBounds = null;
- if (i < 0) {
- i = -(i + 1) - 1;
- }
-
- Bounds bounds = null;
- if (i < nodeViews.getLength()) {
+ for (int i = 0, n = nodeViews.getLength(); i < n; i++) {
NodeView nodeView = nodeViews.get(i);
+ int nodeViewOffset = nodeView.getOffset();
- offset -= nodeView.getOffset();
- bounds = nodeView.getCharacterBounds(offset);
- bounds = bounds.translate(nodeView.getX(), nodeView.getY());
+ // TODO This is wrong; we need to know the number of characters this view
+ // represents, not the length of its node
+ Node node = nodeView.getNode();
+ int characterCount = node.getCharacterCount();
+
+ if (offset >= nodeViewOffset
+ && offset < nodeViewOffset + characterCount) {
+ characterBounds = nodeView.getCharacterBounds(offset - nodeViewOffset);
+ characterBounds = characterBounds.translate(nodeView.getX(), nodeView.getY());
+ break;
+ }
}
- return bounds;
+ return characterBounds;
}
@Override
@@ -925,13 +831,15 @@
public int getCharacterAt(int x, int y) {
validate();
+ LineMetrics lm = font.getLineMetrics("", FONT_RENDER_CONTEXT);
+ float ascent = lm.getAscent();
+
int n = glyphVector.getNumGlyphs();
int i = 0;
while (i < n) {
- GlyphMetrics glyphMetrics = glyphVector.getGlyphMetrics(i++);
- Rectangle2D bounds2D = glyphMetrics.getBounds2D();
- if (bounds2D.contains(x, bounds2D.getY())) {
+ Shape glyphLogicalBounds = glyphVector.getGlyphLogicalBounds(i++);
+ if (glyphLogicalBounds.contains(x, y - ascent)) {
break;
}
}
@@ -950,8 +858,8 @@
public Bounds getCharacterBounds(int offset) {
validate();
- GlyphMetrics glyphMetrics = glyphVector.getGlyphMetrics(offset);
- Rectangle2D bounds2D = glyphMetrics.getBounds2D();
+ Shape glyphLogicalBounds = glyphVector.getGlyphLogicalBounds(offset);
+ Rectangle2D bounds2D = glyphLogicalBounds.getBounds2D();
return new Bounds(0, 0, (int)Math.ceil(bounds2D.getWidth()), getHeight());
}
@@ -1065,8 +973,6 @@
private DocumentView documentView = null;
- private static final FontRenderContext FONT_RENDER_CONTEXT = new FontRenderContext(null, true, true);
-
private int caretX = 0;
private Rectangle caret = new Rectangle();
private boolean caretOn = false;
@@ -1078,6 +984,7 @@
private Insets margin = new Insets(4);
public static final int PARAGRAPH_TERMINATOR_WIDTH = 2;
+ private static final FontRenderContext FONT_RENDER_CONTEXT = new FontRenderContext(null, true, true);
public TextAreaSkin() {
Theme theme = Theme.getTheme();