зеркало из https://github.com/mozilla/pjs.git
Bug 603008 - Android widget multitouch implementation. r=blassey,kats
This commit is contained in:
Родитель
1d9e7d3880
Коммит
dd10ae1492
|
@ -148,6 +148,7 @@ MOZ_SPELLCHECK = @MOZ_SPELLCHECK@
|
|||
MOZ_ANDROID_HISTORY = @MOZ_ANDROID_HISTORY@
|
||||
MOZ_WEBSMS_BACKEND = @MOZ_WEBSMS_BACKEND@
|
||||
MOZ_JAVA_COMPOSITOR = @MOZ_JAVA_COMPOSITOR@
|
||||
MOZ_ONLY_TOUCH_EVENTS = @MOZ_ONLY_TOUCH_EVENTS@
|
||||
MOZ_TOUCH = @MOZ_TOUCH@
|
||||
MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
|
||||
MOZ_FEEDS = @MOZ_FEEDS@
|
||||
|
|
|
@ -1790,4 +1790,7 @@ public class GeckoAppShell
|
|||
public static void disableNetworkNotifications() {
|
||||
GeckoNetworkManager.getInstance().disableNotifications();
|
||||
}
|
||||
|
||||
// This is only used in Native Fennec.
|
||||
public static void preventPanning() { }
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ import android.widget.*;
|
|||
import android.hardware.*;
|
||||
import android.location.*;
|
||||
import android.util.FloatMath;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -101,7 +102,12 @@ public class GeckoEvent {
|
|||
public int mType;
|
||||
public int mAction;
|
||||
public long mTime;
|
||||
public Point mP0, mP1, mP2;
|
||||
public Point[] mPoints;
|
||||
public int[] mPointIndicies;
|
||||
public int mPointerIndex;
|
||||
public float[] mOrientations;
|
||||
public float[] mPressures;
|
||||
public Point[] mPointRadii;
|
||||
public Rect mRect;
|
||||
public double mX, mY, mZ;
|
||||
public double mAlpha, mBeta, mGamma;
|
||||
|
@ -144,10 +150,76 @@ public class GeckoEvent {
|
|||
mAction = m.getAction();
|
||||
mTime = m.getEventTime();
|
||||
mMetaState = m.getMetaState();
|
||||
mP0 = new Point((int)m.getX(0), (int)m.getY(0));
|
||||
mCount = m.getPointerCount();
|
||||
if (mCount > 1)
|
||||
mP1 = new Point((int)m.getX(1), (int)m.getY(1));
|
||||
|
||||
switch (mAction & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
mCount = m.getPointerCount();
|
||||
mPoints = new Point[mCount];
|
||||
mPointIndicies = new int[mCount];
|
||||
mOrientations = new float[mCount];
|
||||
mPressures = new float[mCount];
|
||||
mPointRadii = new Point[mCount];
|
||||
mPointerIndex = (mAction & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
for (int i = 0; i < mCount; i++) {
|
||||
addMotionPoint(i, i, m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
mCount = 0;
|
||||
mPointerIndex = -1;
|
||||
mPoints = new Point[mCount];
|
||||
mPointIndicies = new int[mCount];
|
||||
mOrientations = new float[mCount];
|
||||
mPressures = new float[mCount];
|
||||
mPointRadii = new Point[mCount];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addMotionPoint(int index, int eventIndex, MotionEvent event) {
|
||||
PointF geckoPoint = new PointF(event.getX(eventIndex), event.getY(eventIndex));
|
||||
|
||||
mPoints[index] = new Point((int)Math.round(geckoPoint.x), (int)Math.round(geckoPoint.y));
|
||||
mPointIndicies[index] = event.getPointerId(eventIndex);
|
||||
// getToolMajor, getToolMinor and getOrientation are API Level 9 features
|
||||
if (Build.VERSION.SDK_INT >= 9) {
|
||||
double radians = event.getOrientation(eventIndex);
|
||||
mOrientations[index] = (float) Math.toDegrees(radians);
|
||||
// w3c touchevents spec does not allow orientations == 90
|
||||
// this shifts it to -90, which will be shifted to zero below
|
||||
if (mOrientations[index] == 90)
|
||||
mOrientations[index] = -90;
|
||||
|
||||
// w3c touchevent radius are given by an orientation between 0 and 90
|
||||
// the radius is found by removing the orientation and measuring the x and y
|
||||
// radius of the resulting ellipse
|
||||
// for android orientations >= 0 and < 90, the major axis should correspond to
|
||||
// just reporting the y radius as the major one, and x as minor
|
||||
// however, for a radius < 0, we have to shift the orientation by adding 90, and
|
||||
// reverse which radius is major and minor
|
||||
if (mOrientations[index] < 0) {
|
||||
mOrientations[index] += 90;
|
||||
mPointRadii[index] = new Point((int)event.getToolMajor(eventIndex)/2,
|
||||
(int)event.getToolMinor(eventIndex)/2);
|
||||
} else {
|
||||
mPointRadii[index] = new Point((int)event.getToolMinor(eventIndex)/2,
|
||||
(int)event.getToolMajor(eventIndex)/2);
|
||||
}
|
||||
} else {
|
||||
float size = event.getSize(eventIndex);
|
||||
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||
size = size*Math.min(displaymetrics.heightPixels, displaymetrics.widthPixels);
|
||||
mPointRadii[index] = new Point((int)size,(int)size);
|
||||
mOrientations[index] = 0;
|
||||
}
|
||||
mPressures[index] = event.getPressure(eventIndex);
|
||||
}
|
||||
|
||||
public GeckoEvent(SensorEvent s) {
|
||||
|
@ -227,9 +299,10 @@ public class GeckoEvent {
|
|||
|
||||
mType = etype;
|
||||
|
||||
mP0 = new Point(w, h);
|
||||
mP1 = new Point(screenw, screenh);
|
||||
mP2 = new Point(0, 0);
|
||||
mPoints = new Point[3];
|
||||
mPoints[0] = new Point(w, h);
|
||||
mPoints[1] = new Point(screenw, screenh);
|
||||
mPoints[2] = new Point(0, 0);
|
||||
}
|
||||
|
||||
public GeckoEvent(String subject, String data) {
|
||||
|
|
|
@ -503,6 +503,9 @@ public class GeckoAppShell
|
|||
|
||||
layerController.setOnTouchListener(new View.OnTouchListener() {
|
||||
public boolean onTouch(View view, MotionEvent event) {
|
||||
if (event == null)
|
||||
return true;
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
@ -1117,6 +1120,15 @@ public class GeckoAppShell
|
|||
});
|
||||
}
|
||||
|
||||
public static void preventPanning() {
|
||||
getMainHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
LayerController layerController = GeckoApp.mAppContext.getLayerController();
|
||||
layerController.preventPanning(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isNetworkLinkUp() {
|
||||
ConnectivityManager cm = (ConnectivityManager)
|
||||
GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
|
|
@ -48,6 +48,11 @@ import android.widget.*;
|
|||
import android.hardware.*;
|
||||
import android.location.*;
|
||||
import android.util.FloatMath;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.graphics.PointF;
|
||||
import android.text.format.Time;
|
||||
import android.os.SystemClock;
|
||||
import java.lang.System;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -104,7 +109,12 @@ public class GeckoEvent {
|
|||
public int mType;
|
||||
public int mAction;
|
||||
public long mTime;
|
||||
public Point mP0, mP1, mP2;
|
||||
public Point[] mPoints;
|
||||
public int[] mPointIndicies;
|
||||
public int mPointerIndex; // index of the point that has changed
|
||||
public float[] mOrientations;
|
||||
public float[] mPressures;
|
||||
public Point[] mPointRadii;
|
||||
public Rect mRect;
|
||||
public double mX, mY, mZ;
|
||||
public double mAlpha, mBeta, mGamma;
|
||||
|
@ -145,12 +155,79 @@ public class GeckoEvent {
|
|||
public GeckoEvent(MotionEvent m) {
|
||||
mType = MOTION_EVENT;
|
||||
mAction = m.getAction();
|
||||
mTime = m.getEventTime();
|
||||
mTime = (System.currentTimeMillis() - SystemClock.elapsedRealtime()) + m.getEventTime();
|
||||
mMetaState = m.getMetaState();
|
||||
mP0 = new Point((int)m.getX(0), (int)m.getY(0));
|
||||
mCount = m.getPointerCount();
|
||||
if (mCount > 1)
|
||||
mP1 = new Point((int)m.getX(1), (int)m.getY(1));
|
||||
|
||||
switch (mAction & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
mCount = m.getPointerCount();
|
||||
mPoints = new Point[mCount];
|
||||
mPointIndicies = new int[mCount];
|
||||
mOrientations = new float[mCount];
|
||||
mPressures = new float[mCount];
|
||||
mPointRadii = new Point[mCount];
|
||||
mPointerIndex = (mAction & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
for (int i = 0; i < mCount; i++) {
|
||||
addMotionPoint(i, i, m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
mCount = 0;
|
||||
mPointerIndex = -1;
|
||||
mPoints = new Point[mCount];
|
||||
mPointIndicies = new int[mCount];
|
||||
mOrientations = new float[mCount];
|
||||
mPressures = new float[mCount];
|
||||
mPointRadii = new Point[mCount];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addMotionPoint(int index, int eventIndex, MotionEvent event) {
|
||||
PointF geckoPoint = new PointF(event.getX(eventIndex), event.getY(eventIndex));
|
||||
geckoPoint = GeckoApp.mAppContext.getLayerController().convertViewPointToLayerPoint(geckoPoint);
|
||||
|
||||
mPoints[index] = new Point((int)Math.round(geckoPoint.x), (int)Math.round(geckoPoint.y));
|
||||
mPointIndicies[index] = event.getPointerId(eventIndex);
|
||||
// getToolMajor, getToolMinor and getOrientation are API Level 9 features
|
||||
if (Build.VERSION.SDK_INT >= 9) {
|
||||
double radians = event.getOrientation(eventIndex);
|
||||
mOrientations[index] = (float) Math.toDegrees(radians);
|
||||
// w3c touchevents spec does not allow orientations == 90
|
||||
// this shifts it to -90, which will be shifted to zero below
|
||||
if (mOrientations[index] == 90)
|
||||
mOrientations[index] = -90;
|
||||
|
||||
// w3c touchevent radius are given by an orientation between 0 and 90
|
||||
// the radius is found by removing the orientation and measuring the x and y
|
||||
// radius of the resulting ellipse
|
||||
// for android orientations >= 0 and < 90, the major axis should correspond to
|
||||
// just reporting the y radius as the major one, and x as minor
|
||||
// however, for a radius < 0, we have to shift the orientation by adding 90, and
|
||||
// reverse which radius is major and minor
|
||||
if (mOrientations[index] < 0) {
|
||||
mOrientations[index] += 90;
|
||||
mPointRadii[index] = new Point((int)event.getToolMajor(eventIndex)/2,
|
||||
(int)event.getToolMinor(eventIndex)/2);
|
||||
} else {
|
||||
mPointRadii[index] = new Point((int)event.getToolMinor(eventIndex)/2,
|
||||
(int)event.getToolMajor(eventIndex)/2);
|
||||
}
|
||||
} else {
|
||||
float size = event.getSize(eventIndex);
|
||||
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||
size = size*Math.min(displaymetrics.heightPixels, displaymetrics.widthPixels);
|
||||
mPointRadii[index] = new Point((int)size,(int)size);
|
||||
mOrientations[index] = 0;
|
||||
}
|
||||
mPressures[index] = event.getPressure(eventIndex);
|
||||
}
|
||||
|
||||
public GeckoEvent(SensorEvent s) {
|
||||
|
@ -230,9 +307,10 @@ public class GeckoEvent {
|
|||
|
||||
mType = etype;
|
||||
|
||||
mP0 = new Point(w, h);
|
||||
mP1 = new Point(screenw, screenh);
|
||||
mP2 = new Point(tilew, tileh);
|
||||
mPoints = new Point[3];
|
||||
mPoints[0] = new Point(w, h);
|
||||
mPoints[1] = new Point(screenw, screenh);
|
||||
mPoints[2] = new Point(tilew, tileh);
|
||||
}
|
||||
|
||||
public GeckoEvent(String subject, String data) {
|
||||
|
|
|
@ -45,10 +45,12 @@ import org.mozilla.gecko.gfx.LayerView;
|
|||
import org.mozilla.gecko.ui.PanZoomController;
|
||||
import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
|
||||
import org.mozilla.gecko.GeckoApp;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
|
@ -59,6 +61,8 @@ import android.view.GestureDetector;
|
|||
import android.view.ScaleGestureDetector;
|
||||
import android.view.View.OnTouchListener;
|
||||
import java.lang.Math;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* The layer controller manages a tile that represents the visible page. It does panning and
|
||||
|
@ -100,6 +104,14 @@ public class LayerController {
|
|||
private static final int DANGER_ZONE_X = 75;
|
||||
private static final int DANGER_ZONE_Y = 150;
|
||||
|
||||
/* The time limit for pages to respond with preventDefault on touchevents
|
||||
* before we begin panning the page */
|
||||
private static final int PREVENT_DEFAULT_TIMEOUT = 200;
|
||||
|
||||
private boolean allowDefaultActions = true;
|
||||
private Timer allowDefaultTimer = null;
|
||||
private boolean inTouchSession = false;
|
||||
|
||||
public LayerController(Context context) {
|
||||
mContext = context;
|
||||
|
||||
|
@ -149,6 +161,7 @@ public class LayerController {
|
|||
public Bitmap getBackgroundPattern() { return getDrawable("background"); }
|
||||
public Bitmap getShadowPattern() { return getDrawable("shadow"); }
|
||||
|
||||
public PanZoomController getPanZoomController() { return mPanZoomController; }
|
||||
public GestureDetector.OnGestureListener getGestureListener() { return mPanZoomController; }
|
||||
public SimpleScaleGestureDetector.SimpleScaleGestureListener getScaleGestureListener() {
|
||||
return mPanZoomController;
|
||||
|
@ -347,11 +360,58 @@ public class LayerController {
|
|||
* pan/zoom controller to do the dirty work.
|
||||
*/
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (mPanZoomController.onTouchEvent(event))
|
||||
return true;
|
||||
int action = event.getAction();
|
||||
if ((action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
|
||||
post(new Runnable() {
|
||||
public void run() {
|
||||
mView.clearEventQueue();
|
||||
preventPanning(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (mOnTouchListener != null)
|
||||
return mOnTouchListener.onTouch(mView, event);
|
||||
return false;
|
||||
mOnTouchListener.onTouch(mView, event);
|
||||
|
||||
switch (action & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
if (!inTouchSession && allowDefaultTimer == null) {
|
||||
inTouchSession = true;
|
||||
allowDefaultTimer = new Timer();
|
||||
allowDefaultTimer.schedule(new TimerTask() {
|
||||
public void run() {
|
||||
post(new Runnable() {
|
||||
public void run() {
|
||||
preventPanning(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, PREVENT_DEFAULT_TIMEOUT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP: {
|
||||
inTouchSession = false;
|
||||
}
|
||||
}
|
||||
return !allowDefaultActions;
|
||||
}
|
||||
|
||||
public void preventPanning(boolean aValue) {
|
||||
if (allowDefaultTimer != null) {
|
||||
allowDefaultTimer.cancel();
|
||||
allowDefaultTimer.purge();
|
||||
allowDefaultTimer = null;
|
||||
}
|
||||
allowDefaultActions = !aValue;
|
||||
|
||||
if (aValue) {
|
||||
mView.clearEventQueue();
|
||||
mPanZoomController.cancelTouch();
|
||||
} else {
|
||||
mView.processEventQueue();
|
||||
}
|
||||
}
|
||||
|
||||
/** Retrieves the color that the checkerboard should be. */
|
||||
|
|
|
@ -48,6 +48,8 @@ import android.view.KeyEvent;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.util.Log;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* A view rendered by the layer compositor.
|
||||
|
@ -64,6 +66,10 @@ public class LayerView extends GLSurfaceView {
|
|||
private SimpleScaleGestureDetector mScaleGestureDetector;
|
||||
private long mRenderTime;
|
||||
private boolean mRenderTimeReset;
|
||||
private static String LOGTAG = "GeckoLayerView";
|
||||
/* List of events to be processed if the page does not prevent them. Should only be touched on the main thread */
|
||||
private LinkedList<MotionEvent> mEventQueue = new LinkedList<MotionEvent>();
|
||||
|
||||
|
||||
public LayerView(Context context, LayerController controller) {
|
||||
super(context);
|
||||
|
@ -83,14 +89,40 @@ public class LayerView extends GLSurfaceView {
|
|||
setFocusableInTouchMode(true);
|
||||
}
|
||||
|
||||
private void addToEventQueue(MotionEvent event) {
|
||||
MotionEvent copy = MotionEvent.obtain(event);
|
||||
mEventQueue.add(copy);
|
||||
}
|
||||
|
||||
public void processEventQueue() {
|
||||
MotionEvent event = mEventQueue.poll();
|
||||
while(event != null) {
|
||||
processEvent(event);
|
||||
event = mEventQueue.poll();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearEventQueue() {
|
||||
mEventQueue.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (mController.onTouchEvent(event)) {
|
||||
addToEventQueue(event);
|
||||
return true;
|
||||
}
|
||||
return processEvent(event);
|
||||
}
|
||||
|
||||
private boolean processEvent(MotionEvent event) {
|
||||
if (mGestureDetector.onTouchEvent(event))
|
||||
return true;
|
||||
mScaleGestureDetector.onTouchEvent(event);
|
||||
if (mScaleGestureDetector.isInProgress())
|
||||
return true;
|
||||
return mController.onTouchEvent(event);
|
||||
mController.getPanZoomController().onTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
public LayerController getController() { return mController; }
|
||||
|
|
|
@ -843,7 +843,7 @@ public class PanZoomController
|
|||
return true;
|
||||
}
|
||||
|
||||
private void cancelTouch() {
|
||||
public void cancelTouch() {
|
||||
GeckoEvent e = new GeckoEvent("Gesture:CancelTouch", "");
|
||||
GeckoAppShell.sendEventToGecko(e);
|
||||
}
|
||||
|
|
|
@ -67,6 +67,9 @@ MOZ_APP_COMPONENT_INCLUDE=nsBrowserComponents.h
|
|||
# use custom widget for html:select
|
||||
MOZ_USE_NATIVE_POPUP_WINDOWS=1
|
||||
|
||||
# dispatch only touch events (no mouse events)
|
||||
MOZ_ONLY_TOUCH_EVENTS=1
|
||||
|
||||
MOZ_APP_ID={aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
|
||||
MOZ_JAVA_COMPOSITOR=1
|
||||
|
|
|
@ -139,6 +139,7 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
|||
jGetDpi = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getDpi", "()I");
|
||||
jSetFullScreen = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setFullScreen", "(Z)V");
|
||||
jShowInputMethodPicker = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showInputMethodPicker", "()V");
|
||||
jPreventPanning = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "preventPanning", "()V");
|
||||
jHideProgressDialog = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "hideProgressDialog", "()V");
|
||||
jPerformHapticFeedback = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "performHapticFeedback", "(Z)V");
|
||||
jVibrate1 = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "vibrate", "(J)V");
|
||||
|
@ -1612,3 +1613,9 @@ NS_IMETHODIMP nsAndroidBridge::SetDrawMetadataProvider(nsIAndroidDrawMetadataPro
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::PreventPanning() {
|
||||
ALOG_BRIDGE("AndroidBridge::PreventPanning");
|
||||
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jPreventPanning);
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,8 @@ public:
|
|||
|
||||
void ShowInputMethodPicker();
|
||||
|
||||
void PreventPanning();
|
||||
|
||||
void HideProgressDialogOnce();
|
||||
|
||||
bool IsNetworkLinkUp();
|
||||
|
@ -413,6 +415,7 @@ protected:
|
|||
jmethodID jGetDpi;
|
||||
jmethodID jSetFullScreen;
|
||||
jmethodID jShowInputMethodPicker;
|
||||
jmethodID jPreventPanning;
|
||||
jmethodID jHideProgressDialog;
|
||||
jmethodID jPerformHapticFeedback;
|
||||
jmethodID jVibrate1;
|
||||
|
|
|
@ -44,9 +44,11 @@ jclass AndroidGeckoEvent::jGeckoEventClass = 0;
|
|||
jfieldID AndroidGeckoEvent::jActionField = 0;
|
||||
jfieldID AndroidGeckoEvent::jTypeField = 0;
|
||||
jfieldID AndroidGeckoEvent::jTimeField = 0;
|
||||
jfieldID AndroidGeckoEvent::jP0Field = 0;
|
||||
jfieldID AndroidGeckoEvent::jP1Field = 0;
|
||||
jfieldID AndroidGeckoEvent::jP2Field = 0;
|
||||
jfieldID AndroidGeckoEvent::jPoints = 0;
|
||||
jfieldID AndroidGeckoEvent::jPointIndicies = 0;
|
||||
jfieldID AndroidGeckoEvent::jPressures = 0;
|
||||
jfieldID AndroidGeckoEvent::jPointRadii = 0;
|
||||
jfieldID AndroidGeckoEvent::jOrientations = 0;
|
||||
jfieldID AndroidGeckoEvent::jAlphaField = 0;
|
||||
jfieldID AndroidGeckoEvent::jBetaField = 0;
|
||||
jfieldID AndroidGeckoEvent::jGammaField = 0;
|
||||
|
@ -64,6 +66,7 @@ jfieldID AndroidGeckoEvent::jFlagsField = 0;
|
|||
jfieldID AndroidGeckoEvent::jUnicodeCharField = 0;
|
||||
jfieldID AndroidGeckoEvent::jOffsetField = 0;
|
||||
jfieldID AndroidGeckoEvent::jCountField = 0;
|
||||
jfieldID AndroidGeckoEvent::jPointerIndexField = 0;
|
||||
jfieldID AndroidGeckoEvent::jRangeTypeField = 0;
|
||||
jfieldID AndroidGeckoEvent::jRangeStylesField = 0;
|
||||
jfieldID AndroidGeckoEvent::jRangeForeColorField = 0;
|
||||
|
@ -157,9 +160,11 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
|
|||
jActionField = getField("mAction", "I");
|
||||
jTypeField = getField("mType", "I");
|
||||
jTimeField = getField("mTime", "J");
|
||||
jP0Field = getField("mP0", "Landroid/graphics/Point;");
|
||||
jP1Field = getField("mP1", "Landroid/graphics/Point;");
|
||||
jP2Field = getField("mP2", "Landroid/graphics/Point;");
|
||||
jPoints = getField("mPoints", "[Landroid/graphics/Point;");
|
||||
jPointIndicies = getField("mPointIndicies", "[I");
|
||||
jOrientations = getField("mOrientations", "[F");
|
||||
jPressures = getField("mPressures", "[F");
|
||||
jPointRadii = getField("mPointRadii", "[Landroid/graphics/Point;");
|
||||
jAlphaField = getField("mAlpha", "D");
|
||||
jBetaField = getField("mBeta", "D");
|
||||
jGammaField = getField("mGamma", "D");
|
||||
|
@ -176,6 +181,7 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
|
|||
jUnicodeCharField = getField("mUnicodeChar", "I");
|
||||
jOffsetField = getField("mOffset", "I");
|
||||
jCountField = getField("mCount", "I");
|
||||
jPointerIndexField = getField("mPointerIndex", "I");
|
||||
jRangeTypeField = getField("mRangeType", "I");
|
||||
jRangeStylesField = getField("mRangeStyles", "I");
|
||||
jRangeForeColorField = getField("mRangeForeColor", "I");
|
||||
|
@ -338,27 +344,47 @@ AndroidGeckoSoftwareLayerClient::InitGeckoSoftwareLayerClientClass(JNIEnv *jEnv)
|
|||
#undef getMethod
|
||||
|
||||
void
|
||||
AndroidGeckoEvent::ReadP0Field(JNIEnv *jenv)
|
||||
AndroidGeckoEvent::ReadPointArray(nsTArray<nsIntPoint> &points,
|
||||
JNIEnv *jenv,
|
||||
jfieldID field,
|
||||
PRUint32 count)
|
||||
{
|
||||
AndroidPoint p0(jenv, jenv->GetObjectField(wrappedObject(), jP0Field));
|
||||
mP0.x = p0.X();
|
||||
mP0.y = p0.Y();
|
||||
jobjectArray jObjArray = (jobjectArray)jenv->GetObjectField(wrapped_obj, field);
|
||||
for (PRInt32 i = 0; i < count; i++) {
|
||||
jobject jObj = jenv->GetObjectArrayElement(jObjArray, i);
|
||||
AndroidPoint jpoint(jenv, jObj);
|
||||
|
||||
nsIntPoint p(jpoint.X(), jpoint.Y());
|
||||
points.AppendElement(p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AndroidGeckoEvent::ReadP1Field(JNIEnv *jenv)
|
||||
AndroidGeckoEvent::ReadIntArray(nsTArray<int> &aVals,
|
||||
JNIEnv *jenv,
|
||||
jfieldID field,
|
||||
PRUint32 count)
|
||||
{
|
||||
AndroidPoint p1(jenv, jenv->GetObjectField(wrappedObject(), jP1Field));
|
||||
mP1.x = p1.X();
|
||||
mP1.y = p1.Y();
|
||||
jintArray jIntArray = (jintArray)jenv->GetObjectField(wrapped_obj, field);
|
||||
jint *vals = jenv->GetIntArrayElements(jIntArray, false);
|
||||
for (PRInt32 i = 0; i < count; i++) {
|
||||
aVals.AppendElement(vals[i]);
|
||||
}
|
||||
jenv->ReleaseIntArrayElements(jIntArray, vals, JNI_ABORT);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidGeckoEvent::ReadP2Field(JNIEnv *jenv)
|
||||
AndroidGeckoEvent::ReadFloatArray(nsTArray<float> &aVals,
|
||||
JNIEnv *jenv,
|
||||
jfieldID field,
|
||||
PRUint32 count)
|
||||
{
|
||||
AndroidPoint p2(jenv, jenv->GetObjectField(wrappedObject(), jP2Field));
|
||||
mP2.x = p2.X();
|
||||
mP2.y = p2.Y();
|
||||
jfloatArray jFloatArray = (jfloatArray)jenv->GetObjectField(wrapped_obj, field);
|
||||
jfloat *vals = jenv->GetFloatArrayElements(jFloatArray, false);
|
||||
for (PRInt32 i = 0; i < count; i++) {
|
||||
aVals.AppendElement(vals[i]);
|
||||
}
|
||||
jenv->ReleaseFloatArrayElements(jFloatArray, vals, JNI_ABORT);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -425,9 +451,7 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
|
|||
|
||||
switch (mType) {
|
||||
case SIZE_CHANGED:
|
||||
ReadP0Field(jenv);
|
||||
ReadP1Field(jenv);
|
||||
ReadP2Field(jenv);
|
||||
ReadPointArray(mPoints, jenv, jPoints, 3);
|
||||
break;
|
||||
|
||||
case KEY_EVENT:
|
||||
|
@ -443,9 +467,14 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
|
|||
mTime = jenv->GetLongField(jobj, jTimeField);
|
||||
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
|
||||
mCount = jenv->GetIntField(jobj, jCountField);
|
||||
ReadP0Field(jenv);
|
||||
if (mCount > 1)
|
||||
ReadP1Field(jenv);
|
||||
mPointerIndex = jenv->GetIntField(jobj, jPointerIndexField);
|
||||
|
||||
ReadPointArray(mPointRadii, jenv, jPointRadii, mCount);
|
||||
ReadFloatArray(mOrientations, jenv, jOrientations, mCount);
|
||||
ReadFloatArray(mPressures, jenv, jPressures, mCount);
|
||||
ReadPointArray(mPoints, jenv, jPoints, mCount);
|
||||
ReadIntArray(mPointIndicies, jenv, jPointIndicies, mCount);
|
||||
|
||||
break;
|
||||
|
||||
case IME_EVENT:
|
||||
|
@ -544,10 +573,7 @@ AndroidGeckoEvent::Init(AndroidGeckoEvent *aResizeEvent)
|
|||
|
||||
mType = FORCED_RESIZE;
|
||||
mTime = aResizeEvent->mTime;
|
||||
mP0.x = aResizeEvent->mP0.x;
|
||||
mP0.y = aResizeEvent->mP0.y;
|
||||
mP1.x = aResizeEvent->mP1.x;
|
||||
mP1.y = aResizeEvent->mP1.y;
|
||||
mPoints = aResizeEvent->mPoints; // x,y coordinates
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -434,9 +434,11 @@ public:
|
|||
int Action() { return mAction; }
|
||||
int Type() { return mType; }
|
||||
int64_t Time() { return mTime; }
|
||||
const nsIntPoint& P0() { return mP0; }
|
||||
const nsIntPoint& P1() { return mP1; }
|
||||
const nsIntPoint& P2() { return mP2; }
|
||||
nsTArray<nsIntPoint> Points() { return mPoints; }
|
||||
nsTArray<int> PointIndicies() { return mPointIndicies; }
|
||||
nsTArray<float> Pressures() { return mPressures; }
|
||||
nsTArray<float> Orientations() { return mOrientations; }
|
||||
nsTArray<nsIntPoint> PointRadii() { return mPointRadii; }
|
||||
double Alpha() { return mAlpha; }
|
||||
double Beta() { return mBeta; }
|
||||
double Gamma() { return mGamma; }
|
||||
|
@ -452,6 +454,7 @@ public:
|
|||
int UnicodeChar() { return mUnicodeChar; }
|
||||
int Offset() { return mOffset; }
|
||||
int Count() { return mCount; }
|
||||
int PointerIndex() { return mPointerIndex; }
|
||||
int RangeType() { return mRangeType; }
|
||||
int RangeStyles() { return mRangeStyles; }
|
||||
int RangeForeColor() { return mRangeForeColor; }
|
||||
|
@ -465,9 +468,11 @@ protected:
|
|||
int mAction;
|
||||
int mType;
|
||||
int64_t mTime;
|
||||
nsIntPoint mP0;
|
||||
nsIntPoint mP1;
|
||||
nsIntPoint mP2;
|
||||
nsTArray<nsIntPoint> mPoints;
|
||||
nsTArray<nsIntPoint> mPointRadii;
|
||||
nsTArray<int> mPointIndicies;
|
||||
nsTArray<float> mOrientations;
|
||||
nsTArray<float> mPressures;
|
||||
nsIntRect mRect;
|
||||
int mFlags, mMetaState;
|
||||
int mKeyCode, mUnicodeChar;
|
||||
|
@ -476,15 +481,25 @@ protected:
|
|||
int mRangeForeColor, mRangeBackColor;
|
||||
double mAlpha, mBeta, mGamma;
|
||||
double mX, mY, mZ;
|
||||
int mPointerIndex;
|
||||
nsString mCharacters, mCharactersExtra;
|
||||
nsRefPtr<nsGeoPosition> mGeoPosition;
|
||||
nsRefPtr<nsGeoPositionAddress> mGeoAddress;
|
||||
double mBandwidth;
|
||||
bool mCanBeMetered;
|
||||
|
||||
void ReadP0Field(JNIEnv *jenv);
|
||||
void ReadP1Field(JNIEnv *jenv);
|
||||
void ReadP2Field(JNIEnv *jenv);
|
||||
void ReadIntArray(nsTArray<int> &aVals,
|
||||
JNIEnv *jenv,
|
||||
jfieldID field,
|
||||
PRUint32 count);
|
||||
void ReadFloatArray(nsTArray<float> &aVals,
|
||||
JNIEnv *jenv,
|
||||
jfieldID field,
|
||||
PRUint32 count);
|
||||
void ReadPointArray(nsTArray<nsIntPoint> &mPoints,
|
||||
JNIEnv *jenv,
|
||||
jfieldID field,
|
||||
PRUint32 count);
|
||||
void ReadRectField(JNIEnv *jenv);
|
||||
void ReadCharactersField(JNIEnv *jenv);
|
||||
void ReadCharactersExtraField(JNIEnv *jenv);
|
||||
|
@ -493,9 +508,11 @@ protected:
|
|||
static jfieldID jActionField;
|
||||
static jfieldID jTypeField;
|
||||
static jfieldID jTimeField;
|
||||
static jfieldID jP0Field;
|
||||
static jfieldID jP1Field;
|
||||
static jfieldID jP2Field;
|
||||
static jfieldID jPoints;
|
||||
static jfieldID jPointIndicies;
|
||||
static jfieldID jOrientations;
|
||||
static jfieldID jPressures;
|
||||
static jfieldID jPointRadii;
|
||||
static jfieldID jAlphaField;
|
||||
static jfieldID jBetaField;
|
||||
static jfieldID jGammaField;
|
||||
|
@ -512,6 +529,7 @@ protected:
|
|||
static jfieldID jFlagsField;
|
||||
static jfieldID jOffsetField;
|
||||
static jfieldID jCountField;
|
||||
static jfieldID jPointerIndexField;
|
||||
static jfieldID jUnicodeCharField;
|
||||
static jfieldID jRangeTypeField;
|
||||
static jfieldID jRangeStylesField;
|
||||
|
|
|
@ -103,6 +103,7 @@ LOCAL_INCLUDES += \
|
|||
-I$(topsrcdir)/dom/system/android \
|
||||
-I$(topsrcdir)/toolkit/components/places \
|
||||
-I$(topsrcdir)/docshell/base \
|
||||
-I$(topsrcdir)/content/events/src \
|
||||
-I$(srcdir) \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ using mozilla::unused;
|
|||
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsIDOMSimpleGestureEvent.h"
|
||||
#include "nsDOMTouchEvent.h"
|
||||
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
|
@ -895,8 +896,11 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||
win->mChildren[i]->mBounds.height = 0;
|
||||
}
|
||||
case AndroidGeckoEvent::SIZE_CHANGED: {
|
||||
int nw = ae->P0().x;
|
||||
int nh = ae->P0().y;
|
||||
nsTArray<nsIntPoint> points = ae->Points();
|
||||
NS_ASSERTION(points.Length() != 3, "Size changed does not have enough coordinates");
|
||||
|
||||
int nw = points[0].x;
|
||||
int nh = points[0].y;
|
||||
|
||||
if (ae->Type() == AndroidGeckoEvent::FORCED_RESIZE || nw != gAndroidBounds.width ||
|
||||
nh != gAndroidBounds.height) {
|
||||
|
@ -913,11 +917,11 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||
}
|
||||
}
|
||||
|
||||
gAndroidTileSize.width = ae->P2().x;
|
||||
gAndroidTileSize.height = ae->P2().y;
|
||||
gAndroidTileSize.width = points[2].x;
|
||||
gAndroidTileSize.height = points[2].y;
|
||||
|
||||
int newScreenWidth = ae->P1().x;
|
||||
int newScreenHeight = ae->P1().y;
|
||||
int newScreenWidth = points[1].x;
|
||||
int newScreenHeight = points[1].y;
|
||||
|
||||
if (newScreenWidth == gAndroidScreenBounds.width &&
|
||||
newScreenHeight == gAndroidScreenBounds.height)
|
||||
|
@ -951,29 +955,36 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||
else
|
||||
obs->RemoveObserver(notifier, "ipc:content-created");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AndroidGeckoEvent::MOTION_EVENT: {
|
||||
win->UserActivity();
|
||||
if (!gTopLevelWindows.IsEmpty()) {
|
||||
nsIntPoint pt(ae->P0());
|
||||
nsIntPoint pt(0,0);
|
||||
nsTArray<nsIntPoint> points = ae->Points();
|
||||
if (points.Length() > 0) {
|
||||
pt = points[0];
|
||||
}
|
||||
pt.x = clamped(pt.x, 0, gAndroidBounds.width - 1);
|
||||
pt.y = clamped(pt.y, 0, gAndroidBounds.height - 1);
|
||||
nsWindow *target = win->FindWindowForPoint(pt);
|
||||
|
||||
#if 0
|
||||
ALOG("MOTION_EVENT %f,%f -> %p (visible: %d children: %d)", ae->P0().x, ae->P0().y, (void*)target,
|
||||
ALOG("MOTION_EVENT %f,%f -> %p (visible: %d children: %d)", pt.x, pt.y, (void*)target,
|
||||
target ? target->mIsVisible : 0,
|
||||
target ? target->mChildren.Length() : 0);
|
||||
|
||||
DumpWindows();
|
||||
#endif
|
||||
|
||||
if (target) {
|
||||
if (ae->Count() > 1)
|
||||
target->OnMultitouchEvent(ae);
|
||||
else
|
||||
bool preventDefaultActions = target->OnMultitouchEvent(ae);
|
||||
if (!preventDefaultActions && ae->Count() == 2) {
|
||||
target->OnGestureEvent(ae);
|
||||
}
|
||||
#ifndef MOZ_ONLY_TOUCH_EVENTS
|
||||
if (!preventDefaultActions && ae->Count() < 2)
|
||||
target->OnMotionEvent(ae);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1470,30 +1481,11 @@ nsWindow::OnMotionEvent(AndroidGeckoEvent *ae)
|
|||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsWindow> kungFuDeathGrip(this);
|
||||
nsIntPoint pt(ae->P0());
|
||||
nsIntPoint offset = WidgetToScreenOffset();
|
||||
|
||||
//ALOG("#### motion pt: %d %d offset: %d %d", pt.x, pt.y, offset.x, offset.y);
|
||||
|
||||
pt.x -= offset.x;
|
||||
pt.y -= offset.y;
|
||||
|
||||
// XXX possibly bound the range of pt here. some code may get confused.
|
||||
|
||||
send_again:
|
||||
|
||||
nsMouseEvent event(true,
|
||||
msg, this,
|
||||
nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
||||
InitEvent(event, &pt);
|
||||
|
||||
event.time = ae->Time();
|
||||
event.isShift = !!(ae->MetaState() & AndroidKeyEvent::META_SHIFT_ON);
|
||||
event.isControl = false;
|
||||
event.isMeta = false;
|
||||
event.isAlt = !!(ae->MetaState() & AndroidKeyEvent::META_ALT_ON);
|
||||
|
||||
// XXX can we synthesize different buttons?
|
||||
event.button = nsMouseEvent::eLeftButton;
|
||||
|
||||
|
@ -1501,8 +1493,8 @@ send_again:
|
|||
event.clickCount = 1;
|
||||
|
||||
// XXX add the double-click handling logic here
|
||||
|
||||
DispatchEvent(&event);
|
||||
if (ae->Points().Length() > 0)
|
||||
DispatchMotionEvent(event, ae, ae->Points()[0]);
|
||||
if (Destroyed())
|
||||
return;
|
||||
|
||||
|
@ -1520,16 +1512,87 @@ getDistance(const nsIntPoint &p1, const nsIntPoint &p2)
|
|||
return sqrt(deltaX*deltaX + deltaY*deltaY);
|
||||
}
|
||||
|
||||
void nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae)
|
||||
bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae)
|
||||
{
|
||||
switch (ae->Action() & AndroidMotionEvent::ACTION_MASK) {
|
||||
case AndroidMotionEvent::ACTION_DOWN:
|
||||
case AndroidMotionEvent::ACTION_POINTER_DOWN: {
|
||||
nsTouchEvent event(PR_TRUE, NS_TOUCH_START, this);
|
||||
return DispatchMultitouchEvent(event, ae);
|
||||
}
|
||||
case AndroidMotionEvent::ACTION_MOVE: {
|
||||
nsTouchEvent event(PR_TRUE, NS_TOUCH_MOVE, this);
|
||||
return DispatchMultitouchEvent(event, ae);
|
||||
}
|
||||
case AndroidMotionEvent::ACTION_UP:
|
||||
case AndroidMotionEvent::ACTION_POINTER_UP: {
|
||||
nsTouchEvent event(PR_TRUE, NS_TOUCH_END, this);
|
||||
return DispatchMultitouchEvent(event, ae);
|
||||
}
|
||||
case AndroidMotionEvent::ACTION_OUTSIDE:
|
||||
case AndroidMotionEvent::ACTION_CANCEL: {
|
||||
nsTouchEvent event(PR_TRUE, NS_TOUCH_CANCEL, this);
|
||||
return DispatchMultitouchEvent(event, ae);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsWindow::DispatchMultitouchEvent(nsTouchEvent &event, AndroidGeckoEvent *ae)
|
||||
{
|
||||
nsIntPoint offset = WidgetToScreenOffset();
|
||||
|
||||
event.isShift = false;
|
||||
event.isControl = false;
|
||||
event.isMeta = false;
|
||||
event.isAlt = false;
|
||||
event.time = ae->Time();
|
||||
|
||||
int action = ae->Action() & AndroidMotionEvent::ACTION_MASK;
|
||||
if (action == AndroidMotionEvent::ACTION_UP ||
|
||||
action == AndroidMotionEvent::ACTION_POINTER_UP) {
|
||||
event.touches.SetCapacity(1);
|
||||
int pointerIndex = ae->PointerIndex();
|
||||
nsCOMPtr<nsIDOMTouch> t(new nsDOMTouch(ae->PointIndicies()[pointerIndex],
|
||||
ae->Points()[pointerIndex] - offset,
|
||||
ae->PointRadii()[pointerIndex],
|
||||
ae->Orientations()[pointerIndex],
|
||||
ae->Pressures()[pointerIndex]));
|
||||
event.touches.AppendElement(t);
|
||||
} else {
|
||||
int count = ae->Count();
|
||||
event.touches.SetCapacity(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
nsCOMPtr<nsIDOMTouch> t(new nsDOMTouch(ae->PointIndicies()[i],
|
||||
ae->Points()[i] - offset,
|
||||
ae->PointRadii()[i],
|
||||
ae->Orientations()[i],
|
||||
ae->Pressures()[i]));
|
||||
event.touches.AppendElement(t);
|
||||
}
|
||||
}
|
||||
|
||||
nsEventStatus status;
|
||||
DispatchEvent(&event, status);
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
AndroidBridge::Bridge()->PreventPanning();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::OnGestureEvent(AndroidGeckoEvent *ae)
|
||||
{
|
||||
PRUint32 msg = 0;
|
||||
|
||||
nsIntPoint midPoint;
|
||||
midPoint.x = ((ae->P0().x + ae->P1().x) / 2);
|
||||
midPoint.y = ((ae->P0().y + ae->P1().y) / 2);
|
||||
midPoint.x = ((ae->Points()[0].x + ae->Points()[1].x) / 2);
|
||||
midPoint.y = ((ae->Points()[0].y + ae->Points()[1].y) / 2);
|
||||
nsIntPoint refPoint = midPoint - WidgetToScreenOffset();
|
||||
|
||||
double pinchDist = getDistance(ae->P0(), ae->P1());
|
||||
double pinchDist = getDistance(ae->Points()[0], ae->Points()[1]);
|
||||
double pinchDelta = 0;
|
||||
|
||||
switch (ae->Action() & AndroidMotionEvent::ACTION_MASK) {
|
||||
|
@ -1612,6 +1675,26 @@ nsWindow::DispatchGestureEvent(PRUint32 msg, PRUint32 direction, double delta,
|
|||
DispatchEvent(&event);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsWindow::DispatchMotionEvent(nsInputEvent &event, AndroidGeckoEvent *ae,
|
||||
const nsIntPoint &refPoint)
|
||||
{
|
||||
nsIntPoint offset = WidgetToScreenOffset();
|
||||
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.time = ae->Time();
|
||||
|
||||
// XXX possibly bound the range of event.refPoint here.
|
||||
// some code may get confused.
|
||||
event.refPoint = refPoint - offset;
|
||||
|
||||
DispatchEvent(&event);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::InitKeyEvent(nsKeyEvent& event, AndroidGeckoEvent& key)
|
||||
{
|
||||
|
|
|
@ -73,8 +73,9 @@ public:
|
|||
|
||||
void OnAndroidEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnDraw(mozilla::AndroidGeckoEvent *ae);
|
||||
bool OnMultitouchEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnGestureEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnMotionEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnMultitouchEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnKeyEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnIMEEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
|
||||
|
@ -221,9 +222,13 @@ protected:
|
|||
|
||||
private:
|
||||
void InitKeyEvent(nsKeyEvent& event, mozilla::AndroidGeckoEvent& key);
|
||||
void DispatchGestureEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
bool DispatchMultitouchEvent(nsTouchEvent &event,
|
||||
mozilla::AndroidGeckoEvent *ae);
|
||||
void DispatchMotionEvent(nsInputEvent &event,
|
||||
mozilla::AndroidGeckoEvent *ae,
|
||||
const nsIntPoint &refPoint);
|
||||
void DispatchGestureEvent(PRUint32 msg, PRUint32 direction, double delta,
|
||||
const nsIntPoint &refPoint, PRUint64 time);
|
||||
const nsIntPoint &refPoint, PRUint64 time);
|
||||
void HandleSpecialKey(mozilla::AndroidGeckoEvent *ae);
|
||||
void RedrawAll();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче