summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-06-11 12:00:50 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-06-11 12:00:50 (GMT)
commitecc7f07e612bf156afb7fa2dbcbd2288b9b32e79 (patch)
tree88bbdcb558ef7337d3d3621b3b706f004505c569 /src/gui/kernel
parent666299f9074235185aa7372729c84a2639224601 (diff)
downloadQt-ecc7f07e612bf156afb7fa2dbcbd2288b9b32e79.zip
Qt-ecc7f07e612bf156afb7fa2dbcbd2288b9b32e79.tar.gz
Qt-ecc7f07e612bf156afb7fa2dbcbd2288b9b32e79.tar.bz2
remove duplicated code and API (merge QTouchEvent and QGraphicsSceneTouchEvent)
the API for these 2 classes is identical, the implementation is almost identical, they share the same data structures, so bite the bullet and merge them. this means we go back to using screenPos() instead of globalPos() again
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication.cpp36
-rw-r--r--src/gui/kernel/qapplication_win.cpp22
-rw-r--r--src/gui/kernel/qevent.cpp242
-rw-r--r--src/gui/kernel/qevent.h73
-rw-r--r--src/gui/kernel/qevent_p.h7
5 files changed, 239 insertions, 141 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 7cb1ac1..c072c4a 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -4052,6 +4052,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
while (widget) {
// first, try to deliver the touch event
bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+ touchEvent->setWidget(widget);
touchEvent->setAccepted(acceptTouchEvents);
res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
eventAccepted = touchEvent->isAccepted();
@@ -5258,10 +5259,15 @@ void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEven
QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
// preserve the sub-pixel resolution
- const QPointF delta = touchPoint.globalPos() - touchPoint.globalPos().toPoint();
- touchPoint.setPos(widget->mapFromGlobal(touchPoint.globalPos().toPoint()) + delta);
- touchPoint.setStartPos(widget->mapFromGlobal(touchPoint.startGlobalPos().toPoint()) + delta);
- touchPoint.setLastPos(widget->mapFromGlobal(touchPoint.lastGlobalPos().toPoint()) + delta);
+ QRectF rect = touchPoint.screenRect();
+ const QPointF screenPos = rect.center();
+ const QPointF delta = screenPos - screenPos.toPoint();
+
+ rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
+ touchPoint.setRect(rect);
+
+ touchPoint.setStartPos(widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta);
+ touchPoint.setLastPos(widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta);
}
}
@@ -5281,12 +5287,12 @@ void QApplicationPrivate::cleanupMultitouch()
appCurrentTouchPoints.clear();
}
-int QApplicationPrivate::findClosestTouchPointId(const QPointF &globalPos)
+int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos)
{
int closestTouchPointId = -1;
qreal closestDistance = qreal(0.);
foreach (const QTouchEvent::TouchPoint &touchPoint, appCurrentTouchPoints) {
- qreal distance = QLineF(globalPos, touchPoint.globalPos()).length();
+ qreal distance = QLineF(screenPos, touchPoint.screenPos()).length();
if (closestTouchPointId == -1 || distance < closestDistance) {
closestTouchPointId = touchPoint.id();
closestDistance = distance;
@@ -5314,22 +5320,22 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
{
// determine which widget this event will go to
if (!window)
- window = q->topLevelAt(touchPoint.globalPos().toPoint());
+ window = q->topLevelAt(touchPoint.screenPos().toPoint());
if (!window)
continue;
- widget = window->childAt(window->mapFromGlobal(touchPoint.globalPos().toPoint()));
+ widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
if (!widget)
widget = window;
- int closestTouchPointId = d->findClosestTouchPointId(touchPoint.globalPos());
+ int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos());
QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId);
if (closestWidget
&& (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) {
widget = closestWidget;
}
d->widgetForTouchPointId[touchPoint.id()] = widget;
- touchPoint.setStartGlobalPos(touchPoint.globalPos());
- touchPoint.setLastGlobalPos(touchPoint.globalPos());
+ touchPoint.setStartScreenPos(touchPoint.screenPos());
+ touchPoint.setLastScreenPos(touchPoint.screenPos());
d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
break;
}
@@ -5340,8 +5346,8 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
continue;
QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
- touchPoint.setStartGlobalPos(previousTouchPoint.startGlobalPos());
- touchPoint.setLastGlobalPos(previousTouchPoint.globalPos());
+ touchPoint.setStartScreenPos(previousTouchPoint.startScreenPos());
+ touchPoint.setLastScreenPos(previousTouchPoint.screenPos());
break;
}
default:
@@ -5350,8 +5356,8 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
continue;
Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
- touchPoint.setStartGlobalPos(previousTouchPoint.startGlobalPos());
- touchPoint.setLastGlobalPos(previousTouchPoint.globalPos());
+ touchPoint.setStartScreenPos(previousTouchPoint.startScreenPos());
+ touchPoint.setLastScreenPos(previousTouchPoint.screenPos());
d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
break;
}
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 0c5945d..4ecf299 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -4040,27 +4040,27 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg)
QTouchEvent::TouchPoint touchPoint(touchPointID);
// update state
- QPointF globalPos(qreal(touchInput.x) / qreal(100.), qreal(touchInput.y) / qreal(100.));
- QRectF globalRect;
+ QPointF screenPos(qreal(touchInput.x) / qreal(100.), qreal(touchInput.y) / qreal(100.));
+ QRectF screenRect;
if (touchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
- globalRect.setSize(QSizeF(qreal(touchInput.cxContact) / qreal(100.),
+ screenRect.setSize(QSizeF(qreal(touchInput.cxContact) / qreal(100.),
qreal(touchInput.cyContact) / qreal(100.)));
- globalRect.moveCenter(globalPos);
+ screenRect.moveCenter(screenPos);
if (touchInput.dwFlags & TOUCHEVENTF_DOWN) {
touchPoint.setState(Qt::TouchPointPressed);
- touchPoint.setGlobalPos(globalPos);
- touchPoint.setRect(globalRect);
+ touchPoint.setScreenPos(screenPos);
+ touchPoint.setRect(screenRect);
} else if (touchInput.dwFlags & TOUCHEVENTF_UP) {
touchPoint.setState(Qt::TouchPointReleased);
- touchPoint.setGlobalPos(globalPos);
- touchPoint.setRect(globalRect);
+ touchPoint.setScreenPos(screenPos);
+ touchPoint.setRect(screenRect);
} else {
- touchPoint.setState(globalPos == touchPoint.globalPos()
+ touchPoint.setState(screenPos == touchPoint.screenPos()
? Qt::TouchPointStationary
: Qt::TouchPointMoved);
- touchPoint.setGlobalPos(globalPos);
- touchPoint.setRect(globalRect);
+ touchPoint.setScreenPos(screenPos);
+ touchPoint.setRect(screenRect);
}
touchPoints.append(touchPoint);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 7a86dbf..a55d7e2 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -85,6 +85,13 @@ QInputEvent::~QInputEvent()
\sa QApplication::keyboardModifiers()
*/
+/*! \fn void QInputEvent::setModifiers(Qt::KeyboardModifiers modifiers)
+
+ \internal
+
+ Sets the keyboard modifiers flags for this event.
+*/
+
/*!
\class QMouseEvent
\ingroup events
@@ -3744,21 +3751,34 @@ QTouchEvent::QTouchEvent(QEvent::Type type,
QTouchEvent::~QTouchEvent()
{ }
+/*! \fn QWidget *QTouchEvent::widget() const
+
+ Returns the widget on which the event occurred.
+*/
+
+
/*! \fn Qt::TouchPointStates QTouchEvent::touchPointStates() const
Returns a bitwise OR of all the touch point states for this event.
*/
-/*! \fn void QTouchEvent::setTouchPointStates(Qt::TouchPointStates touchPointStates)
+/*! \fn const QList<QTouchEvent::TouchPoint> &QTouchEvent::touchPoints() const
+
+ Returns the list of touch points contained in the touch event.
+*/
+
+/*! \fn void QTouchEvent::setWidget(QWidget *widget)
\internal
- Sets a bitwise OR of all the touch point states for this event.
+ Sets the widget for this event.
*/
-/*! \fn const QList<QTouchEvent::TouchPoint> &QTouchEvent::TouchPoints() const
+/*! \fn void QTouchEvent::setTouchPointStates(Qt::TouchPointStates touchPointStates)
- Returns the list of touch points contained in the touch event.
+ \internal
+
+ Sets a bitwise OR of all the touch point states for this event.
*/
/*! \fn void QTouchEvent::setTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints)
@@ -3808,14 +3828,6 @@ int QTouchEvent::TouchPoint::id() const
return d->id;
}
-/*! \internal */
-void QTouchEvent::TouchPoint::setId(int id)
-{
- if (d->ref != 1)
- d = d->detach();
- d->id = id;
-}
-
/*!
Returns the current state of this touch point.
*/
@@ -3824,29 +3836,29 @@ Qt::TouchPointState QTouchEvent::TouchPoint::state() const
return d->state;
}
-/*! \internal */
-void QTouchEvent::TouchPoint::setState(Qt::TouchPointState state)
-{
- if (d->ref != 1)
- d = d->detach();
- d->state = state;
-}
-
/*!
Returns the position of this touch point, relative to the widget
or item that received the event.
*/
QPointF QTouchEvent::TouchPoint::pos() const
{
- return d->pos;
+ return d->rect.center();
}
-/*! \internal */
-void QTouchEvent::TouchPoint::setPos(const QPointF &pos)
+/*!
+ Returns the scene position of this touch point.
+*/
+QPointF QTouchEvent::TouchPoint::scenePos() const
{
- if (d->ref != 1)
- d = d->detach();
- d->pos = pos;
+ return d->sceneRect.center();
+}
+
+/*!
+ Returns the screen position of this touch point.
+*/
+QPointF QTouchEvent::TouchPoint::screenPos() const
+{
+ return d->screenRect.center();
}
/*!
@@ -3858,12 +3870,20 @@ QPointF QTouchEvent::TouchPoint::startPos() const
return d->startPos;
}
-/*! \internal */
-void QTouchEvent::TouchPoint::setStartPos(const QPointF &startPos)
+/*!
+ Returns the starting scene position of this touch point.
+*/
+QPointF QTouchEvent::TouchPoint::startScenePos() const
{
- if (d->ref != 1)
- d = d->detach();
- d->startPos = startPos;
+ return d->startScenePos;
+}
+
+/*!
+ Returns the starting screen position of this touch point.
+*/
+QPointF QTouchEvent::TouchPoint::startScreenPos() const
+{
+ return d->startScreenPos;
}
/*!
@@ -3875,70 +3895,144 @@ QPointF QTouchEvent::TouchPoint::lastPos() const
return d->lastPos;
}
+/*!
+ Returns the scene position of this touch point from the previous
+ touch event.
+*/
+QPointF QTouchEvent::TouchPoint::lastScenePos() const
+{
+ return d->lastScenePos;
+}
+
+/*!
+ Returns the screen position of this touch point from the previous
+ touch event.
+*/
+QPointF QTouchEvent::TouchPoint::lastScreenPos() const
+{
+ return d->lastScreenPos;
+}
+
+/*!
+ Returns the rect for this touch point. The rect is centered around the point returned by pos().
+ Note this function returns an empty rect if the device does not report touch point sizes.
+*/
+QRectF QTouchEvent::TouchPoint::rect() const
+{
+ return d->screenRect;
+}
+
+/*!
+ Returns the rect for this touch point in scene coordinates.
+*/
+QRectF QTouchEvent::TouchPoint::sceneRect() const
+{
+ return d->sceneRect;
+}
+
+/*!
+ Returns the rect for this touch point in screen coordinates.
+*/
+QRectF QTouchEvent::TouchPoint::screenRect() const
+{
+ return d->screenRect;
+}
+
+/*!
+ Returns the pressure of this touch point. The return value is in
+ the range 0.0 to 1.0.
+*/
+qreal QTouchEvent::TouchPoint::pressure() const
+{
+ return d->pressure;
+}
+
/*! \internal */
-void QTouchEvent::TouchPoint::setLastPos(const QPointF &lastPos)
+void QTouchEvent::TouchPoint::setId(int id)
{
if (d->ref != 1)
d = d->detach();
- d->lastPos = lastPos;
+ d->id = id;
}
-/*!
- Returns the screen position of this touch point.
-*/
-QPointF QTouchEvent::TouchPoint::globalPos() const
+/*! \internal */
+void QTouchEvent::TouchPoint::setState(Qt::TouchPointState state)
{
- return d->screenPos;
+ if (d->ref != 1)
+ d = d->detach();
+ d->state = state;
}
/*! \internal */
-void QTouchEvent::TouchPoint::setGlobalPos(const QPointF &globalPos)
+void QTouchEvent::TouchPoint::setPos(const QPointF &pos)
{
if (d->ref != 1)
d = d->detach();
- d->screenPos = globalPos;
+ d->rect.moveCenter(pos);
}
-/*!
- Returns the starting screen position of this touch point.
-*/
-QPointF QTouchEvent::TouchPoint::startGlobalPos() const
+/*! \internal */
+void QTouchEvent::TouchPoint::setScenePos(const QPointF &scenePos)
{
- return d->startScreenPos;
+ if (d->ref != 1)
+ d = d->detach();
+ d->sceneRect.moveCenter(scenePos);
}
/*! \internal */
-void QTouchEvent::TouchPoint::setStartGlobalPos(const QPointF &startGlobalPos)
+void QTouchEvent::TouchPoint::setScreenPos(const QPointF &screenPos)
{
if (d->ref != 1)
d = d->detach();
- d->startScreenPos = startGlobalPos;
+ d->screenRect.moveCenter(screenPos);
}
-/*!
- Returns the screen position of this touch point from the previous
- touch event.
-*/
-QPointF QTouchEvent::TouchPoint::lastGlobalPos() const
+/*! \internal */
+void QTouchEvent::TouchPoint::setStartPos(const QPointF &startPos)
{
- return d->lastScreenPos;
+ if (d->ref != 1)
+ d = d->detach();
+ d->startPos = startPos;
}
/*! \internal */
-void QTouchEvent::TouchPoint::setLastGlobalPos(const QPointF &lastGlobalPos)
+void QTouchEvent::TouchPoint::setStartScenePos(const QPointF &startScenePos)
{
if (d->ref != 1)
d = d->detach();
- d->lastScreenPos = lastGlobalPos;
+ d->startScenePos = startScenePos;
}
-/*!
- Returns the rect for this touch point. The rect is centered around the point returned by pos().
- Note this function returns an empty rect if the device does not report touch point sizes.
-*/
-QRectF QTouchEvent::TouchPoint::rect() const
+/*! \internal */
+void QTouchEvent::TouchPoint::setStartScreenPos(const QPointF &startScreenPos)
{
- return d->screenRect;
+ if (d->ref != 1)
+ d = d->detach();
+ d->startScreenPos = startScreenPos;
+}
+
+/*! \internal */
+void QTouchEvent::TouchPoint::setLastPos(const QPointF &lastPos)
+{
+ if (d->ref != 1)
+ d = d->detach();
+ d->lastPos = lastPos;
+}
+
+/*! \internal */
+void QTouchEvent::TouchPoint::setLastScenePos(const QPointF &lastScenePos)
+{
+ if (d->ref != 1)
+ d = d->detach();
+ d->lastScenePos = lastScenePos;
+}
+
+/*! \internal */
+void QTouchEvent::TouchPoint::setLastScreenPos(const QPointF &lastScreenPos)
+{
+ if (d->ref != 1)
+ d = d->detach();
+ d->lastScreenPos = lastScreenPos;
}
/*! \internal */
@@ -3946,16 +4040,23 @@ void QTouchEvent::TouchPoint::setRect(const QRectF &rect)
{
if (d->ref != 1)
d = d->detach();
- d->screenRect = rect;
+ d->rect = rect;
}
-/*!
- Returns the pressure of this touch point. The return value is in
- the range 0.0 to 1.0.
-*/
-qreal QTouchEvent::TouchPoint::pressure() const
+/*! \internal */
+void QTouchEvent::TouchPoint::setSceneRect(const QRectF &sceneRect)
{
- return d->pressure;
+ if (d->ref != 1)
+ d = d->detach();
+ d->sceneRect = sceneRect;
+}
+
+/*! \internal */
+void QTouchEvent::TouchPoint::setScreenRect(const QRectF &screenRect)
+{
+ if (d->ref != 1)
+ d = d->detach();
+ d->screenRect = screenRect;
}
/*! \internal */
@@ -3976,9 +4077,4 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
return *this;
}
-QTouchEventTouchPointPrivate *QTouchEventTouchPointPrivate::get(const QTouchEvent::TouchPoint &tp)
-{
- return tp.d;
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 4d62958..2f735ac 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -70,6 +70,7 @@ public:
QInputEvent(Type type, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
~QInputEvent();
inline Qt::KeyboardModifiers modifiers() const { return modState; }
+ inline void setModifiers(Qt::KeyboardModifiers modifiers) { modState = modifiers; }
protected:
Qt::KeyboardModifiers modState;
};
@@ -769,68 +770,66 @@ public:
~TouchPoint();
int id() const;
- void setId(int id);
Qt::TouchPointState state() const;
- void setState(Qt::TouchPointState state);
QPointF pos() const;
- void setPos(const QPointF &pos);
-
QPointF startPos() const;
- void setStartPos(const QPointF &startPos);
-
QPointF lastPos() const;
- void setLastPos(const QPointF &lastPos);
- QPointF globalPos() const;
- void setGlobalPos(const QPointF &globalPos);
+ QPointF scenePos() const;
+ QPointF startScenePos() const;
+ QPointF lastScenePos() const;
- QPointF startGlobalPos() const;
- void setStartGlobalPos(const QPointF &startGlobalPos);
-
- QPointF lastGlobalPos() const;
- void setLastGlobalPos(const QPointF &lastGlobalPos);
+ QPointF screenPos() const;
+ QPointF startScreenPos() const;
+ QPointF lastScreenPos() const;
QRectF rect() const;
- void setRect(const QRectF &rect);
+ QRectF sceneRect() const;
+ QRectF screenRect() const;
qreal pressure() const;
- void setPressure(qreal pressure);
+ // internal
+ void setId(int id);
+ void setState(Qt::TouchPointState state);
+ void setPos(const QPointF &pos);
+ void setScenePos(const QPointF &scenePos);
+ void setScreenPos(const QPointF &screenPos);
+ void setStartPos(const QPointF &startPos);
+ void setStartScenePos(const QPointF &startScenePos);
+ void setStartScreenPos(const QPointF &startScreenPos);
+ void setLastPos(const QPointF &lastPos);
+ void setLastScenePos(const QPointF &lastScenePos);
+ void setLastScreenPos(const QPointF &lastScreenPos);
+ void setRect(const QRectF &rect);
+ void setSceneRect(const QRectF &sceneRect);
+ void setScreenRect(const QRectF &screenRect);
+ void setPressure(qreal pressure);
TouchPoint &operator=(const TouchPoint &other);
private:
QTouchEventTouchPointPrivate *d;
-
- friend class QTouchEventTouchPointPrivate;
};
QTouchEvent(QEvent::Type type,
- Qt::KeyboardModifiers modifiers,
- Qt::TouchPointStates touchPointStates,
- const QList<QTouchEvent::TouchPoint> &touchPoints);
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier,
+ Qt::TouchPointStates touchPointStates = 0,
+ const QList<QTouchEvent::TouchPoint> &touchPoints = QList<QTouchEvent::TouchPoint>());
~QTouchEvent();
- inline Qt::TouchPointStates touchPointStates() const
- {
- return _touchPointStates;
- }
- inline void setTouchPointStates(Qt::TouchPointStates touchPointStates)
- {
- _touchPointStates = touchPointStates;
- }
+ inline QWidget *widget() const { return _widget; }
+ inline Qt::TouchPointStates touchPointStates() const { return _touchPointStates; }
+ inline const QList<QTouchEvent::TouchPoint> &touchPoints() const { return _touchPoints; }
- inline const QList<QTouchEvent::TouchPoint> &touchPoints() const
- {
- return _touchPoints;
- }
- inline void setTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints)
- {
- _touchPoints = touchPoints;
- }
+ // internal
+ inline void setWidget(QWidget *widget) { _widget = widget; }
+ inline void setTouchPointStates(Qt::TouchPointStates touchPointStates) { _touchPointStates = touchPointStates; }
+ inline void setTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints) { _touchPoints = touchPoints; }
protected:
+ QWidget *_widget;
Qt::TouchPointStates _touchPointStates;
QList<QTouchEvent::TouchPoint> _touchPoints;
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index 3475d0d..2a481fb 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -109,13 +109,10 @@ public:
QAtomicInt ref;
int id;
Qt::TouchPointState state;
- QPointF pos, startPos, lastPos;
- QPointF scenePos, startScenePos, lastScenePos;
- QPointF screenPos, startScreenPos, lastScreenPos;
QRectF rect, sceneRect, screenRect;
+ QPointF startPos, startScenePos, startScreenPos;
+ QPointF lastPos, lastScenePos, lastScreenPos;
qreal pressure;
-
- static QTouchEventTouchPointPrivate *get(const QTouchEvent::TouchPoint &tp);
};
QT_END_NAMESPACE