21 ** If you have questions regarding the use of this file, please contact |
21 ** If you have questions regarding the use of this file, please contact |
22 ** Nokia at developer.feedback@nokia.com. |
22 ** Nokia at developer.feedback@nokia.com. |
23 ** |
23 ** |
24 ****************************************************************************/ |
24 ****************************************************************************/ |
25 |
25 |
26 #include <QDebug> |
|
27 #include <QPainter> |
26 #include <QPainter> |
28 #include <QTextLayout> |
27 #include <QTextLayout> |
29 #include <QGraphicsSceneMouseEvent> |
28 #include <QGraphicsSceneMouseEvent> |
30 #include <QTouchEvent> |
29 #include <QTouchEvent> |
31 #include <QTimer> |
30 #include <QTimer> |
|
31 #include <QApplication> |
|
32 #include <QInputContext> |
32 |
33 |
33 #include <hbmainwindow.h> |
34 #include <hbmainwindow.h> |
34 #include <hbaction.h> |
35 #include <hbaction.h> |
35 #include <hbevent.h> |
36 #include <hbevent.h> |
36 #include <hbcolorscheme.h> |
37 #include <hbcolorscheme.h> |
37 #include <hbdialog.h> |
38 #include <hbdialog.h> |
38 #include <hbframeitem.h> |
39 #include <hbframeitem.h> |
39 #include <hbwidgetfeedback.h> |
40 #include <hbwidgetfeedback.h> |
40 #include <hbdeviceprofile.h> |
41 #include <hbdeviceprofile.h> |
|
42 #include <hbinputregioncollector_p.h> |
41 #include "hbframedrawerpool_p.h" |
43 #include "hbframedrawerpool_p.h" |
42 |
44 |
43 #include "hbinputbuttongroup.h" |
45 #include "hbinputbuttongroup.h" |
44 #include "hbinputbuttongroup_p.h" |
46 #include "hbinputbuttongroup_p.h" |
45 #include "hbinputbutton.h" |
47 #include "hbinputbutton.h" |
312 Q_Q(HbInputButtonGroup); |
314 Q_Q(HbInputButtonGroup); |
313 |
315 |
314 int index = mButtonData.indexOf(item); |
316 int index = mButtonData.indexOf(item); |
315 if (mButtonPreviewEnabled && item->type() != HbInputButton::ButtonTypeFunction && |
317 if (mButtonPreviewEnabled && item->type() != HbInputButton::ButtonTypeFunction && |
316 !mButtonPreview.contains(index)) { |
318 !mButtonPreview.contains(index)) { |
317 HbInputButtonGroup *group = new HbInputButtonGroup(QSize(1, 1), q); |
319 HbInputButtonGroup *group = new HbInputButtonGroup(QSize(1, 1)); |
318 mButtonPreview.insert(index, group); |
320 mButtonPreview.insert(index, group); |
319 |
321 |
320 QList<HbInputButton*> buttons; |
322 QList<HbInputButton*> buttons; |
321 HbInputButton *previewItem = new HbInputButton(item->text(HbInputButton::ButtonTextIndexPrimary).at(0).unicode(), QPoint(0, 0)); |
323 HbInputButton *previewItem = 0; |
|
324 if (!item->icon(HbInputButton::ButtonIconIndexPrimary).isNull()) { |
|
325 int keyCode = -1; |
|
326 if (!item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty()) { |
|
327 keyCode = item->text(HbInputButton::ButtonTextIndexPrimary).at(0).unicode(); |
|
328 } |
|
329 previewItem = new HbInputButton(keyCode, QPoint(0, 0)); |
|
330 previewItem->setIcon(item->icon(HbInputButton::ButtonIconIndexPrimary), HbInputButton::ButtonIconIndexPrimary); |
|
331 } else if (!item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty()) { |
|
332 previewItem = new HbInputButton(item->text(HbInputButton::ButtonTextIndexPrimary).at(0).unicode(), QPoint(0, 0)); |
|
333 previewItem->setText(item->text(HbInputButton::ButtonTextIndexPrimary), HbInputButton::ButtonTextIndexPrimary); |
|
334 } |
322 previewItem->setType(HbInputButton::ButtonTypeLabel); |
335 previewItem->setType(HbInputButton::ButtonTypeLabel); |
323 previewItem->setText(item->text(HbInputButton::ButtonTextIndexPrimary), HbInputButton::ButtonTextIndexPrimary); |
|
324 buttons.append(previewItem); |
336 buttons.append(previewItem); |
325 group->setButtons(buttons); |
337 group->setButtons(buttons); |
326 |
338 |
327 qreal cellWidth = q->boundingRect().width() / mGridSize.width(); |
339 qreal cellWidth = q->boundingRect().width() / mGridSize.width(); |
328 qreal cellHeight = q->boundingRect().height() / mGridSize.height(); |
340 qreal cellHeight = q->boundingRect().height() / mGridSize.height(); |
329 |
341 |
330 QFont font = HbFontSpec(HbFontSpec::Primary).font(); |
342 QFont font = HbFontSpec(HbFontSpec::Primary).font(); |
331 font.setPixelSize(int(fontSize(ButtonTextTypeLabel))); |
343 font.setPixelSize(int(fontSize(ButtonTextTypeLabel))); |
332 QFontMetricsF fontMetrics(font); |
344 QFontMetricsF fontMetrics(font); |
333 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary)); |
345 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary)); |
334 |
346 |
335 qreal width = textWidth + HbPreviewMarginInUnits * mUnitValue; |
347 qreal width = textWidth + HbPreviewMarginInUnits * mUnitValue; |
336 if (width < HbPreviewWidthInUnits * mUnitValue) { |
348 if (!item->icon(HbInputButton::ButtonIconIndexPrimary).isNull()) { |
|
349 width = item->boundingRect().width(); |
|
350 } else if (width < HbPreviewWidthInUnits * mUnitValue) { |
337 width = HbPreviewWidthInUnits * mUnitValue; |
351 width = HbPreviewWidthInUnits * mUnitValue; |
338 } |
352 } |
339 qreal height = HbPreviewHeightInUnits * mUnitValue; |
353 qreal height = HbPreviewHeightInUnits * mUnitValue; |
340 qreal x = (item->position().x() + 0.5 * item->size().width()) * cellWidth - 0.5 * width; |
354 qreal x = q->scenePos().x() + (item->position().x() + 0.5 * item->size().width()) * cellWidth - 0.5 * width; |
341 if (x < 0) { |
355 if (x < 0) { |
342 x = 0; |
356 x = 0; |
343 } else if (x + width > q->boundingRect().width()) { |
357 } else if (x + width > q->boundingRect().width()) { |
344 x = q->boundingRect().width() - width; |
358 x = q->boundingRect().width() - width; |
345 } |
359 } |
346 qreal y = item->position().y() * cellHeight - height; |
360 qreal y = q->scenePos().y() + item->position().y() * cellHeight - height; |
347 group->setGeometry(QRectF(x, y, width, height)); |
361 group->setGeometry(QRectF(x, y, width, height)); |
348 if (q->parentItem()) { |
362 if (q->parentItem()) { |
349 group->setZValue(q->parentItem()->zValue() + 1); |
363 group->setZValue(q->parentItem()->zValue() + 1); |
350 } |
364 } |
351 |
365 |
369 { |
383 { |
370 Q_Q(HbInputButtonGroup); |
384 Q_Q(HbInputButtonGroup); |
371 |
385 |
372 if (mCharacterSelectionPreviewEnabled && item->type() != HbInputButton::ButtonTypeFunction && |
386 if (mCharacterSelectionPreviewEnabled && item->type() != HbInputButton::ButtonTypeFunction && |
373 item->mappedCharacters().count() > 1) { |
387 item->mappedCharacters().count() > 1) { |
|
388 |
|
389 HbWidgetFeedback::triggered(q, Hb::InstantLongPressed); |
374 |
390 |
375 mProbabilities.clear(); |
391 mProbabilities.clear(); |
376 q->cancelButtonPress(); |
392 q->cancelButtonPress(); |
377 |
393 |
378 if (!mCharacterSelectionPreview) { |
394 if (!mCharacterSelectionPreview) { |
379 mCharacterSelectionPreview = new HbDialog(); |
395 mCharacterSelectionPreview = new HbDialog(); |
|
396 HbInputRegionCollector::instance()->attach(mCharacterSelectionPreview); |
380 mCharacterSelectionPreview->setModal(true); |
397 mCharacterSelectionPreview->setModal(true); |
381 mCharacterSelectionPreview->setBackgroundFaded(false); |
398 mCharacterSelectionPreview->setBackgroundFaded(false); |
382 mCharacterSelectionPreview->setTimeout(HbPopup::NoTimeout); |
399 mCharacterSelectionPreview->setTimeout(HbPopup::NoTimeout); |
383 mCharacterSelectionPreview->setDismissPolicy(HbPopup::TapAnywhere); |
400 mCharacterSelectionPreview->setDismissPolicy(HbPopup::TapAnywhere); |
384 mCharacterSelectionPreview->setFlag(QGraphicsItem::ItemIsPanel, true); |
401 mCharacterSelectionPreview->setFlag(QGraphicsItem::ItemIsPanel, true); |
396 |
413 |
397 qreal cellWidth = q->boundingRect().width() / mGridSize.width(); |
414 qreal cellWidth = q->boundingRect().width() / mGridSize.width(); |
398 qreal cellHeight = q->boundingRect().height() / mGridSize.height(); |
415 qreal cellHeight = q->boundingRect().height() / mGridSize.height(); |
399 |
416 |
400 QFont font = HbFontSpec(HbFontSpec::Primary).font(); |
417 QFont font = HbFontSpec(HbFontSpec::Primary).font(); |
401 font.setPixelSize(int(fontSize(ButtonTextTypeLabel))); |
418 font.setPixelSize(int(fontSize(ButtonTextTypeLabel))); |
402 QFontMetricsF fontMetrics(font); |
419 QFontMetricsF fontMetrics(font); |
403 qreal textWidth = fontMetrics.width(item->mappedCharacters()); |
420 qreal textWidth = fontMetrics.width(item->mappedCharacters()); |
404 |
421 |
405 qreal width = textWidth + HbPreviewMarginInUnits * mUnitValue * item->mappedCharacters().count(); |
422 qreal width = textWidth + HbPreviewMarginInUnits * mUnitValue * item->mappedCharacters().count(); |
406 qreal height = HbPreviewHeightInUnits * mUnitValue; |
423 qreal height = HbPreviewHeightInUnits * mUnitValue; |
536 int oldColumn = static_cast<int>(oldPosition.x() / (q->boundingRect().width() / mGridSize.width())); |
553 int oldColumn = static_cast<int>(oldPosition.x() / (q->boundingRect().width() / mGridSize.width())); |
537 int oldRow = static_cast<int>(oldPosition.y() / (q->boundingRect().height() / mGridSize.height())); |
554 int oldRow = static_cast<int>(oldPosition.y() / (q->boundingRect().height() / mGridSize.height())); |
538 int newColumn = static_cast<int>(newPosition.x() / (q->boundingRect().width() / mGridSize.width())); |
555 int newColumn = static_cast<int>(newPosition.x() / (q->boundingRect().width() / mGridSize.width())); |
539 int newRow = static_cast<int>(newPosition.y() / (q->boundingRect().height() / mGridSize.height())); |
556 int newRow = static_cast<int>(newPosition.y() / (q->boundingRect().height() / mGridSize.height())); |
540 |
557 |
541 int oldIndex = mButtonGridPositions.value(QPair<int, int>(oldColumn, oldRow)); |
558 int oldIndex = mButtonGridPositions.value(QPair<int, int>(oldColumn, oldRow), -1); |
542 int newIndex = mButtonGridPositions.value(QPair<int, int>(newColumn, newRow)); |
559 int newIndex = mButtonGridPositions.value(QPair<int, int>(newColumn, newRow), -1); |
543 |
560 |
544 if (newPosition.x() >= 0 && newPosition.x() < q->boundingRect().width() && |
561 if (newPosition.x() >= 0 && newPosition.x() < q->boundingRect().width() && |
545 newPosition.y() >= 0 && newPosition.y() < q->boundingRect().height() && |
562 newPosition.y() >= 0 && newPosition.y() < q->boundingRect().height() && |
546 oldPosition.x() >= 0 && oldPosition.x() < q->boundingRect().width() && |
563 oldPosition.x() >= 0 && oldPosition.x() < q->boundingRect().width() && |
547 oldPosition.y() >= 0 && oldPosition.y() < q->boundingRect().height()) { |
564 oldPosition.y() >= 0 && oldPosition.y() < q->boundingRect().height()) { |
654 QKeyEvent releaeEvent(QEvent::KeyRelease, item->keyCode(), Qt::NoModifier, text, true); |
672 QKeyEvent releaeEvent(QEvent::KeyRelease, item->keyCode(), Qt::NoModifier, text, true); |
655 q->emitButtonReleased(releaeEvent); |
673 q->emitButtonReleased(releaeEvent); |
656 QKeyEvent pressEvent(QEvent::KeyPress, item->keyCode(), Qt::NoModifier, text, true); |
674 QKeyEvent pressEvent(QEvent::KeyPress, item->keyCode(), Qt::NoModifier, text, true); |
657 q->emitButtonPressed(pressEvent); |
675 q->emitButtonPressed(pressEvent); |
658 } else { |
676 } else { |
659 if (mCharacterSelectionPreviewEnabled) { |
677 if (mCharacterSelectionPreviewEnabled && item->type() != HbInputButton::ButtonTypeFunction && item->mappedCharacters().count() > 1) { |
660 showCharacterSelectionPreview(item); |
678 showCharacterSelectionPreview(item); |
661 } |
679 } else { |
662 |
680 HbWidgetFeedback::triggered(q, Hb::InstantLongPressed); |
663 HbWidgetFeedback::triggered(q, Hb::InstantLongPressed); |
681 |
664 |
682 delete timer; |
665 delete timer; |
683 |
666 |
684 QString text; |
667 QString text; |
685 if (item->type() == HbInputButton::ButtonTypeLabel) { |
668 if (item->type() == HbInputButton::ButtonTypeLabel) { |
686 text = item->text(HbInputButton::ButtonTextIndexPrimary); |
669 text = item->text(HbInputButton::ButtonTextIndexPrimary); |
687 } |
670 } |
688 QKeyEvent event(QEvent::KeyPress, item->keyCode(), Qt::NoModifier, text, true); |
671 QKeyEvent event(QEvent::KeyPress, item->keyCode(), Qt::NoModifier, text, true); |
689 q->emitButtonLongPressed(event); |
672 q->emitButtonLongPressed(event); |
690 } |
673 } |
691 } |
674 } |
692 } |
675 } |
693 } |
676 |
694 |
677 void HbInputButtonGroupPrivate::calculateButtonProbabilities(const QPointF &position) |
695 void HbInputButtonGroupPrivate::calculateButtonProbabilities(const QPointF &position) |
740 item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull()) { |
758 item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull()) { |
741 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary)); |
759 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary)); |
742 qreal textHeight = fontMetrics.height(); |
760 qreal textHeight = fontMetrics.height(); |
743 |
761 |
744 QTextLine line = mTextLayouts.at(index)->createLine(); |
762 QTextLine line = mTextLayouts.at(index)->createLine(); |
745 line.setNumColumns(1); |
763 line.setNumColumns(item->text(HbInputButton::ButtonTextIndexPrimary).length()); |
746 |
764 |
747 if (typeIndex == HbInputButton::ButtonTypeLabel) { |
765 if (typeIndex == HbInputButton::ButtonTypeLabel) { |
748 layoutTextLine(ButtonTextTypeLabel, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
766 layoutTextLine(ButtonTextTypeLabel, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
749 } else { |
767 } else { |
750 layoutTextLine(ButtonTextTypeSingle, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
768 layoutTextLine(ButtonTextTypeSingle, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
782 item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull())) { |
800 item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull())) { |
783 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary)); |
801 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary)); |
784 qreal textHeight = fontMetrics.height(); |
802 qreal textHeight = fontMetrics.height(); |
785 |
803 |
786 QTextLine line = mTextLayouts.at(index)->createLine(); |
804 QTextLine line = mTextLayouts.at(index)->createLine(); |
787 line.setNumColumns(1); |
805 line.setNumColumns(item->text(HbInputButton::ButtonTextIndexPrimary).length()); |
788 |
806 |
789 layoutTextLine(ButtonTextTypePrimary, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
807 layoutTextLine(ButtonTextTypePrimary, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
790 } |
808 } |
791 } |
809 } |
792 mTextLayouts.at(index)->endLayout(); |
810 mTextLayouts.at(index)->endLayout(); |
817 item->icon(HbInputButton::ButtonIconIndexSecondaryFirstRow).isNull()) { |
835 item->icon(HbInputButton::ButtonIconIndexSecondaryFirstRow).isNull()) { |
818 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow)); |
836 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow)); |
819 qreal textHeight = fontMetrics.height(); |
837 qreal textHeight = fontMetrics.height(); |
820 |
838 |
821 QTextLine line = mTextLayouts.at(index)->createLine(); |
839 QTextLine line = mTextLayouts.at(index)->createLine(); |
822 line.setNumColumns(1); |
840 line.setNumColumns(item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow).length()); |
823 |
841 |
824 layoutTextLine(ButtonTextTypeSecondaryFirstRow, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
842 layoutTextLine(ButtonTextTypeSecondaryFirstRow, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
825 } |
843 } |
826 |
844 |
827 if (!item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).isEmpty() && |
845 if (!item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).isEmpty() && |
828 item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull()) { |
846 item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull()) { |
829 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexSecondarySecondRow)); |
847 qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexSecondarySecondRow)); |
830 qreal textHeight = fontMetrics.height(); |
848 qreal textHeight = fontMetrics.height(); |
831 |
849 |
832 QTextLine line = mTextLayouts.at(index)->createLine(); |
850 QTextLine line = mTextLayouts.at(index)->createLine(); |
833 line.setNumColumns(1); |
851 line.setNumColumns(item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).length()); |
834 |
852 |
835 layoutTextLine(ButtonTextTypeSecondarySecondRow, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
853 layoutTextLine(ButtonTextTypeSecondarySecondRow, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight)); |
836 } |
854 } |
837 } |
855 } |
838 } |
856 } |
1241 void HbInputButtonGroup::setCustomButtonActions(const QList<HbAction*> &actions) |
1268 void HbInputButtonGroup::setCustomButtonActions(const QList<HbAction*> &actions) |
1242 { |
1269 { |
1243 Q_D(HbInputButtonGroup); |
1270 Q_D(HbInputButtonGroup); |
1244 |
1271 |
1245 disconnect(this, SLOT(updateCustomButtons())); |
1272 disconnect(this, SLOT(updateCustomButtons())); |
|
1273 disconnect(this, SLOT(_q_customActionDestroyed(QObject *))); |
1246 |
1274 |
1247 d->mCustomActions = actions; |
1275 d->mCustomActions = actions; |
1248 |
1276 |
1249 foreach (HbAction *action, d->mCustomActions) { |
1277 foreach (HbAction *action, d->mCustomActions) { |
1250 connect(action, SIGNAL(changed()), this, SLOT(updateCustomButtons())); |
1278 connect(action, SIGNAL(changed()), this, SLOT(updateCustomButtons())); |
|
1279 connect(action, SIGNAL(destroyed(QObject *)), this, SLOT(_q_customActionDestroyed(QObject *))); |
1251 } |
1280 } |
1252 |
1281 |
1253 d->updateCustomActions(); |
1282 d->updateCustomActions(); |
1254 d->updateGraphics(QSizeF(boundingRect().width(), boundingRect().height())); |
1283 d->updateGraphics(QSizeF(boundingRect().width(), boundingRect().height())); |
1255 d->updateTextLayouts(QSizeF(boundingRect().width(), boundingRect().height())); |
1284 d->updateTextLayouts(QSizeF(boundingRect().width(), boundingRect().height())); |