KDEUI
kgesturemap.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kgesturemap.h"
00021
00022 #include <kapplication.h>
00023 #include <kaction.h>
00024 #include <QtGui/QActionEvent>
00025
00026 #include <kglobal.h>
00027
00028 #include <kdebug.h>
00029
00030
00031
00032
00033
00034
00035
00036 class KGestureMapContainer {
00037 public:
00038 KGestureMap gestureMap;
00039 };
00040
00041
00042 K_GLOBAL_STATIC(KGestureMapContainer, g_instance)
00043
00044
00045 KGestureMap::~KGestureMap()
00046 {
00047 }
00048
00049
00050 KGestureMap *KGestureMap::self()
00051 {
00052 return &g_instance->gestureMap;
00053 }
00054
00055
00056 KGestureMap::KGestureMap()
00057 {
00058 m_gestureTimeout.setSingleShot(true);
00059 connect(&m_gestureTimeout, SIGNAL(timeout()), this, SLOT(stopAcquisition()));
00060
00061
00062
00063 if (qApp)
00064 qApp->installEventFilter(this);
00065 }
00066
00067
00068 void KGestureMap::addGesture(const KShapeGesture &gesture, KAction *act)
00069 {
00070 if (!gesture.isValid() || !act)
00071 return;
00072 kDebug(283) << "KGestureMap::addGesture(KShapeGesture ...)";
00073 if (!m_shapeGestures.contains(gesture))
00074 m_shapeGestures.insert(gesture, act);
00075 else
00076 kDebug(283) << "Tried to register an action for a gesture already taken";
00077 }
00078
00079
00080 void KGestureMap::addGesture(const KRockerGesture &gesture, KAction *act)
00081 {
00082 if (!gesture.isValid() || !act)
00083 return;
00084 kDebug(283) << "KGestureMap::addGesture(KRockerGesture ...)";
00085 if (!m_rockerGestures.contains(gesture))
00086 m_rockerGestures.insert(gesture, act);
00087 else
00088 kDebug(283) << "Tried to register an action for a gesture already taken";
00089 }
00090
00091
00092 void KGestureMap::removeGesture(const KShapeGesture &gesture, KAction *act)
00093 {
00094 if (!gesture.isValid())
00095 return;
00096 kDebug(283) << "KGestureMap::removeGesture(KShapeGesture ...)";
00097 KAction *oldAct = m_shapeGestures.value(gesture);
00098 if (oldAct == act || !act )
00099 m_shapeGestures.remove(gesture);
00100 }
00101
00102
00103 void KGestureMap::removeGesture(const KRockerGesture &gesture, KAction *act)
00104 {
00105 if (!gesture.isValid())
00106 return;
00107 kDebug(283) << "KGestureMap::removeGesture(KRockerGesture ...)";
00108 KAction *oldAct = m_rockerGestures.value(gesture);
00109 if (oldAct == act || !act )
00110 m_rockerGestures.remove(gesture);
00111 }
00112
00113
00114 KAction *KGestureMap::findAction(const KShapeGesture &gesture) const
00115 {
00116 return m_shapeGestures.value(gesture);
00117 }
00118
00119
00120 KAction *KGestureMap::findAction(const KRockerGesture &gesture) const
00121 {
00122 return m_rockerGestures.value(gesture);
00123 }
00124
00125
00126 void KGestureMap::installEventFilterOnMe(KApplication *app)
00127 {
00128 app->installEventFilter(this);
00129 }
00130
00131
00132 inline int KGestureMap::bitCount(int n)
00133 {
00134 int count = 0;
00135 while (n) {
00136 n &= (n - 1);
00137 count++;
00138 }
00139 return count;
00140 }
00141
00142
00143 void KGestureMap::handleAction(KAction *kact)
00144 {
00145 if (!kact)
00146 return;
00147 kDebug(283) << "handleAction";
00148
00149 kact->trigger();
00150 return;
00151 }
00152
00153
00154 void KGestureMap::matchShapeGesture()
00155 {
00156
00157 m_shapeGesture.setShape(m_points);
00158 float dist, minDist = 20.0;
00159 KAction *bestMatch = 0;
00160
00161 for (QHash<KShapeGesture, KAction *>::const_iterator it = m_shapeGestures.constBegin();
00162 it != m_shapeGestures.constEnd(); ++it) {
00163 dist = m_shapeGesture.distance(it.key(), 1000.0);
00164 if (dist < minDist) {
00165 minDist = dist;
00166 bestMatch = it.value();
00167 }
00168 }
00169 handleAction(bestMatch);
00170 }
00171
00172
00173
00174 void KGestureMap::stopAcquisition()
00175 {
00176 m_gestureTimeout.stop();
00177 m_acquiring = false;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 bool KGestureMap::eventFilter(QObject *obj, QEvent *e)
00193 {
00194
00195 return false;
00196 Q_UNUSED(obj);
00197 int type = e->type();
00198
00199
00200
00201
00202
00203 if (type == QEvent::ContextMenu) {
00204 QContextMenuEvent *cme = static_cast<QContextMenuEvent *>(e);
00205 if (cme->reason() == QContextMenuEvent::Mouse) {
00206 cme->ignore();
00207 return true;
00208 }
00209 return false;
00210 }
00211
00212 if (type < QEvent::MouseButtonPress || type > QEvent::MouseMove)
00213 return false;
00214
00215 QMouseEvent *me = static_cast<QMouseEvent *>(e);
00216 if (type == QEvent::MouseButtonPress) {
00217 int nButtonsDown = bitCount(me->buttons());
00218 kDebug(283) << "number of buttons down:" << nButtonsDown;
00219
00220
00221 if (nButtonsDown == 1 && me->button() == Qt::RightButton) {
00222
00223 m_acquiring = true;
00224 m_gestureTimeout.start(4000);
00225 kDebug(283) << "========================";
00226 m_points.clear();
00227 m_points.append(me->pos());
00228 return true;
00229 } else if (nButtonsDown != 2)
00230 return false;
00231
00232
00233 stopAcquisition();
00234 int buttonHeld = me->buttons() ^ me->button();
00235 m_rockerGesture.setButtons(static_cast<Qt::MouseButton>(buttonHeld), me->button());
00236 KAction *match = m_rockerGestures.value(m_rockerGesture);
00237 if (!match)
00238 return false;
00239 handleAction(match);
00240 return true;
00241 }
00242
00243 if (m_acquiring) {
00244 if (type == QEvent::MouseMove) {
00245 m_points.append(me->pos());
00246
00247
00248
00249 if (m_points.size() > 1010)
00250 stopAcquisition();
00251 return true;
00252 } else if (type == QEvent::MouseButtonRelease && me->button() == Qt::RightButton) {
00253 stopAcquisition();
00254
00255
00256
00257
00258 int dist = 0;
00259 for (int i = 1; i < m_points.size(); i++) {
00260 dist += (m_points[i] - m_points[i-1]).manhattanLength();
00261 if (dist > 40) {
00262 matchShapeGesture();
00263 return true;
00264 }
00265
00266
00267 }
00268 return false;
00269 }
00270 }
00271 return false;
00272 }
00273
00274 #include "kgesturemap.moc"