src/hbplugins/feedback/feedbackeffectplugin/hbfeedbackeffectengine.cpp
changeset 2 06ff229162e9
parent 1 f7ac710697a9
child 5 627c4a0fd0e7
equal deleted inserted replaced
1:f7ac710697a9 2:06ff229162e9
    24 ****************************************************************************/
    24 ****************************************************************************/
    25 
    25 
    26 #include "hbfeedbackeffectengine.h"
    26 #include "hbfeedbackeffectengine.h"
    27 #include "hbfeedbackeffectutils.h"
    27 #include "hbfeedbackeffectutils.h"
    28 
    28 
    29 #include <hbfeedbackplayer.h>
       
    30 #include <hbinstantfeedback.h>
    29 #include <hbinstantfeedback.h>
    31 #include <hbcontinuousfeedback.h>
    30 #include <hbcontinuousfeedback.h>
    32 
    31 
    33 #include <hbwidget.h>
    32 #include <hbwidget.h>
    34 #include <hbabstractitemview.h>
    33 #include <hbabstractitemview.h>
    40 #include <hbabstractedit.h>
    39 #include <hbabstractedit.h>
    41 #include "hbmenucontainer_p.h"
    40 #include "hbmenucontainer_p.h"
    42 #include "hbinputvirtualrocker.h"
    41 #include "hbinputvirtualrocker.h"
    43 #include <hbnamespace_p.h>
    42 #include <hbnamespace_p.h>
    44 
    43 
    45 /*!
    44 /*
    46     Constructor
    45     Constructor
    47 */
    46 */
    48 HbFeedbackEffectEngine::HbFeedbackEffectEngine() : activelyScrollingItemView(0), previousCursorPosition(0)
    47 HbFeedbackEffectEngine::HbFeedbackEffectEngine() : activelyScrollingItemView(0), previousCursorPosition(0)
    49 {
    48 {
    50     // initialize
    49     instantFeedback = new HbInstantFeedback(HbFeedback::None);
    51     HbFeedbackPlayer::instance();
    50 }
    52 }
    51 
    53 
    52 /*
    54 /*!
       
    55     Destructor
    53     Destructor
    56 */
    54 */
    57 HbFeedbackEffectEngine::~HbFeedbackEffectEngine()
    55 HbFeedbackEffectEngine::~HbFeedbackEffectEngine()
    58 {
    56 {
    59     if (hbFeedbackPlayer) {
    57     if(instantFeedback)
    60         foreach(int identifier, continuousFeedbacks) {
    58         delete instantFeedback;
    61             hbFeedbackPlayer->cancelContinuousFeedback(identifier);
    59     foreach(HbContinuousFeedback *feedback, continuousFeedbacks) {
    62         }
    60         feedback->stop();
       
    61         delete feedback;
    63     }
    62     }
    64 
    63 
    65     continuousFeedbacks.clear();
    64     continuousFeedbacks.clear();
    66     boundaryWidgets.clear();
    65     boundaryWidgets.clear();
    67 }
    66 }
   228 bool HbFeedbackEffectEngine::widgetOverridesModalities(const HbWidget *widget,Hb::ContinuousInteraction interaction) {
   227 bool HbFeedbackEffectEngine::widgetOverridesModalities(const HbWidget *widget,Hb::ContinuousInteraction interaction) {
   229     return (widget == overrider.widget && overrider.overridesModalities && overrider.continuousInteraction == interaction);
   228     return (widget == overrider.widget && overrider.overridesModalities && overrider.continuousInteraction == interaction);
   230 }
   229 }
   231 
   230 
   232 
   231 
   233 /*!
   232 /*
   234     Called by the feedback manager when an interaction is triggered.
   233     Called by the feedback manager when an interaction is triggered.
   235 */
   234 */
   236 void HbFeedbackEffectEngine::triggered(const HbWidget *widget, Hb::InstantInteraction interaction, Hb::InteractionModifiers modifiers)
   235 void HbFeedbackEffectEngine::triggered(const HbWidget *widget, Hb::InstantInteraction interaction, Hb::InteractionModifiers modifiers)
   237 {
   236 {
   238     
   237     
   263         // use default values for unspecified effect/modalities
   262         // use default values for unspecified effect/modalities
   264         HbFeedbackEngine::triggered(widget,interaction,modifiers);
   263         HbFeedbackEngine::triggered(widget,interaction,modifiers);
   265     }
   264     }
   266 }
   265 }
   267 
   266 
   268 /*!
   267 /*
   269     Called by the feedback manager when a widget is pressed.
   268     Called by the feedback manager when a widget is pressed.
   270 */
   269 */
   271 void HbFeedbackEffectEngine::pressed(const HbWidget *widget)
   270 void HbFeedbackEffectEngine::pressed(const HbWidget *widget)
   272 {
   271 {
   273     HbFeedback::InstantEffect effect = HbFeedback::None;
   272     HbFeedback::InstantEffect effect = HbFeedback::None;
   287     }
   286     }
   288 
   287 
   289     playInstantFeedback(widget, effect, modalities);
   288     playInstantFeedback(widget, effect, modalities);
   290 }
   289 }
   291 
   290 
   292 /*!
   291 /*
   293     Called by the feedback manager when a widget is released.
   292     Called by the feedback manager when a widget is released.
   294 */
   293 */
   295 void HbFeedbackEffectEngine::released(const HbWidget *widget)
   294 void HbFeedbackEffectEngine::released(const HbWidget *widget)
   296 {
   295 {
   297     HbFeedback::InstantEffect effect = HbFeedback::None;
   296     HbFeedback::InstantEffect effect = HbFeedback::None;
   341     playInstantFeedback(widget,effect, modalities);
   340     playInstantFeedback(widget,effect, modalities);
   342 
   341 
   343     // normally touch end feedback effect is initiated with a clicked signal
   342     // normally touch end feedback effect is initiated with a clicked signal
   344 }
   343 }
   345 
   344 
   346 /*!
   345 /*
   347     Called by the feedback manager when a long press is detected for a widget.
   346     Called by the feedback manager when a long press is detected for a widget.
   348 */
   347 */
   349 void HbFeedbackEffectEngine::longPressed(const HbWidget *widget)
   348 void HbFeedbackEffectEngine::longPressed(const HbWidget *widget)
   350 {
   349 {
   351     HbFeedback::InstantEffect effect = HbFeedback::None;
   350     HbFeedback::InstantEffect effect = HbFeedback::None;
   354 
   353 
   355     if(widgetOverridesEffect(widget, interaction)) {
   354     if(widgetOverridesEffect(widget, interaction)) {
   356         effect = overrider.newInstantEffect;
   355         effect = overrider.newInstantEffect;
   357     } else {
   356     } else {
   358         effect = HbFeedback::None;
   357         effect = HbFeedback::None;
   359         if (widget->type() == Hb::ItemType_InputCharacterButton) {
   358         if (widget->type() == Hb::ItemType_InputButtonGroup) {
   360             effect = HbFeedback::SensitiveKeypad;
   359             effect = HbFeedback::SensitiveKeypad;
   361         }
   360         }
   362         else {
   361         else {
   363             effect = HbFeedback::LongPress;
   362             effect = HbFeedback::LongPress;
   364         }
   363         }
   372 
   371 
   373     playInstantFeedback(widget, effect, modalities);
   372     playInstantFeedback(widget, effect, modalities);
   374 
   373 
   375 }
   374 }
   376 
   375 
   377 /*!
   376 /*
   378     Called by the feedback manager when a widget is clicked.
   377     Called by the feedback manager when a widget is clicked.
   379 */
   378 */
   380 void HbFeedbackEffectEngine::clicked(const HbWidget *widget)
   379 void HbFeedbackEffectEngine::clicked(const HbWidget *widget)
   381 {
   380 {
   382     HbFeedback::InstantEffect effect = HbFeedback::None ;
   381     HbFeedback::InstantEffect effect = HbFeedback::None ;
   400     }
   399     }
   401 
   400 
   402     playInstantFeedback(widget, effect, modalities);
   401     playInstantFeedback(widget, effect, modalities);
   403 }
   402 }
   404 
   403 
   405 /*!
   404 /*
   406     Called by the feedback manager when keyrepeats are detected for a widget.
   405     Called by the feedback manager when keyrepeats are detected for a widget.
   407 */
   406 */
   408 void HbFeedbackEffectEngine::keyRepeated(const HbWidget *widget)
   407 void HbFeedbackEffectEngine::keyRepeated(const HbWidget *widget)
   409 {
   408 {
   410     HbFeedback::InstantEffect effect = HbFeedback::None ;
   409     HbFeedback::InstantEffect effect = HbFeedback::None ;
   424     }
   423     }
   425 
   424 
   426     playInstantFeedback(widget, effect, modalities);
   425     playInstantFeedback(widget, effect, modalities);
   427 }
   426 }
   428 
   427 
   429 /*!
   428 /*
   430     Called by the feedback manager when a dragged over event is detected for a widget.
   429     Called by the feedback manager when a dragged over event is detected for a widget.
   431 */
   430 */
   432 void HbFeedbackEffectEngine::draggedOver(const HbWidget *widget)
   431 void HbFeedbackEffectEngine::draggedOver(const HbWidget *widget)
   433 {
   432 {
   434     HbFeedback::InstantEffect effect = HbFeedback::None ;
   433     HbFeedback::InstantEffect effect = HbFeedback::None ;
   474     }
   473     }
   475 
   474 
   476     playInstantFeedback(widget, effect, modalities);
   475     playInstantFeedback(widget, effect, modalities);
   477 }
   476 }
   478 
   477 
   479 /*!
   478 /*
   480     Called by the feedback manager when a widget is flicked.
   479     Called by the feedback manager when a widget is flicked.
   481 */
   480 */
   482 void HbFeedbackEffectEngine::flicked(const HbWidget *widget)
   481 void HbFeedbackEffectEngine::flicked(const HbWidget *widget)
   483 {
   482 {
   484     HbFeedback::InstantEffect effect = HbFeedback::None ;
   483     HbFeedback::InstantEffect effect = HbFeedback::None ;
   498     }
   497     }
   499 
   498 
   500     playInstantFeedback(widget, effect, modalities);
   499     playInstantFeedback(widget, effect, modalities);
   501 }
   500 }
   502 
   501 
   503 /*!
   502 /*
   504     Called by the feedback manager when a scroll area widget is flicked or dragged and the boundary reached.
   503     Called by the feedback manager when a scroll area widget is flicked or dragged and the boundary reached.
   505 */
   504 */
   506 void HbFeedbackEffectEngine::boundaryReached(const HbWidget *widget)
   505 void HbFeedbackEffectEngine::boundaryReached(const HbWidget *widget)
   507 {
   506 {
   508     boundaryWidgets.append(widget);
   507     boundaryWidgets.append(widget);
   509 }
   508 }
   510 
   509 
   511 /*!
   510 /*
   512     Called by the feedback manager when a rotate gesture is recognized for a widget.
   511     Called by the feedback manager when a rotate gesture is recognized for a widget.
   513 */
   512 */
   514 void HbFeedbackEffectEngine::rotated90Degrees(const HbWidget *widget)
   513 void HbFeedbackEffectEngine::rotated90Degrees(const HbWidget *widget)
   515 {
   514 {
   516     HbFeedback::InstantEffect effect = HbFeedback::None ;
   515     HbFeedback::InstantEffect effect = HbFeedback::None ;
   531     }
   530     }
   532 
   531 
   533     playInstantFeedback(widget, effect, modalities);
   532     playInstantFeedback(widget, effect, modalities);
   534 }
   533 }
   535 
   534 
   536 /*!
   535 /*
   537     Called by the feedback manager when a popup opens.
   536     Called by the feedback manager when a popup opens.
   538 */
   537 */
   539 void HbFeedbackEffectEngine::popupOpened(const HbWidget *widget)
   538 void HbFeedbackEffectEngine::popupOpened(const HbWidget *widget)
   540 {
   539 {
   541     HbFeedback::Modalities modalities = 0 ;
   540     HbFeedback::Modalities modalities = 0 ;
   554             playInstantFeedback(widget, HbFeedback::PopupOpen, modalities);
   553             playInstantFeedback(widget, HbFeedback::PopupOpen, modalities);
   555         }
   554         }
   556     }
   555     }
   557 }
   556 }
   558 
   557 
   559 /*!
   558 /*
   560     Called by the feedback manager when a popup closes.
   559     Called by the feedback manager when a popup closes.
   561 */
   560 */
   562 void HbFeedbackEffectEngine::popupClosed(const HbWidget *widget)
   561 void HbFeedbackEffectEngine::popupClosed(const HbWidget *widget)
   563 {
   562 {
   564     HbFeedback::Modalities modalities = 0 ;
   563     HbFeedback::Modalities modalities = 0 ;
   577             playInstantFeedback(widget, HbFeedback::PopupClose, modalities);
   576             playInstantFeedback(widget, HbFeedback::PopupClose, modalities);
   578         }
   577         }
   579     }
   578     }
   580 }
   579 }
   581 
   580 
   582 /*!
   581 /*
   583     Called by the feedback manager when an item view selection has changed.
   582     Called by the feedback manager when an item view selection has changed.
   584 */
   583 */
   585 void HbFeedbackEffectEngine::selectionChanged(const HbWidget *widget)
   584 void HbFeedbackEffectEngine::selectionChanged(const HbWidget *widget)
   586 {
   585 {
   587     HbFeedback::InstantEffect effect = HbFeedback::None ;
   586     HbFeedback::InstantEffect effect = HbFeedback::None ;
   601     }
   600     }
   602 
   601 
   603     playInstantFeedback(widget, effect, modalities);
   602     playInstantFeedback(widget, effect, modalities);
   604 }
   603 }
   605 
   604 
   606 /*!
   605 /*
   607     Called by the feedback manager when multitouch is activated.
   606     Called by the feedback manager when multitouch is activated.
   608 */
   607 */
   609 void HbFeedbackEffectEngine::multitouchActivated(const HbWidget *widget)
   608 void HbFeedbackEffectEngine::multitouchActivated(const HbWidget *widget)
   610 {
   609 {
   611     HbFeedback::InstantEffect effect = HbFeedback::None ;
   610     HbFeedback::InstantEffect effect = HbFeedback::None ;
   625     }
   624     }
   626 
   625 
   627     playInstantFeedback(widget, effect, modalities);
   626     playInstantFeedback(widget, effect, modalities);
   628 }
   627 }
   629 
   628 
   630 /*!
   629 /*
   631     Called by the feedback manager when a continuous interaction is triggered.
   630     Called by the feedback manager when a continuous interaction is triggered.
   632 */
   631 */
   633 void HbFeedbackEffectEngine::continuousTriggered(const HbWidget *widget, Hb::ContinuousInteraction interaction, QPointF delta)
   632 void HbFeedbackEffectEngine::continuousTriggered(const HbWidget *widget, Hb::ContinuousInteraction interaction, QPointF delta)
   634 {
   633 {
   635     HbFeedback::ContinuousEffect effect = HbFeedback::ContinuousNone ;
   634     HbFeedback::ContinuousEffect effect = HbFeedback::ContinuousNone ;
   704                         }
   703                         }
   705                         if (widget != activelyScrollingItemView){
   704                         if (widget != activelyScrollingItemView){
   706                             activelyScrollingItemView = widget;
   705                             activelyScrollingItemView = widget;
   707                             newItemFound = false;
   706                             newItemFound = false;
   708                         }
   707                         }
       
   708                         // To prevent the uninitialized list to cause false new item detections
       
   709                         if (oldVisibleIndexes.empty()) {
       
   710                             newItemFound = false;
       
   711                         }
   709                         oldVisibleIndexes.clear();
   712                         oldVisibleIndexes.clear();
   710                         oldVisibleIndexes = visibleIndexes;
   713                         oldVisibleIndexes = visibleIndexes;
   711                         
   714                         
   712                         if (newItemFound) {
   715                         if (newItemFound) {
   713                             const HbListView* listView = qobject_cast<const HbListView*>(widget);
   716                             const HbListView* listView = qobject_cast<const HbListView*>(widget);
   748 
   751 
   749         }
   752         }
   750     }
   753     }
   751 }
   754 }
   752 
   755 
   753 /*!
   756 /*
   754     Called by the feedback manager when a continuous interaction is stopped.
   757     Called by the feedback manager when a continuous interaction is stopped.
   755 */
   758 */
   756 void HbFeedbackEffectEngine::continuousStopped(const HbWidget *widget, Hb::ContinuousInteraction interaction)
   759 void HbFeedbackEffectEngine::continuousStopped(const HbWidget *widget, Hb::ContinuousInteraction interaction)
   757 {
   760 {
   758     HbFeedback::InstantEffect effect = HbFeedback::None;
   761     HbFeedback::InstantEffect effect = HbFeedback::None;
   786         }
   789         }
   787         playInstantFeedback(widget, effect, modalities);
   790         playInstantFeedback(widget, effect, modalities);
   788     }
   791     }
   789 }
   792 }
   790 
   793 
   791 /*!
   794 /*
   792     Plays the instant feedback.
   795     Plays the instant feedback.
   793 */
   796 */
   794 void HbFeedbackEffectEngine::playInstantFeedback(const HbWidget* widget, HbFeedback::InstantEffect effect, HbFeedback::Modalities modalities)
   797 void HbFeedbackEffectEngine::playInstantFeedback(const HbWidget* widget, HbFeedback::InstantEffect effect, HbFeedback::Modalities modalities)
   795 {
   798 {
   796     const QGraphicsView* view = widget->mainWindow();
   799     const QGraphicsView* view = widget->mainWindow();
       
   800     if (view && HbFeedbackEffectUtils::isFeedbackAllowed(widget) && instantFeedback) {
       
   801         instantFeedback->setInstantEffect(effect);
       
   802         instantFeedback->setRect(widget, view);
       
   803         instantFeedback->setOwningWindow(view);
       
   804         instantFeedback->setModalities(modalities);
       
   805         
       
   806         if (instantFeedback->isLocated()) {
       
   807             instantFeedback->play();
       
   808         }
       
   809     }
       
   810 }
       
   811 
       
   812 /*
       
   813     Plays the continuous feedback.
       
   814 */
       
   815 void HbFeedbackEffectEngine::playContinuousFeedback(const HbWidget* widget, HbFeedback::ContinuousEffect effect, int intensity, HbFeedback::Modalities modalities)
       
   816 {
       
   817     const QGraphicsView* view = widget->mainWindow();
       
   818 
       
   819     // if feedback can be played
   797     if (view && HbFeedbackEffectUtils::isFeedbackAllowed(widget)) {
   820     if (view && HbFeedbackEffectUtils::isFeedbackAllowed(widget)) {
   798         HbInstantFeedback feedback(effect);
   821 
   799         feedback.setRect(widget, view);
   822         // if this widget has been playing
   800         feedback.setOwningWindow(view);
   823         if (continuousFeedbacks.contains(widget)) {
   801         feedback.setModalities(modalities);
   824             HbContinuousFeedback* feedback = continuousFeedbacks.value(widget);
   802 
   825 
   803         if (hbFeedbackPlayer && feedback.isLocated()) {
   826             // if this feedback is already playing then only its effect and intensity are updated
   804             hbFeedbackPlayer->playInstantFeedback(feedback);
   827             feedback->setModalities(modalities);
   805         }
   828             feedback->setOwningWindow(view);
   806     }
   829             feedback->setRect(widget, view);
   807 }
   830             feedback->setContinuousEffect(effect);
   808 
   831             feedback->setIntensity(intensity);
   809 /*!
   832             // if this feedback is not being played, play it
   810     Plays the continuous feedback.
   833             if (!feedback->isPlaying()) {
   811 */
   834                 feedback->play();
   812 void HbFeedbackEffectEngine::playContinuousFeedback(const HbWidget* widget, HbFeedback::ContinuousEffect effect, int intensity, HbFeedback::Modalities modalities)
   835             }
   813 {
   836         } else {
   814     const QGraphicsView* view = widget->mainWindow();
   837             // this widget has not played anything before
   815     if (view && HbFeedbackEffectUtils::isFeedbackAllowed(widget)) {
   838             HbContinuousFeedback *feedback = new HbContinuousFeedback();
   816         HbContinuousFeedback feedback(effect,view);
   839             feedback->setModalities(modalities);
   817         feedback.setRect(widget, view);
   840             feedback->setOwningWindow(view);
   818         feedback.setIntensity(intensity);
   841             feedback->setRect(widget, view);
   819         feedback.setModalities(modalities);
   842             feedback->setContinuousEffect(effect);
   820 
   843             feedback->setIntensity(intensity);
   821         if (hbFeedbackPlayer && feedback.isLocated()) {
   844             continuousFeedbacks.insert(widget, feedback);
   822             // if continuous feedback is still active and not stopped by continuous feedback timeout
   845             feedback->play();
   823             if (continuousFeedbacks.contains(widget)
   846         }
   824                 && hbFeedbackPlayer->continuousFeedbackOngoing(continuousFeedbacks.value(widget))) {
   847     }
   825                 hbFeedbackPlayer->updateContinuousFeedback(continuousFeedbacks.value(widget), feedback);
   848 }
   826             } else {
   849 
   827                 // if timeout has happened remove the item from the map storing continuous feedback identifiers
   850 /*
   828                 if (continuousFeedbacks.contains(widget)) {
       
   829                     continuousFeedbacks.remove(widget);
       
   830                 }
       
   831                 // create a new continuous feedback
       
   832                 continuousFeedbacks.insert(widget, hbFeedbackPlayer->startContinuousFeedback(feedback));
       
   833             }
       
   834         }
       
   835     }
       
   836 }
       
   837 
       
   838 /*!
       
   839     Cancels the playing of a continuous feedback.
   851     Cancels the playing of a continuous feedback.
   840 */
   852 */
   841 void HbFeedbackEffectEngine::cancelContinuousFeedback(const HbWidget* widget)
   853 void HbFeedbackEffectEngine::cancelContinuousFeedback(const HbWidget* widget)
   842 {
   854 {
   843     if (hbFeedbackPlayer && continuousFeedbacks.contains(widget)) {
   855     if (continuousFeedbacks.contains(widget)) {
   844         hbFeedbackPlayer->cancelContinuousFeedback(continuousFeedbacks.take(widget));
   856         HbContinuousFeedback *feedback = continuousFeedbacks.take(widget);
   845     }
   857         feedback->stop();
   846 }
   858         delete feedback;
   847 
   859     }
       
   860 }
       
   861