--- a/telutils/dialpad/src/dialpadkeypad.cpp Tue Jul 06 14:53:02 2010 +0300
+++ b/telutils/dialpad/src/dialpadkeypad.cpp Wed Jul 21 18:26:52 2010 +0300
@@ -25,9 +25,12 @@
#include <hbinputsettingproxy.h>
#include <hbinputlanguage.h>
#include <hbapplication.h>
+#include <hbcolorscheme.h>
#include <hblineedit.h>
-#include <hbinputbutton.h>
+#include <hbfontspec.h>
+#include <hbevent.h>
+#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<HbInputButton*> 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,6 +232,7 @@
void DialpadKeypad::sendKeyPressEvent(const QKeyEvent& event)
{
+ updateButtonLabels();
mPressedNumericKey = event.key();
postKeyEvent(QEvent::KeyPress, event.key());
}
@@ -246,7 +250,6 @@
void DialpadKeypad::sendLongPressEvent(const QKeyEvent& event)
{
sendKeyEventToEditor(QEvent::KeyPress, event.key());
- resetButtons();
mPressedNumericKey = 0;
}
@@ -275,3 +278,298 @@
{
return *mCallButton;
}
+
+DialpadNumericButton* DialpadKeypad::button(int i) const
+{
+ return static_cast<DialpadNumericButton*>(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::Alignment>(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<QString> textContent;
+ resolveTextContent(textContent);
+
+ // layout the texts
+ createTextLayouts(size, textContent);
+}
+
+void DialpadKeypad::resolveTextContent(QList<QString> &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<QString> &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;
+}