--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/telutils/dialpad/src/dialpad.cpp Tue Aug 31 15:45:17 2010 +0300
@@ -0,0 +1,489 @@
+/*!
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Dialpad popup
+*
+*/
+
+#include <QGraphicsLinearLayout>
+
+#include <hbframedrawer.h>
+#include <hbinstance.h>
+#include <hbeffect.h>
+#include <hbinstance.h>
+#include <hbmainwindow.h>
+#include <hbstyleloader.h>
+#include <hblineedit.h>
+#include <hbapplication.h>
+#include <hbswipegesture.h>
+#include <hbeffect.h>
+#include <hbevent.h>
+
+#include "dialpad.h"
+#include "dialpadinputfield.h"
+#include "dialpadkeypad.h"
+#include "dialpadbutton.h"
+#include "dialpadmultitaphandler.h"
+#include "dialpadbackground.h"
+#include "dialpadbutton.h"
+
+static const QLatin1String backgroundGraphics("qtg_fr_input_v_bg");
+static const QLatin1String backgroundGraphicsH("qtg_fr_input_h_bg");
+static const QLatin1String minimizeIcon("qtg_graf_input_v_swipe");
+static const QLatin1String minimizeIconH("qtg_graf_input_h_swipe");
+static const int DialpadCloseAnimDuration = 200; // ms
+static const int DialpadOpenAnimDuration = 200; // ms
+static const qreal DialpadComponentMargin = 0.75; // units
+static const qreal DialpadCloseHandleHeight = 2.23; // units
+static const qreal DialpadCloseHandleWidth = 18.8; // units
+static const qreal DialpadCallButtonHeight = 8.75; // units, same as numeric buttons
+static const qreal DialpadCallButtonHeightH = 7.25; // units
+
+static const QLatin1String handsetIcon("qtg_mono_call");
+static const QLatin1String vmbxIcon("qtg_mono_voice_mailbox");
+
+const QLatin1String DIALPAD_TO_PRT_FXML(":/dialpad_to_prt.fxml");
+const QLatin1String DIALPAD_TO_LSC_FXML(":/dialpad_to_lsc.fxml");
+const QLatin1String DIALPAD_TO_PRT_EVENT("prt_activated");
+const QLatin1String DIALPAD_TO_LSC_EVENT("lsc_activated");
+
+Dialpad::Dialpad() :
+ mMainWindow(*hbInstance->allMainWindows().at(0)),
+ mBackgroundItem(0),
+ mOpenTimeLine(DialpadOpenAnimDuration),
+ mCloseTimeLine(DialpadCloseAnimDuration),
+ mAnimationOngoing(false),
+ mOrientation(Qt::Vertical),
+ mIsOpen(false)
+{
+ // this constuctor is deprecated
+ initialize();
+}
+
+Dialpad::Dialpad(const HbMainWindow& mainWindow) :
+ mMainWindow(mainWindow),
+ mBackgroundItem(0),
+ mOpenTimeLine(DialpadOpenAnimDuration),
+ mCloseTimeLine(DialpadCloseAnimDuration),
+ mAnimationOngoing(false),
+ mOrientation(Qt::Vertical),
+ mIsOpen(false)
+{
+ initialize();
+}
+
+void Dialpad::initialize()
+{
+ setFocusPolicy(Qt::StrongFocus);
+ setFlag(QGraphicsItem::ItemIsFocusable,true);
+ setFlag(QGraphicsItem::ItemHasNoContents, false);
+
+ // create input field
+ mInputField = new DialpadInputField(this);
+
+ // create keypad
+ mKeypad = new DialpadKeypad(mMainWindow,*mInputField,this);
+
+ // layouting params
+ qreal unit = HbDeviceProfile::current().unitValue();
+ qreal margin = DialpadComponentMargin * unit;
+ mCloseHandleHeight = DialpadCloseHandleHeight * unit;
+ mCloseHandleWidth = DialpadCloseHandleWidth * unit;
+
+ mKeypad->callButton().setPreferredHeight(DialpadCallButtonHeight*unit);
+ mKeypad->callButton().setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ // create popup background
+ mBackgroundDrawer = new HbFrameDrawer();
+ mIconDrawer = new HbFrameDrawer();
+
+ // popup layout
+ QGraphicsLinearLayout* popupLayout =
+ new QGraphicsLinearLayout(Qt::Vertical);
+ popupLayout->addItem(mInputField);
+ popupLayout->addItem(mKeypad);
+ popupLayout->addItem(&mKeypad->callButton());
+ popupLayout->setContentsMargins(margin, mCloseHandleHeight, margin, margin);
+ popupLayout->setSpacing(0);
+ popupLayout->setItemSpacing(0,margin);
+ setLayout(popupLayout);
+ setLayoutDirection(Qt::LeftToRight);
+
+ // asterisk multitap handler
+ mMultitap = new DialpadMultitapHandler(mInputField->editor(),this);
+ mInputField->editor().installEventFilter(mMultitap);
+
+ // close animation
+ mCloseTimeLine.setUpdateInterval(16);
+ mCloseTimeLine.setEasingCurve(QEasingCurve::InQuad);
+ connect(&mCloseTimeLine, SIGNAL(finished()),
+ SLOT(closeAnimFinished()));
+ connect(&mCloseTimeLine, SIGNAL(valueChanged(qreal)),
+ SLOT(closeAnimValueChanged(qreal)));
+
+ // open animation
+ mOpenTimeLine.setUpdateInterval(16);
+ mOpenTimeLine.setEasingCurve(QEasingCurve::OutQuad);
+ connect(&mOpenTimeLine, SIGNAL(finished()),
+ SLOT(openAnimFinished()));
+ connect(&mOpenTimeLine, SIGNAL(valueChanged(qreal)),
+ SLOT(openAnimValueChanged(qreal)));
+
+ // default values
+ setPos(0,0);
+ setPreferredSize(360,360);
+ setZValue(0x00004000); // Hb PopupZValueRangeStart
+ hide();
+ mMainWindow.scene()->addItem(this);
+
+ // custom button style
+ HbStyleLoader::registerFilePath(QLatin1String(":/dialpad.css"));
+ HbStyleLoader::registerFilePath(QLatin1String(":/dialpad_color.css"));
+
+ // grab gestures so that those are not passed to widgets behind dialpad
+ grabGesture(Qt::TapGesture);
+ grabGesture(Qt::TapAndHoldGesture);
+ grabGesture(Qt::PanGesture);
+ grabGesture(Qt::SwipeGesture);
+ grabGesture(Qt::PinchGesture);
+
+ // effects
+ HbEffect::add(this, DIALPAD_TO_PRT_FXML, DIALPAD_TO_PRT_EVENT);
+ HbEffect::add(this, DIALPAD_TO_LSC_FXML, DIALPAD_TO_LSC_EVENT);
+}
+
+Dialpad::~Dialpad()
+{
+ delete mBackgroundDrawer;
+ delete mIconDrawer;
+ delete mBackgroundItem;
+}
+
+void Dialpad::paint(
+ QPainter* painter,
+ const QStyleOptionGraphicsItem* option,
+ QWidget* widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ // paint popup background
+ if ( mOrientation == Qt::Vertical ) {
+ mBackgroundDrawer->setFrameGraphicsName(backgroundGraphics);
+ mIconDrawer->setFrameGraphicsName(minimizeIcon);
+ mBackgroundDrawer->setFrameType(HbFrameDrawer::ThreePiecesVertical);
+ mBackgroundDrawer->setBorderWidths(0.0, mCloseHandleHeight, 0.0, 0.0);
+ } else {
+ mBackgroundDrawer->setFrameGraphicsName(backgroundGraphicsH);
+ mIconDrawer->setFrameGraphicsName(minimizeIconH);
+ mBackgroundDrawer->setFrameType(HbFrameDrawer::ThreePiecesHorizontal);
+ mBackgroundDrawer->setBorderWidths(mCloseHandleHeight, 0.0, 0.0, 0.0);
+ }
+
+ // draw background
+ QRectF rect = boundingRect();
+ mBackgroundDrawer->setFillWholeRect(true);
+ mBackgroundDrawer->paint(painter, rect);
+
+ // adjust rectangle to close bar position
+ if ( mOrientation == Qt::Vertical ) {
+ rect.setLeft((rect.width()- mCloseHandleWidth)/2);
+ rect.setWidth(mCloseHandleWidth);
+ rect.setHeight(mCloseHandleHeight);
+ } else {
+ rect.setTop((rect.height() - mCloseHandleWidth)/2);
+ rect.setWidth(mCloseHandleHeight);
+ rect.setHeight(mCloseHandleWidth);
+ }
+
+ mIconDrawer->setFrameType(HbFrameDrawer::OnePiece);
+ mIconDrawer->paint(painter, rect);
+}
+
+void Dialpad::changeEvent(QEvent *event)
+{
+ if (event->type() == QEvent::LayoutDirectionChange) {
+ mBackgroundDrawer->setLayoutDirection(layoutDirection());
+ } else if (event->type() == HbEvent::ThemeChanged) {
+ mBackgroundDrawer->themeChanged();
+ mIconDrawer->themeChanged();
+ }
+}
+
+bool Dialpad::isOpen() const
+{
+ return mIsOpen;
+}
+
+bool Dialpad::isCallButtonEnabled() const
+{
+ return mKeypad->callButton().isEnabled();
+}
+
+void Dialpad::openDialpad()
+{
+ mKeypad->resetButtons();
+
+ if (mIsOpen) {
+ return;
+ }
+
+ connect(&mMainWindow,SIGNAL(aboutToChangeOrientation()),
+ SLOT(orientationChangeStarted()));
+ connect(&mMainWindow,SIGNAL(orientationChanged(Qt::Orientation)),
+ SLOT(orientationChangeFinished(Qt::Orientation)));
+
+ // set offset for open animation
+ int previousOrientation = mOrientation;
+ mOrientation = mMainWindow.orientation();
+
+ mPosition = pos();
+ if (mOrientation==Qt::Vertical) {
+ qreal height = geometry().height();
+ setPos(mPosition.x(),mPosition.y()+height);
+ } else {
+ qreal width = geometry().width();
+ setPos(mPosition.x()+width,mPosition.y());
+ }
+
+ if (mOrientation!=previousOrientation) {
+ updateLayout((Qt::Orientation)mOrientation);
+ }
+
+ show();
+
+ setFocusProxy(&mInputField->editor());
+ mInputField->editor().setFocus();
+
+ mOpenTimeLine.start();
+ mAnimationOngoing = true;
+ if (!mInputField->editor().text().isEmpty()) {
+ setCallButtonEnabled(true);
+ }
+ mIsOpen = true;
+
+ emit aboutToOpen();
+}
+
+void Dialpad::closeDialpad()
+{
+ close();
+
+ disconnect(&mMainWindow,SIGNAL(aboutToChangeOrientation()),
+ this, SLOT(orientationChangeStarted()));
+ disconnect(&mMainWindow,SIGNAL(orientationChanged(Qt::Orientation)),
+ this, SLOT(orientationChangeFinished(Qt::Orientation)));
+
+ if (mBackgroundItem) {
+ mBackgroundItem->hide();
+ }
+}
+
+HbLineEdit& Dialpad::editor() const
+{
+ return mInputField->editor();
+}
+
+void Dialpad::setCallButtonEnabled(bool enabled)
+{
+ mKeypad->setCallButtonEnabled(enabled);
+}
+
+void Dialpad::setTapOutsideDismiss(bool dismiss)
+{
+ // set dismiss policy before opening dialpad
+ Q_ASSERT(!isVisible());
+
+ if (dismiss) {
+ mBackgroundItem = new DialpadBackground(*this);
+ mBackgroundItem->setZValue(zValue()-1);
+ mMainWindow.scene()->addItem(mBackgroundItem);
+ qreal chromeHeight = 0;
+ hbInstance->style()->parameter(QLatin1String("hb-param-widget-chrome-height"),
+ chromeHeight);
+ mTitleBarHeight = chromeHeight;
+ } else {
+ delete mBackgroundItem;
+ mBackgroundItem = 0;
+ }
+}
+
+void Dialpad::startCloseAnimation()
+{
+ if (!mAnimationOngoing) {
+ mCloseTimeLine.start();
+ mAnimationOngoing = true;
+ }
+}
+
+void Dialpad::showEvent(QShowEvent *event)
+{
+ HbWidget::showEvent(event);
+
+ if (mBackgroundItem) {
+ layoutBackgroundItem();
+ mBackgroundItem->show();
+ }
+}
+
+void Dialpad::hideEvent(QHideEvent *event)
+{
+ HbWidget::hideEvent(event);
+}
+
+void Dialpad::closeEvent(QCloseEvent * event)
+{
+ mIsOpen = false;
+ HbWidget::closeEvent(event);
+ emit aboutToClose();
+}
+
+void Dialpad::closeAnimValueChanged(qreal value)
+{
+ QPointF currentPos = pos();
+ QPointF newPos;
+
+ if (mOrientation==Qt::Vertical) {
+ qreal height = geometry().height();
+
+ newPos.setX(currentPos.x());
+ newPos.setY(mPosition.y()+(height*value));
+ } else {
+ qreal width = geometry().width();
+
+ newPos.setY(currentPos.y());
+ newPos.setX(mPosition.x()+(width*value));
+ }
+
+ setPos(newPos);
+}
+
+
+void Dialpad::closeAnimFinished()
+{
+ mAnimationOngoing = false;
+ closeDialpad();
+ setPos(mPosition);
+}
+
+void Dialpad::openAnimValueChanged(qreal value)
+{
+ QPointF currentPos = pos();
+ QPointF newPos;
+
+ if (mOrientation==Qt::Vertical) {
+ qreal height = geometry().height();
+
+ newPos.setX(currentPos.x());
+ newPos.setY(mPosition.y()+(height*(1-value)));
+ } else {
+ qreal width = geometry().width();
+
+ newPos.setY(currentPos.y());
+ newPos.setX(mPosition.x()+(width*(1-value)));
+ }
+
+ setPos(newPos);
+}
+
+void Dialpad::openAnimFinished()
+{
+ mAnimationOngoing = false;
+ setPos(mPosition);
+}
+
+void Dialpad::orientationChangeStarted()
+{
+ hide();
+}
+
+void Dialpad::orientationChangeFinished(Qt::Orientation current)
+{
+ updateLayout(current);
+
+ show();
+
+ // run orientation change effect
+ if (current==Qt::Horizontal) {
+ HbEffect::start(this, DIALPAD_TO_LSC_EVENT);
+ } else {
+ HbEffect::start(this, DIALPAD_TO_PRT_EVENT);
+ }
+
+ mOrientation = current;
+
+ mPosition = pos();
+
+ if (mBackgroundItem) {
+ layoutBackgroundItem();
+ }
+}
+
+void Dialpad::layoutBackgroundItem()
+{
+ Q_ASSERT(mBackgroundItem);
+ QRectF backgroundRect(mMainWindow.layoutRect());
+ backgroundRect.adjust(0,mTitleBarHeight,0,0);
+ mBackgroundItem->setRect(backgroundRect);
+}
+
+void Dialpad::updateLayout(Qt::Orientation orientation)
+{
+ Q_ASSERT(layout());
+
+ qreal unit = HbDeviceProfile::current().unitValue();
+ qreal margin = DialpadComponentMargin * unit;
+
+ QGraphicsLinearLayout* mainLayout =
+ static_cast<QGraphicsLinearLayout*>(layout());
+
+ // close handle location changes, update margin values
+ if (orientation==Qt::Vertical) {
+ mainLayout->setContentsMargins(margin,
+ mCloseHandleHeight,
+ margin,
+ margin);
+ mKeypad->callButton().setPreferredHeight(DialpadCallButtonHeight*unit);
+ } else {
+ mainLayout->setContentsMargins(mCloseHandleHeight,
+ margin,
+ margin,
+ margin);
+ mKeypad->callButton().setPreferredHeight(DialpadCallButtonHeightH*unit);
+ }
+}
+
+void Dialpad::gestureEvent(QGestureEvent *event)
+{
+ bool closeGesture(false);
+
+ if(HbSwipeGesture *gesture = qobject_cast<HbSwipeGesture*>(
+ event->gesture(Qt::SwipeGesture))) {
+ if (gesture->state() == Qt::GestureFinished) {
+ if ( mOrientation==Qt::Vertical &&
+ gesture->sceneVerticalDirection() == QSwipeGesture::Down ) {
+ closeGesture = true;
+ } else if (mOrientation==Qt::Horizontal &&
+ gesture->sceneHorizontalDirection() == QSwipeGesture::Right) {
+ closeGesture = true;
+ }
+ }
+ }
+
+ if (closeGesture) {
+ startCloseAnimation();
+ event->accept();
+ } else {
+ event->ignore();
+ }
+}