Bug 552026 - Pinch zoom support for Mozilla Qt port. r=dougt. Landed on CLOSED TREE.

This commit is contained in:
Oleg Romashin 2010-03-13 00:11:42 +02:00
parent be03beb41e
commit d3d3956267
4 changed files with 158 additions and 1 deletions

View File

@ -19,6 +19,12 @@ MozQWidget::MozQWidget(nsWindow* aReceiver, QGraphicsItem* aParent)
mReceiver(aReceiver)
{
setFlag(QGraphicsItem::ItemAcceptsInputMethod);
// Enable gestures: only available in qt > 4.6
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
setAcceptTouchEvents(true);
grabGesture(Qt::PinchGesture);
#endif
}
MozQWidget::~MozQWidget()
@ -127,6 +133,35 @@ void MozQWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent* aEvent)
mReceiver->OnButtonReleaseEvent(aEvent);
}
bool MozQWidget::event ( QEvent * event )
{
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
switch (event->type())
{
case QEvent::TouchBegin:
case QEvent::TouchEnd:
case QEvent::TouchUpdate:
{
// Do not send this event to other handlers, this is needed
// to be able to receive the gesture events
PRBool handled = PR_FALSE;
mReceiver->OnTouchEvent(static_cast<QTouchEvent *>(event),handled);
return handled;
}
case (QEvent::Gesture):
{
PRBool handled = PR_FALSE;
mReceiver->OnGestureEvent(static_cast<QGestureEvent*>(event),handled);
return handled;
}
default:
break;
}
#endif
return QGraphicsWidget::event(event);
}
void MozQWidget::wheelEvent(QGraphicsSceneWheelEvent* aEvent)
{
mReceiver->OnScrollEvent(aEvent);

View File

@ -65,6 +65,7 @@ protected:
virtual void closeEvent(QCloseEvent* aEvent);
virtual void hideEvent(QHideEvent* aEvent);
virtual void showEvent(QShowEvent* aEvent);
virtual bool event(QEvent* aEvent);
bool SetCursor(const QPixmap& aPixmap, int, int);

View File

@ -60,6 +60,9 @@
#include <QtCore/QDebug>
#include <QtCore/QEvent>
#include <QtCore/QVariant>
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
#include <QPinchGesture>
#endif // QT version check
#include "prlink.h"
@ -91,6 +94,8 @@
#include "gfxContext.h"
#include "gfxSharedImageSurface.h"
#include "nsIDOMSimpleGestureEvent.h" //Gesture support
// imported in nsWidgetFactory.cpp
PRBool gDisableNativeTheme = PR_FALSE;
@ -169,7 +174,9 @@ nsWindow::nsWindow()
mIsDestroyed = PR_FALSE;
mIsShown = PR_FALSE;
mEnabled = PR_TRUE;
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
mMouseEventsDisabled = PR_FALSE;
#endif // qt version check
mWidget = nsnull;
mIsVisible = PR_FALSE;
mActivatePending = PR_FALSE;
@ -1186,6 +1193,14 @@ nsWindow::OnLeaveNotifyEvent(QGraphicsSceneHoverEvent *aEvent)
nsEventStatus
nsWindow::OnMotionNotifyEvent(QGraphicsSceneMouseEvent *aEvent)
{
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
if (mMouseEventsDisabled) {
// Block the mouse events if currently executing pinch gesture; otherwise there
// will be also some panning during the zooming
return nsEventStatus_eIgnore;
}
#endif
nsMouseEvent event(PR_TRUE, NS_MOUSE_MOVE, this, nsMouseEvent::eReal);
event.refPoint.x = nscoord(aEvent->pos().x());
@ -1494,6 +1509,94 @@ nsWindow::hideEvent(QHideEvent *)
return nsEventStatus_eConsumeDoDefault;
}
//Gestures are only supported in 4.6.0 >
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
nsEventStatus nsWindow::OnTouchEvent(QTouchEvent *event, PRBool &handled)
{
handled = PR_FALSE;
const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
if (event->type() == QEvent::TouchBegin) {
handled = PR_TRUE;
for (int i = touchPoints.count() -1; i >= 0; i--) {
QPointF fpos = touchPoints[i].pos();
nsGestureNotifyEvent gestureNotifyEvent(PR_TRUE, NS_GESTURENOTIFY_EVENT_START, this);
gestureNotifyEvent.refPoint = nsIntPoint(fpos.x(), fpos.y());
DispatchEvent(&gestureNotifyEvent);
}
}
if (touchPoints.count() == 2) {
mTouchPointDistance = DistanceBetweenPoints(touchPoints.at(0).scenePos(),
touchPoints.at(1).scenePos());
if (event->type() == QEvent::TouchBegin) {
mLastPinchDistance = mTouchPointDistance;
}
}
//Disable mouse events when gestures are used, because they cause problems with
//Fennec
mMouseEventsDisabled = touchPoints.count() >= 2;
return nsEventStatus_eIgnore;
}
nsEventStatus nsWindow::OnGestureEvent(QGestureEvent *event, PRBool &handled)
{
handled = PR_FALSE;
nsSimpleGestureEvent mozGesture(PR_TRUE, 0, this, 0, 0.0);
if (QGesture *gesture = event->gesture(Qt::PinchGesture)) {
QPinchGesture *pinch = static_cast<QPinchGesture*>(gesture);
handled = PR_TRUE;
QPointF centerPoint = pinch->centerPoint();
mozGesture.refPoint.x = nscoord(centerPoint.x());
mozGesture.refPoint.y = nscoord(centerPoint.y());
if (pinch->state() == Qt::GestureStarted) {
mozGesture.message = NS_SIMPLE_GESTURE_MAGNIFY_START;
mozGesture.delta = 0.0;
mLastPinchDistance = mTouchPointDistance;
event->accept();
}
else if (pinch->state() == Qt::GestureUpdated) {
mozGesture.message = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
//-1 because zoom in is positive
mozGesture.delta = -1.0 * (mLastPinchDistance - mTouchPointDistance);
mLastPinchDistance = mTouchPointDistance;
}
else {
handled = PR_FALSE;
}
}
if (handled) {
Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
mozGesture.isShift = (modifiers & Qt::ShiftModifier) ? PR_TRUE : PR_FALSE;
mozGesture.isControl = (modifiers & Qt::ControlModifier) ? PR_TRUE : PR_FALSE;
mozGesture.isMeta = PR_FALSE;
mozGesture.isAlt = (modifiers & Qt::AltModifier) ? PR_TRUE : PR_FALSE;
mozGesture.button = 0;
mozGesture.time = 0;
return DispatchEvent(&mozGesture);
}
return nsEventStatus_eIgnore;
}
double
nsWindow::DistanceBetweenPoints(const QPointF &aFirstPoint, const QPointF &aSecondPoint)
{
double result = 0;
double deltaX = abs(aFirstPoint.x() - aSecondPoint.x());
double deltaY = abs(aFirstPoint.y() - aSecondPoint.y());
result = sqrt(deltaX*deltaX + deltaY*deltaY);
return result;
}
#endif //qt version check
void
nsWindow::ThemeChanged()
{
@ -1981,6 +2084,11 @@ nsWindow::createQWidget(MozQWidget *parent, nsWidgetInitData *aInitData)
return nsnull;
}
// Enable gestures:
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
newView->grabGesture(Qt::PinchGesture);
newView->viewport()->grabGesture(Qt::PinchGesture);
#endif
newView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
newView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
newView->showNormal();

View File

@ -273,6 +273,13 @@ protected:
virtual nsEventStatus showEvent(QShowEvent *);
virtual nsEventStatus hideEvent(QHideEvent *);
//Gestures are only supported in qt > 4.6
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
virtual nsEventStatus OnTouchEvent(QTouchEvent *event, PRBool &handled);
virtual nsEventStatus OnGestureEvent(QGestureEvent *event, PRBool &handled);
double DistanceBetweenPoints(const QPointF &aFirstPoint, const QPointF &aSecondPoint);
#endif
void NativeResize(PRInt32 aWidth,
PRInt32 aHeight,
PRBool aRepaint);
@ -359,6 +366,12 @@ private:
// Remember dirty area caused by ::Scroll
QRegion mDirtyScrollArea;
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
double mTouchPointDistance;
double mLastPinchDistance;
PRBool mMouseEventsDisabled;
#endif
};
class nsChildWindow : public nsWindow