diff -r 1f002146abb4 -r cee7e9e0906c telutils/dialpad/src/dialpadkeypad.cpp --- a/telutils/dialpad/src/dialpadkeypad.cpp Tue Jul 06 14:53:02 2010 +0300 +++ b/telutils/dialpad/src/dialpadkeypad.cpp Wed Aug 18 10:19:22 2010 +0300 @@ -25,9 +25,12 @@ #include #include #include +#include #include -#include +#include +#include +#include "dialpadnumericbutton.h" #include "dialpadkeypad.h" #include "dialpadbutton.h" #include "dialpadinputfield.h" @@ -36,7 +39,12 @@ static const int DialpadColumnCount = 3; static const QLatin1String handsetIcon("qtg_mono_call"); static const QLatin1String vmbxIcon("qtg_mono_voice_mailbox"); -static const qreal DialpadKeypadBorderWidth = 0.25; +// layout values in units +static const qreal DialpadPrimaryTextSize = 5.5; +static const qreal DialpadSecondaryTextSize = 4.0; +static const qreal DialpadIconSize = 4.0; +static const qreal DialpadPrimaryTextLeftMargin = 1.5; +static const qreal DialpadPrimarySecondaryMargin = 0.75; static const int DialpadKeyCodeTable[DialpadRowCount*DialpadColumnCount] = { @@ -53,7 +61,8 @@ QGraphicsItem* parent) : HbInputButtonGroup(parent), mMainWindow(mainWindow), - mInputField(inputField) + mInputField(inputField), + mMaxPrimaryLineWidth(0) { setObjectName("keypad"); @@ -70,12 +79,12 @@ // create keypad setGridSize(QSize(DialpadColumnCount, DialpadRowCount)); - setButtonBorderSize(DialpadKeypadBorderWidth); + setButtonBorderSize(0); QList buttons; for (int i = 0; i < DialpadRowCount * DialpadColumnCount; ++i) { - HbInputButton *item = new HbInputButton( + DialpadNumericButton *item = new DialpadNumericButton( DialpadKeyCodeTable[i], QPoint(i % DialpadColumnCount, i / DialpadColumnCount)); buttons.append(item); @@ -114,13 +123,16 @@ // set button texts setButtonTexts(); // set button icons - button(0)->setIcon(HbIcon(vmbxIcon), - HbInputButton::ButtonIconIndexSecondaryFirstRow); + button(0)->setIcon(HbIcon(vmbxIcon)); // update button texts when input language is changed connect(HbInputSettingProxy::instance(), SIGNAL(globalInputLanguageChanged(HbInputLanguage)), this,SLOT(setButtonTexts())); + + updateColorArray(); + + mUnit = HbDeviceProfile::profile(this).unitValue(); } DialpadKeypad::~DialpadKeypad() @@ -144,10 +156,8 @@ if (keyCode == Qt::Key_Asterisk) { // asterisk is not localized QChar asterisk('*'); - button(i)->setText(asterisk, - HbInputButton::ButtonTextIndexPrimary); - button(i)->setText("+", - HbInputButton::ButtonTextIndexSecondaryFirstRow); + button(i)->setText(asterisk); + button(i)->setSecondaryText(QLatin1String("+")); mGeneratedChar.insert(Qt::Key_Asterisk, asterisk); continue; } @@ -155,10 +165,7 @@ if (keyCode == Qt::Key_NumberSign) { // number sign is not localized QChar numberSign('#'); - button(i)->setText(numberSign, - HbInputButton::ButtonTextIndexPrimary); - button(i)->setText(" ", - HbInputButton::ButtonTextIndexSecondaryFirstRow); + button(i)->setText(numberSign); mGeneratedChar.insert(Qt::Key_NumberSign, numberSign); continue; } @@ -175,11 +182,11 @@ QChar numberChar = HbInputUtils::findFirstNumberCharacterBoundToKey( key, - inputLanguage.language()); + inputLanguage.language(), + HbInputUtils::inputDigitType(inputLanguage.language())); // button text - button(i)->setText(numberChar, - HbInputButton::ButtonTextIndexPrimary); + button(i)->setText(numberChar); mGeneratedChar.insert(keyCode,numberChar); // additional text (letters) @@ -194,12 +201,8 @@ QString characters = key->characters(HbModifierNone); - if (numberOfCharacters==0 && keyCode!=Qt::Key_1) { - button(i)->setText(" ", - HbInputButton::ButtonTextIndexSecondaryFirstRow); - } else { - button(i)->setText(characters.left(numberOfCharacters), - HbInputButton::ButtonTextIndexSecondaryFirstRow); + if (numberOfCharacters!=0 && keyCode!=Qt::Key_1) { + button(i)->setSecondaryText(characters.left(numberOfCharacters)); } } } @@ -229,12 +232,15 @@ void DialpadKeypad::sendKeyPressEvent(const QKeyEvent& event) { + updateButtonLabels(); mPressedNumericKey = event.key(); postKeyEvent(QEvent::KeyPress, event.key()); } void DialpadKeypad::sendKeyReleaseEvent(const QKeyEvent& event) { + updateButtonLabels(); + if (mPressedNumericKey) { // short press, update editor here sendKeyEventToEditor(QEvent::KeyPress, event.key()); @@ -246,7 +252,6 @@ void DialpadKeypad::sendLongPressEvent(const QKeyEvent& event) { sendKeyEventToEditor(QEvent::KeyPress, event.key()); - resetButtons(); mPressedNumericKey = 0; } @@ -275,3 +280,298 @@ { return *mCallButton; } + +DialpadNumericButton* DialpadKeypad::button(int i) const +{ + return static_cast(HbInputButtonGroup::button(i)); +} + +void DialpadKeypad::updateButtonLabels() +{ + // update numeric buttons according to button state (pressed/released) + updateIconColor(); + updateTextLayouts(rect().size()); +} + +void DialpadKeypad::paint( + QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + // Paints empty buttons + HbInputButtonGroup::paint(painter,option,widget); + + qreal cellWidth = boundingRect().width() / gridSize().width(); + qreal cellHeight = boundingRect().height() / gridSize().height(); + + // Draw icons + for (int i = 0; i < DialpadRowCount * DialpadColumnCount; i++) { + DialpadNumericButton *item = button(i); + + if (!item->icon().isNull()) { + // icon is centered to button + qreal x = (item->position().x() * cellWidth) + (cellWidth / 2) - + ((DialpadIconSize * mUnit) / 2); + qreal y = (item->position().y() * cellHeight) + (cellHeight / 2) - + ((DialpadIconSize * mUnit) / 2); + + qreal width = DialpadIconSize * mUnit; + qreal height = DialpadIconSize * mUnit; + + Qt::Alignment alignment = + static_cast(Qt::AlignVCenter | Qt::AlignHCenter); + item->icon().paint(painter, + QRectF(x,y,width,height), + Qt::KeepAspectRatio, + alignment); + } + } + + // Draw texts + QPen origPen = painter->pen(); + for (int i = 0; i < mTextLayouts.count(); ++i) { + if (i==SecondaryText) { + // dimmed in normal state + painter->setPen(mColors.at(Pressed+1)); + } else { + // otherwise normal or pressed color + painter->setPen(mColors.at(i/TextTypeCount)); + } + mTextLayouts.at(i)->draw(painter, QPointF(0, 0)); + } + painter->setPen(origPen); +} + +void DialpadKeypad::updateColorArray() +{ + mColors.clear(); + + QColor normalColor = HbColorScheme::color("qtc_input_button_normal"); + mColors.insert(Normal, normalColor); + + QColor pressedColor = HbColorScheme::color("qtc_input_button_pressed"); + mColors.insert(Pressed, pressedColor); + + // this is used for alphabets shown dimmed, use alpha until exact color + // is specified + QColor disabledColor = HbColorScheme::color("qtc_input_button_normal"); + disabledColor.setAlpha(128); + mColors.insert(Pressed+1, disabledColor); +} + +void DialpadKeypad::updateIconColor() +{ + for (int i = 0; i < (DialpadRowCount * DialpadColumnCount); i++) { + DialpadNumericButton *item = button(i); + + if (item->state()==HbInputButton::ButtonStatePressed) { + item->icon().setColor(mColors.at(Pressed)); + } else { + item->icon().setColor(mColors.at(Normal)); + } + } +} + +void DialpadKeypad::cancelButtonPress() +{ + HbInputButtonGroup::cancelButtonPress(); + updateButtonLabels(); +} + +void DialpadKeypad::setGeometry(const QRectF &rect) +{ + HbInputButtonGroup::setGeometry(rect); + updateTextLayouts(rect.size()); +} + +void DialpadKeypad::changeEvent(QEvent *event) +{ + HbInputButtonGroup::changeEvent(event); + + if (event->type() == HbEvent::ThemeChanged) { + updateColorArray(); + updateIconColor(); + } +} + +void DialpadKeypad::updateTextLayouts(const QSizeF &size) +{ + if (!size.width() && !size.height()) { + return; + } + + // get normal and pressed state texts + QList textContent; + resolveTextContent(textContent); + + // layout the texts + createTextLayouts(size, textContent); +} + +void DialpadKeypad::resolveTextContent(QList &content) +{ + QString normalState; + QString normalStateSecondary; + QString pressedState; + QString pressedStateSecondary; + + for (int i = 0; i < (DialpadRowCount*DialpadColumnCount); i++) { + DialpadNumericButton *item = button(i); + if (item->state()==HbInputButton::ButtonStatePressed) { + if (item->text().length()) { + pressedState.append(item->text()); + pressedState.append(QChar(QChar::LineSeparator)); + } + + if (item->secondaryText().length()) { + pressedStateSecondary.append(item->secondaryText()); + pressedStateSecondary.append(QChar(QChar::LineSeparator)); + } + } else { // ButtonStateNormal + if (item->text().length()) { + normalState.append(item->text()); + normalState.append(QChar(QChar::LineSeparator)); + } + + if (item->secondaryText().length()) { + normalStateSecondary.append(item->secondaryText()); + normalStateSecondary.append(QChar(QChar::LineSeparator)); + } + } + } + + content.insert(PrimaryText, normalState); + content.insert(SecondaryText, normalStateSecondary); + content.insert(TextTypeCount + Pressed, pressedState); + content.insert(StateCount + SecondaryText, pressedStateSecondary); +} + +void DialpadKeypad::createTextLayouts( + const QSizeF &size, const QList &content) +{ + // clear old layouts + qDeleteAll(mTextLayouts); + mTextLayouts.clear(); + + if (content.count()==2) { + // line width is measured only when all buttons are in normal state + mMaxPrimaryLineWidth = 0; + } + + QFont primaryfFont = HbFontSpec(HbFontSpec::Primary).font(); + primaryfFont.setPixelSize(DialpadPrimaryTextSize * mUnit); + + QFont secondaryFont = HbFontSpec(HbFontSpec::Secondary).font(); + secondaryFont.setPixelSize(DialpadSecondaryTextSize * mUnit); + + for (int i=0; i < (StateCount*TextTypeCount); i++ ) { + QString text = content.at(i); + + if (!text.isNull()) { + QTextLayout* textLayout; + int type; + + if (i%TextTypeCount) { + textLayout = new QTextLayout(text,secondaryFont); + type = SecondaryText; + } else { + textLayout = new QTextLayout(text,primaryfFont); + type = PrimaryText; + } + + mTextLayouts.append(textLayout); + + textLayout->beginLayout(); + + int state = (i>=TextTypeCount) ? Pressed : Normal; + + layoutTextLines(size,*textLayout,state,type); + + textLayout->endLayout(); + + textLayout->setCacheEnabled(true); + } + } +} + +void DialpadKeypad::layoutTextLines( + const QSizeF &size, + QTextLayout &textLayout, + int state, + int type) +{ + QFontMetricsF fontMetrics(textLayout.font()); + qreal textHeight = fontMetrics.height(); + + qreal cellWidth = size.width() / gridSize().width(); + qreal cellHeight = size.height() / gridSize().height(); + qreal maxLineWidth = 0; + + for (int j = 0; j < (DialpadRowCount*DialpadColumnCount); j++) { + DialpadNumericButton *item = button(j); + + if ((type==PrimaryText && item->text().isNull()) || + (type==SecondaryText && item->secondaryText().isNull())) { + continue; // no text for this button -> next button + } + + if ( ( state==Normal && + item->state()==HbInputButton::ButtonStateReleased ) || + ( state==Pressed && + item->state()==HbInputButton::ButtonStatePressed ) ) { + + QTextLine line = textLayout.createLine(); + + qreal textPositionX = 0; + qreal textPositionY = 0; + + if (line.isValid()) { + line.setNumColumns(item->text().length()); + // layout text line + if (type==SecondaryText) { + if (j==9) { + // + is centered to button + qreal lineWidth = fontMetrics.width(item->text()); + textPositionX = (item->position().x() * cellWidth) + + (cellWidth / 2) - + (lineWidth / 2); + textPositionY = (item->position().y() + + (0.5 * item->size().height())) * + cellHeight - (0.5 * textHeight); + + } else { + textPositionX = (item->position().x() * cellWidth) + + (DialpadPrimaryTextLeftMargin * mUnit) + + mMaxPrimaryLineWidth + + (DialpadPrimarySecondaryMargin * mUnit) + + buttonBorderSize(); + textPositionY = (item->position().y() + + (0.5 * item->size().height())) * + cellHeight - (0.5 * textHeight); + } + } else { + textPositionX = (item->position().x() * cellWidth) + + (DialpadPrimaryTextLeftMargin * mUnit) + + buttonBorderSize(); + textPositionY = (item->position().y() + + (0.5 * item->size().height())) * + cellHeight - (0.5 * textHeight); + + // store line width, for drawing secondary text + qreal lineWidth = fontMetrics.width(item->text()); + if (mMaxPrimaryLineWidth == 0 && (j>0 && j<10) && + lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + } + + line.setPosition(QPointF(textPositionX, textPositionY)); + } + } + + mMaxPrimaryLineWidth = maxLineWidth; +}