28 |
28 |
29 #include "hblistlayout_p.h" |
29 #include "hblistlayout_p.h" |
30 #include "hblistviewitem.h" |
30 #include "hblistviewitem.h" |
31 #include "hblistitemcontainer_p.h" |
31 #include "hblistitemcontainer_p.h" |
32 #include "hblistitemcontainer_p.h" |
32 #include "hblistitemcontainer_p.h" |
33 #include "hbgesturefilter.h" |
|
34 #include "hbscrollbar.h" |
33 #include "hbscrollbar.h" |
35 #include <hbwidgetfeedback.h> |
34 #include <hbwidgetfeedback.h> |
36 #include "hbmodeliterator.h" |
35 #include "hbmodeliterator.h" |
37 |
36 |
38 #include <QGraphicsSceneMouseEvent> |
37 #include <QGraphicsSceneMouseEvent> |
39 #include <QGraphicsScene> |
38 #include <QGraphicsScene> |
40 #include <QAbstractItemModel> |
39 #include <QAbstractItemModel> |
|
40 |
|
41 #include <QPanGesture> |
41 |
42 |
42 #include <qdebug.h> |
43 #include <qdebug.h> |
43 /*! |
44 /*! |
44 @beta |
45 @beta |
45 @hbwidgets |
46 @hbwidgets |
242 if (d->mSelectionMode != HbAbstractItemView::NoSelection |
237 if (d->mSelectionMode != HbAbstractItemView::NoSelection |
243 || !d->mModelIterator->model() |
238 || !d->mModelIterator->model() |
244 || !(d->mModelIterator->model()->supportedDropActions().testFlag(Qt::MoveAction))) { |
239 || !(d->mModelIterator->model()->supportedDropActions().testFlag(Qt::MoveAction))) { |
245 return false; |
240 return false; |
246 } |
241 } |
247 if (d->mGestureFilter) { |
|
248 removeSceneEventFilter(d->mGestureFilter); |
|
249 d->mFilterRemoved = true; |
|
250 } |
|
251 verticalScrollBar()->setInteractive(true); |
242 verticalScrollBar()->setInteractive(true); |
252 |
|
253 } else { |
243 } else { |
254 if (d->mFilterRemoved) { |
|
255 installSceneEventFilter(d->mGestureFilter); |
|
256 d->mFilterRemoved = false; |
|
257 } |
|
258 verticalScrollBar()->setInteractive(false); |
244 verticalScrollBar()->setInteractive(false); |
259 } |
245 } |
260 d->mArrangeMode = arrangeMode; |
246 d->mArrangeMode = arrangeMode; |
261 d->mAnimateItems = !d->mArrangeMode; |
247 d->mAnimateItems = !d->mArrangeMode; |
|
248 |
|
249 if (d->mArrangeMode == true) { |
|
250 d->mOriginalFriction = d->mFrictionEnabled; |
|
251 setFrictionEnabled(false); |
|
252 } else { |
|
253 setFrictionEnabled(d->mOriginalFriction); |
|
254 } |
262 } |
255 } |
263 return true; |
256 return true; |
264 } |
257 } |
265 |
|
266 /*! |
|
267 \reimp |
|
268 */ |
|
269 void HbListView::mousePressEvent(QGraphicsSceneMouseEvent *event) |
|
270 { |
|
271 Q_D(HbListView); |
|
272 if (d->mArrangeMode |
|
273 && d->mSelectionMode == HbAbstractItemView::NoSelection |
|
274 && !d->mDraggedItem) { |
|
275 |
|
276 if (d->mFilterRemoved == false && d->mGestureFilter) { |
|
277 removeSceneEventFilter(d->mGestureFilter); |
|
278 d->mFilterRemoved = true; |
|
279 } |
|
280 |
|
281 d->mDraggedItem = d->itemAt(event->scenePos()); |
|
282 if(d->mDraggedItem) { |
|
283 d->mDraggedItemIndex = d->mDraggedItem->modelIndex(); |
|
284 |
|
285 if (d->mDraggedItemIndex.isValid()) { |
|
286 setCurrentIndex(d->mDraggedItemIndex); |
|
287 d->mMousePressTimer.restart(); |
|
288 d->mMousePressPos = event->scenePos(); |
|
289 d->mOriginalTransform = d->mDraggedItem->transform(); |
|
290 d->mDraggedItem->setZValue(d->mDraggedItem->zValue() + 1); |
|
291 d->mDraggedItem->setPressed(true); |
|
292 |
|
293 connect(this, SIGNAL(scrollPositionChanged(QPointF)), this, SLOT(scrolling(QPointF))); |
|
294 Hb::InteractionModifiers modifiers = 0; |
|
295 if (d->mWasScrolling) { |
|
296 modifiers |= Hb::ModifierScrolling; |
|
297 } |
|
298 HbWidgetFeedback::triggered(d->mDraggedItem,Hb::InstantPressed,modifiers); |
|
299 } else { |
|
300 d->mDraggedItem = 0; |
|
301 } |
|
302 } |
|
303 } else { |
|
304 if (!d->mDraggedItem) { |
|
305 HbAbstractItemView::mousePressEvent(event); |
|
306 } |
|
307 } |
|
308 } |
|
309 |
|
310 /*! |
|
311 \reimp |
|
312 */ |
|
313 void HbListView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) |
|
314 { |
|
315 Q_D(HbListView); |
|
316 |
|
317 if (d->mArrangeMode |
|
318 && d->mSelectionMode == HbAbstractItemView::NoSelection |
|
319 && d->mDraggedItem) { |
|
320 |
|
321 if (!isScrolling()) { |
|
322 // move the item with the cursor to indicate the move |
|
323 d->mDraggedItem->translate(0, event->scenePos().y() - event->lastScenePos().y()); |
|
324 |
|
325 if (d->mMousePressTimer.elapsed() >= FLICK_TIMEOUT) { |
|
326 d->moveDraggedItemTo(event->scenePos()); |
|
327 } |
|
328 } |
|
329 |
|
330 // in case we are "dragging" an item and at the top/bottom of |
|
331 // the view the view is scrolled to reveal more items in |
|
332 // that direction |
|
333 QModelIndex firstVisible; |
|
334 QModelIndex lastVisible; |
|
335 d->mContainer->firstAndLastVisibleModelIndex(firstVisible, lastVisible); |
|
336 if (firstVisible.isValid() && lastVisible.isValid()) { |
|
337 // above indexes are valid so container contain at least one item - so it is |
|
338 // safe to call first and last |
|
339 QModelIndex firstItemIndex = d->mContainer->items().first()->modelIndex(); |
|
340 QModelIndex lastItemIndex = d->mContainer->items().last()->modelIndex(); |
|
341 // If the item is dragged up in the list (and there are more items to show), scroll up |
|
342 if (!isScrolling() |
|
343 && !isVisible(firstItemIndex) |
|
344 && event->scenePos().y() < d->mMousePressPos.y() |
|
345 && event->pos().y() < itemByIndex(firstVisible)->size().height()) { |
|
346 d->mScrollStartMousePos = event->scenePos(); |
|
347 d->mLastScrollPos = QPointF(0,0); |
|
348 d->animateScroll(QPointF(0.0f , DRAGGED_ITEM_SCROLL_SPEED)); |
|
349 } |
|
350 // If the item is dragged down in the list (and there are more items to show), scroll down |
|
351 else if (!isScrolling() |
|
352 && !isVisible(lastItemIndex) |
|
353 && event->scenePos().y() > d->mMousePressPos.y() |
|
354 && event->pos().y() > (size().height() - itemByIndex(lastVisible)->size().height())) { |
|
355 d->mScrollStartMousePos = event->scenePos(); |
|
356 d->mLastScrollPos = QPointF(0,0); |
|
357 d->animateScroll(QPointF(0.0f , (-1 * DRAGGED_ITEM_SCROLL_SPEED))); |
|
358 } |
|
359 // If the view is scrolling and the drag event is inside the view, we need to stop the scrolling |
|
360 else if (event->pos().y() < (size().height() - itemByIndex(lastVisible)->size().height()) |
|
361 && event->pos().y() > itemByIndex(firstVisible)->size().height() |
|
362 && isScrolling()) { |
|
363 d->stopAnimating(); |
|
364 } |
|
365 } |
|
366 } else { |
|
367 HbAbstractItemView::mouseMoveEvent(event); |
|
368 } |
|
369 } |
|
370 |
|
371 |
258 |
372 /*! |
259 /*! |
373 This slot is called when the arrangeMode is true, user is dragging an item |
260 This slot is called when the arrangeMode is true, user is dragging an item |
374 and the underlying scrollarea is moving. |
261 and the underlying scrollarea is moving. |
375 */void HbListView::scrolling(QPointF newPosition) |
262 */ |
|
263 void HbListView::scrolling(QPointF newPosition) |
376 { |
264 { |
377 Q_UNUSED(newPosition); |
265 Q_UNUSED(newPosition); |
378 |
266 |
379 Q_D(HbListView); |
267 Q_D(HbListView); |
380 if (d->mArrangeMode |
268 if (d->mArrangeMode |
392 d->moveDraggedItemTo(d->mScrollStartMousePos); |
280 d->moveDraggedItemTo(d->mScrollStartMousePos); |
393 |
281 |
394 if (d->mDraggedItem) { |
282 if (d->mDraggedItem) { |
395 d->mDraggedItem->translate(delta.x(), delta.y()); |
283 d->mDraggedItem->translate(delta.x(), delta.y()); |
396 } |
284 } |
397 } |
|
398 } |
|
399 |
|
400 |
|
401 |
|
402 /*! |
|
403 \reimp |
|
404 */ |
|
405 void HbListView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) |
|
406 { |
|
407 Q_D(HbListView); |
|
408 |
|
409 if (d->mArrangeMode |
|
410 && d->mSelectionMode == HbAbstractItemView::NoSelection |
|
411 && d->mDraggedItem) { |
|
412 |
|
413 disconnect(this, SIGNAL(scrollPositionChanged(QPointF)), this, SLOT(scrolling(QPointF))); |
|
414 |
|
415 if (isScrolling()) { |
|
416 d->stopAnimating(); |
|
417 } |
|
418 |
|
419 // remove item's drag indications |
|
420 d->mDraggedItem->setOpacity(1.0); |
|
421 d->mDraggedItem->setTransform(d->mOriginalTransform); |
|
422 d->mDraggedItem->setZValue(d->mDraggedItem->zValue() - 1); |
|
423 d->mDraggedItem->setPressed(false); |
|
424 |
|
425 if (d->itemAt(event->scenePos())) { |
|
426 int downTime = d->mMousePressTimer.elapsed(); |
|
427 // this seems to be a flick rather than item move, so start |
|
428 // scrolling |
|
429 qreal distance = event->scenePos().y() - d->mMousePressPos.y(); |
|
430 if (downTime > 0 && downTime < FLICK_TIMEOUT |
|
431 && qAbs(distance) > FLICKMINDISTANCE ) { |
|
432 d->animateScroll(QPointF (0.0f, (distance * 1000 / downTime) * SCROLLSPEED_FACTOR)); |
|
433 } |
|
434 } |
|
435 |
|
436 Hb::InteractionModifiers modifiers = 0; |
|
437 if (d->mWasScrolling) { |
|
438 modifiers |= Hb::ModifierScrolling; |
|
439 } |
|
440 HbWidgetFeedback::triggered(d->mDraggedItem,Hb::InstantReleased,modifiers); |
|
441 d->mDraggedItem = 0; |
|
442 |
|
443 } else { |
|
444 HbAbstractItemView::mouseReleaseEvent(event); |
|
445 } |
285 } |
446 } |
286 } |
447 |
287 |
448 /*! |
288 /*! |
449 Moves the item in row \a from to row \a to. |
289 Moves the item in row \a from to row \a to. |
516 |
355 |
517 void HbListView::rowsRemoved(const QModelIndex &parent, int start, int end) |
356 void HbListView::rowsRemoved(const QModelIndex &parent, int start, int end) |
518 { |
357 { |
519 Q_D(HbListView); |
358 Q_D(HbListView); |
520 if (parent == d->mModelIterator->rootIndex()) { |
359 if (parent == d->mModelIterator->rootIndex()) { |
521 bool animate = d->mEnabledAnimations & HbAbstractItemView::Disappear ? d->mAnimateItems: false; |
360 if (d->animationEnabled(false)) { |
522 if (animate) { |
|
523 for (int i = 0; i < d->mItemsAboutToBeDeleted.count(); i++) { |
361 for (int i = 0; i < d->mItemsAboutToBeDeleted.count(); i++) { |
524 HbEffect::start(d->mItemsAboutToBeDeleted.at(i), |
362 QGraphicsItem *item = d->mItemsAboutToBeDeleted.at(i); |
|
363 HbEffect::cancel(item, "appear"); |
|
364 |
|
365 item->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); |
|
366 HbEffect::start(item, |
525 "viewitem", |
367 "viewitem", |
526 "disappear", |
368 "disappear", |
527 d->mContainer, |
369 d->mContainer, |
528 "animationFinished"); |
370 "animationFinished"); |
529 } |
371 } |
530 d->mItemsAboutToBeDeleted.clear(); |
372 d->mItemsAboutToBeDeleted.clear(); |
531 } |
373 } |
532 HbAbstractItemView::rowsRemoved(parent, start, end); |
374 HbAbstractItemView::rowsRemoved(parent, start, end); |
533 } |
375 } |