comparison src/panned.cpp @ 403:44cef6368690

Ensure drags are constrained to either horizontal or vertical once the user's primary direction has become clear, switching to free drag only if the user makes a big move in the other axis
author Chris Cannam
date Wed, 25 May 2011 16:16:01 +0100
parents b9c153e00e84
children 533519ebc0cb
comparison
equal deleted inserted replaced
402:75003687f364 403:44cef6368690
172 172
173 if (!ev->isAccepted()) { 173 if (!ev->isAccepted()) {
174 ev->accept(); 174 ev->accept();
175 m_dragging = true; 175 m_dragging = true;
176 m_lastDragPos = ev->pos(); 176 m_lastDragPos = ev->pos();
177 m_lastDragStart = ev->pos();
177 m_lastOrigin = QPoint(horizontalScrollBar()->value(), 178 m_lastOrigin = QPoint(horizontalScrollBar()->value(),
178 verticalScrollBar()->value()); 179 verticalScrollBar()->value());
179 m_velocity = QPointF(0, 0); 180 m_velocity = QPointF(0, 0);
180 m_dragTimer->start(m_dragTimerMs); 181 m_dragTimer->start(m_dragTimerMs);
181 } 182 m_dragDirection = UnknownDrag;
182 183 }
184 }
185
186 void
187 Panned::updateDragDirection(QPoint pos)
188 {
189 if (m_dragDirection == FreeDrag) {
190 return;
191 }
192
193 QPoint overall = pos - m_lastDragStart;
194
195 int smallThreshold = 10;
196 int largeThreshold = 30;
197 int dx = qAbs(overall.x());
198 int dy = qAbs(overall.y());
199
200 switch (m_dragDirection) {
201
202 case UnknownDrag:
203 if (dx > smallThreshold) {
204 if (dy > smallThreshold) {
205 m_dragDirection = FreeDrag;
206 } else {
207 m_dragDirection = HorizontalDrag;
208 }
209 } else if (dy > smallThreshold) {
210 m_dragDirection = VerticalDrag;
211 }
212 break;
213
214 case HorizontalDrag:
215 if (dy > largeThreshold) {
216 m_dragDirection = FreeDrag;
217 }
218 break;
219
220 case VerticalDrag:
221 if (dx > largeThreshold) {
222 m_dragDirection = FreeDrag;
223 }
224 break;
225 };
183 } 226 }
184 227
185 void 228 void
186 Panned::mouseMoveEvent(QMouseEvent *ev) 229 Panned::mouseMoveEvent(QMouseEvent *ev)
187 { 230 {
189 QGraphicsView::mouseMoveEvent(ev); 232 QGraphicsView::mouseMoveEvent(ev);
190 return; 233 return;
191 } 234 }
192 DEBUG << "Panned::mouseMoveEvent: dragging" << endl; 235 DEBUG << "Panned::mouseMoveEvent: dragging" << endl;
193 ev->accept(); 236 ev->accept();
237 updateDragDirection(ev->pos());
194 QScrollBar *hBar = horizontalScrollBar(); 238 QScrollBar *hBar = horizontalScrollBar();
195 QScrollBar *vBar = verticalScrollBar(); 239 QScrollBar *vBar = verticalScrollBar();
196 QPoint delta = ev->pos() - m_lastDragPos; 240 QPoint delta = ev->pos() - m_lastDragPos;
197 hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x())); 241 if (m_dragDirection != VerticalDrag) {
198 vBar->setValue(vBar->value() - delta.y()); 242 hBar->setValue(hBar->value() +
243 (isRightToLeft() ? delta.x() : -delta.x()));
244 }
245 if (m_dragDirection != HorizontalDrag) {
246 vBar->setValue(vBar->value() - delta.y());
247 }
199 m_lastDragPos = ev->pos(); 248 m_lastDragPos = ev->pos();
200 } 249 }
201 250
202 void 251 void
203 Panned::mouseReleaseEvent(QMouseEvent *ev) 252 Panned::mouseReleaseEvent(QMouseEvent *ev)
233 else y = 0.f; 282 else y = 0.f;
234 m_velocity = QPointF(x, y); 283 m_velocity = QPointF(x, y);
235 DEBUG << "Panned::dragTimerTimeout: velocity adjusted to " << m_velocity << endl; 284 DEBUG << "Panned::dragTimerTimeout: velocity adjusted to " << m_velocity << endl;
236 m_lastOrigin = origin; 285 m_lastOrigin = origin;
237 //!!! need to store origin in floats 286 //!!! need to store origin in floats
238 horizontalScrollBar()->setValue(m_lastOrigin.x() + 287 if (m_dragDirection != VerticalDrag) {
239 m_velocity.x() * m_dragTimerMs); 288 horizontalScrollBar()->setValue(m_lastOrigin.x() +
240 verticalScrollBar()->setValue(m_lastOrigin.y() + 289 m_velocity.x() * m_dragTimerMs);
241 m_velocity.y() * m_dragTimerMs); 290 }
291 if (m_dragDirection != HorizontalDrag) {
292 verticalScrollBar()->setValue(m_lastOrigin.y() +
293 m_velocity.y() * m_dragTimerMs);
294 }
242 } 295 }
243 } 296 }
244 297
245 void 298 void
246 Panned::leaveEvent(QEvent *) 299 Panned::leaveEvent(QEvent *)