36 #include <hblistview.h> |
36 #include <hblistview.h> |
37 #include <hbgridview.h> |
37 #include <hbgridview.h> |
38 #include <hbmainwindow.h> |
38 #include <hbmainwindow.h> |
39 #include <hbabstractedit.h> |
39 #include <hbabstractedit.h> |
40 #include "hbmenucontainer_p.h" |
40 #include "hbmenucontainer_p.h" |
41 #include "hbinputvirtualrocker.h" |
|
42 #include <hbnamespace_p.h> |
41 #include <hbnamespace_p.h> |
|
42 #include <hbglobal_p.h> // remove with HB_DEPRECATED |
|
43 #include <hbratingslider.h> |
43 |
44 |
44 /* |
45 /* |
45 Constructor |
46 Constructor |
46 */ |
47 */ |
47 HbFeedbackEffectEngine::HbFeedbackEffectEngine() : activelyScrollingItemView(0), previousCursorPosition(0) |
48 HbFeedbackEffectEngine::HbFeedbackEffectEngine() : activelyScrollingItemView(0), previousCursorPosition(0) |
55 HbFeedbackEffectEngine::~HbFeedbackEffectEngine() |
56 HbFeedbackEffectEngine::~HbFeedbackEffectEngine() |
56 { |
57 { |
57 if(instantFeedback) |
58 if(instantFeedback) |
58 delete instantFeedback; |
59 delete instantFeedback; |
59 foreach(HbContinuousFeedback *feedback, continuousFeedbacks) { |
60 foreach(HbContinuousFeedback *feedback, continuousFeedbacks) { |
60 feedback->stop(); |
61 // This implementation expects the platform to stop the feedback on application exit. |
|
62 // At this point the winId might not point to an active window, so cancelling |
|
63 // the ongoing continuous feedbacks could lead to application crash. |
61 delete feedback; |
64 delete feedback; |
62 } |
65 } |
63 |
66 |
64 continuousFeedbacks.clear(); |
67 continuousFeedbacks.clear(); |
65 boundaryWidgets.clear(); |
68 boundaryWidgets.clear(); |
103 propertyName = "rotated90DegreesFeedbackEffect"; |
106 propertyName = "rotated90DegreesFeedbackEffect"; |
104 break; |
107 break; |
105 case Hb::InstantSelectionChanged: |
108 case Hb::InstantSelectionChanged: |
106 propertyName = "selectionChangedFeedbackEffect"; |
109 propertyName = "selectionChangedFeedbackEffect"; |
107 break; |
110 break; |
108 case Hb::InstantMultitouchActivated: |
111 case Hb::InstantAdvancedGestureActivated: |
109 propertyName = "multitouchActivatedFeedbackEffect"; |
112 propertyName = "advancedGestureActivatedFeedbackEffect"; |
110 break; |
113 break; |
111 default: |
114 default: |
112 propertyName = "defaultFeedbackEffect"; |
115 propertyName = "defaultFeedbackEffect"; |
113 break; |
116 break; |
114 } |
117 } |
176 propertyName = "rotated90DegreesFeedbackModalities"; |
179 propertyName = "rotated90DegreesFeedbackModalities"; |
177 break; |
180 break; |
178 case Hb::InstantSelectionChanged: |
181 case Hb::InstantSelectionChanged: |
179 propertyName = "selectionChangedFeedbackModalities"; |
182 propertyName = "selectionChangedFeedbackModalities"; |
180 break; |
183 break; |
181 case Hb::InstantMultitouchActivated: |
184 case Hb::InstantAdvancedGestureActivated: |
182 propertyName = "multitouchActivatedFeedbackModalities"; |
185 propertyName = "advancedGestureActivatedFeedbackModalities"; |
183 break; |
186 break; |
184 default: |
187 default: |
185 propertyName = "defaultFeedbackModalities"; |
188 propertyName = "defaultFeedbackModalities"; |
186 break; |
189 break; |
187 } |
190 } |
386 |
389 |
387 if (continuousFeedbacks.contains(widget)) { |
390 if (continuousFeedbacks.contains(widget)) { |
388 cancelContinuousFeedback(widget); |
391 cancelContinuousFeedback(widget); |
389 } |
392 } |
390 |
393 |
391 if(widgetOverridesEffect( widget, interaction)) { |
394 if(widgetOverridesEffect(widget, interaction)) { |
392 effect = overrider.newInstantEffect; |
395 effect = overrider.newInstantEffect; |
393 } else { |
396 } |
|
397 else { |
394 effect = HbFeedbackEffectUtils::instantOnRelease(widget, modifiers()); |
398 effect = HbFeedbackEffectUtils::instantOnRelease(widget, modifiers()); |
|
399 } |
|
400 |
|
401 // Lists in arrange mode do not react on click |
|
402 if (const HbListViewItem *listViewItem = qobject_cast<const HbListViewItem *>(widget)) { |
|
403 const HbAbstractItemView* itemView = listViewItem->itemView(); |
|
404 if (const HbListView * listView = qobject_cast<const HbListView *>(itemView)) { |
|
405 if(listView->arrangeMode()) { |
|
406 effect = HbFeedback::None; |
|
407 } |
|
408 } |
|
409 } |
|
410 else if (widget->type() == HbPrivate::ItemType_IndicatorButton) { |
|
411 effect = HbFeedback::None; |
395 } |
412 } |
396 |
413 |
397 if(widgetOverridesModalities(widget,interaction)) { |
414 if(widgetOverridesModalities(widget,interaction)) { |
398 modalities = overrider.newModalities ; |
415 modalities = overrider.newModalities ; |
399 } else { |
416 } else { |
443 if (const HbAbstractEdit *edit = qobject_cast<const HbAbstractEdit *>(widget)) { |
460 if (const HbAbstractEdit *edit = qobject_cast<const HbAbstractEdit *>(widget)) { |
444 if (edit->cursorPosition() != previousCursorPosition) { |
461 if (edit->cursorPosition() != previousCursorPosition) { |
445 effect = HbFeedbackEffectUtils::instantOnEditorHighlight(edit, previousCursorPosition) ; |
462 effect = HbFeedbackEffectUtils::instantOnEditorHighlight(edit, previousCursorPosition) ; |
446 previousCursorPosition = edit->cursorPosition(); |
463 previousCursorPosition = edit->cursorPosition(); |
447 } |
464 } |
448 } |
|
449 else if (const HbInputVirtualRocker *trackPoint = qobject_cast<const HbInputVirtualRocker *>(widget)) { |
|
450 if (trackPoint && trackPoint->mainWindow() && trackPoint->mainWindow()->scene() && |
|
451 trackPoint->mainWindow()->scene()->focusItem()) { |
|
452 |
|
453 QGraphicsItem* graphicsItem = trackPoint->mainWindow()->scene()->focusItem(); |
|
454 |
|
455 if (graphicsItem->isWidget()) { |
|
456 if (static_cast<QGraphicsWidget*>(graphicsItem)->inherits("HbAbstractEdit")) { |
|
457 if (HbAbstractEdit* edit = static_cast<HbAbstractEdit*>(graphicsItem)) { |
|
458 if (edit->cursorPosition() != previousCursorPosition) { |
|
459 effect = HbFeedbackEffectUtils::instantOnEditorHighlight(edit, previousCursorPosition); |
|
460 previousCursorPosition = edit->cursorPosition(); |
|
461 } |
|
462 } |
|
463 } |
|
464 else if (static_cast<QGraphicsWidget*>(graphicsItem)->inherits("QGraphicsWebView") ) |
|
465 { |
|
466 // This takes care of the case when the track point is used on a QGraphicsWebView (for e.g. cWRT) |
|
467 QVariant v; |
|
468 v = graphicsItem->scene()->inputMethodQuery( Qt::ImCursorPosition ); |
|
469 if ( v.isValid() && v.canConvert<int>()) { |
|
470 int currentCursorPosition = v.toInt(); |
|
471 if (currentCursorPosition != previousCursorPosition) { |
|
472 effect = HbFeedbackEffectUtils::instantOnEditorHighlight(trackPoint, previousCursorPosition); |
|
473 previousCursorPosition = currentCursorPosition; |
|
474 } |
|
475 } |
|
476 } |
|
477 } |
|
478 } |
|
479 } else { |
465 } else { |
480 effect = HbFeedbackEffectUtils::instantOnDrag(widget, modifiers()); |
466 effect = HbFeedbackEffectUtils::instantOnDrag(widget, modifiers()); |
481 } |
467 } |
482 } |
468 } |
483 |
469 |
619 |
605 |
620 playInstantFeedback(widget, effect, modalities); |
606 playInstantFeedback(widget, effect, modalities); |
621 } |
607 } |
622 |
608 |
623 /* |
609 /* |
624 Called by the feedback manager when multitouch is activated. |
610 Called by the feedback manager when a touch gesture with more than one finger is detected. |
625 */ |
611 */ |
626 void HbFeedbackEffectEngine::multitouchActivated(const HbWidget *widget) |
612 void HbFeedbackEffectEngine::advancedGestureActivated(const HbWidget *widget) |
627 { |
613 { |
628 HbFeedback::InstantEffect effect = HbFeedback::None ; |
614 HbFeedback::InstantEffect effect = HbFeedback::None ; |
629 HbFeedback::Modalities modalities = 0 ; |
615 HbFeedback::Modalities modalities = 0 ; |
630 Hb::InstantInteraction interaction = Hb::InstantMultitouchActivated; |
616 Hb::InstantInteraction interaction = Hb::InstantAdvancedGestureActivated; |
631 |
617 |
632 if(widgetOverridesEffect( widget, interaction)) { |
618 if(widgetOverridesEffect( widget, interaction)) { |
633 effect = overrider.newInstantEffect; |
619 effect = overrider.newInstantEffect; |
634 } else { |
620 } else { |
635 effect = HbFeedback::MultitouchActivate; |
621 effect = HbFeedback::AdvancedGestureActivate; |
636 } |
622 } |
637 |
623 |
638 if(widgetOverridesModalities(widget,interaction)) { |
624 if(widgetOverridesModalities(widget,interaction)) { |
639 modalities = overrider.newModalities ; |
625 modalities = overrider.newModalities ; |
640 } else { |
626 } else { |
689 |
675 |
690 switch(HbFeedbackEffectUtils::widgetFamily(widget)) |
676 switch(HbFeedbackEffectUtils::widgetFamily(widget)) |
691 { |
677 { |
692 case HbFeedbackEffectUtils::Slider: |
678 case HbFeedbackEffectUtils::Slider: |
693 { |
679 { |
694 if (!HbFeedbackEffectUtils::isSliderMoveContinuous(widget)) { |
680 if(!widgetOverridesModalities(widget,interaction)) { |
695 if(!widgetOverridesModalities(widget,interaction)) { |
681 modalities = HbFeedback::Audio | HbFeedback::Tactile; |
696 modalities = HbFeedback::Audio | HbFeedback::Tactile; |
682 } |
|
683 |
|
684 if (const HbRatingSlider *ratingSlider = qobject_cast<const HbRatingSlider *>(widget)) { |
|
685 int sliderValue = ratingSlider->currentRating(); |
|
686 if (sliderValue != previousSliderValue) { |
|
687 playInstantFeedback(widget, HbFeedback::SensitiveSlider, modalities); |
697 } |
688 } |
|
689 previousSliderValue = sliderValue; |
|
690 feedbackPlayed = true; |
|
691 } |
|
692 else if (!HbFeedbackEffectUtils::isSliderMoveContinuous(widget)) { |
698 playInstantFeedback(widget, HbFeedback::SensitiveSlider, modalities); |
693 playInstantFeedback(widget, HbFeedback::SensitiveSlider, modalities); |
699 feedbackPlayed = true; |
694 feedbackPlayed = true; |
700 } |
695 } |
701 break; |
696 break; |
702 } |
697 } |
709 if (interaction == Hb::ContinuousScrolled) { |
704 if (interaction == Hb::ContinuousScrolled) { |
710 // menu widget does scroll feedback elsewhere |
705 // menu widget does scroll feedback elsewhere |
711 if (widget->type() == HbPrivate::ItemType_MenuListView) { |
706 if (widget->type() == HbPrivate::ItemType_MenuListView) { |
712 feedbackPlayed = true; |
707 feedbackPlayed = true; |
713 } |
708 } |
714 if(widget->type() == Hb::ItemType_TumbleView) |
709 if(widget->type() == Hb::ItemType_TumbleView |
|
710 // The condition below should be a temporary fix until the date picker widget returns a |
|
711 // more specific item type that the current ItemType_HbWidget |
|
712 || QString(widget->metaObject()->className()) == "HbDatePickerView") |
715 { |
713 { |
716 if (const HbAbstractItemView * itemView = qobject_cast<const HbAbstractItemView *>(widget)) { |
714 if (const HbAbstractItemView * itemView = qobject_cast<const HbAbstractItemView *>(widget)) { |
717 feedbackPlayed = true; |
715 feedbackPlayed = true; |
718 QList<HbAbstractViewItem *> visibleItems = itemView->visibleItems(); |
716 QList<HbAbstractViewItem *> visibleItems = itemView->visibleItems(); |
719 bool newItemFound(false); |
717 bool newItemFound(false); |