23 #include <hbinputkeymap.h> |
23 #include <hbinputkeymap.h> |
24 #include <hbinpututils.h> |
24 #include <hbinpututils.h> |
25 #include <hbinputsettingproxy.h> |
25 #include <hbinputsettingproxy.h> |
26 #include <hbinputlanguage.h> |
26 #include <hbinputlanguage.h> |
27 #include <hbapplication.h> |
27 #include <hbapplication.h> |
|
28 #include <hbcolorscheme.h> |
28 #include <hblineedit.h> |
29 #include <hblineedit.h> |
29 #include <hbinputbutton.h> |
30 #include <hbfontspec.h> |
30 |
31 #include <hbevent.h> |
|
32 |
|
33 #include "dialpadnumericbutton.h" |
31 #include "dialpadkeypad.h" |
34 #include "dialpadkeypad.h" |
32 #include "dialpadbutton.h" |
35 #include "dialpadbutton.h" |
33 #include "dialpadinputfield.h" |
36 #include "dialpadinputfield.h" |
34 |
37 |
35 static const int DialpadRowCount = 4; |
38 static const int DialpadRowCount = 4; |
36 static const int DialpadColumnCount = 3; |
39 static const int DialpadColumnCount = 3; |
37 static const QLatin1String handsetIcon("qtg_mono_call"); |
40 static const QLatin1String handsetIcon("qtg_mono_call"); |
38 static const QLatin1String vmbxIcon("qtg_mono_voice_mailbox"); |
41 static const QLatin1String vmbxIcon("qtg_mono_voice_mailbox"); |
39 static const qreal DialpadKeypadBorderWidth = 0.25; |
42 // layout values in units |
|
43 static const qreal DialpadPrimaryTextSize = 5.5; |
|
44 static const qreal DialpadSecondaryTextSize = 4.0; |
|
45 static const qreal DialpadIconSize = 4.0; |
|
46 static const qreal DialpadPrimaryTextLeftMargin = 1.5; |
|
47 static const qreal DialpadPrimarySecondaryMargin = 0.75; |
40 |
48 |
41 static const int DialpadKeyCodeTable[DialpadRowCount*DialpadColumnCount] = |
49 static const int DialpadKeyCodeTable[DialpadRowCount*DialpadColumnCount] = |
42 { |
50 { |
43 Qt::Key_1, Qt::Key_2, Qt::Key_3, |
51 Qt::Key_1, Qt::Key_2, Qt::Key_3, |
44 Qt::Key_4, Qt::Key_5, Qt::Key_6, |
52 Qt::Key_4, Qt::Key_5, Qt::Key_6, |
273 |
278 |
274 DialpadButton& DialpadKeypad::callButton() const |
279 DialpadButton& DialpadKeypad::callButton() const |
275 { |
280 { |
276 return *mCallButton; |
281 return *mCallButton; |
277 } |
282 } |
|
283 |
|
284 DialpadNumericButton* DialpadKeypad::button(int i) const |
|
285 { |
|
286 return static_cast<DialpadNumericButton*>(HbInputButtonGroup::button(i)); |
|
287 } |
|
288 |
|
289 void DialpadKeypad::updateButtonLabels() |
|
290 { |
|
291 // update numeric buttons according to button state (pressed/released) |
|
292 updateIconColor(); |
|
293 updateTextLayouts(rect().size()); |
|
294 } |
|
295 |
|
296 void DialpadKeypad::paint( |
|
297 QPainter* painter, |
|
298 const QStyleOptionGraphicsItem* option, |
|
299 QWidget* widget) |
|
300 { |
|
301 Q_UNUSED(option); |
|
302 Q_UNUSED(widget); |
|
303 |
|
304 // Paints empty buttons |
|
305 HbInputButtonGroup::paint(painter,option,widget); |
|
306 |
|
307 qreal cellWidth = boundingRect().width() / gridSize().width(); |
|
308 qreal cellHeight = boundingRect().height() / gridSize().height(); |
|
309 |
|
310 // Draw icons |
|
311 for (int i = 0; i < DialpadRowCount * DialpadColumnCount; i++) { |
|
312 DialpadNumericButton *item = button(i); |
|
313 |
|
314 if (!item->icon().isNull()) { |
|
315 // icon is centered to button |
|
316 qreal x = (item->position().x() * cellWidth) + (cellWidth / 2) - |
|
317 ((DialpadIconSize * mUnit) / 2); |
|
318 qreal y = (item->position().y() * cellHeight) + (cellHeight / 2) - |
|
319 ((DialpadIconSize * mUnit) / 2); |
|
320 |
|
321 qreal width = DialpadIconSize * mUnit; |
|
322 qreal height = DialpadIconSize * mUnit; |
|
323 |
|
324 Qt::Alignment alignment = |
|
325 static_cast<Qt::Alignment>(Qt::AlignVCenter | Qt::AlignHCenter); |
|
326 item->icon().paint(painter, |
|
327 QRectF(x,y,width,height), |
|
328 Qt::KeepAspectRatio, |
|
329 alignment); |
|
330 } |
|
331 } |
|
332 |
|
333 // Draw texts |
|
334 QPen origPen = painter->pen(); |
|
335 for (int i = 0; i < mTextLayouts.count(); ++i) { |
|
336 if (i==SecondaryText) { |
|
337 // dimmed in normal state |
|
338 painter->setPen(mColors.at(Pressed+1)); |
|
339 } else { |
|
340 // otherwise normal or pressed color |
|
341 painter->setPen(mColors.at(i/TextTypeCount)); |
|
342 } |
|
343 mTextLayouts.at(i)->draw(painter, QPointF(0, 0)); |
|
344 } |
|
345 painter->setPen(origPen); |
|
346 } |
|
347 |
|
348 void DialpadKeypad::updateColorArray() |
|
349 { |
|
350 mColors.clear(); |
|
351 |
|
352 QColor normalColor = HbColorScheme::color("qtc_input_button_normal"); |
|
353 mColors.insert(Normal, normalColor); |
|
354 |
|
355 QColor pressedColor = HbColorScheme::color("qtc_input_button_pressed"); |
|
356 mColors.insert(Pressed, pressedColor); |
|
357 |
|
358 // this is used for alphabets shown dimmed, use alpha until exact color |
|
359 // is specified |
|
360 QColor disabledColor = HbColorScheme::color("qtc_input_button_normal"); |
|
361 disabledColor.setAlpha(128); |
|
362 mColors.insert(Pressed+1, disabledColor); |
|
363 } |
|
364 |
|
365 void DialpadKeypad::updateIconColor() |
|
366 { |
|
367 for (int i = 0; i < (DialpadRowCount * DialpadColumnCount); i++) { |
|
368 DialpadNumericButton *item = button(i); |
|
369 |
|
370 if (item->state()==HbInputButton::ButtonStatePressed) { |
|
371 item->icon().setColor(mColors.at(Pressed)); |
|
372 } else { |
|
373 item->icon().setColor(mColors.at(Normal)); |
|
374 } |
|
375 } |
|
376 } |
|
377 |
|
378 void DialpadKeypad::cancelButtonPress() |
|
379 { |
|
380 HbInputButtonGroup::cancelButtonPress(); |
|
381 updateButtonLabels(); |
|
382 } |
|
383 |
|
384 void DialpadKeypad::setGeometry(const QRectF &rect) |
|
385 { |
|
386 HbInputButtonGroup::setGeometry(rect); |
|
387 updateTextLayouts(rect.size()); |
|
388 } |
|
389 |
|
390 void DialpadKeypad::changeEvent(QEvent *event) |
|
391 { |
|
392 HbInputButtonGroup::changeEvent(event); |
|
393 |
|
394 if (event->type() == HbEvent::ThemeChanged) { |
|
395 updateColorArray(); |
|
396 updateIconColor(); |
|
397 } |
|
398 } |
|
399 |
|
400 void DialpadKeypad::updateTextLayouts(const QSizeF &size) |
|
401 { |
|
402 if (!size.width() && !size.height()) { |
|
403 return; |
|
404 } |
|
405 |
|
406 // get normal and pressed state texts |
|
407 QList<QString> textContent; |
|
408 resolveTextContent(textContent); |
|
409 |
|
410 // layout the texts |
|
411 createTextLayouts(size, textContent); |
|
412 } |
|
413 |
|
414 void DialpadKeypad::resolveTextContent(QList<QString> &content) |
|
415 { |
|
416 QString normalState; |
|
417 QString normalStateSecondary; |
|
418 QString pressedState; |
|
419 QString pressedStateSecondary; |
|
420 |
|
421 for (int i = 0; i < (DialpadRowCount*DialpadColumnCount); i++) { |
|
422 DialpadNumericButton *item = button(i); |
|
423 if (item->state()==HbInputButton::ButtonStatePressed) { |
|
424 if (item->text().length()) { |
|
425 pressedState.append(item->text()); |
|
426 pressedState.append(QChar(QChar::LineSeparator)); |
|
427 } |
|
428 |
|
429 if (item->secondaryText().length()) { |
|
430 pressedStateSecondary.append(item->secondaryText()); |
|
431 pressedStateSecondary.append(QChar(QChar::LineSeparator)); |
|
432 } |
|
433 } else { // ButtonStateNormal |
|
434 if (item->text().length()) { |
|
435 normalState.append(item->text()); |
|
436 normalState.append(QChar(QChar::LineSeparator)); |
|
437 } |
|
438 |
|
439 if (item->secondaryText().length()) { |
|
440 normalStateSecondary.append(item->secondaryText()); |
|
441 normalStateSecondary.append(QChar(QChar::LineSeparator)); |
|
442 } |
|
443 } |
|
444 } |
|
445 |
|
446 content.insert(PrimaryText, normalState); |
|
447 content.insert(SecondaryText, normalStateSecondary); |
|
448 content.insert(TextTypeCount + Pressed, pressedState); |
|
449 content.insert(StateCount + SecondaryText, pressedStateSecondary); |
|
450 } |
|
451 |
|
452 void DialpadKeypad::createTextLayouts( |
|
453 const QSizeF &size, const QList<QString> &content) |
|
454 { |
|
455 // clear old layouts |
|
456 qDeleteAll(mTextLayouts); |
|
457 mTextLayouts.clear(); |
|
458 |
|
459 if (content.count()==2) { |
|
460 // line width is measured only when all buttons are in normal state |
|
461 mMaxPrimaryLineWidth = 0; |
|
462 } |
|
463 |
|
464 QFont primaryfFont = HbFontSpec(HbFontSpec::Primary).font(); |
|
465 primaryfFont.setPixelSize(DialpadPrimaryTextSize * mUnit); |
|
466 |
|
467 QFont secondaryFont = HbFontSpec(HbFontSpec::Secondary).font(); |
|
468 secondaryFont.setPixelSize(DialpadSecondaryTextSize * mUnit); |
|
469 |
|
470 for (int i=0; i < (StateCount*TextTypeCount); i++ ) { |
|
471 QString text = content.at(i); |
|
472 |
|
473 if (!text.isNull()) { |
|
474 QTextLayout* textLayout; |
|
475 int type; |
|
476 |
|
477 if (i%TextTypeCount) { |
|
478 textLayout = new QTextLayout(text,secondaryFont); |
|
479 type = SecondaryText; |
|
480 } else { |
|
481 textLayout = new QTextLayout(text,primaryfFont); |
|
482 type = PrimaryText; |
|
483 } |
|
484 |
|
485 mTextLayouts.append(textLayout); |
|
486 |
|
487 textLayout->beginLayout(); |
|
488 |
|
489 int state = (i>=TextTypeCount) ? Pressed : Normal; |
|
490 |
|
491 layoutTextLines(size,*textLayout,state,type); |
|
492 |
|
493 textLayout->endLayout(); |
|
494 |
|
495 textLayout->setCacheEnabled(true); |
|
496 } |
|
497 } |
|
498 } |
|
499 |
|
500 void DialpadKeypad::layoutTextLines( |
|
501 const QSizeF &size, |
|
502 QTextLayout &textLayout, |
|
503 int state, |
|
504 int type) |
|
505 { |
|
506 QFontMetricsF fontMetrics(textLayout.font()); |
|
507 qreal textHeight = fontMetrics.height(); |
|
508 |
|
509 qreal cellWidth = size.width() / gridSize().width(); |
|
510 qreal cellHeight = size.height() / gridSize().height(); |
|
511 qreal maxLineWidth = 0; |
|
512 |
|
513 for (int j = 0; j < (DialpadRowCount*DialpadColumnCount); j++) { |
|
514 DialpadNumericButton *item = button(j); |
|
515 |
|
516 if ((type==PrimaryText && item->text().isNull()) || |
|
517 (type==SecondaryText && item->secondaryText().isNull())) { |
|
518 continue; // no text for this button -> next button |
|
519 } |
|
520 |
|
521 if ( ( state==Normal && |
|
522 item->state()==HbInputButton::ButtonStateReleased ) || |
|
523 ( state==Pressed && |
|
524 item->state()==HbInputButton::ButtonStatePressed ) ) { |
|
525 |
|
526 QTextLine line = textLayout.createLine(); |
|
527 |
|
528 qreal textPositionX = 0; |
|
529 qreal textPositionY = 0; |
|
530 |
|
531 if (line.isValid()) { |
|
532 line.setNumColumns(item->text().length()); |
|
533 // layout text line |
|
534 if (type==SecondaryText) { |
|
535 if (j==9) { |
|
536 // + is centered to button |
|
537 qreal lineWidth = fontMetrics.width(item->text()); |
|
538 textPositionX = (item->position().x() * cellWidth) + |
|
539 (cellWidth / 2) - |
|
540 (lineWidth / 2); |
|
541 textPositionY = (item->position().y() + |
|
542 (0.5 * item->size().height())) * |
|
543 cellHeight - (0.5 * textHeight); |
|
544 |
|
545 } else { |
|
546 textPositionX = (item->position().x() * cellWidth) + |
|
547 (DialpadPrimaryTextLeftMargin * mUnit) + |
|
548 mMaxPrimaryLineWidth + |
|
549 (DialpadPrimarySecondaryMargin * mUnit) |
|
550 + buttonBorderSize(); |
|
551 textPositionY = (item->position().y() + |
|
552 (0.5 * item->size().height())) * |
|
553 cellHeight - (0.5 * textHeight); |
|
554 } |
|
555 } else { |
|
556 textPositionX = (item->position().x() * cellWidth) + |
|
557 (DialpadPrimaryTextLeftMargin * mUnit) |
|
558 + buttonBorderSize(); |
|
559 textPositionY = (item->position().y() + |
|
560 (0.5 * item->size().height())) * |
|
561 cellHeight - (0.5 * textHeight); |
|
562 |
|
563 // store line width, for drawing secondary text |
|
564 qreal lineWidth = fontMetrics.width(item->text()); |
|
565 if (mMaxPrimaryLineWidth == 0 && (j>0 && j<10) && |
|
566 lineWidth > maxLineWidth) { |
|
567 maxLineWidth = lineWidth; |
|
568 } |
|
569 } |
|
570 } |
|
571 |
|
572 line.setPosition(QPointF(textPositionX, textPositionY)); |
|
573 } |
|
574 } |
|
575 |
|
576 mMaxPrimaryLineWidth = maxLineWidth; |
|
577 } |