src/hbinput/inputwidgets/hbinputbuttongroup.cpp
changeset 34 ed14f46c0e55
parent 7 923ff622b8b9
equal deleted inserted replaced
31:7516d6d86cf5 34:ed14f46c0e55
    35 
    35 
    36 #include <hbmainwindow.h>
    36 #include <hbmainwindow.h>
    37 #include <hbaction.h>
    37 #include <hbaction.h>
    38 #include <hbevent.h>
    38 #include <hbevent.h>
    39 #include <hbcolorscheme.h>
    39 #include <hbcolorscheme.h>
    40 #include <hbdialog.h>
    40 #include <hbinputpopupbase.h>
    41 #include <hbframeitem.h>
    41 #include <hbframeitem.h>
    42 #include <hbwidgetfeedback.h>
    42 #include <hbwidgetfeedback.h>
    43 #include <hbdeviceprofile.h>
    43 #include <hbdeviceprofile.h>
    44 #include <hbinputregioncollector_p.h>
    44 #include <hbinputregioncollector_p.h>
       
    45 #include <hbinputsettingproxy.h>
    45 #include "hbframedrawerpool_p.h"
    46 #include "hbframedrawerpool_p.h"
    46 
    47 
    47 #include "hbinputbutton.h"
    48 #include "hbinputbutton.h"
       
    49 
       
    50 /*!
       
    51 @stable
       
    52 @hbinput
       
    53 \class HbInputButtonGroup
       
    54 \brief A widget presenting group of buttons for virtual keyboards.
       
    55 
       
    56 HbInputButtonGroup is a widget displaying a mat of buttons, performance-optimized
       
    57 as a single widget instead of multiple separate button widgets.
       
    58 
       
    59 \sa HbInputButton
       
    60 */
    48 
    61 
    49 /// @cond
    62 /// @cond
    50 
    63 
    51 const QString HbNormalBackground("qtg_fr_input_btn_keypad_normal");
    64 const QString HbNormalBackground("qtg_fr_input_btn_keypad_normal");
    52 const QString HbNormalPressedBackground("qtg_fr_input_btn_keypad_pressed");
    65 const QString HbNormalPressedBackground("qtg_fr_input_btn_keypad_pressed");
    70 const QString HbFunctionColorInActive("qtc_input_function_disabled");
    83 const QString HbFunctionColorInActive("qtc_input_function_disabled");
    71 const QString HbFunctionColorLatched("qtc_input_function_latched");
    84 const QString HbFunctionColorLatched("qtc_input_function_latched");
    72 
    85 
    73 const QString HbButtonPreviewColor("qtc_input_preview_normal");
    86 const QString HbButtonPreviewColor("qtc_input_preview_normal");
    74 const QString HbCharacterSelectionPreviewColor("qtc_input_button_accented_normal");
    87 const QString HbCharacterSelectionPreviewColor("qtc_input_button_accented_normal");
    75 
    88 const QString HbHwrSctKeyboard("hwr_symbol_keypad");
    76 const int HbLongPressTimeout = 600;
    89 
       
    90 const int HbLongPressTimeout = 800;
    77 const int HbAutoRepeatTimeout = 100;
    91 const int HbAutoRepeatTimeout = 100;
    78 
    92 
    79 const int HbTextTypeCount = HbInputButton::ButtonTypeCount * HbInputButton::ButtonStateCount;
    93 const int HbTextTypeCount = HbInputButton::ButtonTypeCount * HbInputButton::ButtonStateCount;
    80 const int HbTextLayoutCount = HbTextTypeCount * 3;
    94 const int HbTextLayoutCount = HbTextTypeCount * 3;
    81 
    95 
    82 const qreal HbTextSizeInUnits = 5.75;
    96 const qreal HbTextSizeInUnits = 4.6;
    83 const qreal HbPrimaryTextSizeInUnits = 5.37;
    97 const qreal HbPrimaryTextSizeInUnits = 5.37;
    84 const qreal HbSecondaryTextSizeInUnits = 3.36;
    98 const qreal HbSecondaryTextSizeInUnits = 3.36;
    85 const qreal HbLabelTextSizeInUnits = 9;
    99 const qreal HbLabelTextSizeInUnits = 9;
    86 const qreal HbPrimaryIconSizeInUnits = 5;
   100 const qreal HbPrimaryIconSizeInUnits = 5;
    87 const qreal HbSecondaryIconSizeInUnits = 3.36;
   101 const qreal HbSecondaryIconSizeInUnits = 3.36;
    94 const qreal HbTouchAreaSizeInUnits = 8;
   108 const qreal HbTouchAreaSizeInUnits = 8;
    95 
   109 
    96 HbInputButtonGroupPrivate::HbInputButtonGroupPrivate()
   110 HbInputButtonGroupPrivate::HbInputButtonGroupPrivate()
    97     : mUnitValue(0), mGridSize(1, 1), mButtonBorderSize(1.0), mEnabled(true),
   111     : mUnitValue(0), mGridSize(1, 1), mButtonBorderSize(1.0), mEnabled(true),
    98       mButtonPreviewEnabled(false), mCharacterSelectionPreviewEnabled(false),
   112       mButtonPreviewEnabled(false), mCharacterSelectionPreviewEnabled(false),
    99       mMultiTouchEnabled(true), mCharacterSelectionPreview(0), mBackground(0)
   113       mMultiTouchEnabled(true), mCharacterSelectionPreview(0), mBackground(0),
       
   114       mHasMouseGrab(false)
   100 {
   115 {
   101     for (int i = 0; i < HbTextLayoutCount; ++i) {
   116     for (int i = 0; i < HbTextLayoutCount; ++i) {
   102         mTextLayouts.append(0);
   117         mTextLayouts.append(0);
   103     }
   118     }
   104 
   119 
   345         group->setButtons(buttons);
   360         group->setButtons(buttons);
   346 
   361 
   347         qreal cellWidth = q->boundingRect().width() / mGridSize.width();
   362         qreal cellWidth = q->boundingRect().width() / mGridSize.width();
   348         qreal cellHeight = q->boundingRect().height() / mGridSize.height();
   363         qreal cellHeight = q->boundingRect().height() / mGridSize.height();
   349 
   364 
       
   365         Qt::Orientation orientation = Qt::Horizontal;
       
   366         if (q->mainWindow()) {
       
   367             orientation = q->mainWindow()->orientation();
       
   368         }
       
   369 
   350         // Calculate text size
   370         // Calculate text size
   351         QFont font = HbFontSpec(HbFontSpec::Primary).font();
   371         QFont font = HbFontSpec(HbFontSpec::Primary).font();
   352         font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypeLabel)));
   372         font.setPixelSize(int(group->fontSize(HbInputButtonGroup::ButtonTextTypeLabel)));
   353         QFontMetricsF fontMetrics(font);
   373         QFontMetricsF fontMetrics(font);
   354         qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary));
   374         qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary));
   355 
   375 
   356         // Calculate preview size
   376         // Calculate preview size
   357         qreal width = textWidth + HbPreviewMarginInUnits * mUnitValue;
   377         qreal width = textWidth + HbPreviewMarginInUnits * mUnitValue;
   359             width = item->boundingRect().width();
   379             width = item->boundingRect().width();
   360         } else if (width < HbPreviewWidthInUnits * mUnitValue) {
   380         } else if (width < HbPreviewWidthInUnits * mUnitValue) {
   361             width = HbPreviewWidthInUnits * mUnitValue;
   381             width = HbPreviewWidthInUnits * mUnitValue;
   362         }
   382         }
   363         qreal height = HbPreviewHeightInUnits * mUnitValue;
   383         qreal height = HbPreviewHeightInUnits * mUnitValue;
   364         qreal x = q->scenePos().x() + (item->position().x() + 0.5 * item->size().width()) * cellWidth - 0.5 * width;
   384         qreal x = (item->position().x() + 0.5 * item->size().width()) * cellWidth - 0.5 * width;
   365         if (x < 0) {
   385         if (x < 0) {
   366             x = 0;
   386             x = 0;
   367         } else if (x + width > q->boundingRect().width()) {
   387         } else if (x + width > q->boundingRect().width()) {
   368             x = q->boundingRect().width() - width;
   388             x = q->boundingRect().width() - width;
   369         }
   389         }
   370         qreal y = q->scenePos().y() + item->position().y() * cellHeight - height;
   390         qreal y = item->position().y() * cellHeight - height;
   371         group->setGeometry(QRectF(x, y, width, height));
   391         if (y < 0 && 
       
   392             orientation == Qt::Horizontal &&
       
   393             q->objectName() == HbHwrSctKeyboard) {
       
   394             y = (item->position().y() + 1)* cellHeight;
       
   395         }
       
   396         group->setGeometry(QRectF(q->mapToScene(x, y), QSizeF(width, height)));
   372         if (q->parentItem()) {
   397         if (q->parentItem()) {
   373             group->setZValue(q->parentItem()->zValue() + 1);
   398             group->setZValue(q->parentItem()->zValue() + 1);
   374         }
   399         }
   375 
   400 
   376         group->setButtonBorderSize(0);
   401         group->setButtonBorderSize(0);
   398     if (mCharacterSelectionPreviewEnabled && item->type() != HbInputButton::ButtonTypeFunction &&
   423     if (mCharacterSelectionPreviewEnabled && item->type() != HbInputButton::ButtonTypeFunction &&
   399         item->mappedCharacters().count() > 1) {
   424         item->mappedCharacters().count() > 1) {
   400 
   425 
   401         if (item->type() == HbInputButton::ButtonTypeFunction) {
   426         if (item->type() == HbInputButton::ButtonTypeFunction) {
   402             HbWidgetFeedback::triggered(q, Hb::InstantLongPressed, Hb::ModifierInputFunctionButton);
   427             HbWidgetFeedback::triggered(q, Hb::InstantLongPressed, Hb::ModifierInputFunctionButton);
   403         }
   428         } else {
   404         else {
       
   405             HbWidgetFeedback::triggered(q, Hb::InstantLongPressed);
   429             HbWidgetFeedback::triggered(q, Hb::InstantLongPressed);
   406         }
   430         }
   407 
   431 
   408         mProbabilities.clear();
   432         mProbabilities.clear();
   409         q->cancelButtonPress();
   433         q->cancelButtonPress();
   410 
   434 
   411         // Create and initialize character preview
   435         // Create and initialize character preview
   412         if (!mCharacterSelectionPreview) {
   436         if (!mCharacterSelectionPreview) {
   413             mCharacterSelectionPreview = new HbDialog();
   437             mCharacterSelectionPreview = new HbInputPopupBase();
   414             HbInputRegionCollector::instance()->attach(mCharacterSelectionPreview);
   438             HbInputRegionCollector::instance()->attach(mCharacterSelectionPreview);
   415             mCharacterSelectionPreview->setModal(true);
   439             mCharacterSelectionPreview->setModal(true);
   416             mCharacterSelectionPreview->setBackgroundFaded(false);
   440             mCharacterSelectionPreview->setBackgroundFaded(false);
   417             mCharacterSelectionPreview->setTimeout(HbPopup::NoTimeout);
   441             mCharacterSelectionPreview->setTimeout(HbPopup::NoTimeout);
   418             mCharacterSelectionPreview->setDismissPolicy(HbPopup::TapAnywhere);
   442             mCharacterSelectionPreview->setDismissPolicy(HbPopup::TapAnywhere);
   419             mCharacterSelectionPreview->setFlag(QGraphicsItem::ItemIsPanel, true);
       
   420             mCharacterSelectionPreview->setActive(false);
       
   421             qreal margin = HbPreviewMarginInUnits * mUnitValue * 0.5;
   443             qreal margin = HbPreviewMarginInUnits * mUnitValue * 0.5;
   422             mCharacterSelectionPreview->setContentsMargins(margin, 0, margin, 0);
   444             mCharacterSelectionPreview->setContentsMargins(margin, 0, margin, 0);
   423         }
   445         }
   424 
   446 
   425         HbInputButtonGroup *group = new HbInputButtonGroup(QSize(item->mappedCharacters().count(), 1));
   447         HbInputButtonGroup *group = new HbInputButtonGroup(QSize(item->mappedCharacters().count(), 1));
   483     int index = mButtonGridPositions.value(QPair<int, int>(column, row), -1);
   505     int index = mButtonGridPositions.value(QPair<int, int>(column, row), -1);
   484 
   506 
   485     if (index >= 0 && index < mButtonData.count()) {
   507     if (index >= 0 && index < mButtonData.count()) {
   486         HbInputButton *item = mButtonData.at(index);
   508         HbInputButton *item = mButtonData.at(index);
   487 
   509 
       
   510         // Check whether we are actually supposed to handle the event.
   488         if ((item->state() != HbInputButton::ButtonStateReleased &&
   511         if ((item->state() != HbInputButton::ButtonStateReleased &&
   489              item->state() != HbInputButton::ButtonStateLatched) ||
   512              item->state() != HbInputButton::ButtonStateLatched) ||
   490             (mCharacterSelectionPreview && mCharacterSelectionPreview->isVisible())) {
   513             (mCharacterSelectionPreview && mCharacterSelectionPreview->isVisible())) {
   491             if (item->state() == HbInputButton::ButtonStateDisabled) {
   514             if (item->state() == HbInputButton::ButtonStateDisabled) {
   492                 startLongPress(index);
   515                 startLongPress(index);
       
   516                 mActiveButtons.append(index);        
       
   517                 item->setLastTriggeredPosition(position);
   493             }
   518             }
   494             return;
   519             return;
   495         }
   520         }
       
   521 
       
   522         mActiveButtons.append(index);        
       
   523         item->setLastTriggeredPosition(position);
   496         
   524         
   497         if (item->type() == HbInputButton::ButtonTypeFunction) {
   525         if (item->type() == HbInputButton::ButtonTypeFunction) {
   498             HbWidgetFeedback::triggered(q, Hb::InstantPressed, Hb::ModifierInputFunctionButton);
   526             HbWidgetFeedback::triggered(q, Hb::InstantPressed, Hb::ModifierInputFunctionButton);
   499         }
   527         } else {
   500         else {
       
   501             HbWidgetFeedback::triggered(q, Hb::InstantPressed);        
   528             HbWidgetFeedback::triggered(q, Hb::InstantPressed);        
   502         }
   529         }
   503 
   530 
   504         item->setState(HbInputButton::ButtonStatePressed);
   531         item->setState(HbInputButton::ButtonStatePressed);
   505         updateGraphics(QSizeF(q->boundingRect().width(), q->boundingRect().height()));
   532         updateGraphics(QSizeF(q->boundingRect().width(), q->boundingRect().height()));
   508 
   535 
   509         showButtonPreview(item);
   536         showButtonPreview(item);
   510 
   537 
   511         startLongPress(index);
   538         startLongPress(index);
   512 
   539 
   513         if (!mUsedCustomButtons.contains(index)) {
   540         if (emitSignal) {
   514             if (emitSignal) {
   541             item->setTouchPointPosition(position);
       
   542             if (!mUsedCustomButtons.contains(index)) {
   515                 QString text;
   543                 QString text;
   516                 if (item->type() == HbInputButton::ButtonTypeLabel) {
   544                 if (item->type() == HbInputButton::ButtonTypeLabel) {
   517                     text = item->text(HbInputButton::ButtonTextIndexPrimary);
   545                     text = item->text(HbInputButton::ButtonTextIndexPrimary);
   518                 }
   546                 }
   519                 QKeyEvent event(QEvent::KeyPress, item->keyCode(), Qt::NoModifier, text);
   547                 QKeyEvent event(QEvent::KeyPress, item->keyCode(), Qt::NoModifier, text);
   539     int index = mButtonGridPositions.value(QPair<int, int>(column, row), -1);
   567     int index = mButtonGridPositions.value(QPair<int, int>(column, row), -1);
   540 
   568 
   541     if (index >= 0 && index < mButtonData.count()) {
   569     if (index >= 0 && index < mButtonData.count()) {
   542         HbInputButton *item = mButtonData.at(index);
   570         HbInputButton *item = mButtonData.at(index);
   543 
   571 
       
   572         // Check whether we are actually supposed to handle the event.
   544         if ((item->state() != HbInputButton::ButtonStateReleased &&
   573         if ((item->state() != HbInputButton::ButtonStateReleased &&
   545              item->state() != HbInputButton::ButtonStateLatched) ||
   574              item->state() != HbInputButton::ButtonStateLatched) ||
   546             (mCharacterSelectionPreview && mCharacterSelectionPreview->isVisible())) {
   575             (mCharacterSelectionPreview && mCharacterSelectionPreview->isVisible())) {
   547             if (item->state() == HbInputButton::ButtonStateDisabled) {
   576             if (item->state() == HbInputButton::ButtonStateDisabled) {
   548                 startLongPress(index);
   577                 startLongPress(index);
       
   578                 mActiveButtons.append(index);        
       
   579                 item->setLastTriggeredPosition(position);
   549             }
   580             }
   550             return;
   581             return;
   551         }
   582         }
       
   583 
       
   584         mActiveButtons.append(index);        
       
   585         item->setLastTriggeredPosition(position);
   552 
   586 
   553         if (item->type() == HbInputButton::ButtonTypeFunction) {
   587         if (item->type() == HbInputButton::ButtonTypeFunction) {
   554             HbWidgetFeedback::triggered(q, Hb::InstantPressed, Hb::ModifierInputFunctionButton);
   588             HbWidgetFeedback::triggered(q, Hb::InstantPressed, Hb::ModifierInputFunctionButton);
   555         }
   589         } else {
   556         else {
       
   557             HbWidgetFeedback::triggered(q, Hb::InstantPressed);        
   590             HbWidgetFeedback::triggered(q, Hb::InstantPressed);        
   558         }
   591         }
   559 
   592 
   560         item->setState(HbInputButton::ButtonStatePressed);
   593         item->setState(HbInputButton::ButtonStatePressed);
   561         updateGraphics(QSizeF(q->boundingRect().width(), q->boundingRect().height()));
   594         updateGraphics(QSizeF(q->boundingRect().width(), q->boundingRect().height()));
   581 
   614 
   582 void HbInputButtonGroupPrivate::moveEvent(const QPointF &oldPosition, const QPointF &newPosition)
   615 void HbInputButtonGroupPrivate::moveEvent(const QPointF &oldPosition, const QPointF &newPosition)
   583 {
   616 {
   584     Q_Q(HbInputButtonGroup);
   617     Q_Q(HbInputButtonGroup);
   585 
   618 
   586     int oldColumn = static_cast<int>(oldPosition.x() / (q->boundingRect().width() / mGridSize.width()));
   619     int itemIndex = activeButtonIndex(oldPosition);
   587     int oldRow = static_cast<int>(oldPosition.y() / (q->boundingRect().height() / mGridSize.height()));
   620     if (itemIndex >= 0) {
       
   621         HbInputButton* activeItem = mButtonData.at(itemIndex);
       
   622         // If move event happens within short timeout near the original touch point 
       
   623         // or after timeout inside button's touch area the move event needs to be ignored
       
   624         if (activeItem && activeItem->suppressMoveEvent(newPosition)) {
       
   625             return;
       
   626         }
       
   627     }
       
   628     
   588     int newColumn = static_cast<int>(newPosition.x() / (q->boundingRect().width() / mGridSize.width()));
   629     int newColumn = static_cast<int>(newPosition.x() / (q->boundingRect().width() / mGridSize.width()));
   589     int newRow = static_cast<int>(newPosition.y() / (q->boundingRect().height() / mGridSize.height()));
   630     int newRow = static_cast<int>(newPosition.y() / (q->boundingRect().height() / mGridSize.height()));
   590 
   631 
   591     int oldIndex = mButtonGridPositions.value(QPair<int, int>(oldColumn, oldRow), -1);
       
   592     int newIndex = mButtonGridPositions.value(QPair<int, int>(newColumn, newRow), -1);
   632     int newIndex = mButtonGridPositions.value(QPair<int, int>(newColumn, newRow), -1);
   593 
   633 
   594     // Check if movement happens inside button group
   634     // Check if movement happens inside button group and both oldIndex and newIndex are valid
   595     if (newPosition.x() >= 0 && newPosition.x() < q->boundingRect().width() &&
   635     if (newPosition.x() >= 0 && newPosition.x() < q->boundingRect().width() &&
   596         newPosition.y() >= 0 && newPosition.y() < q->boundingRect().height() &&
   636         newPosition.y() >= 0 && newPosition.y() < q->boundingRect().height() &&
   597         oldPosition.x() >= 0 && oldPosition.x() < q->boundingRect().width() &&
   637         oldPosition.x() >= 0 && oldPosition.x() < q->boundingRect().width() &&
   598         oldPosition.y() >= 0 && oldPosition.y() < q->boundingRect().height()) {
   638         oldPosition.y() >= 0 && oldPosition.y() < q->boundingRect().height() &&
   599 
   639         itemIndex >= 0 && newIndex >= 0) {
   600         if (oldIndex != newIndex) {
   640 
       
   641         // When user moves a finger on the keyboard, currently active button(s) should consume events
       
   642         // as long as the finger position is within the touch area of the button. Button should be removed
       
   643         // from the mActiveButtons, when finger moves outside the button's touch area.
       
   644 
       
   645         // The button, this event belongs to, can be determined by checking which button handled the
       
   646         // 'oldPosition' coordinate in previous run of either pressEvent or moveEvent.
       
   647         // If button is no longer active just return.
       
   648         int activeItemIndex = activeButtonIndex(oldPosition);
       
   649         if (activeItemIndex < 0) {
       
   650             return;
       
   651         }
       
   652         HbInputButton* activeItem = mButtonData.at(activeItemIndex);        
       
   653 
       
   654         // In case user has moved finger far enough away from the original button, old active
       
   655         // item needs to be removed and the new one should be added to active list.
       
   656         if (!mActiveButtons.contains(newIndex)) {
   601             releaseEvent(oldPosition, false);
   657             releaseEvent(oldPosition, false);
   602             pressEvent(newPosition, false);
   658             pressEvent(newPosition, false);
   603 
   659 
   604             QString text;
   660             QString text;
   605             HbInputButton *oldItem = mButtonData.at(oldIndex);
   661             if (activeItem->type() == HbInputButton::ButtonTypeLabel) {
   606             if (oldItem->type() == HbInputButton::ButtonTypeLabel) {
   662                 text = activeItem->text(HbInputButton::ButtonTextIndexPrimary);
   607                 text = oldItem->text(HbInputButton::ButtonTextIndexPrimary);
   663             }
   608             }
   664             QKeyEvent releaseEvent(QEvent::KeyRelease, activeItem->keyCode(), Qt::NoModifier, text);
   609             QKeyEvent releaseEvent(QEvent::KeyRelease, oldItem->keyCode(), Qt::NoModifier, text);
       
   610 
   665 
   611             HbInputButton *newItem = mButtonData.at(newIndex);
   666             HbInputButton *newItem = mButtonData.at(newIndex);
   612             if (newItem->type() == HbInputButton::ButtonTypeLabel) {
   667             if (newItem->type() == HbInputButton::ButtonTypeLabel) {
   613                 text = newItem->text(HbInputButton::ButtonTextIndexPrimary);
   668                 text = newItem->text(HbInputButton::ButtonTextIndexPrimary);
   614             }
   669             }
   615             QKeyEvent pressEvent(QEvent::KeyPress, newItem->keyCode(), Qt::NoModifier, text);
   670             QKeyEvent pressEvent(QEvent::KeyPress, newItem->keyCode(), Qt::NoModifier, text);
   616 
   671 
   617             q->emitPressedButtonChanged(releaseEvent, pressEvent);
   672             q->emitPressedButtonChanged(releaseEvent, pressEvent);
       
   673         } else {
       
   674             // Even though we do nothing with this button this time, update the status
       
   675             // of the item, so next time this function is invoked, this button is correctly
       
   676             // detected as the owner of the new event.
       
   677             activeItem->setLastTriggeredPosition(newPosition);
   618         }
   678         }
   619     } else {
   679     } else {
   620         // Move event came from outside button group so create new release and press events
   680         // Move event came from outside button group or one of the positions does not contain
   621         // for old and new position. If one of the positions is inside button group
   681         // button so create new release and press events for old and new position.
   622         // a new event will get generated.
   682         // If one of the positions is inside button group a new key event will get emitted automatically.
   623         releaseEvent(oldPosition, false);
   683         releaseEvent(oldPosition, false);
   624         pressEvent(newPosition);
   684         pressEvent(newPosition);
   625     }
   685     }
   626 }
   686 }
   627 
   687 
   628 void HbInputButtonGroupPrivate::releaseEvent(const QPointF &position, bool emitSignal)
   688 void HbInputButtonGroupPrivate::releaseEvent(const QPointF &position, bool emitSignal)
   629 {
   689 {
   630     Q_Q(HbInputButtonGroup);
   690     Q_Q(HbInputButtonGroup);
   631 
   691 
   632     // Ignore release events outside button group
   692     int activeIndex = activeButtonIndex(position);
   633     if (!(position.x() >= 0 && position.x() < q->boundingRect().width() &&
   693     if (activeIndex >= 0) {
   634           position.y() >= 0 && position.y() < q->boundingRect().height())) {
   694         HbInputButton *item = mButtonData.at(activeIndex);
   635         return;
   695 
   636     }
   696         cancelLongPress(activeIndex);
   637 
   697 
   638     int column = static_cast<int>(position.x() / (q->boundingRect().width() / mGridSize.width()));
   698         // Check if we need to handle this event
   639     int row = static_cast<int>(position.y() / (q->boundingRect().height() / mGridSize.height()));
       
   640 
       
   641     int index = mButtonGridPositions.value(QPair<int, int>(column, row), -1);
       
   642 
       
   643     if (index >= 0 && index < mButtonData.count()) {
       
   644         HbInputButton *item = mButtonData.at(index);
       
   645 
       
   646         cancelLongPress(index);
       
   647 
       
   648         if (item->state() != HbInputButton::ButtonStatePressed) {
   699         if (item->state() != HbInputButton::ButtonStatePressed) {
   649             return;
   700             return;
   650         }
   701         }
   651 
   702 
       
   703         // This item is pressed, so release can happen for this.
       
   704         mActiveButtons.removeAll(activeIndex);
       
   705         QPointF releasePosition = item->currentTouchPointPosition();
       
   706 
   652         if (item->type() == HbInputButton::ButtonTypeFunction) {
   707         if (item->type() == HbInputButton::ButtonTypeFunction) {
   653             HbWidgetFeedback::triggered(q, Hb::InstantReleased, Hb::ModifierInputFunctionButton);
   708             HbWidgetFeedback::triggered(q, Hb::InstantReleased, Hb::ModifierInputFunctionButton);
   654         }
   709         } else {
   655         else {
       
   656             HbWidgetFeedback::triggered(q, Hb::InstantReleased);
   710             HbWidgetFeedback::triggered(q, Hb::InstantReleased);
   657         }
   711         }
   658 
   712 
   659         item->setState(HbInputButton::ButtonStateReleased);
   713         item->setState(HbInputButton::ButtonStateReleased);
   660         updateGraphics(QSizeF(q->boundingRect().width(), q->boundingRect().height()));
   714         updateGraphics(QSizeF(q->boundingRect().width(), q->boundingRect().height()));
   668         hideButtonPreview(item);
   722         hideButtonPreview(item);
   669 
   723 
   670         if (emitSignal) {
   724         if (emitSignal) {
   671             if (item->type() == HbInputButton::ButtonTypeFunction) {
   725             if (item->type() == HbInputButton::ButtonTypeFunction) {
   672                 HbWidgetFeedback::triggered(q, Hb::InstantClicked, Hb::ModifierInputFunctionButton);
   726                 HbWidgetFeedback::triggered(q, Hb::InstantClicked, Hb::ModifierInputFunctionButton);
   673             }
   727             } else {
   674             else {
       
   675                 HbWidgetFeedback::triggered(q, Hb::InstantClicked);
   728                 HbWidgetFeedback::triggered(q, Hb::InstantClicked);
   676             }
   729             }
   677             int actionIndex = item->keyCode() - HbInputButton::ButtonKeyCodeCustom;
   730             int actionIndex = item->keyCode() - HbInputButton::ButtonKeyCodeCustom;
   678             if (actionIndex >= 0 && actionIndex < mCustomActions.count()) {
   731             if (actionIndex >= 0 && actionIndex < mCustomActions.count()) {
   679                 emit q->aboutToActivateCustomAction(mCustomActions.at(actionIndex));
   732                 emit q->aboutToActivateCustomAction(mCustomActions.at(actionIndex));
   680                 mCustomActions.at(actionIndex)->activate(QAction::Trigger);
   733                 mCustomActions.at(actionIndex)->activate(QAction::Trigger);
   681             } else {
   734             } else {
   682                 calculateButtonProbabilities(position);
   735                 calculateButtonProbabilities(releasePosition);
   683 
   736 
   684                 QString text;
   737                 QString text;
   685                 if (item->type() == HbInputButton::ButtonTypeLabel) {
   738                 if (item->type() == HbInputButton::ButtonTypeLabel) {
   686                     text = item->text(HbInputButton::ButtonTextIndexPrimary);
   739                     text = item->text(HbInputButton::ButtonTextIndexPrimary);
   687                 }
   740                 }
   697     Q_Q(HbInputButtonGroup);
   750     Q_Q(HbInputButtonGroup);
   698 
   751 
   699     int index = mLongPressButtons.at(0);
   752     int index = mLongPressButtons.at(0);
   700     mLongPressButtons.removeAt(0);
   753     mLongPressButtons.removeAt(0);
   701     QTimer *timer = mLongPressTimers.at(0);
   754     QTimer *timer = mLongPressTimers.at(0);
   702     mLongPressTimers.removeAt(0);
   755     mLongPressTimers.removeAt(0);    
   703 
   756 
   704     if (index >= 0 && index < mButtonData.count()) {
   757     if (index >= 0 && index < mButtonData.count()) {
   705         HbInputButton *item = mButtonData.at(index);
   758         HbInputButton *item = mButtonData.at(index);
   706 
   759 
   707         // Handle autorepeating buttons
   760         // Handle autorepeating buttons
   712             mLongPressTimers.append(timer);
   765             mLongPressTimers.append(timer);
   713             timer->start(HbAutoRepeatTimeout);
   766             timer->start(HbAutoRepeatTimeout);
   714 
   767 
   715             if (item->type() == HbInputButton::ButtonTypeFunction) {
   768             if (item->type() == HbInputButton::ButtonTypeFunction) {
   716                 HbWidgetFeedback::triggered(q, Hb::InstantKeyRepeated, Hb::ModifierInputFunctionButton);
   769                 HbWidgetFeedback::triggered(q, Hb::InstantKeyRepeated, Hb::ModifierInputFunctionButton);
   717             }
   770             } else {
   718             else {
       
   719                 HbWidgetFeedback::triggered(q, Hb::InstantKeyRepeated);
   771                 HbWidgetFeedback::triggered(q, Hb::InstantKeyRepeated);
   720             }
   772             }
   721 
   773 
   722             QString text;
   774             QString text;
   723             if (item->type() == HbInputButton::ButtonTypeLabel) {
   775             if (item->type() == HbInputButton::ButtonTypeLabel) {
   724                 text = item->text(HbInputButton::ButtonTextIndexPrimary);
   776                 text = item->text(HbInputButton::ButtonTextIndexPrimary);
   725             }
   777             }
   726             int keycode = item->keyCode();
   778             int keycode = item->keyCode();
   727             QKeyEvent releaeEvent(QEvent::KeyRelease, keycode, Qt::NoModifier, text, true);
   779             QKeyEvent releaseEvent(QEvent::KeyRelease, keycode, Qt::NoModifier, text, true);
   728             q->emitButtonReleased(releaeEvent);
   780             q->emitButtonReleased(releaseEvent);
   729             QKeyEvent pressEvent(QEvent::KeyPress, keycode, Qt::NoModifier, text, true);
   781             QKeyEvent pressEvent(QEvent::KeyPress, keycode, Qt::NoModifier, text, true);
   730             q->emitButtonPressed(pressEvent);
   782             q->emitButtonPressed(pressEvent);
   731         } else {
   783         } else {
   732             // Buttons that doesn't support autorepeat can either show character preview
   784             // Buttons that doesn't support autorepeat can either show character preview
   733             // or generate a long press
   785             // or generate a long press
   735                 && item->mappedCharacters().count() > 1) {
   787                 && item->mappedCharacters().count() > 1) {
   736                 showCharacterSelectionPreview(item);
   788                 showCharacterSelectionPreview(item);
   737             } else {
   789             } else {
   738                 if (item->type() == HbInputButton::ButtonTypeFunction) {
   790                 if (item->type() == HbInputButton::ButtonTypeFunction) {
   739                     HbWidgetFeedback::triggered(q, Hb::InstantLongPressed, Hb::ModifierInputFunctionButton);
   791                     HbWidgetFeedback::triggered(q, Hb::InstantLongPressed, Hb::ModifierInputFunctionButton);
   740                 }
   792                 } else {
   741                 else {
       
   742                     HbWidgetFeedback::triggered(q, Hb::InstantLongPressed);
   793                     HbWidgetFeedback::triggered(q, Hb::InstantLongPressed);
   743                 }
   794                 }
   744 
   795 
   745                 QString text;
   796                 QString text;
   746                 if (item->type() == HbInputButton::ButtonTypeLabel) {
   797                 if (item->type() == HbInputButton::ButtonTypeLabel) {
   786     for (int i = 0; i < mProbabilities.count(); ++i) {
   837     for (int i = 0; i < mProbabilities.count(); ++i) {
   787         mProbabilities[i].probability /= probabilities;
   838         mProbabilities[i].probability /= probabilities;
   788     }
   839     }
   789 }
   840 }
   790 
   841 
       
   842 /*!
       
   843 \internal
       
   844 \brief Search active button based on position.
       
   845 
       
   846 Locates active button based on its last interaction point.
       
   847 
       
   848 \param position Location of triggered user action.
       
   849 \return NULL, when no button has reacted to given coordinates.
       
   850 \return Pointer to active button.
       
   851 */
       
   852 int HbInputButtonGroupPrivate::activeButtonIndex(const QPointF &position)
       
   853 {
       
   854     // Here we get the position, where last interaction occurred.
       
   855     // Start searching from the end of the list, because it is likely,
       
   856     // that the triggered position happens on the button that was added last.
       
   857     for (int i = mActiveButtons.count() - 1; i >= 0; --i) {
       
   858         int activeIndex = mActiveButtons[i];
       
   859         if (mButtonData[activeIndex]->wasTriggeredAt(position)) {
       
   860             return activeIndex;
       
   861         }
       
   862     }
       
   863 
       
   864     // Position is not inside any single active button.
       
   865     return -1;
       
   866 }
       
   867 
   791 void HbInputButtonGroupPrivate::createPrimarySingleTextLayout(int index, const QHash<int, QString> &textContent, const QSizeF &size)
   868 void HbInputButtonGroupPrivate::createPrimarySingleTextLayout(int index, const QHash<int, QString> &textContent, const QSizeF &size)
   792 {
   869 {
   793     qreal cellWidth = size.width() / mGridSize.width();
   870     qreal cellWidth = size.width() / mGridSize.width();
   794     qreal cellHeight = size.height() / mGridSize.height();
   871     qreal cellHeight = size.height() / mGridSize.height();
   795 
   872 
   801     } else {
   878     } else {
   802         font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypeSingle)));
   879         font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypeSingle)));
   803     }
   880     }
   804 
   881 
   805     mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
   882     mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
   806     QFontMetricsF fontMetrics(font);
       
   807 
   883 
   808     // Create text line for each button with primary text and correct type and state. Layout it
   884     // Create text line for each button with primary text and correct type and state. Layout it
   809     // to correct position
   885     // to correct position
   810     mTextLayouts.at(index)->beginLayout();
   886     mTextLayouts.at(index)->beginLayout();
   811     foreach(HbInputButton *item, mButtonData) {
   887     foreach(HbInputButton *item, mButtonData) {
   812         int layoutIndex = item->type() * HbInputButton::ButtonStateCount + item->state() + HbTextTypeCount;
   888         int layoutIndex = item->type() * HbInputButton::ButtonStateCount + item->state() + HbTextTypeCount;
   813         if (!mEnabled) {
   889         if (!mEnabled) {
   814             layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled + HbTextTypeCount;
   890             layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled + HbTextTypeCount;
   815         }
   891         }
   816         if (index == layoutIndex && !item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
   892         if (index == layoutIndex && item->size().isValid() &&
       
   893             !item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
   817             item->icon(HbInputButton::ButtonIconIndexPrimary).isNull() &&
   894             item->icon(HbInputButton::ButtonIconIndexPrimary).isNull() &&
   818             item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow).isEmpty() &&
   895             item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow).isEmpty() &&
   819             item->icon(HbInputButton::ButtonIconIndexSecondaryFirstRow).isNull() &&
   896             item->icon(HbInputButton::ButtonIconIndexSecondaryFirstRow).isNull() &&
   820             item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).isEmpty() &&
   897             item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).isEmpty() &&
   821             item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull()) {
   898             item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull()) {
   822             qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary));
       
   823             qreal textHeight = fontMetrics.height();
       
   824 
   899 
   825             QTextLine line = mTextLayouts.at(index)->createLine();
   900             QTextLine line = mTextLayouts.at(index)->createLine();
   826             line.setNumColumns(item->text(HbInputButton::ButtonTextIndexPrimary).length());
   901             line.setNumColumns(item->text(HbInputButton::ButtonTextIndexPrimary).length());
       
   902             qreal textWidth = line.naturalTextWidth();
       
   903             qreal textHeight = line.height();
   827 
   904 
   828             if (typeIndex == HbInputButton::ButtonTypeLabel) {
   905             if (typeIndex == HbInputButton::ButtonTypeLabel) {
   829                 layoutTextLine(HbInputButtonGroup::ButtonTextTypeLabel, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
   906                 layoutTextLine(HbInputButtonGroup::ButtonTextTypeLabel, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
   830             } else {
   907             } else {
   831                 layoutTextLine(HbInputButtonGroup::ButtonTextTypeSingle, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
   908                 layoutTextLine(HbInputButtonGroup::ButtonTextTypeSingle, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
   843 
   920 
   844     QFont font = HbFontSpec(HbFontSpec::Primary).font();
   921     QFont font = HbFontSpec(HbFontSpec::Primary).font();
   845     font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypePrimary)));
   922     font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypePrimary)));
   846 
   923 
   847     mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
   924     mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
   848     QFontMetricsF fontMetrics(font);
       
   849 
       
   850     // Create text line for each button with primary text and correct type and state. Layout it
   925     // Create text line for each button with primary text and correct type and state. Layout it
   851     // to correct position
   926     // to correct position
   852     mTextLayouts.at(index)->beginLayout();
   927     mTextLayouts.at(index)->beginLayout();
   853     foreach(HbInputButton *item, mButtonData) {
   928     foreach(HbInputButton *item, mButtonData) {
   854         int layoutIndex = item->type() * HbInputButton::ButtonStateCount + item->state();
   929         int layoutIndex = item->type() * HbInputButton::ButtonStateCount + item->state();
   855         if (!mEnabled) {
   930         if (!mEnabled) {
   856             layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled;
   931             layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled;
   857         }
   932         }
   858         if (index == layoutIndex && !item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
   933         if (index == layoutIndex && item->size().isValid() &&
       
   934             !item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
   859             item->icon(HbInputButton::ButtonIconIndexPrimary).isNull() &&
   935             item->icon(HbInputButton::ButtonIconIndexPrimary).isNull() &&
   860             !(item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow).isEmpty() &&
   936             !(item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow).isEmpty() &&
   861               item->icon(HbInputButton::ButtonIconIndexSecondaryFirstRow).isNull() &&
   937               item->icon(HbInputButton::ButtonIconIndexSecondaryFirstRow).isNull() &&
   862               item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).isEmpty() &&
   938               item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).isEmpty() &&
   863               item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull())) {
   939               item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull())) {
   864             qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary));
       
   865             qreal textHeight = fontMetrics.height();
       
   866 
   940 
   867             QTextLine line = mTextLayouts.at(index)->createLine();
   941             QTextLine line = mTextLayouts.at(index)->createLine();
   868             line.setNumColumns(item->text(HbInputButton::ButtonTextIndexPrimary).length());
   942             line.setNumColumns(item->text(HbInputButton::ButtonTextIndexPrimary).length());
   869 
   943 
       
   944             qreal textWidth = line.naturalTextWidth();
       
   945             qreal textHeight = line.height();
       
   946 
   870             layoutTextLine(HbInputButtonGroup::ButtonTextTypePrimary, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
   947             layoutTextLine(HbInputButtonGroup::ButtonTextTypePrimary, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
   871         }
   948         }
   872     }
   949     }
   873     mTextLayouts.at(index)->endLayout();
   950     mTextLayouts.at(index)->endLayout();
   874     mTextLayouts.at(index)->setCacheEnabled(true);
   951     mTextLayouts.at(index)->setCacheEnabled(true);
   878 {
   955 {
   879     QFont font = HbFontSpec(HbFontSpec::Primary).font();
   956     QFont font = HbFontSpec(HbFontSpec::Primary).font();
   880     font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow)));
   957     font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow)));
   881 
   958 
   882     mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
   959     mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
   883     QFontMetricsF fontMetrics(font);
       
   884 
   960 
   885     // Create text line for each button with secondary first row or second row text and correct type and state.
   961     // Create text line for each button with secondary first row or second row text and correct type and state.
   886     // Layout it to correct position
   962     // Layout it to correct position
   887     mTextLayouts.at(index)->beginLayout();
   963     mTextLayouts.at(index)->beginLayout();
   888     foreach(HbInputButton *item, mButtonData) {
   964     foreach(HbInputButton *item, mButtonData) {
   889         int layoutIndex = item->type() * HbInputButton::ButtonStateCount + item->state() + HbTextTypeCount * 2;
   965         int layoutIndex = item->type() * HbInputButton::ButtonStateCount + item->state() + HbTextTypeCount * 2;
   890         if (!mEnabled) {
   966         if (!mEnabled) {
   891             layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled + HbTextTypeCount * 2;
   967             layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled + HbTextTypeCount * 2;
   892         }
   968         }
   893         if (index == layoutIndex) {
   969         if (index == layoutIndex && item->size().isValid()) {
   894             // Layout secondary text for first row
   970             // Layout secondary text for first row
   895             layoutSecondaryText(index, item, fontMetrics, size,
   971             layoutSecondaryText(index, item, size,
   896                                 HbInputButton::ButtonTextIndexSecondaryFirstRow,
   972                                 HbInputButton::ButtonTextIndexSecondaryFirstRow,
   897                                 HbInputButton::ButtonIconIndexSecondaryFirstRow,
   973                                 HbInputButton::ButtonIconIndexSecondaryFirstRow,
   898                                 HbInputButton::ButtonTextIndexSecondarySecondRow,
   974                                 HbInputButton::ButtonTextIndexSecondarySecondRow,
   899                                 HbInputButton::ButtonIconIndexSecondarySecondRow,
   975                                 HbInputButton::ButtonIconIndexSecondarySecondRow,
   900                                 HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow);
   976                                 HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow);
   901                                 
   977                                 
   902 
   978 
   903             // Layout secondary text for second row
   979             // Layout secondary text for second row
   904             layoutSecondaryText(index, item, fontMetrics, size,
   980             layoutSecondaryText(index, item, size,
   905                                 HbInputButton::ButtonTextIndexSecondarySecondRow,
   981                                 HbInputButton::ButtonTextIndexSecondarySecondRow,
   906                                 HbInputButton::ButtonIconIndexSecondarySecondRow,
   982                                 HbInputButton::ButtonIconIndexSecondarySecondRow,
   907                                 HbInputButton::ButtonTextIndexSecondaryFirstRow,
   983                                 HbInputButton::ButtonTextIndexSecondaryFirstRow,
   908                                 HbInputButton::ButtonIconIndexSecondaryFirstRow,
   984                                 HbInputButton::ButtonIconIndexSecondaryFirstRow,
   909                                 HbInputButtonGroup::ButtonTextTypeSecondarySecondRow);
   985                                 HbInputButtonGroup::ButtonTextTypeSecondarySecondRow);
   911     }
   987     }
   912     mTextLayouts.at(index)->endLayout();
   988     mTextLayouts.at(index)->endLayout();
   913     mTextLayouts.at(index)->setCacheEnabled(true);
   989     mTextLayouts.at(index)->setCacheEnabled(true);
   914 }
   990 }
   915 
   991 
   916 void HbInputButtonGroupPrivate::layoutSecondaryText(int index, HbInputButton *item, QFontMetricsF &fontMetrics, const QSizeF &size,
   992 void HbInputButtonGroupPrivate::layoutSecondaryText(int index, HbInputButton *item, const QSizeF &size,
   917                                                     HbInputButton::HbInputButtonTextIndex firstTextIndex,
   993                                                     HbInputButton::HbInputButtonTextIndex firstTextIndex,
   918                                                     HbInputButton::HbInputButtonIconIndex firstIconIndex,
   994                                                     HbInputButton::HbInputButtonIconIndex firstIconIndex,
   919                                                     HbInputButton::HbInputButtonTextIndex secondTextIndex,
   995                                                     HbInputButton::HbInputButtonTextIndex secondTextIndex,
   920                                                     HbInputButton::HbInputButtonIconIndex secondIconIndex,
   996                                                     HbInputButton::HbInputButtonIconIndex secondIconIndex,
   921                                                     HbInputButtonGroup::HbInputButtonTextType textType)
   997                                                     HbInputButtonGroup::HbInputButtonTextType textType)
   923     qreal cellWidth = size.width() / mGridSize.width();
   999     qreal cellWidth = size.width() / mGridSize.width();
   924     qreal cellHeight = size.height() / mGridSize.height();
  1000     qreal cellHeight = size.height() / mGridSize.height();
   925 
  1001 
   926     if (!item->text(firstTextIndex).isEmpty() &&
  1002     if (!item->text(firstTextIndex).isEmpty() &&
   927         item->icon(firstIconIndex).isNull()) {
  1003         item->icon(firstIconIndex).isNull()) {
   928         qreal textWidth = fontMetrics.width(item->text(firstTextIndex));
       
   929         qreal textHeight = fontMetrics.height();
       
   930 
  1004 
   931         QTextLine line = mTextLayouts.at(index)->createLine();
  1005         QTextLine line = mTextLayouts.at(index)->createLine();
   932         line.setNumColumns(item->text(firstTextIndex).length());
  1006         line.setNumColumns(item->text(firstTextIndex).length());
       
  1007         qreal textWidth = line.naturalTextWidth();
       
  1008         qreal textHeight = line.height();
   933 
  1009 
   934         if (item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() && 
  1010         if (item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() && 
   935             item->icon(HbInputButton::ButtonIconIndexPrimary).isNull() &&
  1011             item->icon(HbInputButton::ButtonIconIndexPrimary).isNull()) {
   936             item->text(secondTextIndex).isEmpty() && 
  1012             if (item->text(secondTextIndex).isEmpty() && 
   937             item->icon(secondIconIndex).isNull()) {
  1013                 item->icon(secondIconIndex).isNull()) {
   938             layoutTextLine(HbInputButtonGroup::ButtonTextTypeSingle, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
  1014                 layoutTextLine(HbInputButtonGroup::ButtonTextTypeSingle, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
       
  1015             } else {
       
  1016                 layoutTextLine(textType, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight), true);
       
  1017             }
   939         } else {
  1018         } else {
   940             layoutTextLine(textType, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
  1019             layoutTextLine(textType, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
   941         }
  1020         }
   942     }
  1021     }
   943 }
  1022 }
   944 
  1023 
   945 void HbInputButtonGroupPrivate::layoutTextLine(HbInputButtonGroup::HbInputButtonTextType textType, const HbInputButton *button, const QSizeF &cellSize,
  1024 void HbInputButtonGroupPrivate::layoutTextLine(HbInputButtonGroup::HbInputButtonTextType textType, const HbInputButton *button, const QSizeF &cellSize,
   946         QTextLine &textLine, const QSizeF &textSize)
  1025         QTextLine &textLine, const QSizeF &textSize, const bool centered)
   947 {
  1026 {
   948     qreal textPositionX = 0.0;
  1027     qreal textPositionX = 0.0;
   949     qreal textPositionY = 0.0;
  1028     qreal textPositionY = 0.0;
   950     
  1029     
   951     switch(textType) {
  1030     switch(textType) {
   952         case HbInputButtonGroup::ButtonTextTypeSingle:
  1031     case HbInputButtonGroup::ButtonTextTypeSingle:
   953         case HbInputButtonGroup::ButtonTextTypeLabel:
  1032     case HbInputButtonGroup::ButtonTextTypeLabel:
       
  1033         textPositionX = (button->position().x() + 0.5 * button->size().width()) * cellSize.width() - 0.5 * textSize.width();
       
  1034         textPositionY = (button->position().y() + 0.5 * button->size().height()) * cellSize.height() - 0.5 * textSize.height();
       
  1035         break;
       
  1036 
       
  1037     case HbInputButtonGroup::ButtonTextTypePrimary:
       
  1038         textPositionX = button->position().x() * cellSize.width() + HbHorizontalMarginInUnits * mUnitValue + mButtonBorderSize;
       
  1039         textPositionY = (button->position().y() + 0.5 * button->size().height()) * cellSize.height() - 0.5 * textSize.height();
       
  1040         break;
       
  1041 
       
  1042     case HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow:
       
  1043         if (centered) {
   954             textPositionX = (button->position().x() + 0.5 * button->size().width()) * cellSize.width() - 0.5 * textSize.width();
  1044             textPositionX = (button->position().x() + 0.5 * button->size().width()) * cellSize.width() - 0.5 * textSize.width();
   955             textPositionY = (button->position().y() + 0.5 * button->size().height()) * cellSize.height() - 0.5 * textSize.height();
  1045         } else {
   956             break;
  1046             textPositionX = (button->position().x() + button->size().width()) * cellSize.width() -
   957 
  1047                         textSize.width() - HbHorizontalMarginInUnits * mUnitValue - mButtonBorderSize;
   958         case HbInputButtonGroup::ButtonTextTypePrimary:
  1048         }
   959             textPositionX = button->position().x() * cellSize.width() + HbHorizontalMarginInUnits * mUnitValue + mButtonBorderSize;
  1049         textPositionY = (button->position().y() + button->size().height()) * cellSize.height() -
   960             textPositionY = (button->position().y() + 0.5 * button->size().height()) * cellSize.height() - 0.5 * textSize.height();
  1050                         textSize.height() - HbVerticalMarginInUnits * mUnitValue - mButtonBorderSize;
   961             break;
  1051         break;
   962 
  1052 
   963         case HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow:
  1053     case HbInputButtonGroup::ButtonTextTypeSecondarySecondRow:
       
  1054         if (centered) {
       
  1055             textPositionX = (button->position().x() + 0.5 * button->size().width()) * cellSize.width() - 0.5 * textSize.width();
       
  1056         } else {
   964             textPositionX = (button->position().x() + button->size().width()) * cellSize.width() -
  1057             textPositionX = (button->position().x() + button->size().width()) * cellSize.width() -
   965                             textSize.width() - HbHorizontalMarginInUnits * mUnitValue - mButtonBorderSize;
  1058                             textSize.width() - HbHorizontalMarginInUnits * mUnitValue - mButtonBorderSize;
   966             textPositionY = (button->position().y() + button->size().height()) * cellSize.height() -
  1059         }
   967                             textSize.height() - HbVerticalMarginInUnits * mUnitValue - mButtonBorderSize;
  1060         textPositionY = button->position().y() * cellSize.height() + HbVerticalMarginInUnits * mUnitValue + mButtonBorderSize;
   968             break;
  1061         break;
   969 
  1062     default:
   970         case HbInputButtonGroup::ButtonTextTypeSecondarySecondRow:
  1063         break;
   971             textPositionX = (button->position().x() + button->size().width()) * cellSize.width() -
       
   972                             textSize.width() - HbHorizontalMarginInUnits * mUnitValue - mButtonBorderSize;
       
   973             textPositionY = button->position().y() * cellSize.height() + HbVerticalMarginInUnits * mUnitValue + mButtonBorderSize;
       
   974             break;
       
   975 
       
   976         default:
       
   977             break;
       
   978     }
  1064     }
   979     textLine.setPosition(QPointF(textPositionX, textPositionY));
  1065     textLine.setPosition(QPointF(textPositionX, textPositionY));
   980 }
  1066 }
   981 
  1067 
   982 QString HbInputButtonGroupPrivate::buttonGraphics(HbInputButton::HbInputButtonType type, HbInputButton::HbInputButtonState state)
  1068 QString HbInputButtonGroupPrivate::buttonGraphics(HbInputButton::HbInputButtonType type, HbInputButton::HbInputButtonState state)
  1037     return QString("");
  1123     return QString("");
  1038 }
  1124 }
  1039 
  1125 
  1040 qreal HbInputButtonGroupPrivate::fontSize(HbInputButtonGroup::HbInputButtonTextType textType)
  1126 qreal HbInputButtonGroupPrivate::fontSize(HbInputButtonGroup::HbInputButtonTextType textType)
  1041 {
  1127 {
  1042     switch(textType) {
  1128     return mFontSize[textType];
  1043         case HbInputButtonGroup::ButtonTextTypeSingle:
  1129 }
  1044             return HbTextSizeInUnits * mUnitValue;
  1130 
  1045 
  1131 void HbInputButtonGroupPrivate::setFontSize(HbInputButtonGroup::HbInputButtonTextType textType,qreal size)
  1046         case HbInputButtonGroup::ButtonTextTypePrimary:
  1132 {
  1047             return HbPrimaryTextSizeInUnits * mUnitValue;
  1133     mFontSize[textType] = size;
  1048 
  1134 }
  1049         case HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow:
  1135 
  1050         case HbInputButtonGroup::ButtonTextTypeSecondarySecondRow:
  1136 void HbInputButtonGroupPrivate::resetFontSizes()
  1051             return HbSecondaryTextSizeInUnits * mUnitValue;
  1137 {
  1052 
  1138     mFontSize[HbInputButtonGroup::ButtonTextTypeSingle] = HbTextSizeInUnits * mUnitValue;
  1053         case HbInputButtonGroup::ButtonTextTypeLabel:
  1139     mFontSize[HbInputButtonGroup::ButtonTextTypePrimary] = HbPrimaryTextSizeInUnits * mUnitValue;
  1054             return HbLabelTextSizeInUnits * mUnitValue;
  1140     mFontSize[HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow] = HbSecondaryTextSizeInUnits * mUnitValue;
  1055 
  1141     mFontSize[HbInputButtonGroup::ButtonTextTypeSecondarySecondRow] = HbSecondaryTextSizeInUnits * mUnitValue;
  1056         default:
  1142     mFontSize[HbInputButtonGroup::ButtonTextTypeLabel] = HbLabelTextSizeInUnits * mUnitValue;
  1057             return 0;
       
  1058     }
       
  1059 }
  1143 }
  1060 
  1144 
  1061 void HbInputButtonGroupPrivate::startLongPress(int index)
  1145 void HbInputButtonGroupPrivate::startLongPress(int index)
  1062 {
  1146 {
  1063     Q_Q(HbInputButtonGroup);
  1147     Q_Q(HbInputButtonGroup);
  1099 {
  1183 {
  1100     Q_D(HbInputButtonGroup);
  1184     Q_D(HbInputButtonGroup);
  1101 
  1185 
  1102     d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
  1186     d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
  1103 
  1187 
       
  1188     resetFontSizes();
       
  1189 
  1104     setAcceptedMouseButtons(Qt::LeftButton);
  1190     setAcceptedMouseButtons(Qt::LeftButton);
  1105 }
  1191 }
  1106 
  1192 
  1107 /*!
  1193 /*!
  1108 Constructor
  1194 Constructor
  1112 {
  1198 {
  1113     Q_D(HbInputButtonGroup);
  1199     Q_D(HbInputButtonGroup);
  1114 
  1200 
  1115     d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
  1201     d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
  1116 
  1202 
       
  1203     resetFontSizes();
       
  1204 
  1117     setAcceptedMouseButtons(Qt::LeftButton);
  1205     setAcceptedMouseButtons(Qt::LeftButton);
  1118 }
  1206 }
  1119 
  1207 
  1120 /*!
  1208 /*!
  1121 Constructor
  1209 Constructor
  1125 {
  1213 {
  1126     Q_D(HbInputButtonGroup);
  1214     Q_D(HbInputButtonGroup);
  1127 
  1215 
  1128     d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
  1216     d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
  1129 
  1217 
       
  1218     resetFontSizes();
       
  1219 
  1130     setAcceptedMouseButtons(Qt::LeftButton);
  1220     setAcceptedMouseButtons(Qt::LeftButton);
  1131 
  1221 
  1132     setGridSize(size);
  1222     setGridSize(size);
  1133 }
  1223 }
  1134 
  1224 
  1139     : HbWidget(dd, parent)
  1229     : HbWidget(dd, parent)
  1140 {
  1230 {
  1141     Q_D(HbInputButtonGroup);
  1231     Q_D(HbInputButtonGroup);
  1142 
  1232 
  1143     d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
  1233     d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
       
  1234 
       
  1235     resetFontSizes();
  1144 
  1236 
  1145     setAcceptedMouseButtons(Qt::LeftButton);
  1237     setAcceptedMouseButtons(Qt::LeftButton);
  1146 
  1238 
  1147     setGridSize(size);
  1239     setGridSize(size);
  1148 }
  1240 }
  1200 */
  1292 */
  1201 void HbInputButtonGroup::setButtons(const QList<HbInputButton *> &data)
  1293 void HbInputButtonGroup::setButtons(const QList<HbInputButton *> &data)
  1202 {
  1294 {
  1203     Q_D(HbInputButtonGroup);
  1295     Q_D(HbInputButtonGroup);
  1204 
  1296 
  1205     foreach(HbInputButton *button, d->mButtonData) {
  1297     for (int i = 0; i < d->mButtonData.count(); ++i) {
  1206         if (!data.contains(button)) {
  1298         if (!data.contains(d->mButtonData.at(i))) {
  1207             delete button;
  1299             delete d->mButtonData.at(i);
       
  1300             d->cancelLongPress(i);
  1208         }
  1301         }
  1209     }
  1302     }
  1210     d->mButtonData = data;
  1303     d->mButtonData = data;
  1211 
  1304 
  1212     d->updateButtonGrid(QSizeF(boundingRect().width(), boundingRect().height()));
  1305     d->updateButtonGrid(QSizeF(boundingRect().width(), boundingRect().height()));
  1231     Q_D(HbInputButtonGroup);
  1324     Q_D(HbInputButtonGroup);
  1232 
  1325 
  1233     if (index >= 0 && index < d->mButtonData.count()) {
  1326     if (index >= 0 && index < d->mButtonData.count()) {
  1234         if (data != d->mButtonData.at(index)) {
  1327         if (data != d->mButtonData.at(index)) {
  1235             delete d->mButtonData.at(index);
  1328             delete d->mButtonData.at(index);
       
  1329             d->cancelLongPress(index);
  1236         }
  1330         }
  1237         if (data) {
  1331         if (data) {
  1238             d->mButtonData.replace(index, data);
  1332             d->mButtonData.replace(index, data);
  1239         } else {
  1333         } else {
  1240             d->mButtonData.removeAt(index);
  1334             d->mButtonData.removeAt(index);
  1487     return d->mCharacterSelectionPreviewEnabled;
  1581     return d->mCharacterSelectionPreviewEnabled;
  1488 }
  1582 }
  1489 
  1583 
  1490 
  1584 
  1491 /*!
  1585 /*!
  1492 Sets multi touch enabled or disabled.
  1586 If given parameter is true more that one touch points are accepted
       
  1587 simultaneously.
  1493 
  1588 
  1494 \sa isMultiTouchEnabled
  1589 \sa isMultiTouchEnabled
  1495 */
  1590 */
  1496 void HbInputButtonGroup::setMultiTouchEnabled(bool enabled)
  1591 void HbInputButtonGroup::setMultiTouchEnabled(bool enabled)
  1497 {
  1592 {
  1500     d->mMultiTouchEnabled = enabled;
  1595     d->mMultiTouchEnabled = enabled;
  1501     setAcceptTouchEvents(enabled);
  1596     setAcceptTouchEvents(enabled);
  1502 }
  1597 }
  1503 
  1598 
  1504 /*!
  1599 /*!
  1505 Returns multi touch state.
  1600 Returns true if more than one touch points are accepted simultaneously.
  1506 
  1601 
  1507 \sa setMultiTouchEnabled
  1602 \sa setMultiTouchEnabled
  1508 */
  1603 */
  1509 bool HbInputButtonGroup::isMultiTouchEnabled() const
  1604 bool HbInputButtonGroup::isMultiTouchEnabled() const
  1510 {
  1605 {
  1531 qreal HbInputButtonGroup::fontSize(HbInputButtonTextType textType)
  1626 qreal HbInputButtonGroup::fontSize(HbInputButtonTextType textType)
  1532 {
  1627 {
  1533     Q_D(HbInputButtonGroup);
  1628     Q_D(HbInputButtonGroup);
  1534 
  1629 
  1535     return d->fontSize(textType);
  1630     return d->fontSize(textType);
       
  1631 }
       
  1632 
       
  1633 /*!
       
  1634 Set font size for given text type
       
  1635 */
       
  1636 void HbInputButtonGroup::setFontSize(HbInputButtonTextType textType,qreal size)
       
  1637 {
       
  1638     Q_D(HbInputButtonGroup);
       
  1639 
       
  1640     return d->setFontSize(textType,size);
       
  1641 }
       
  1642 
       
  1643 /*!
       
  1644 Reset font size for all text type
       
  1645 */
       
  1646 void HbInputButtonGroup::resetFontSizes()
       
  1647 {
       
  1648     Q_D(HbInputButtonGroup);
       
  1649 
       
  1650     return d->resetFontSizes();
  1536 }
  1651 }
  1537 
  1652 
  1538 /*!
  1653 /*!
  1539 Returns all possible buttons the user could have intended to press
  1654 Returns all possible buttons the user could have intended to press
  1540 for the last registered touch along with their corresponding probabilities.
  1655 for the last registered touch along with their corresponding probabilities.
  1672 */
  1787 */
  1673 bool HbInputButtonGroup::sceneEvent(QEvent *event)
  1788 bool HbInputButtonGroup::sceneEvent(QEvent *event)
  1674 {
  1789 {
  1675     Q_D(HbInputButtonGroup);
  1790     Q_D(HbInputButtonGroup);
  1676 
  1791 
  1677     if (!d->mEnabled) {
  1792     // In case disabled or there is a preview popup open for any button, ignore events in this group.
       
  1793     if (!d->mEnabled || (d->mCharacterSelectionPreview && d->mCharacterSelectionPreview->isVisible())) {
  1678         event->ignore();
  1794         event->ignore();
  1679         return false;
  1795         return false;
  1680     }
  1796     }
  1681 
  1797 
  1682     switch(event->type()) {
  1798     switch(event->type()) {
  1683         case QEvent::TouchBegin: {
  1799     case QEvent::TouchBegin: {            
  1684             QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
  1800         QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
  1685             foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
  1801         foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
  1686                 if (!point.isPrimary() && d->mMultiTouchEnabled) {
  1802             if (!point.isPrimary() && d->mMultiTouchEnabled) {
       
  1803                 d->pressEvent(point.pos());
       
  1804             }
       
  1805         }
       
  1806         break;
       
  1807     }
       
  1808 
       
  1809     case QEvent::TouchUpdate: {
       
  1810         QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
       
  1811         foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
       
  1812             if (!point.isPrimary() && d->mMultiTouchEnabled) {
       
  1813                 if (point.state() & Qt::TouchPointPressed) {
  1687                     d->pressEvent(point.pos());
  1814                     d->pressEvent(point.pos());
  1688                 }
  1815                 } else if (point.state() & Qt::TouchPointMoved) {
  1689             }
  1816                     d->moveEvent(point.lastPos(), point.pos());
  1690             break;
  1817                 } else if (point.state() & Qt::TouchPointReleased) {
  1691         }
  1818                     d->moveEvent(point.lastPos(), point.pos());
  1692 
       
  1693         case QEvent::TouchUpdate: {
       
  1694             QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
       
  1695             foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
       
  1696                 if (!point.isPrimary() && d->mMultiTouchEnabled) {
       
  1697                     if (point.state() & Qt::TouchPointPressed) {
       
  1698                         d->pressEvent(point.pos());
       
  1699                     } else if (point.state() & Qt::TouchPointMoved) {
       
  1700                         d->moveEvent(point.lastPos(), point.pos());
       
  1701                     } else if (point.state() & Qt::TouchPointReleased) {
       
  1702                         d->releaseEvent(point.pos());
       
  1703                     }
       
  1704                 }
       
  1705             }
       
  1706             break;
       
  1707         }
       
  1708 
       
  1709         case QEvent::TouchEnd: {
       
  1710             QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
       
  1711             foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
       
  1712                 if (!point.isPrimary() && d->mMultiTouchEnabled) {
       
  1713                     d->releaseEvent(point.pos());
  1819                     d->releaseEvent(point.pos());
  1714                 }
  1820                 }
  1715             }
  1821             }
  1716             break;
  1822         }
  1717         }
  1823         break;
  1718 
  1824     }
  1719         case QEvent::GraphicsSceneMousePress: {
  1825 
  1720             QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
  1826     case QEvent::TouchEnd: {
  1721             d->pressEvent(mouseEvent->pos());
  1827         QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
  1722             break;
  1828         foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
  1723         }
  1829             if (!point.isPrimary() && d->mMultiTouchEnabled) {
  1724 
  1830                 d->moveEvent(point.lastPos(), point.pos());
  1725         case QEvent::GraphicsSceneMouseDoubleClick: {
  1831                 d->releaseEvent(point.pos());
  1726             QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
  1832             }
  1727             d->doublePressEvent(mouseEvent->pos());
  1833         }
  1728             break;
  1834         break;
  1729         }
  1835     }
  1730 
  1836 
  1731         case QEvent::GraphicsSceneMouseMove: {
  1837     case QEvent::GraphicsSceneMousePress: {
  1732             QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
  1838         QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
  1733             d->moveEvent(mouseEvent->lastPos(), mouseEvent->pos());
  1839         d->pressEvent(mouseEvent->pos());
  1734             break;
  1840         break;
  1735         }
  1841     }
  1736 
  1842 
  1737         case QEvent::GraphicsSceneMouseRelease: {
  1843     case QEvent::GraphicsSceneMouseDoubleClick: {
  1738             QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
  1844         QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
  1739             d->releaseEvent(mouseEvent->pos());
  1845         d->doublePressEvent(mouseEvent->pos());
  1740             cancelButtonPress();
  1846         break;
  1741             break;
  1847     }
  1742         }
  1848 
  1743 
  1849     case QEvent::GraphicsSceneMouseMove: {
  1744         default:
  1850         QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
  1745             return HbWidget::event(event);
  1851         d->moveEvent(mouseEvent->lastPos(), mouseEvent->pos());
       
  1852         break;
       
  1853     }
       
  1854 
       
  1855     case QEvent::GraphicsSceneMouseRelease: {            
       
  1856         QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
       
  1857         d->moveEvent(mouseEvent->lastPos(), mouseEvent->pos());
       
  1858         d->releaseEvent(mouseEvent->pos());
       
  1859         break;
       
  1860     }
       
  1861 
       
  1862     case QEvent::GrabMouse:
       
  1863         d->mHasMouseGrab = true;
       
  1864         break;
       
  1865 
       
  1866     case QEvent::UngrabMouse:
       
  1867         d->mHasMouseGrab = false;
       
  1868         break;
       
  1869 
       
  1870     default:
       
  1871         return HbWidget::event(event);
  1746     }
  1872     }
  1747     return true;
  1873     return true;
  1748 }
  1874 }
  1749 
  1875 
  1750 /*!
  1876 /*!
  1804     HbWidget::changeEvent(event);
  1930     HbWidget::changeEvent(event);
  1805 }
  1931 }
  1806 
  1932 
  1807 /*!
  1933 /*!
  1808 \reimp
  1934 \reimp
  1809 
       
  1810 Enables touch events if multi touch is enabled.
       
  1811 */
  1935 */
  1812 void HbInputButtonGroup::showEvent(QShowEvent *event)
  1936 void HbInputButtonGroup::showEvent(QShowEvent *event)
  1813 {
  1937 {
  1814     Q_D(HbInputButtonGroup);
  1938     Q_D(HbInputButtonGroup);
  1815 
  1939 
  1816     setAcceptTouchEvents(d->mMultiTouchEnabled);
  1940     setAcceptTouchEvents(d->mMultiTouchEnabled);
  1817 
  1941 
       
  1942     if (qApp) {
       
  1943         qApp->installEventFilter(this);
       
  1944     }
       
  1945 
  1818     HbWidget::showEvent(event);
  1946     HbWidget::showEvent(event);
  1819 }
  1947 }
  1820 
  1948 
  1821 /*!
  1949 /*!
  1822 \reimp
  1950 \reimp
  1825 */
  1953 */
  1826 void HbInputButtonGroup::hideEvent(QHideEvent *event)
  1954 void HbInputButtonGroup::hideEvent(QHideEvent *event)
  1827 {
  1955 {
  1828     cancelButtonPress();
  1956     cancelButtonPress();
  1829 
  1957 
       
  1958     if (qApp) {
       
  1959         qApp->removeEventFilter(this);
       
  1960     }
       
  1961 
  1830     HbWidget::hideEvent(event);
  1962     HbWidget::hideEvent(event);
       
  1963 }
       
  1964 
       
  1965 /*!
       
  1966 Releases all pressed buttons when deactivated.
       
  1967 */
       
  1968 bool HbInputButtonGroup::eventFilter(QObject *obj, QEvent *event)
       
  1969 {
       
  1970     Q_UNUSED(obj);
       
  1971 
       
  1972     if (event->type() == QEvent::ApplicationDeactivate) {
       
  1973         cancelButtonPress();
       
  1974     }
       
  1975     return false;
  1831 }
  1976 }
  1832 
  1977 
  1833 /*!
  1978 /*!
  1834 Emits buttonPressed signal.
  1979 Emits buttonPressed signal.
  1835 */
  1980 */
  1881 */
  2026 */
  1882 void HbInputButtonGroup::cancelButtonPress()
  2027 void HbInputButtonGroup::cancelButtonPress()
  1883 {
  2028 {
  1884     Q_D(HbInputButtonGroup);
  2029     Q_D(HbInputButtonGroup);
  1885 
  2030 
  1886     ungrabMouse();
  2031     if (d->mHasMouseGrab) {
       
  2032         ungrabMouse();
       
  2033     }
       
  2034 
       
  2035     d->mActiveButtons.clear();
  1887 
  2036 
  1888     // Cancel long press timers
  2037     // Cancel long press timers
  1889     d->mLongPressButtons.clear();
  2038     d->mLongPressButtons.clear();
  1890     foreach (QTimer *timer, d->mLongPressTimers) {
  2039     foreach (QTimer *timer, d->mLongPressTimers) {
  1891         delete timer;
  2040         delete timer;
  1897         if (button->state() == HbInputButton::ButtonStatePressed) {
  2046         if (button->state() == HbInputButton::ButtonStatePressed) {
  1898             button->setState(HbInputButton::ButtonStateReleased);
  2047             button->setState(HbInputButton::ButtonStateReleased);
  1899         }
  2048         }
  1900         d->hideButtonPreview(button);
  2049         d->hideButtonPreview(button);
  1901     }
  2050     }
  1902     if (d->mCharacterSelectionPreview) {
  2051     if (d->mCharacterSelectionPreview) { 
  1903         d->mCharacterSelectionPreview->hide();
  2052         d->mCharacterSelectionPreview->hide();
  1904     }
  2053     }
  1905 
  2054     
  1906     d->updateGraphics(QSizeF(boundingRect().width(), boundingRect().height()));
  2055     d->updateGraphics(QSizeF(boundingRect().width(), boundingRect().height()));
  1907     d->updateTextLayouts(QSizeF(boundingRect().width(), boundingRect().height()));
  2056     d->updateTextLayouts(QSizeF(boundingRect().width(), boundingRect().height()));
  1908     update();
  2057     update();
  1909 }
  2058 }
  1910 
  2059