--- a/src/hbinput/inputwidgets/hbinputbuttongroup.cpp Mon Oct 04 17:49:30 2010 +0300
+++ b/src/hbinput/inputwidgets/hbinputbuttongroup.cpp Mon Oct 18 18:23:13 2010 +0300
@@ -37,15 +37,28 @@
#include <hbaction.h>
#include <hbevent.h>
#include <hbcolorscheme.h>
-#include <hbdialog.h>
+#include <hbinputpopupbase.h>
#include <hbframeitem.h>
#include <hbwidgetfeedback.h>
#include <hbdeviceprofile.h>
#include <hbinputregioncollector_p.h>
+#include <hbinputsettingproxy.h>
#include "hbframedrawerpool_p.h"
#include "hbinputbutton.h"
+/*!
+@stable
+@hbinput
+\class HbInputButtonGroup
+\brief A widget presenting group of buttons for virtual keyboards.
+
+HbInputButtonGroup is a widget displaying a mat of buttons, performance-optimized
+as a single widget instead of multiple separate button widgets.
+
+\sa HbInputButton
+*/
+
/// @cond
const QString HbNormalBackground("qtg_fr_input_btn_keypad_normal");
@@ -72,14 +85,15 @@
const QString HbButtonPreviewColor("qtc_input_preview_normal");
const QString HbCharacterSelectionPreviewColor("qtc_input_button_accented_normal");
+const QString HbHwrSctKeyboard("hwr_symbol_keypad");
-const int HbLongPressTimeout = 600;
+const int HbLongPressTimeout = 800;
const int HbAutoRepeatTimeout = 100;
const int HbTextTypeCount = HbInputButton::ButtonTypeCount * HbInputButton::ButtonStateCount;
const int HbTextLayoutCount = HbTextTypeCount * 3;
-const qreal HbTextSizeInUnits = 5.75;
+const qreal HbTextSizeInUnits = 4.6;
const qreal HbPrimaryTextSizeInUnits = 5.37;
const qreal HbSecondaryTextSizeInUnits = 3.36;
const qreal HbLabelTextSizeInUnits = 9;
@@ -96,7 +110,8 @@
HbInputButtonGroupPrivate::HbInputButtonGroupPrivate()
: mUnitValue(0), mGridSize(1, 1), mButtonBorderSize(1.0), mEnabled(true),
mButtonPreviewEnabled(false), mCharacterSelectionPreviewEnabled(false),
- mMultiTouchEnabled(true), mCharacterSelectionPreview(0), mBackground(0)
+ mMultiTouchEnabled(true), mCharacterSelectionPreview(0), mBackground(0),
+ mHasMouseGrab(false)
{
for (int i = 0; i < HbTextLayoutCount; ++i) {
mTextLayouts.append(0);
@@ -347,9 +362,14 @@
qreal cellWidth = q->boundingRect().width() / mGridSize.width();
qreal cellHeight = q->boundingRect().height() / mGridSize.height();
+ Qt::Orientation orientation = Qt::Horizontal;
+ if (q->mainWindow()) {
+ orientation = q->mainWindow()->orientation();
+ }
+
// Calculate text size
QFont font = HbFontSpec(HbFontSpec::Primary).font();
- font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypeLabel)));
+ font.setPixelSize(int(group->fontSize(HbInputButtonGroup::ButtonTextTypeLabel)));
QFontMetricsF fontMetrics(font);
qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary));
@@ -361,14 +381,19 @@
width = HbPreviewWidthInUnits * mUnitValue;
}
qreal height = HbPreviewHeightInUnits * mUnitValue;
- qreal x = q->scenePos().x() + (item->position().x() + 0.5 * item->size().width()) * cellWidth - 0.5 * width;
+ qreal x = (item->position().x() + 0.5 * item->size().width()) * cellWidth - 0.5 * width;
if (x < 0) {
x = 0;
} else if (x + width > q->boundingRect().width()) {
x = q->boundingRect().width() - width;
}
- qreal y = q->scenePos().y() + item->position().y() * cellHeight - height;
- group->setGeometry(QRectF(x, y, width, height));
+ qreal y = item->position().y() * cellHeight - height;
+ if (y < 0 &&
+ orientation == Qt::Horizontal &&
+ q->objectName() == HbHwrSctKeyboard) {
+ y = (item->position().y() + 1)* cellHeight;
+ }
+ group->setGeometry(QRectF(q->mapToScene(x, y), QSizeF(width, height)));
if (q->parentItem()) {
group->setZValue(q->parentItem()->zValue() + 1);
}
@@ -400,8 +425,7 @@
if (item->type() == HbInputButton::ButtonTypeFunction) {
HbWidgetFeedback::triggered(q, Hb::InstantLongPressed, Hb::ModifierInputFunctionButton);
- }
- else {
+ } else {
HbWidgetFeedback::triggered(q, Hb::InstantLongPressed);
}
@@ -410,14 +434,12 @@
// Create and initialize character preview
if (!mCharacterSelectionPreview) {
- mCharacterSelectionPreview = new HbDialog();
+ mCharacterSelectionPreview = new HbInputPopupBase();
HbInputRegionCollector::instance()->attach(mCharacterSelectionPreview);
mCharacterSelectionPreview->setModal(true);
mCharacterSelectionPreview->setBackgroundFaded(false);
mCharacterSelectionPreview->setTimeout(HbPopup::NoTimeout);
mCharacterSelectionPreview->setDismissPolicy(HbPopup::TapAnywhere);
- mCharacterSelectionPreview->setFlag(QGraphicsItem::ItemIsPanel, true);
- mCharacterSelectionPreview->setActive(false);
qreal margin = HbPreviewMarginInUnits * mUnitValue * 0.5;
mCharacterSelectionPreview->setContentsMargins(margin, 0, margin, 0);
}
@@ -485,19 +507,24 @@
if (index >= 0 && index < mButtonData.count()) {
HbInputButton *item = mButtonData.at(index);
+ // Check whether we are actually supposed to handle the event.
if ((item->state() != HbInputButton::ButtonStateReleased &&
item->state() != HbInputButton::ButtonStateLatched) ||
(mCharacterSelectionPreview && mCharacterSelectionPreview->isVisible())) {
if (item->state() == HbInputButton::ButtonStateDisabled) {
startLongPress(index);
+ mActiveButtons.append(index);
+ item->setLastTriggeredPosition(position);
}
return;
}
+
+ mActiveButtons.append(index);
+ item->setLastTriggeredPosition(position);
if (item->type() == HbInputButton::ButtonTypeFunction) {
HbWidgetFeedback::triggered(q, Hb::InstantPressed, Hb::ModifierInputFunctionButton);
- }
- else {
+ } else {
HbWidgetFeedback::triggered(q, Hb::InstantPressed);
}
@@ -510,8 +537,9 @@
startLongPress(index);
- if (!mUsedCustomButtons.contains(index)) {
- if (emitSignal) {
+ if (emitSignal) {
+ item->setTouchPointPosition(position);
+ if (!mUsedCustomButtons.contains(index)) {
QString text;
if (item->type() == HbInputButton::ButtonTypeLabel) {
text = item->text(HbInputButton::ButtonTextIndexPrimary);
@@ -541,19 +569,24 @@
if (index >= 0 && index < mButtonData.count()) {
HbInputButton *item = mButtonData.at(index);
+ // Check whether we are actually supposed to handle the event.
if ((item->state() != HbInputButton::ButtonStateReleased &&
item->state() != HbInputButton::ButtonStateLatched) ||
(mCharacterSelectionPreview && mCharacterSelectionPreview->isVisible())) {
if (item->state() == HbInputButton::ButtonStateDisabled) {
startLongPress(index);
+ mActiveButtons.append(index);
+ item->setLastTriggeredPosition(position);
}
return;
}
+ mActiveButtons.append(index);
+ item->setLastTriggeredPosition(position);
+
if (item->type() == HbInputButton::ButtonTypeFunction) {
HbWidgetFeedback::triggered(q, Hb::InstantPressed, Hb::ModifierInputFunctionButton);
- }
- else {
+ } else {
HbWidgetFeedback::triggered(q, Hb::InstantPressed);
}
@@ -583,30 +616,52 @@
{
Q_Q(HbInputButtonGroup);
- int oldColumn = static_cast<int>(oldPosition.x() / (q->boundingRect().width() / mGridSize.width()));
- int oldRow = static_cast<int>(oldPosition.y() / (q->boundingRect().height() / mGridSize.height()));
+ int itemIndex = activeButtonIndex(oldPosition);
+ if (itemIndex >= 0) {
+ HbInputButton* activeItem = mButtonData.at(itemIndex);
+ // If move event happens within short timeout near the original touch point
+ // or after timeout inside button's touch area the move event needs to be ignored
+ if (activeItem && activeItem->suppressMoveEvent(newPosition)) {
+ return;
+ }
+ }
+
int newColumn = static_cast<int>(newPosition.x() / (q->boundingRect().width() / mGridSize.width()));
int newRow = static_cast<int>(newPosition.y() / (q->boundingRect().height() / mGridSize.height()));
- int oldIndex = mButtonGridPositions.value(QPair<int, int>(oldColumn, oldRow), -1);
int newIndex = mButtonGridPositions.value(QPair<int, int>(newColumn, newRow), -1);
- // Check if movement happens inside button group
+ // Check if movement happens inside button group and both oldIndex and newIndex are valid
if (newPosition.x() >= 0 && newPosition.x() < q->boundingRect().width() &&
newPosition.y() >= 0 && newPosition.y() < q->boundingRect().height() &&
oldPosition.x() >= 0 && oldPosition.x() < q->boundingRect().width() &&
- oldPosition.y() >= 0 && oldPosition.y() < q->boundingRect().height()) {
+ oldPosition.y() >= 0 && oldPosition.y() < q->boundingRect().height() &&
+ itemIndex >= 0 && newIndex >= 0) {
+
+ // When user moves a finger on the keyboard, currently active button(s) should consume events
+ // as long as the finger position is within the touch area of the button. Button should be removed
+ // from the mActiveButtons, when finger moves outside the button's touch area.
- if (oldIndex != newIndex) {
+ // The button, this event belongs to, can be determined by checking which button handled the
+ // 'oldPosition' coordinate in previous run of either pressEvent or moveEvent.
+ // If button is no longer active just return.
+ int activeItemIndex = activeButtonIndex(oldPosition);
+ if (activeItemIndex < 0) {
+ return;
+ }
+ HbInputButton* activeItem = mButtonData.at(activeItemIndex);
+
+ // In case user has moved finger far enough away from the original button, old active
+ // item needs to be removed and the new one should be added to active list.
+ if (!mActiveButtons.contains(newIndex)) {
releaseEvent(oldPosition, false);
pressEvent(newPosition, false);
QString text;
- HbInputButton *oldItem = mButtonData.at(oldIndex);
- if (oldItem->type() == HbInputButton::ButtonTypeLabel) {
- text = oldItem->text(HbInputButton::ButtonTextIndexPrimary);
+ if (activeItem->type() == HbInputButton::ButtonTypeLabel) {
+ text = activeItem->text(HbInputButton::ButtonTextIndexPrimary);
}
- QKeyEvent releaseEvent(QEvent::KeyRelease, oldItem->keyCode(), Qt::NoModifier, text);
+ QKeyEvent releaseEvent(QEvent::KeyRelease, activeItem->keyCode(), Qt::NoModifier, text);
HbInputButton *newItem = mButtonData.at(newIndex);
if (newItem->type() == HbInputButton::ButtonTypeLabel) {
@@ -615,11 +670,16 @@
QKeyEvent pressEvent(QEvent::KeyPress, newItem->keyCode(), Qt::NoModifier, text);
q->emitPressedButtonChanged(releaseEvent, pressEvent);
+ } else {
+ // Even though we do nothing with this button this time, update the status
+ // of the item, so next time this function is invoked, this button is correctly
+ // detected as the owner of the new event.
+ activeItem->setLastTriggeredPosition(newPosition);
}
} else {
- // Move event came from outside button group so create new release and press events
- // for old and new position. If one of the positions is inside button group
- // a new event will get generated.
+ // Move event came from outside button group or one of the positions does not contain
+ // button so create new release and press events for old and new position.
+ // If one of the positions is inside button group a new key event will get emitted automatically.
releaseEvent(oldPosition, false);
pressEvent(newPosition);
}
@@ -629,30 +689,24 @@
{
Q_Q(HbInputButtonGroup);
- // Ignore release events outside button group
- if (!(position.x() >= 0 && position.x() < q->boundingRect().width() &&
- position.y() >= 0 && position.y() < q->boundingRect().height())) {
- return;
- }
+ int activeIndex = activeButtonIndex(position);
+ if (activeIndex >= 0) {
+ HbInputButton *item = mButtonData.at(activeIndex);
- int column = static_cast<int>(position.x() / (q->boundingRect().width() / mGridSize.width()));
- int row = static_cast<int>(position.y() / (q->boundingRect().height() / mGridSize.height()));
-
- int index = mButtonGridPositions.value(QPair<int, int>(column, row), -1);
+ cancelLongPress(activeIndex);
- if (index >= 0 && index < mButtonData.count()) {
- HbInputButton *item = mButtonData.at(index);
-
- cancelLongPress(index);
-
+ // Check if we need to handle this event
if (item->state() != HbInputButton::ButtonStatePressed) {
return;
}
+ // This item is pressed, so release can happen for this.
+ mActiveButtons.removeAll(activeIndex);
+ QPointF releasePosition = item->currentTouchPointPosition();
+
if (item->type() == HbInputButton::ButtonTypeFunction) {
HbWidgetFeedback::triggered(q, Hb::InstantReleased, Hb::ModifierInputFunctionButton);
- }
- else {
+ } else {
HbWidgetFeedback::triggered(q, Hb::InstantReleased);
}
@@ -670,8 +724,7 @@
if (emitSignal) {
if (item->type() == HbInputButton::ButtonTypeFunction) {
HbWidgetFeedback::triggered(q, Hb::InstantClicked, Hb::ModifierInputFunctionButton);
- }
- else {
+ } else {
HbWidgetFeedback::triggered(q, Hb::InstantClicked);
}
int actionIndex = item->keyCode() - HbInputButton::ButtonKeyCodeCustom;
@@ -679,7 +732,7 @@
emit q->aboutToActivateCustomAction(mCustomActions.at(actionIndex));
mCustomActions.at(actionIndex)->activate(QAction::Trigger);
} else {
- calculateButtonProbabilities(position);
+ calculateButtonProbabilities(releasePosition);
QString text;
if (item->type() == HbInputButton::ButtonTypeLabel) {
@@ -699,7 +752,7 @@
int index = mLongPressButtons.at(0);
mLongPressButtons.removeAt(0);
QTimer *timer = mLongPressTimers.at(0);
- mLongPressTimers.removeAt(0);
+ mLongPressTimers.removeAt(0);
if (index >= 0 && index < mButtonData.count()) {
HbInputButton *item = mButtonData.at(index);
@@ -714,8 +767,7 @@
if (item->type() == HbInputButton::ButtonTypeFunction) {
HbWidgetFeedback::triggered(q, Hb::InstantKeyRepeated, Hb::ModifierInputFunctionButton);
- }
- else {
+ } else {
HbWidgetFeedback::triggered(q, Hb::InstantKeyRepeated);
}
@@ -724,8 +776,8 @@
text = item->text(HbInputButton::ButtonTextIndexPrimary);
}
int keycode = item->keyCode();
- QKeyEvent releaeEvent(QEvent::KeyRelease, keycode, Qt::NoModifier, text, true);
- q->emitButtonReleased(releaeEvent);
+ QKeyEvent releaseEvent(QEvent::KeyRelease, keycode, Qt::NoModifier, text, true);
+ q->emitButtonReleased(releaseEvent);
QKeyEvent pressEvent(QEvent::KeyPress, keycode, Qt::NoModifier, text, true);
q->emitButtonPressed(pressEvent);
} else {
@@ -737,8 +789,7 @@
} else {
if (item->type() == HbInputButton::ButtonTypeFunction) {
HbWidgetFeedback::triggered(q, Hb::InstantLongPressed, Hb::ModifierInputFunctionButton);
- }
- else {
+ } else {
HbWidgetFeedback::triggered(q, Hb::InstantLongPressed);
}
@@ -788,6 +839,32 @@
}
}
+/*!
+\internal
+\brief Search active button based on position.
+
+Locates active button based on its last interaction point.
+
+\param position Location of triggered user action.
+\return NULL, when no button has reacted to given coordinates.
+\return Pointer to active button.
+*/
+int HbInputButtonGroupPrivate::activeButtonIndex(const QPointF &position)
+{
+ // Here we get the position, where last interaction occurred.
+ // Start searching from the end of the list, because it is likely,
+ // that the triggered position happens on the button that was added last.
+ for (int i = mActiveButtons.count() - 1; i >= 0; --i) {
+ int activeIndex = mActiveButtons[i];
+ if (mButtonData[activeIndex]->wasTriggeredAt(position)) {
+ return activeIndex;
+ }
+ }
+
+ // Position is not inside any single active button.
+ return -1;
+}
+
void HbInputButtonGroupPrivate::createPrimarySingleTextLayout(int index, const QHash<int, QString> &textContent, const QSizeF &size)
{
qreal cellWidth = size.width() / mGridSize.width();
@@ -803,7 +880,6 @@
}
mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
- QFontMetricsF fontMetrics(font);
// Create text line for each button with primary text and correct type and state. Layout it
// to correct position
@@ -813,17 +889,18 @@
if (!mEnabled) {
layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled + HbTextTypeCount;
}
- if (index == layoutIndex && !item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
+ if (index == layoutIndex && item->size().isValid() &&
+ !item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
item->icon(HbInputButton::ButtonIconIndexPrimary).isNull() &&
item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow).isEmpty() &&
item->icon(HbInputButton::ButtonIconIndexSecondaryFirstRow).isNull() &&
item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).isEmpty() &&
item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull()) {
- qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary));
- qreal textHeight = fontMetrics.height();
QTextLine line = mTextLayouts.at(index)->createLine();
line.setNumColumns(item->text(HbInputButton::ButtonTextIndexPrimary).length());
+ qreal textWidth = line.naturalTextWidth();
+ qreal textHeight = line.height();
if (typeIndex == HbInputButton::ButtonTypeLabel) {
layoutTextLine(HbInputButtonGroup::ButtonTextTypeLabel, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
@@ -845,8 +922,6 @@
font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypePrimary)));
mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
- QFontMetricsF fontMetrics(font);
-
// Create text line for each button with primary text and correct type and state. Layout it
// to correct position
mTextLayouts.at(index)->beginLayout();
@@ -855,18 +930,20 @@
if (!mEnabled) {
layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled;
}
- if (index == layoutIndex && !item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
+ if (index == layoutIndex && item->size().isValid() &&
+ !item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
item->icon(HbInputButton::ButtonIconIndexPrimary).isNull() &&
!(item->text(HbInputButton::ButtonTextIndexSecondaryFirstRow).isEmpty() &&
item->icon(HbInputButton::ButtonIconIndexSecondaryFirstRow).isNull() &&
item->text(HbInputButton::ButtonTextIndexSecondarySecondRow).isEmpty() &&
item->icon(HbInputButton::ButtonIconIndexSecondarySecondRow).isNull())) {
- qreal textWidth = fontMetrics.width(item->text(HbInputButton::ButtonTextIndexPrimary));
- qreal textHeight = fontMetrics.height();
QTextLine line = mTextLayouts.at(index)->createLine();
line.setNumColumns(item->text(HbInputButton::ButtonTextIndexPrimary).length());
+ qreal textWidth = line.naturalTextWidth();
+ qreal textHeight = line.height();
+
layoutTextLine(HbInputButtonGroup::ButtonTextTypePrimary, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
}
}
@@ -880,7 +957,6 @@
font.setPixelSize(int(fontSize(HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow)));
mTextLayouts[index] = new QTextLayout(textContent.value(index), font);
- QFontMetricsF fontMetrics(font);
// Create text line for each button with secondary first row or second row text and correct type and state.
// Layout it to correct position
@@ -890,9 +966,9 @@
if (!mEnabled) {
layoutIndex = item->type() * HbInputButton::ButtonStateCount + HbInputButton::ButtonStateDisabled + HbTextTypeCount * 2;
}
- if (index == layoutIndex) {
+ if (index == layoutIndex && item->size().isValid()) {
// Layout secondary text for first row
- layoutSecondaryText(index, item, fontMetrics, size,
+ layoutSecondaryText(index, item, size,
HbInputButton::ButtonTextIndexSecondaryFirstRow,
HbInputButton::ButtonIconIndexSecondaryFirstRow,
HbInputButton::ButtonTextIndexSecondarySecondRow,
@@ -901,7 +977,7 @@
// Layout secondary text for second row
- layoutSecondaryText(index, item, fontMetrics, size,
+ layoutSecondaryText(index, item, size,
HbInputButton::ButtonTextIndexSecondarySecondRow,
HbInputButton::ButtonIconIndexSecondarySecondRow,
HbInputButton::ButtonTextIndexSecondaryFirstRow,
@@ -913,7 +989,7 @@
mTextLayouts.at(index)->setCacheEnabled(true);
}
-void HbInputButtonGroupPrivate::layoutSecondaryText(int index, HbInputButton *item, QFontMetricsF &fontMetrics, const QSizeF &size,
+void HbInputButtonGroupPrivate::layoutSecondaryText(int index, HbInputButton *item, const QSizeF &size,
HbInputButton::HbInputButtonTextIndex firstTextIndex,
HbInputButton::HbInputButtonIconIndex firstIconIndex,
HbInputButton::HbInputButtonTextIndex secondTextIndex,
@@ -925,17 +1001,20 @@
if (!item->text(firstTextIndex).isEmpty() &&
item->icon(firstIconIndex).isNull()) {
- qreal textWidth = fontMetrics.width(item->text(firstTextIndex));
- qreal textHeight = fontMetrics.height();
QTextLine line = mTextLayouts.at(index)->createLine();
line.setNumColumns(item->text(firstTextIndex).length());
+ qreal textWidth = line.naturalTextWidth();
+ qreal textHeight = line.height();
if (item->text(HbInputButton::ButtonTextIndexPrimary).isEmpty() &&
- item->icon(HbInputButton::ButtonIconIndexPrimary).isNull() &&
- item->text(secondTextIndex).isEmpty() &&
- item->icon(secondIconIndex).isNull()) {
- layoutTextLine(HbInputButtonGroup::ButtonTextTypeSingle, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
+ item->icon(HbInputButton::ButtonIconIndexPrimary).isNull()) {
+ if (item->text(secondTextIndex).isEmpty() &&
+ item->icon(secondIconIndex).isNull()) {
+ layoutTextLine(HbInputButtonGroup::ButtonTextTypeSingle, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
+ } else {
+ layoutTextLine(textType, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight), true);
+ }
} else {
layoutTextLine(textType, item, QSizeF(cellWidth, cellHeight), line, QSizeF(textWidth, textHeight));
}
@@ -943,38 +1022,45 @@
}
void HbInputButtonGroupPrivate::layoutTextLine(HbInputButtonGroup::HbInputButtonTextType textType, const HbInputButton *button, const QSizeF &cellSize,
- QTextLine &textLine, const QSizeF &textSize)
+ QTextLine &textLine, const QSizeF &textSize, const bool centered)
{
qreal textPositionX = 0.0;
qreal textPositionY = 0.0;
switch(textType) {
- case HbInputButtonGroup::ButtonTextTypeSingle:
- case HbInputButtonGroup::ButtonTextTypeLabel:
- textPositionX = (button->position().x() + 0.5 * button->size().width()) * cellSize.width() - 0.5 * textSize.width();
- textPositionY = (button->position().y() + 0.5 * button->size().height()) * cellSize.height() - 0.5 * textSize.height();
- break;
+ case HbInputButtonGroup::ButtonTextTypeSingle:
+ case HbInputButtonGroup::ButtonTextTypeLabel:
+ textPositionX = (button->position().x() + 0.5 * button->size().width()) * cellSize.width() - 0.5 * textSize.width();
+ textPositionY = (button->position().y() + 0.5 * button->size().height()) * cellSize.height() - 0.5 * textSize.height();
+ break;
+
+ case HbInputButtonGroup::ButtonTextTypePrimary:
+ textPositionX = button->position().x() * cellSize.width() + HbHorizontalMarginInUnits * mUnitValue + mButtonBorderSize;
+ textPositionY = (button->position().y() + 0.5 * button->size().height()) * cellSize.height() - 0.5 * textSize.height();
+ break;
- case HbInputButtonGroup::ButtonTextTypePrimary:
- textPositionX = button->position().x() * cellSize.width() + HbHorizontalMarginInUnits * mUnitValue + mButtonBorderSize;
- textPositionY = (button->position().y() + 0.5 * button->size().height()) * cellSize.height() - 0.5 * textSize.height();
- break;
+ case HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow:
+ if (centered) {
+ textPositionX = (button->position().x() + 0.5 * button->size().width()) * cellSize.width() - 0.5 * textSize.width();
+ } else {
+ textPositionX = (button->position().x() + button->size().width()) * cellSize.width() -
+ textSize.width() - HbHorizontalMarginInUnits * mUnitValue - mButtonBorderSize;
+ }
+ textPositionY = (button->position().y() + button->size().height()) * cellSize.height() -
+ textSize.height() - HbVerticalMarginInUnits * mUnitValue - mButtonBorderSize;
+ break;
- case HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow:
+ case HbInputButtonGroup::ButtonTextTypeSecondarySecondRow:
+ if (centered) {
+ textPositionX = (button->position().x() + 0.5 * button->size().width()) * cellSize.width() - 0.5 * textSize.width();
+ } else {
textPositionX = (button->position().x() + button->size().width()) * cellSize.width() -
textSize.width() - HbHorizontalMarginInUnits * mUnitValue - mButtonBorderSize;
- textPositionY = (button->position().y() + button->size().height()) * cellSize.height() -
- textSize.height() - HbVerticalMarginInUnits * mUnitValue - mButtonBorderSize;
- break;
-
- case HbInputButtonGroup::ButtonTextTypeSecondarySecondRow:
- textPositionX = (button->position().x() + button->size().width()) * cellSize.width() -
- textSize.width() - HbHorizontalMarginInUnits * mUnitValue - mButtonBorderSize;
- textPositionY = button->position().y() * cellSize.height() + HbVerticalMarginInUnits * mUnitValue + mButtonBorderSize;
- break;
-
- default:
- break;
+ }
+ textPositionY = button->position().y() * cellSize.height() + HbVerticalMarginInUnits * mUnitValue + mButtonBorderSize;
+ break;
+ default:
+ break;
}
textLine.setPosition(QPointF(textPositionX, textPositionY));
}
@@ -1039,23 +1125,21 @@
qreal HbInputButtonGroupPrivate::fontSize(HbInputButtonGroup::HbInputButtonTextType textType)
{
- switch(textType) {
- case HbInputButtonGroup::ButtonTextTypeSingle:
- return HbTextSizeInUnits * mUnitValue;
+ return mFontSize[textType];
+}
- case HbInputButtonGroup::ButtonTextTypePrimary:
- return HbPrimaryTextSizeInUnits * mUnitValue;
+void HbInputButtonGroupPrivate::setFontSize(HbInputButtonGroup::HbInputButtonTextType textType,qreal size)
+{
+ mFontSize[textType] = size;
+}
- case HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow:
- case HbInputButtonGroup::ButtonTextTypeSecondarySecondRow:
- return HbSecondaryTextSizeInUnits * mUnitValue;
-
- case HbInputButtonGroup::ButtonTextTypeLabel:
- return HbLabelTextSizeInUnits * mUnitValue;
-
- default:
- return 0;
- }
+void HbInputButtonGroupPrivate::resetFontSizes()
+{
+ mFontSize[HbInputButtonGroup::ButtonTextTypeSingle] = HbTextSizeInUnits * mUnitValue;
+ mFontSize[HbInputButtonGroup::ButtonTextTypePrimary] = HbPrimaryTextSizeInUnits * mUnitValue;
+ mFontSize[HbInputButtonGroup::ButtonTextTypeSecondaryFirstRow] = HbSecondaryTextSizeInUnits * mUnitValue;
+ mFontSize[HbInputButtonGroup::ButtonTextTypeSecondarySecondRow] = HbSecondaryTextSizeInUnits * mUnitValue;
+ mFontSize[HbInputButtonGroup::ButtonTextTypeLabel] = HbLabelTextSizeInUnits * mUnitValue;
}
void HbInputButtonGroupPrivate::startLongPress(int index)
@@ -1101,6 +1185,8 @@
d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
+ resetFontSizes();
+
setAcceptedMouseButtons(Qt::LeftButton);
}
@@ -1114,6 +1200,8 @@
d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
+ resetFontSizes();
+
setAcceptedMouseButtons(Qt::LeftButton);
}
@@ -1127,6 +1215,8 @@
d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
+ resetFontSizes();
+
setAcceptedMouseButtons(Qt::LeftButton);
setGridSize(size);
@@ -1142,6 +1232,8 @@
d->mUnitValue = HbDeviceProfile::profile(mainWindow()).unitValue();
+ resetFontSizes();
+
setAcceptedMouseButtons(Qt::LeftButton);
setGridSize(size);
@@ -1202,9 +1294,10 @@
{
Q_D(HbInputButtonGroup);
- foreach(HbInputButton *button, d->mButtonData) {
- if (!data.contains(button)) {
- delete button;
+ for (int i = 0; i < d->mButtonData.count(); ++i) {
+ if (!data.contains(d->mButtonData.at(i))) {
+ delete d->mButtonData.at(i);
+ d->cancelLongPress(i);
}
}
d->mButtonData = data;
@@ -1233,6 +1326,7 @@
if (index >= 0 && index < d->mButtonData.count()) {
if (data != d->mButtonData.at(index)) {
delete d->mButtonData.at(index);
+ d->cancelLongPress(index);
}
if (data) {
d->mButtonData.replace(index, data);
@@ -1489,7 +1583,8 @@
/*!
-Sets multi touch enabled or disabled.
+If given parameter is true more that one touch points are accepted
+simultaneously.
\sa isMultiTouchEnabled
*/
@@ -1502,7 +1597,7 @@
}
/*!
-Returns multi touch state.
+Returns true if more than one touch points are accepted simultaneously.
\sa setMultiTouchEnabled
*/
@@ -1536,6 +1631,26 @@
}
/*!
+Set font size for given text type
+*/
+void HbInputButtonGroup::setFontSize(HbInputButtonTextType textType,qreal size)
+{
+ Q_D(HbInputButtonGroup);
+
+ return d->setFontSize(textType,size);
+}
+
+/*!
+Reset font size for all text type
+*/
+void HbInputButtonGroup::resetFontSizes()
+{
+ Q_D(HbInputButtonGroup);
+
+ return d->resetFontSizes();
+}
+
+/*!
Returns all possible buttons the user could have intended to press
for the last registered touch along with their corresponding probabilities.
*/
@@ -1674,75 +1789,86 @@
{
Q_D(HbInputButtonGroup);
- if (!d->mEnabled) {
+ // In case disabled or there is a preview popup open for any button, ignore events in this group.
+ if (!d->mEnabled || (d->mCharacterSelectionPreview && d->mCharacterSelectionPreview->isVisible())) {
event->ignore();
return false;
}
switch(event->type()) {
- case QEvent::TouchBegin: {
- QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
- foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
- if (!point.isPrimary() && d->mMultiTouchEnabled) {
- d->pressEvent(point.pos());
- }
+ case QEvent::TouchBegin: {
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
+ if (!point.isPrimary() && d->mMultiTouchEnabled) {
+ d->pressEvent(point.pos());
}
- break;
}
+ break;
+ }
- case QEvent::TouchUpdate: {
- QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
- foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
- if (!point.isPrimary() && d->mMultiTouchEnabled) {
- if (point.state() & Qt::TouchPointPressed) {
- d->pressEvent(point.pos());
- } else if (point.state() & Qt::TouchPointMoved) {
- d->moveEvent(point.lastPos(), point.pos());
- } else if (point.state() & Qt::TouchPointReleased) {
- d->releaseEvent(point.pos());
- }
- }
- }
- break;
- }
-
- case QEvent::TouchEnd: {
- QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
- foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
- if (!point.isPrimary() && d->mMultiTouchEnabled) {
+ case QEvent::TouchUpdate: {
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
+ if (!point.isPrimary() && d->mMultiTouchEnabled) {
+ if (point.state() & Qt::TouchPointPressed) {
+ d->pressEvent(point.pos());
+ } else if (point.state() & Qt::TouchPointMoved) {
+ d->moveEvent(point.lastPos(), point.pos());
+ } else if (point.state() & Qt::TouchPointReleased) {
+ d->moveEvent(point.lastPos(), point.pos());
d->releaseEvent(point.pos());
}
}
- break;
}
+ break;
+ }
- case QEvent::GraphicsSceneMousePress: {
- QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
- d->pressEvent(mouseEvent->pos());
- break;
+ case QEvent::TouchEnd: {
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ foreach(const QTouchEvent::TouchPoint &point, touchEvent->touchPoints()) {
+ if (!point.isPrimary() && d->mMultiTouchEnabled) {
+ d->moveEvent(point.lastPos(), point.pos());
+ d->releaseEvent(point.pos());
+ }
}
+ break;
+ }
- case QEvent::GraphicsSceneMouseDoubleClick: {
- QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
- d->doublePressEvent(mouseEvent->pos());
- break;
- }
+ case QEvent::GraphicsSceneMousePress: {
+ QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
+ d->pressEvent(mouseEvent->pos());
+ break;
+ }
- case QEvent::GraphicsSceneMouseMove: {
- QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
- d->moveEvent(mouseEvent->lastPos(), mouseEvent->pos());
- break;
- }
+ case QEvent::GraphicsSceneMouseDoubleClick: {
+ QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
+ d->doublePressEvent(mouseEvent->pos());
+ break;
+ }
+
+ case QEvent::GraphicsSceneMouseMove: {
+ QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
+ d->moveEvent(mouseEvent->lastPos(), mouseEvent->pos());
+ break;
+ }
- case QEvent::GraphicsSceneMouseRelease: {
- QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
- d->releaseEvent(mouseEvent->pos());
- cancelButtonPress();
- break;
- }
+ case QEvent::GraphicsSceneMouseRelease: {
+ QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
+ d->moveEvent(mouseEvent->lastPos(), mouseEvent->pos());
+ d->releaseEvent(mouseEvent->pos());
+ break;
+ }
- default:
- return HbWidget::event(event);
+ case QEvent::GrabMouse:
+ d->mHasMouseGrab = true;
+ break;
+
+ case QEvent::UngrabMouse:
+ d->mHasMouseGrab = false;
+ break;
+
+ default:
+ return HbWidget::event(event);
}
return true;
}
@@ -1806,8 +1932,6 @@
/*!
\reimp
-
-Enables touch events if multi touch is enabled.
*/
void HbInputButtonGroup::showEvent(QShowEvent *event)
{
@@ -1815,6 +1939,10 @@
setAcceptTouchEvents(d->mMultiTouchEnabled);
+ if (qApp) {
+ qApp->installEventFilter(this);
+ }
+
HbWidget::showEvent(event);
}
@@ -1827,10 +1955,27 @@
{
cancelButtonPress();
+ if (qApp) {
+ qApp->removeEventFilter(this);
+ }
+
HbWidget::hideEvent(event);
}
/*!
+Releases all pressed buttons when deactivated.
+*/
+bool HbInputButtonGroup::eventFilter(QObject *obj, QEvent *event)
+{
+ Q_UNUSED(obj);
+
+ if (event->type() == QEvent::ApplicationDeactivate) {
+ cancelButtonPress();
+ }
+ return false;
+}
+
+/*!
Emits buttonPressed signal.
*/
void HbInputButtonGroup::emitButtonPressed(const QKeyEvent &event)
@@ -1883,7 +2028,11 @@
{
Q_D(HbInputButtonGroup);
- ungrabMouse();
+ if (d->mHasMouseGrab) {
+ ungrabMouse();
+ }
+
+ d->mActiveButtons.clear();
// Cancel long press timers
d->mLongPressButtons.clear();
@@ -1899,10 +2048,10 @@
}
d->hideButtonPreview(button);
}
- if (d->mCharacterSelectionPreview) {
+ if (d->mCharacterSelectionPreview) {
d->mCharacterSelectionPreview->hide();
}
-
+
d->updateGraphics(QSizeF(boundingRect().width(), boundingRect().height()));
d->updateTextLayouts(QSizeF(boundingRect().width(), boundingRect().height()));
update();