29 #include "dialpad.h" |
29 #include "dialpad.h" |
30 #include "dialpadinputfield.h" |
30 #include "dialpadinputfield.h" |
31 #include "dialpadkeypad.h" |
31 #include "dialpadkeypad.h" |
32 #include "dialpadbutton.h" |
32 #include "dialpadbutton.h" |
33 #include "dialpadmultitaphandler.h" |
33 #include "dialpadmultitaphandler.h" |
34 |
34 #include "dialpadbackground.h" |
35 static const QString backgroundGraphics(":/inputmethods/qtg_fr_input_bg"); |
35 |
36 static const QString minimizeIcon(":/inputmethods/qtg_mono_input_down"); |
36 static const QString backgroundGraphics("qtg_fr_input_bg"); |
37 static const qreal DialpadCloseSwipeDistance = 0.25; //compared to total height |
37 static const QString backgroundGraphicsH("qtg_fr_input_h_bg"); |
|
38 static const QString minimizeIcon("qtg_graf_input_swipe"); |
|
39 static const QString minimizeIconH("qtg_graf_input_h_swipe"); |
|
40 static const qreal DialpadCloseSwipeDistanceV = 0.25; //compared to total height |
|
41 static const qreal DialpadCloseSwipeDistanceH = 0.33; // > button width |
38 static const int DialpadMaxSwipeTime = 300; // ms |
42 static const int DialpadMaxSwipeTime = 300; // ms |
39 static const int DialpadCloseAnimDuration = 400; // ms |
43 static const int DialpadCloseAnimDuration = 200; // ms |
40 static const int DialpadOpenAnimDuration = 200; // ms |
44 static const int DialpadOpenAnimDuration = 200; // ms |
41 static const qreal DialpadComponentMargin = 0.75; // units |
45 static const qreal DialpadComponentMargin = 0.75; // units |
42 static const qreal DialpadCloseHandleHeight = 2.23; // units |
46 static const qreal DialpadCloseHandleHeight = 2.23; // units |
43 |
47 static const qreal DialpadCloseHandleWidth = 18.8; // units |
44 Dialpad::Dialpad() : mMouseButtonPressedDown(false), |
48 |
45 mOpenTimeLine(DialpadOpenAnimDuration), |
49 Dialpad::Dialpad() : |
46 mCloseTimeLine(DialpadCloseAnimDuration), |
50 mMainWindow(*hbInstance->allMainWindows().at(0)), |
47 mAnimationOngoing(false) |
51 mBackgroundItem(0), |
|
52 mMouseButtonPressedDown(false), |
|
53 mOpenTimeLine(DialpadOpenAnimDuration), |
|
54 mCloseTimeLine(DialpadCloseAnimDuration), |
|
55 mAnimationOngoing(false), |
|
56 mOrientation(Qt::Vertical), |
|
57 mIsOpen(false) |
|
58 { |
|
59 // this constuctor is deprecated |
|
60 initialize(); |
|
61 } |
|
62 |
|
63 Dialpad::Dialpad(const HbMainWindow& mainWindow) : |
|
64 mMainWindow(mainWindow), |
|
65 mBackgroundItem(0), |
|
66 mMouseButtonPressedDown(false), |
|
67 mOpenTimeLine(DialpadOpenAnimDuration), |
|
68 mCloseTimeLine(DialpadCloseAnimDuration), |
|
69 mAnimationOngoing(false), |
|
70 mOrientation(Qt::Vertical), |
|
71 mIsOpen(false) |
|
72 { |
|
73 initialize(); |
|
74 } |
|
75 |
|
76 void Dialpad::initialize() |
48 { |
77 { |
49 setFocusPolicy(Qt::StrongFocus); |
78 setFocusPolicy(Qt::StrongFocus); |
50 setFlag(QGraphicsItem::ItemIsFocusable,true); |
79 setFlag(QGraphicsItem::ItemIsFocusable,true); |
51 |
80 |
52 // create input field |
81 // create input field |
53 mInputField = new DialpadInputField(this); |
82 mInputField = new DialpadInputField(this); |
54 |
83 |
55 // create keypad |
84 // create keypad |
56 mKeypad = new DialpadKeypad(*mInputField,this); |
85 mKeypad = new DialpadKeypad(mMainWindow,*mInputField,this); |
57 mKeypad->setLongPressDuration(DialpadMaxSwipeTime); |
86 mKeypad->setLongPressDuration(DialpadMaxSwipeTime); |
58 |
87 |
59 // layouting params |
88 // layouting params |
60 qreal unit = HbDeviceProfile::current().unitValue(); |
89 qreal unit = HbDeviceProfile::current().unitValue(); |
61 qreal margin = DialpadComponentMargin * unit; |
90 qreal margin = DialpadComponentMargin * unit; |
62 mCloseHandleHeight = DialpadCloseHandleHeight * unit; |
91 mCloseHandleHeight = DialpadCloseHandleHeight * unit; |
63 |
92 mCloseHandleWidth = DialpadCloseHandleWidth * unit; |
64 // create popup close handler and background |
93 |
65 QGraphicsWidget* closeHandle = new QGraphicsWidget(this); |
94 // create popup background |
66 closeHandle->setPreferredHeight(mCloseHandleHeight); |
|
67 closeHandle->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed); |
|
68 mBackgroundDrawer = new HbFrameDrawer(); |
95 mBackgroundDrawer = new HbFrameDrawer(); |
69 mIconDrawer = new HbFrameDrawer(); |
96 mIconDrawer = new HbFrameDrawer(); |
70 |
97 |
71 // popup layout |
98 // popup layout |
72 QGraphicsLinearLayout* popupLayout |
99 QGraphicsLinearLayout* popupLayout |
73 = new QGraphicsLinearLayout(Qt::Vertical); |
100 = new QGraphicsLinearLayout(mMainWindow.orientation()); |
74 popupLayout->addItem(closeHandle); |
|
75 popupLayout->addItem(mInputField); |
101 popupLayout->addItem(mInputField); |
76 popupLayout->addItem(mKeypad); |
102 popupLayout->addItem(mKeypad); |
77 popupLayout->setContentsMargins(margin, 0, margin, margin); |
103 popupLayout->setContentsMargins(margin, mCloseHandleHeight, margin, margin); |
78 popupLayout->setSpacing(margin); |
104 popupLayout->setSpacing(margin); |
79 setLayout(popupLayout); |
105 setLayout(popupLayout); |
80 |
106 |
81 // asterisk multitap handler |
107 // asterisk multitap handler |
82 mMultitap = new DialpadMultitapHandler(mInputField->editor(),this); |
108 mMultitap = new DialpadMultitapHandler(mInputField->editor(),this); |
99 // default values |
125 // default values |
100 setPos(0,0); |
126 setPos(0,0); |
101 setPreferredSize(360,360); |
127 setPreferredSize(360,360); |
102 setZValue(0x00004000); // Hb PopupZValueRangeStart |
128 setZValue(0x00004000); // Hb PopupZValueRangeStart |
103 hide(); |
129 hide(); |
|
130 mMainWindow.scene()->addItem(this); |
104 |
131 |
105 // custom button style |
132 // custom button style |
106 HbStyleLoader::registerFilePath(":/dialpad.css"); |
133 HbStyleLoader::registerFilePath(":/dialpad.css"); |
107 HbStyleLoader::registerFilePath(":/dialpad.dialpadbutton.widgetml"); |
134 HbStyleLoader::registerFilePath(":/dialpad.dialpadbutton.widgetml"); |
108 } |
135 } |
109 |
136 |
110 Dialpad::~Dialpad() |
137 Dialpad::~Dialpad() |
111 { |
138 { |
112 delete mBackgroundDrawer; |
139 delete mBackgroundDrawer; |
113 delete mIconDrawer; |
140 delete mIconDrawer; |
114 } |
141 delete mBackgroundItem; |
115 |
142 } |
116 |
143 |
117 void Dialpad::paint( |
144 void Dialpad::paint( |
118 QPainter* painter, |
145 QPainter* painter, |
119 const QStyleOptionGraphicsItem* option, |
146 const QStyleOptionGraphicsItem* option, |
120 QWidget* widget) |
147 QWidget* widget) |
121 { |
148 { |
122 Q_UNUSED(option); |
149 Q_UNUSED(option); |
123 Q_UNUSED(widget); |
150 Q_UNUSED(widget); |
124 |
151 |
125 // paint popup background |
152 // paint popup background |
126 mBackgroundDrawer->setFrameGraphicsName(backgroundGraphics); |
153 if ( mOrientation == Qt::Vertical ) { |
127 mBackgroundDrawer->setFrameType(HbFrameDrawer::ThreePiecesVertical); |
154 mBackgroundDrawer->setFrameGraphicsName(backgroundGraphics); |
|
155 mIconDrawer->setFrameGraphicsName(minimizeIcon); |
|
156 mBackgroundDrawer->setFrameType(HbFrameDrawer::ThreePiecesVertical); |
|
157 mBackgroundDrawer->setBorderWidths(0.0, mCloseHandleHeight, 0.0, 0.0); |
|
158 } else { |
|
159 mBackgroundDrawer->setFrameGraphicsName(backgroundGraphicsH); |
|
160 mIconDrawer->setFrameGraphicsName(minimizeIconH); |
|
161 mBackgroundDrawer->setFrameType(HbFrameDrawer::ThreePiecesHorizontal); |
|
162 mBackgroundDrawer->setBorderWidths(mCloseHandleHeight, 0.0, 0.0, 0.0); |
|
163 } |
|
164 |
|
165 // draw background |
|
166 QRectF rect = boundingRect(); |
128 mBackgroundDrawer->setFillWholeRect(true); |
167 mBackgroundDrawer->setFillWholeRect(true); |
129 |
|
130 QRectF rect = boundingRect(); |
|
131 mBackgroundDrawer->setBorderWidths(0.0, mCloseHandleHeight, 0.0, |
|
132 (rect.height()-mCloseHandleHeight)/2.0); |
|
133 mBackgroundDrawer->paint(painter, rect); |
168 mBackgroundDrawer->paint(painter, rect); |
134 |
169 |
|
170 // adjust rectangle to close bar position |
|
171 if ( mOrientation == Qt::Vertical ) { |
|
172 rect.setLeft((rect.width()- mCloseHandleWidth)/2); |
|
173 rect.setWidth(mCloseHandleWidth); |
|
174 rect.setHeight(mCloseHandleHeight); |
|
175 } else { |
|
176 if (layoutDirection()==Qt::LeftToRight) { |
|
177 rect.setTop((rect.height() - mCloseHandleWidth)/2); |
|
178 rect.setWidth(mCloseHandleHeight); |
|
179 rect.setHeight(mCloseHandleWidth); |
|
180 } else { |
|
181 rect.setLeft((rect.width() - mCloseHandleHeight)); |
|
182 rect.setTop((rect.height() - mCloseHandleWidth)/2); |
|
183 rect.setWidth(mCloseHandleHeight); |
|
184 rect.setHeight(mCloseHandleWidth); |
|
185 } |
|
186 } |
|
187 |
135 mIconDrawer->setFrameType(HbFrameDrawer::OnePiece); |
188 mIconDrawer->setFrameType(HbFrameDrawer::OnePiece); |
136 rect.setLeft((rect.width() - mCloseHandleHeight)/2); |
|
137 rect.setWidth(mCloseHandleHeight); |
|
138 rect.setHeight(mCloseHandleHeight); |
|
139 mIconDrawer->setFrameGraphicsName(minimizeIcon); |
|
140 mIconDrawer->paint(painter, rect); |
189 mIconDrawer->paint(painter, rect); |
141 } |
190 } |
142 |
191 |
|
192 bool Dialpad::isOpen() const |
|
193 { |
|
194 return mIsOpen; |
|
195 } |
|
196 |
143 void Dialpad::openDialpad() |
197 void Dialpad::openDialpad() |
144 { |
198 { |
145 HbMainWindow* window = hbInstance->allMainWindows().at(0); |
199 if (mIsOpen) { |
146 window->scene()->addItem(this); |
200 return; |
147 connect(window,SIGNAL(aboutToChangeOrientation()), |
201 } |
|
202 |
|
203 connect(&mMainWindow,SIGNAL(aboutToChangeOrientation()), |
148 SLOT(orientationChangeStarted())); |
204 SLOT(orientationChangeStarted())); |
149 connect(window,SIGNAL(orientationChanged(Qt::Orientation)), |
205 connect(&mMainWindow,SIGNAL(orientationChanged(Qt::Orientation)), |
150 SLOT(orientationChangeFinished())); |
206 SLOT(orientationChangeFinished(Qt::Orientation))); |
151 |
207 |
152 // set offset for open animation |
208 // set offset for open animation |
|
209 int previousOrientation = mOrientation; |
|
210 mOrientation = mMainWindow.orientation(); |
|
211 |
153 mPosition = pos(); |
212 mPosition = pos(); |
154 qreal height = geometry().height(); |
213 if (mOrientation==Qt::Vertical) { |
155 setPos(mPosition.x(),mPosition.y()+height); |
214 qreal height = geometry().height(); |
|
215 setPos(mPosition.x(),mPosition.y()+height); |
|
216 } else { |
|
217 qreal width = geometry().width(); |
|
218 if (layoutDirection()==Qt::LeftToRight) { |
|
219 setPos(mPosition.x()+width,mPosition.y()); |
|
220 } else { |
|
221 setPos(mPosition.x()-width,mPosition.y()); |
|
222 } |
|
223 } |
|
224 |
|
225 if (mOrientation!=previousOrientation) { |
|
226 mKeypad->createButtonGrid(); |
|
227 updateLayout((Qt::Orientation)mOrientation); |
|
228 } |
156 |
229 |
157 show(); |
230 show(); |
158 |
231 |
159 setFocusProxy(&mInputField->editor()); |
232 setFocusProxy(&mInputField->editor()); |
160 mInputField->editor().setFocus(); |
233 mInputField->editor().setFocus(); |
161 |
234 |
162 mOpenTimeLine.start(); |
235 mOpenTimeLine.start(); |
163 mAnimationOngoing = true; |
236 mAnimationOngoing = true; |
|
237 if (!mInputField->editor().text().isEmpty()) { |
|
238 setCallButtonEnabled(true); |
|
239 } |
|
240 mIsOpen = true; |
|
241 |
|
242 emit aboutToOpen(); |
164 } |
243 } |
165 |
244 |
166 void Dialpad::closeDialpad() |
245 void Dialpad::closeDialpad() |
167 { |
246 { |
168 close(); |
247 close(); |
169 |
248 |
170 HbMainWindow* window = hbInstance->allMainWindows().at(0); |
249 disconnect(&mMainWindow,SIGNAL(aboutToChangeOrientation()), |
171 window->scene()->removeItem(this); |
250 this, SLOT(orientationChangeStarted())); |
172 disconnect(window,SIGNAL(aboutToChangeOrientation())); |
251 disconnect(&mMainWindow,SIGNAL(orientationChanged(Qt::Orientation)), |
173 disconnect(window,SIGNAL(orientationChanged(Qt::Orientation))); |
252 this, SLOT(orientationChangeFinished(Qt::Orientation))); |
174 } |
253 |
|
254 if (mBackgroundItem) { |
|
255 mBackgroundItem->hide(); |
|
256 } |
|
257 } |
175 |
258 |
176 HbLineEdit& Dialpad::editor() const |
259 HbLineEdit& Dialpad::editor() const |
177 { |
260 { |
178 return mInputField->editor(); |
261 return mInputField->editor(); |
179 } |
262 } |
180 |
263 |
181 void Dialpad::setCallButtonEnabled(bool enabled) |
264 void Dialpad::setCallButtonEnabled(bool enabled) |
182 { |
265 { |
183 mKeypad->setCallButtonEnabled(enabled); |
266 mKeypad->setCallButtonEnabled(enabled); |
|
267 } |
|
268 |
|
269 void Dialpad::setTapOutsideDismiss(bool dismiss) |
|
270 { |
|
271 // set dismiss policy before opening dialpad |
|
272 Q_ASSERT(!isVisible()); |
|
273 |
|
274 if (dismiss) { |
|
275 mBackgroundItem = new DialpadBackground(*this); |
|
276 mBackgroundItem->setZValue(zValue()-1); |
|
277 mMainWindow.scene()->addItem(mBackgroundItem); |
|
278 qreal chromeHeight = 0; |
|
279 hbInstance->style()->parameter("hb-param-widget-chrome-height", |
|
280 chromeHeight); |
|
281 mTitleBarHeight = chromeHeight; |
|
282 } else { |
|
283 delete mBackgroundItem; |
|
284 mBackgroundItem = 0; |
|
285 } |
184 } |
286 } |
185 |
287 |
186 bool Dialpad::sceneEvent(QEvent *event) |
288 bool Dialpad::sceneEvent(QEvent *event) |
187 { |
289 { |
188 return handleSceneEvent(event); |
290 return handleSceneEvent(event); |
209 |
311 |
210 // check if mouse has moved DialpadCloseSwipeDistance vertically |
312 // check if mouse has moved DialpadCloseSwipeDistance vertically |
211 QPointF delta = mouseEvent->scenePos() - |
313 QPointF delta = mouseEvent->scenePos() - |
212 mouseEvent->buttonDownScenePos(Qt::LeftButton); |
314 mouseEvent->buttonDownScenePos(Qt::LeftButton); |
213 |
315 |
214 qreal height = geometry().height() * DialpadCloseSwipeDistance; |
316 if (mOrientation==Qt::Vertical) { |
215 |
317 qreal height = geometry().height() * DialpadCloseSwipeDistanceV; |
216 if ( (delta.y() >= height) && |
318 |
217 (mSwipeTimer.elapsed() <= DialpadMaxSwipeTime) && |
319 if ( (delta.y() >= height) && |
218 !mAnimationOngoing) { |
320 (mSwipeTimer.elapsed() <= DialpadMaxSwipeTime)) { |
219 mCloseTimeLine.start(); |
321 startCloseAnimation(); |
220 mAnimationOngoing = true; |
322 } |
|
323 } else { |
|
324 qreal width = geometry().width() * DialpadCloseSwipeDistanceH; |
|
325 bool swipe = (layoutDirection()==Qt::LeftToRight && |
|
326 delta.x() >= width) || |
|
327 (layoutDirection()==Qt::RightToLeft && |
|
328 -delta.x() >= width); |
|
329 |
|
330 if ( swipe && |
|
331 (mSwipeTimer.elapsed() <= DialpadMaxSwipeTime)) { |
|
332 startCloseAnimation(); |
|
333 } |
221 } |
334 } |
222 } |
335 } |
223 |
336 |
224 return false; |
337 return false; |
|
338 } |
|
339 |
|
340 void Dialpad::startCloseAnimation() |
|
341 { |
|
342 if (!mAnimationOngoing) { |
|
343 mCloseTimeLine.start(); |
|
344 mAnimationOngoing = true; |
|
345 } |
225 } |
346 } |
226 |
347 |
227 void Dialpad::showEvent(QShowEvent *event) |
348 void Dialpad::showEvent(QShowEvent *event) |
228 { |
349 { |
229 HbWidget::showEvent(event); |
350 HbWidget::showEvent(event); |
230 |
351 |
231 // for closing swipe gesture |
352 // for closing swipe gesture |
232 installSceneEventFilter(this); |
353 installSceneEventFilter(this); |
233 setFiltersChildEvents(true); |
354 setFiltersChildEvents(true); |
|
355 |
|
356 if (mBackgroundItem) { |
|
357 layoutBackgroundItem(); |
|
358 mBackgroundItem->show(); |
|
359 } |
234 } |
360 } |
235 |
361 |
236 void Dialpad::hideEvent(QHideEvent *event) |
362 void Dialpad::hideEvent(QHideEvent *event) |
237 { |
363 { |
238 HbWidget::hideEvent(event); |
364 HbWidget::hideEvent(event); |
268 |
408 |
269 void Dialpad::openAnimValueChanged(qreal value) |
409 void Dialpad::openAnimValueChanged(qreal value) |
270 { |
410 { |
271 QPointF currentPos = pos(); |
411 QPointF currentPos = pos(); |
272 QPointF newPos; |
412 QPointF newPos; |
273 qreal height = geometry().height(); |
413 |
274 |
414 if (mOrientation==Qt::Vertical) { |
275 newPos.setX(currentPos.x()); |
415 qreal height = geometry().height(); |
276 newPos.setY(mPosition.y()+(height*(1-value))); |
416 |
|
417 newPos.setX(currentPos.x()); |
|
418 newPos.setY(mPosition.y()+(height*(1-value))); |
|
419 } else { |
|
420 qreal width = geometry().width(); |
|
421 |
|
422 if (layoutDirection()==Qt::LeftToRight) { |
|
423 newPos.setY(currentPos.y()); |
|
424 newPos.setX(mPosition.x()+(width*(1-value))); |
|
425 } else { |
|
426 newPos.setY(currentPos.y()); |
|
427 newPos.setX(mPosition.x()-(width*(1-value))); |
|
428 } |
|
429 } |
277 |
430 |
278 setPos(newPos); |
431 setPos(newPos); |
279 } |
432 } |
280 |
433 |
281 void Dialpad::openAnimFinished() |
434 void Dialpad::openAnimFinished() |
282 { |
435 { |
283 mAnimationOngoing = false; |
436 mAnimationOngoing = false; |
284 setPos(mPosition); |
437 setPos(mPosition); |
285 } |
438 } |
286 |
439 |
287 void Dialpad::orientationChangeStarted() |
440 void Dialpad::orientationChangeStarted() |
288 { |
441 { |
289 hide(); |
442 hide(); |
290 // needs to re-create grid layout to get |
443 // needs to re-create grid layout to get |
291 // scale with uniform item sizes |
444 // scale with uniform item sizes |
292 mKeypad->createButtonGrid(); |
445 mKeypad->createButtonGrid(); |
293 } |
446 } |
294 |
447 |
295 void Dialpad::orientationChangeFinished() |
448 void Dialpad::orientationChangeFinished(Qt::Orientation current) |
296 { |
449 { |
|
450 updateLayout(current); |
|
451 |
297 show(); |
452 show(); |
298 } |
453 |
|
454 mOrientation = current; |
|
455 |
|
456 mPosition = pos(); |
|
457 |
|
458 if (mBackgroundItem) { |
|
459 layoutBackgroundItem(); |
|
460 } |
|
461 } |
|
462 |
|
463 void Dialpad::layoutBackgroundItem() |
|
464 { |
|
465 Q_ASSERT(mBackgroundItem); |
|
466 QRectF backgroundRect(mMainWindow.layoutRect()); |
|
467 backgroundRect.adjust(0,mTitleBarHeight,0,0); |
|
468 mBackgroundItem->setRect(backgroundRect); |
|
469 } |
|
470 |
|
471 void Dialpad::updateLayout(Qt::Orientation orientation) |
|
472 { |
|
473 Q_ASSERT(layout()); |
|
474 |
|
475 qreal unit = HbDeviceProfile::current().unitValue(); |
|
476 qreal margin = DialpadComponentMargin * unit; |
|
477 |
|
478 QGraphicsLinearLayout* mainLayout = |
|
479 static_cast<QGraphicsLinearLayout*>(layout()); |
|
480 |
|
481 // close handle location changes, update margin values |
|
482 if (orientation==Qt::Vertical) { |
|
483 mainLayout->setContentsMargins(margin, |
|
484 mCloseHandleHeight, |
|
485 margin, |
|
486 margin); |
|
487 } else { |
|
488 mainLayout->setContentsMargins(mCloseHandleHeight, |
|
489 margin, |
|
490 margin, |
|
491 margin); |
|
492 } |
|
493 } |