Kaydet (Commit) 94e5223f authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Miklos Vajna

android: account for handle repositioning, limit update to 50ms

Text handles are usually shown under the current selection or
cursor position. Previously this was done in InvalidationHandler,
now the TextSelectionHandle takes this into account just before
drawing. The reason is that the repositioning needs to be taken
into account when the handle moves to reposition the coordinates
back to original position.
In addition to that, the number of times the move handle update
event is send is now limited to 50ms to reduce stress for the
device (less in queue, less messages via LOKit). This also makes
the handle more fluid and jump around less.

Change-Id: Idc401375c82b3eeac66328d98c80bf3cb7b675ea
üst 9c7016b5
...@@ -118,16 +118,6 @@ public class InvalidationHandler { ...@@ -118,16 +118,6 @@ public class InvalidationHandler {
return rectangles; return rectangles;
} }
/**
* From input rectangle, create a new rectangle which positions under the input rectangle.
*
* @param rectangle - input rectangle
* @return new rectangle positioned under the input rectangle
*/
private RectF createRectangleUnderSelection(RectF rectangle) {
return new RectF(rectangle.centerX(), rectangle.bottom, rectangle.centerX(), rectangle.bottom);
}
/** /**
* Handles the tile invalidation message * Handles the tile invalidation message
* *
...@@ -149,7 +139,7 @@ public class InvalidationHandler { ...@@ -149,7 +139,7 @@ public class InvalidationHandler {
RectF cursorRectangle = convertPayloadToRectangle(payload); RectF cursorRectangle = convertPayloadToRectangle(payload);
if (cursorRectangle != null) { if (cursorRectangle != null) {
if (mState == OverlayState.CURSOR) { if (mState == OverlayState.CURSOR) {
mTextSelection.positionHandle(TextSelectionHandle.HandleType.MIDDLE, createRectangleUnderSelection(cursorRectangle)); mTextSelection.positionHandle(TextSelectionHandle.HandleType.MIDDLE, cursorRectangle);
mTextSelection.showHandle(TextSelectionHandle.HandleType.MIDDLE); mTextSelection.showHandle(TextSelectionHandle.HandleType.MIDDLE);
mTextSelection.hideHandle(TextSelectionHandle.HandleType.START); mTextSelection.hideHandle(TextSelectionHandle.HandleType.START);
mTextSelection.hideHandle(TextSelectionHandle.HandleType.END); mTextSelection.hideHandle(TextSelectionHandle.HandleType.END);
...@@ -170,7 +160,7 @@ public class InvalidationHandler { ...@@ -170,7 +160,7 @@ public class InvalidationHandler {
} }
RectF selectionRectangle = convertPayloadToRectangle(payload); RectF selectionRectangle = convertPayloadToRectangle(payload);
if (selectionRectangle != null) { if (selectionRectangle != null) {
mTextSelection.positionHandle(TextSelectionHandle.HandleType.START, createRectangleUnderSelection(selectionRectangle)); mTextSelection.positionHandle(TextSelectionHandle.HandleType.START, selectionRectangle);
mTextSelection.showHandle(TextSelectionHandle.HandleType.START); mTextSelection.showHandle(TextSelectionHandle.HandleType.START);
mTextSelection.hideHandle(TextSelectionHandle.HandleType.MIDDLE); mTextSelection.hideHandle(TextSelectionHandle.HandleType.MIDDLE);
mState = OverlayState.SELECTION; mState = OverlayState.SELECTION;
...@@ -188,7 +178,7 @@ public class InvalidationHandler { ...@@ -188,7 +178,7 @@ public class InvalidationHandler {
} }
RectF selectionRect = convertPayloadToRectangle(payload); RectF selectionRect = convertPayloadToRectangle(payload);
if (selectionRect != null) { if (selectionRect != null) {
mTextSelection.positionHandle(TextSelectionHandle.HandleType.END, createRectangleUnderSelection(selectionRect)); mTextSelection.positionHandle(TextSelectionHandle.HandleType.END, selectionRect);
mTextSelection.showHandle(TextSelectionHandle.HandleType.END); mTextSelection.showHandle(TextSelectionHandle.HandleType.END);
mTextSelection.hideHandle(TextSelectionHandle.HandleType.MIDDLE); mTextSelection.hideHandle(TextSelectionHandle.HandleType.MIDDLE);
mState = OverlayState.SELECTION; mState = OverlayState.SELECTION;
......
...@@ -108,7 +108,7 @@ public class TextSelection extends Layer { ...@@ -108,7 +108,7 @@ public class TextSelection extends Layer {
LOKitShell.getMainHandler().post(new Runnable() { LOKitShell.getMainHandler().post(new Runnable() {
public void run() { public void run() {
TextSelectionHandle handle = getHandle(handleType); TextSelectionHandle handle = getHandle(handleType);
handle.positionFromGecko((int) position.left, (int) position.top, false); handle.positionFromGecko(position, false);
} }
}); });
} }
......
...@@ -7,6 +7,7 @@ package org.mozilla.gecko; ...@@ -7,6 +7,7 @@ package org.mozilla.gecko;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
...@@ -22,6 +23,10 @@ import org.mozilla.gecko.gfx.LayerView; ...@@ -22,6 +23,10 @@ import org.mozilla.gecko.gfx.LayerView;
public class TextSelectionHandle extends ImageView implements View.OnTouchListener { public class TextSelectionHandle extends ImageView implements View.OnTouchListener {
private static final String LOGTAG = TextSelectionHandle.class.getSimpleName(); private static final String LOGTAG = TextSelectionHandle.class.getSimpleName();
private long mLastTime = 0;
// Minimum time lapsed between 2 handle updates
private static final long MINIMUM_HANDLE_UPDATE_TIME = 50 * 1000000;
public enum HandleType { START, MIDDLE, END }; public enum HandleType { START, MIDDLE, END };
...@@ -33,7 +38,8 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen ...@@ -33,7 +38,8 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
private int mLeft; private int mLeft;
private int mTop; private int mTop;
private boolean mIsRTL; private boolean mIsRTL;
private PointF mGeckoPoint; private PointF mPoint;
private PointF mReposition;
private int mTouchStartX; private int mTouchStartX;
private int mTouchStartY; private int mTouchStartY;
...@@ -49,15 +55,16 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen ...@@ -49,15 +55,16 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextSelectionHandle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextSelectionHandle);
int handleType = a.getInt(R.styleable.TextSelectionHandle_handleType, 0x01); int handleType = a.getInt(R.styleable.TextSelectionHandle_handleType, 0x01);
if (handleType == 0x01) if (handleType == 0x01) {
mHandleType = HandleType.START; mHandleType = HandleType.START;
else if (handleType == 0x02) } else if (handleType == 0x02) {
mHandleType = HandleType.MIDDLE; mHandleType = HandleType.MIDDLE;
else } else if (handleType == 0x03) {
mHandleType = HandleType.END; mHandleType = HandleType.END;
}
mIsRTL = false; mIsRTL = false;
mGeckoPoint = new PointF(0.0f, 0.0f); mPoint = new PointF(0.0f, 0.0f);
mWidth = getResources().getDimensionPixelSize(R.dimen.text_selection_handle_width); mWidth = getResources().getDimensionPixelSize(R.dimen.text_selection_handle_width);
mHeight = getResources().getDimensionPixelSize(R.dimen.text_selection_handle_height); mHeight = getResources().getDimensionPixelSize(R.dimen.text_selection_handle_height);
...@@ -77,7 +84,11 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen ...@@ -77,7 +84,11 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
break; break;
} }
case MotionEvent.ACTION_MOVE: { case MotionEvent.ACTION_MOVE: {
move(event.getX(), event.getY()); long currentTime = System.nanoTime();
if (currentTime - mLastTime > MINIMUM_HANDLE_UPDATE_TIME) {
mLastTime = currentTime;
move(event.getX(), event.getY());
}
break; break;
} }
} }
...@@ -99,18 +110,32 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen ...@@ -99,18 +110,32 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
PointF documentPoint = new PointF(left, newTop); PointF documentPoint = new PointF(left, newTop);
documentPoint = layerView.getLayerClient().convertViewPointToLayerPoint(documentPoint); documentPoint = layerView.getLayerClient().convertViewPointToLayerPoint(documentPoint);
documentPoint.x += mReposition.x;
documentPoint.y += mReposition.y;
LOKitShell.sendChangeHandlePositionEvent(mHandleType, documentPoint); LOKitShell.sendChangeHandlePositionEvent(mHandleType, documentPoint);
} }
void positionFromGecko(int left, int top, boolean rtl) { /**
* Calculate the position just under (and centered horizontally) rectangle from the input rectangle.
*
* @param rectangle - input rectangle
* @return position just under the selection
*/
private PointF positionUnderSelection(RectF rectangle) {
return new PointF(rectangle.centerX(), rectangle.bottom);
}
void positionFromGecko(RectF position, boolean rtl) {
LayerView layerView = LOKitShell.getLayerView(); LayerView layerView = LOKitShell.getLayerView();
if (layerView == null) { if (layerView == null) {
Log.e(LOGTAG, "Can't position handle because layerView is null"); Log.e(LOGTAG, "Can't position handle because layerView is null");
return; return;
} }
mGeckoPoint = new PointF((float) left, (float) top); mPoint = positionUnderSelection(position);
mReposition = new PointF(position.left - mPoint.x, position.top - mPoint.y);
if (mIsRTL != rtl) { if (mIsRTL != rtl) {
mIsRTL = rtl; mIsRTL = rtl;
setImageLevel(mIsRTL ? IMAGE_LEVEL_RTL : IMAGE_LEVEL_LTR); setImageLevel(mIsRTL ? IMAGE_LEVEL_RTL : IMAGE_LEVEL_LTR);
...@@ -121,8 +146,8 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen ...@@ -121,8 +146,8 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
} }
void repositionWithViewport(float x, float y, float zoom) { void repositionWithViewport(float x, float y, float zoom) {
PointF viewPoint = new PointF((mGeckoPoint.x * zoom) - x, PointF viewPoint = new PointF(mPoint.x * zoom - x,
(mGeckoPoint.y * zoom) - y); mPoint.y * zoom - y);
mLeft = Math.round(viewPoint.x) - (int) adjustLeftForHandle(); mLeft = Math.round(viewPoint.x) - (int) adjustLeftForHandle();
mTop = Math.round(viewPoint.y); mTop = Math.round(viewPoint.y);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment