208 |
208 |
209 //Priority to widgets that overlap on the same coordinate. |
209 //Priority to widgets that overlap on the same coordinate. |
210 //In that case, the distance in the direction will be used as significant score, |
210 //In that case, the distance in the direction will be used as significant score, |
211 //take also in account orthogonal distance in case two widget are in the same distance. |
211 //take also in account orthogonal distance in case two widget are in the same distance. |
212 int score; |
212 int score; |
213 if ((buttonRect.x() < target.right() && target.x() < buttonRect.right()) |
213 if ( keyNavigation() && (buttonRect.x() < target.right() && target.x() < buttonRect.right()) |
214 && (key == Qt::Key_Up || key == Qt::Key_Down)) { |
214 && (key == Qt::Key_Up || key == Qt::Key_Down)) { |
215 //one item's is at the vertical of the other |
215 //one item's is at the vertical of the other |
216 score = (qAbs(p.y() - goal.y()) << 16) + qAbs(p.x() - goal.x()); |
216 score = (qAbs(p.y() - goal.y()) << 16) + qAbs(p.x() - goal.x()); |
217 } else if ((buttonRect.y() < target.bottom() && target.y() < buttonRect.bottom()) |
217 } else if ( keyNavigation() && (buttonRect.y() < target.bottom() && target.y() < buttonRect.bottom()) |
218 && (key == Qt::Key_Left || key == Qt::Key_Right) ) { |
218 && (key == Qt::Key_Left || key == Qt::Key_Right) ) { |
219 //one item's is at the horizontal of the other |
219 //one item's is at the horizontal of the other |
220 score = (qAbs(p.x() - goal.x()) << 16) + qAbs(p.y() - goal.y()); |
220 score = (qAbs(p.x() - goal.x()) << 16) + qAbs(p.y() - goal.y()); |
221 } else { |
221 } else { |
222 score = (1 << 30) + (p.y() - goal.y()) * (p.y() - goal.y()) + (p.x() - goal.x()) * (p.x() - goal.x()); |
222 score = (1 << 30) + (p.y() - goal.y()) * (p.y() - goal.y()) + (p.x() - goal.x()) * (p.x() - goal.x()); |
223 } |
223 } |
224 |
224 |
225 if (score > bestScore && candidate) |
225 if (score > bestScore && candidate) |
226 continue; |
226 continue; |
227 |
227 if ( keyNavigation()) { |
228 switch(key) { |
228 switch(key) { |
229 case Qt::Key_Up: |
229 case Qt::Key_Up: |
230 if (p.y() < goal.y()) { |
230 if (p.y() < goal.y()) { |
231 candidate = button; |
231 candidate = button; |
232 bestScore = score; |
232 bestScore = score; |
|
233 } |
|
234 break; |
|
235 case Qt::Key_Down: |
|
236 if (p.y() > goal.y()) { |
|
237 candidate = button; |
|
238 bestScore = score; |
|
239 } |
|
240 break; |
|
241 case Qt::Key_Left: |
|
242 if (p.x() < goal.x()) { |
|
243 candidate = button; |
|
244 bestScore = score; |
|
245 } |
|
246 break; |
|
247 case Qt::Key_Right: |
|
248 if (p.x() > goal.x()) { |
|
249 candidate = button; |
|
250 bestScore = score; |
|
251 } |
|
252 break; |
233 } |
253 } |
234 break; |
|
235 case Qt::Key_Down: |
|
236 if (p.y() > goal.y()) { |
|
237 candidate = button; |
|
238 bestScore = score; |
|
239 } |
|
240 break; |
|
241 case Qt::Key_Left: |
|
242 if (p.x() < goal.x()) { |
|
243 candidate = button; |
|
244 bestScore = score; |
|
245 } |
|
246 break; |
|
247 case Qt::Key_Right: |
|
248 if (p.x() > goal.x()) { |
|
249 candidate = button; |
|
250 bestScore = score; |
|
251 } |
|
252 break; |
|
253 } |
254 } |
254 } |
255 } |
255 } |
256 } |
256 |
257 |
257 if (exclusive |
258 if (exclusive |
258 #ifdef QT_KEYPAD_NAVIGATION |
259 && !keyNavigation() |
259 && !QApplication::keypadNavigationEnabled() |
|
260 #endif |
|
261 && candidate |
260 && candidate |
262 && focusButton->isChecked() |
261 && focusButton->isChecked() |
263 && candidate->isCheckable()) |
262 && candidate->isCheckable()) |
264 candidate->click(); |
263 candidate->click(); |
265 |
264 |
266 if (candidate) { |
265 if ( keyNavigation() && candidate) { |
267 if (key == Qt::Key_Up || key == Qt::Key_Left) |
266 if (key == Qt::Key_Up || key == Qt::Key_Left) |
268 candidate->setFocus(Qt::BacktabFocusReason); |
267 candidate->setFocus(Qt::BacktabFocusReason); |
269 else |
268 else |
270 candidate->setFocus(Qt::TabFocusReason); |
269 candidate->setFocus(Qt::TabFocusReason); |
271 } |
270 } |
297 |
296 |
298 #ifdef HB_GESTURE_FW |
297 #ifdef HB_GESTURE_FW |
299 q->grabGesture(Qt::TapGesture); |
298 q->grabGesture(Qt::TapGesture); |
300 #endif |
299 #endif |
301 |
300 |
302 q->setFlag(QGraphicsItem::ItemHasNoContents, true); |
|
303 // FIXME: size policy is commented out b/c of a bug in Qt #236689, also in our bugtracker. |
301 // FIXME: size policy is commented out b/c of a bug in Qt #236689, also in our bugtracker. |
304 //q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, controlType)); |
302 //q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, controlType)); |
305 |
303 |
306 //q->setForegroundRole(QPalette::ButtonText); TODO: check |
304 //q->setForegroundRole(QPalette::ButtonText); TODO: check |
307 //q->setBackgroundRole(QPalette::Button); TODO: check |
305 //q->setBackgroundRole(QPalette::Button); TODO: check |
953 { |
951 { |
954 Q_D(HbAbstractButton); |
952 Q_D(HbAbstractButton); |
955 |
953 |
956 if (HbTapGesture *tap = qobject_cast<HbTapGesture *>(event->gesture(Qt::TapGesture))) { |
954 if (HbTapGesture *tap = qobject_cast<HbTapGesture *>(event->gesture(Qt::TapGesture))) { |
957 bool hit = hitButton(mapFromScene(event->mapToGraphicsScene(tap->position()))); |
955 bool hit = hitButton(mapFromScene(event->mapToGraphicsScene(tap->position()))); |
958 |
|
959 switch(tap->state()) { |
956 switch(tap->state()) { |
960 case Qt::GestureStarted: |
957 case Qt::GestureStarted: |
961 setDown(true); |
958 if( hit ){ |
962 HbWidgetFeedback::triggered(this, Hb::InstantPressed); |
959 setDown(true); |
963 updatePrimitives(); |
960 HbWidgetFeedback::triggered(this, Hb::InstantPressed); |
964 d->emitPressed(); |
961 updatePrimitives(); |
965 break; |
962 d->emitPressed(); |
966 case Qt::GestureCanceled: |
963 } |
967 if(d->down) { |
964 break; |
|
965 case Qt::GestureCanceled: |
|
966 if(d->down) { |
|
967 HbWidgetFeedback::triggered(this, Hb::InstantReleased); |
|
968 setDown(false); |
|
969 d->longPress = false; |
|
970 d->emitReleased(); |
|
971 } |
|
972 break; |
|
973 case Qt::GestureFinished: |
|
974 if (!d->down){ |
|
975 return; |
|
976 } |
|
977 if ( hit ){ |
|
978 HbWidgetFeedback::triggered(this, Hb::InstantClicked); |
|
979 d->repeatTimer.stop(); |
|
980 d->click(); |
|
981 }else{ |
|
982 setDown(false); |
|
983 } |
968 HbWidgetFeedback::triggered(this, Hb::InstantReleased); |
984 HbWidgetFeedback::triggered(this, Hb::InstantReleased); |
969 setDown(false); |
|
970 d->longPress = false; |
985 d->longPress = false; |
971 d->emitReleased(); |
986 break; |
|
987 default: |
|
988 break; |
972 } |
989 } |
973 break; |
|
974 case Qt::GestureFinished: |
|
975 if (!d->down) { |
|
976 return; |
|
977 } |
|
978 if ( hit ) { |
|
979 HbWidgetFeedback::triggered(this, Hb::InstantClicked); |
|
980 } |
|
981 HbWidgetFeedback::triggered(this, Hb::InstantReleased); |
|
982 if ( hit ) { |
|
983 d->repeatTimer.stop(); |
|
984 d->click(); |
|
985 } else { |
|
986 setDown(false); |
|
987 } |
|
988 d->longPress = false; |
|
989 break; |
|
990 default: |
|
991 break; |
|
992 } |
|
993 } |
990 } |
994 } |
991 } |
995 #endif |
992 #endif |
996 |
993 |
997 /*! |
994 /*! |
1013 d->emitPressed(); |
1010 d->emitPressed(); |
1014 } |
1011 } |
1015 break; |
1012 break; |
1016 case Qt::Key_Up: |
1013 case Qt::Key_Up: |
1017 case Qt::Key_Left: |
1014 case Qt::Key_Left: |
1018 next = false; |
1015 if ( d->keyNavigation() ) { |
|
1016 next = false; |
|
1017 } |
1019 // fall through |
1018 // fall through |
1020 case Qt::Key_Right: |
1019 case Qt::Key_Right: |
1021 case Qt::Key_Down: |
1020 case Qt::Key_Down: |
1022 #ifdef QT_KEYPAD_NAVIGATION |
1021 if ( d->keyNavigation() ) { |
1023 if (QApplication::keypadNavigationEnabled() && (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right)) { |
1022 if ( d->keyNavigation() && (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right)) { |
1024 event->ignore(); |
|
1025 return; |
|
1026 } |
|
1027 #endif |
|
1028 if (d->autoExclusive) { |
|
1029 // ### Using qobject_cast to check if the parent is a viewport of |
|
1030 // QAbstractItemView is a crude hack, and should be revisited and |
|
1031 // cleaned up when fixing task 194373. It's here to ensure that we |
|
1032 // keep compatibility outside QAbstractItemView. |
|
1033 d->moveFocus(event->key()); |
|
1034 if (hasFocus()) // nothing happend, propagate |
|
1035 event->ignore(); |
1023 event->ignore(); |
1036 } else { |
1024 return; |
1037 focusNextPrevChild(next); |
1025 } |
|
1026 if (d->autoExclusive) { |
|
1027 // ### Using qobject_cast to check if the parent is a viewport of |
|
1028 // QAbstractItemView is a crude hack, and should be revisited and |
|
1029 // cleaned up when fixing task 194373. It's here to ensure that we |
|
1030 // keep compatibility outside QAbstractItemView. |
|
1031 d->moveFocus(event->key()); |
|
1032 if (hasFocus()) // nothing happend, propagate |
|
1033 event->ignore(); |
|
1034 } else { |
|
1035 focusNextPrevChild(next); |
|
1036 } |
1038 } |
1037 } |
1039 break; |
1038 break; |
1040 case Qt::Key_Escape: |
1039 case Qt::Key_Escape: |
1041 if (d->down) { |
1040 if (d->down) { |
1042 setDown(false); |
1041 setDown(false); |