equal
deleted
inserted
replaced
33 #ifdef HB_EFFECTS |
33 #ifdef HB_EFFECTS |
34 #include "hbeffect.h" |
34 #include "hbeffect.h" |
35 #include "hbeffectinternal_p.h" |
35 #include "hbeffectinternal_p.h" |
36 bool HbMenuPrivate::menuEffectsLoaded = false; |
36 bool HbMenuPrivate::menuEffectsLoaded = false; |
37 #endif |
37 #endif |
|
38 #include "hbglobal_p.h" |
38 |
39 |
39 #include <QPointer> |
40 #include <QPointer> |
40 |
41 |
41 Q_DECLARE_METATYPE (QAction*)// krazy:exclude=qclasses |
42 Q_DECLARE_METATYPE (QAction*)// krazy:exclude=qclasses |
42 |
43 |
67 subMenuAction = new HbAction(q); |
68 subMenuAction = new HbAction(q); |
68 subMenuAction->setMenu(q); |
69 subMenuAction->setMenu(q); |
69 q->setTimeout(HbPopup::ContextMenuTimeout); |
70 q->setTimeout(HbPopup::ContextMenuTimeout); |
70 |
71 |
71 q->setBackgroundFaded(false); |
72 q->setBackgroundFaded(false); |
72 q->setFlag(QGraphicsItem::ItemClipsChildrenToShape); |
|
73 } |
73 } |
74 |
74 |
75 void HbMenuPrivate::addPopupEffects() |
75 void HbMenuPrivate::addPopupEffects() |
76 { |
76 { |
77 #ifdef HB_EFFECTS |
77 #ifdef HB_EFFECTS |
106 if (hasEffects) { |
106 if (hasEffects) { |
107 HbEffect::start(currentItem, "HB_menuitem", "clicked"); |
107 HbEffect::start(currentItem, "HB_menuitem", "clicked"); |
108 } |
108 } |
109 #endif |
109 #endif |
110 HbAction *hbAction = qobject_cast<HbAction *>(currentItem->action()); |
110 HbAction *hbAction = qobject_cast<HbAction *>(currentItem->action()); |
111 if (hbAction && hbAction->menu()) { |
111 if (hbAction && hbAction->menu() && !actionTriggered) { |
112 hbAction->trigger(); |
112 hbAction->trigger(); |
113 stopTimeout(); |
113 stopTimeout(); |
114 openSubmenu(currentItem); |
114 openSubmenu(currentItem); |
115 } else { |
115 } else { |
116 q->close(); |
116 q->close(); |
129 { |
129 { |
130 Q_Q(HbMenu); |
130 Q_Q(HbMenu); |
131 if (!menuItemView && q->actions().count()){ |
131 if (!menuItemView && q->actions().count()){ |
132 menuItemView = new HbMenuListView(q, q); |
132 menuItemView = new HbMenuListView(q, q); |
133 HbStyle::setItemName(menuItemView, "content"); |
133 HbStyle::setItemName(menuItemView, "content"); |
134 /* This is for qt versions 4.5,which had the clipping problem. |
134 //This optimises case of options menu which otherwise updates its primitives twice. |
135 FOR http://www.qtsoftware.com/developer/task-tracker/index_html?id=257232&method=entry |
|
136 see also HbMenu constructor */ |
|
137 #if QT_VERSION < 0x040600 |
|
138 menuItemView->setFlag( QGraphicsItem::ItemClipsChildrenToShape, false ); |
|
139 #endif |
|
140 //This optimises case of options menu which otherwise updates its primitives twice. |
|
141 if (menuType == HbMenu::OptionsMenu) |
135 if (menuType == HbMenu::OptionsMenu) |
142 q->setFrameType(HbPopup::Strong); |
136 q->setFrameType(HbPopup::Strong); |
143 else |
137 else |
144 q->setFrameType(HbPopup::Weak); |
138 q->setFrameType(HbPopup::Weak); |
145 if (polished)//This check can be removed once base class repolish is fixed. |
139 if (polished)//This check can be removed once base class repolish is fixed. |
292 } |
286 } |
293 q->close(); |
287 q->close(); |
294 } |
288 } |
295 } |
289 } |
296 |
290 |
|
291 void HbMenuPrivate::_q_handleMenuAfterOrientationChange() |
|
292 { |
|
293 Q_Q(HbMenu); |
|
294 if ( menuType == HbMenu::ContextMenu || menuType == HbMenu::OptionsMenu ) { |
|
295 if(activeSubMenu){ |
|
296 HbAction* action = activeSubMenu->activeAction(); |
|
297 if(action) { |
|
298 closeMenuRecursively(action); |
|
299 } |
|
300 closeSubmenu(); |
|
301 } |
|
302 q->close(); |
|
303 } |
|
304 } |
|
305 |
|
306 /*! |
|
307 * closes the menu after Orientation change |
|
308 */ |
|
309 void HbMenuPrivate::closeMenuAfterOrientationChange() |
|
310 { |
|
311 Q_Q(HbMenu); |
|
312 HbMainWindow* w(q->mainWindow()); |
|
313 if ( w ){ |
|
314 QObject::disconnect( w, SIGNAL(aboutToChangeOrientation()), |
|
315 q, SLOT(_q_handleMenuAfterOrientationChange())); |
|
316 QObject::connect( w, SIGNAL(aboutToChangeOrientation()), |
|
317 q, SLOT(_q_handleMenuAfterOrientationChange())); |
|
318 } |
|
319 } |
|
320 |
|
321 void HbMenuPrivate::closeMenuRecursively(HbAction* menuAction) |
|
322 { |
|
323 if(menuAction->menu() && menuAction->menu()->activeAction()) { |
|
324 closeMenuRecursively(menuAction->menu()->activeAction()); |
|
325 } |
|
326 if(menuAction->menu()) { |
|
327 menuAction->menu()->close(); |
|
328 } |
|
329 } |
|
330 |
|
331 |
297 bool HbMenuPrivate::menuTimedOut(HbMenu* menu) |
332 bool HbMenuPrivate::menuTimedOut(HbMenu* menu) |
298 { |
333 { |
299 return (menu && menu->timeout() > 0 && HbMenuPrivate::d_ptr(menu)->timedOut); |
334 return (menu && menu->timeout() > 0 && HbMenuPrivate::d_ptr(menu)->timedOut); |
300 } |
335 } |
301 |
336 |
312 Q_Q(HbMenu); |
347 Q_Q(HbMenu); |
313 if (mSubMenuItem) { |
348 if (mSubMenuItem) { |
314 qreal upperEdge = mSubMenuItem->scenePos().y() + mSubMenuItem->size().height() * 2 / 3; |
349 qreal upperEdge = mSubMenuItem->scenePos().y() + mSubMenuItem->size().height() * 2 / 3; |
315 QSizeF windowSize = QSizeF(0,0); |
350 QSizeF windowSize = QSizeF(0,0); |
316 if (q->mainWindow()) { |
351 if (q->mainWindow()) { |
317 QGraphicsWidget *viewPortItem = q->mainWindow()->element(HbMainWindow::ViewportItem); |
352 windowSize = q->mainWindow()->layoutRect().size(); |
318 if (viewPortItem) { |
|
319 windowSize = viewPortItem->size(); |
|
320 } |
|
321 } |
353 } |
322 if (windowSize.height() - mDownMargin - q->preferredHeight() < upperEdge) { |
354 if (windowSize.height() - mDownMargin - q->preferredHeight() < upperEdge) { |
323 upperEdge = windowSize.height() - mDownMargin - q->preferredHeight(); |
355 upperEdge = windowSize.height() - mDownMargin - q->preferredHeight(); |
324 } |
356 } |
325 if (q->layoutDirection() == Qt::LeftToRight) { |
357 if (q->layoutDirection() == Qt::LeftToRight) { |
341 } |
373 } |
342 } |
374 } |
343 } |
375 } |
344 |
376 |
345 /*! |
377 /*! |
346 @stable |
378 @beta |
347 @hbcore |
379 @hbcore |
348 \class HbMenu |
380 \class HbMenu |
349 \brief HbMenu is a menu widget for use in HbView. |
381 \brief HbMenu is a menu widget for use in HbView. |
350 |
382 |
351 \image html hbmenu.png A menu with checkable items and a sub-menu. |
383 \image html hbmenu.png A menu with checkable items and a sub-menu. |
444 HbPopup(*new HbMenuPrivate, parent) |
476 HbPopup(*new HbMenuPrivate, parent) |
445 { |
477 { |
446 Q_D(HbMenu); |
478 Q_D(HbMenu); |
447 d->q_ptr = this; |
479 d->q_ptr = this; |
448 d->init(); |
480 d->init(); |
449 /* This is for qt versions 4.5,which had the clipping problem. |
481 setModal(true); |
450 FOR http://www.qtsoftware.com/developer/task-tracker/index_html?id=257232&method=entry |
|
451 */ |
|
452 #if QT_VERSION < 0x040600 |
|
453 setFlag( QGraphicsItem::ItemClipsChildrenToShape, true ); |
|
454 #endif |
|
455 } |
482 } |
456 |
483 |
457 /*! |
484 /*! |
458 Constructs a menu with \a title and \a parent graphics item. |
485 Constructs a menu with \a title and \a parent graphics item. |
459 \param title is the menu title. |
486 \param title is the menu title. |
490 } |
517 } |
491 } |
518 } |
492 } |
519 } |
493 |
520 |
494 /*! |
521 /*! |
495 \deprecated HbMenu::exec(HbAction*) |
522 \deprecated HbMenu::exec(HbAction*) |
496 is deprecated. Please use void HbMenu::open( QObject *receiver, const char *member ) |
523 is deprecated. Please use |
497 or HbMenu::show() instead. |
524 void HbMenu::open( QObject *receiver, const char *member ) or |
|
525 HbMenu::show() instead. |
498 |
526 |
499 Executes the menu synchronously so that given \a action |
527 Executes the menu synchronously so that given \a action |
500 is active. |
528 is active. |
501 |
529 |
502 \param action is the action that is active when the menu is shown. |
530 \param action is the action that is active when the menu is shown. |
517 of its sub-menus, or 0 if no item was triggered (normally because |
545 of its sub-menus, or 0 if no item was triggered (normally because |
518 the user closed or cancelled the menu). |
546 the user closed or cancelled the menu). |
519 */ |
547 */ |
520 HbAction *HbMenu::exec(HbAction *action) |
548 HbAction *HbMenu::exec(HbAction *action) |
521 { |
549 { |
|
550 HB_DEPRECATED("HbMenu::exec is deprecated. Use HbMenu::show() or HbMenu::open() instead!"); |
522 Q_D(HbMenu); |
551 Q_D(HbMenu); |
523 if (actions().count() == 0) { |
552 if (actions().count() == 0) { |
524 return 0; |
553 return 0; |
525 } |
554 } |
526 |
555 |
546 return 0; |
575 return 0; |
547 } |
576 } |
548 } |
577 } |
549 |
578 |
550 /*! |
579 /*! |
551 \deprecated HbMenu::exec(const QPointF&, HbAction*) |
580 \deprecated HbMenu::exec(const QPointF&, HbAction*) |
552 is deprecated. Please use void HbMenu::open( QObject *receiver, const char *member ) |
581 is deprecated. Please use |
553 or HbMenu::show() and setPreferredPos() instead. |
582 void HbMenu::open( QObject *receiver, const char *member ) or |
|
583 HbMenu::show() and setPreferredPos() instead. |
554 |
584 |
555 Executes the menu synchronously at \a pos so that given \a action |
585 Executes the menu synchronously at \a pos so that given \a action |
556 is active. |
586 is active. |
557 |
587 |
558 \param pos is the position at which the menu is shown. |
588 \param pos is the position at which the menu is shown. |
691 HbAction *HbMenu::insertSeparator(HbAction *before) |
721 HbAction *HbMenu::insertSeparator(HbAction *before) |
692 { |
722 { |
693 HbAction *action = new HbAction(this); |
723 HbAction *action = new HbAction(this); |
694 action->setSeparator(true); |
724 action->setSeparator(true); |
695 action->setEnabled(false); |
725 action->setEnabled(false); |
|
726 action->setVisible(false); |
696 insertAction(before, action); |
727 insertAction(before, action); |
697 return action; |
728 return action; |
698 } |
729 } |
699 |
730 |
700 /*! |
731 /*! |
764 */ |
795 */ |
765 QVariant HbMenu::itemChange( GraphicsItemChange change, const QVariant & value ) |
796 QVariant HbMenu::itemChange( GraphicsItemChange change, const QVariant & value ) |
766 { |
797 { |
767 Q_D(HbMenu); |
798 Q_D(HbMenu); |
768 |
799 |
|
800 if (change == QGraphicsItem::ItemSceneHasChanged) { |
|
801 d->closeMenuAfterOrientationChange(); |
|
802 } |
769 if (change == QGraphicsItem::ItemVisibleChange) { |
803 if (change == QGraphicsItem::ItemVisibleChange) { |
770 if (value.toBool() && d->delayMenuConstruction) { |
804 if (value.toBool() && d->delayMenuConstruction) { |
771 d->delayedLayout(); |
805 d->delayedLayout(); |
772 } |
806 } |
773 if (value.toBool()) { |
807 if (value.toBool()) { |
777 else if (!value.toBool() && !d->menuItemView){ |
811 else if (!value.toBool() && !d->menuItemView){ |
778 d->delayMenuConstruction = true; |
812 d->delayMenuConstruction = true; |
779 } |
813 } |
780 } |
814 } |
781 return HbPopup::itemChange(change,value); |
815 return HbPopup::itemChange(change,value); |
782 } |
|
783 |
|
784 /*! |
|
785 \reimp |
|
786 */ |
|
787 void HbMenu::keyPressEvent(QKeyEvent *event) |
|
788 { |
|
789 //TODO: check if non-touch version works with the key bindings below |
|
790 Q_D(HbMenu); |
|
791 switch( event->key() ) { |
|
792 case Qt::Key_Up: |
|
793 case Qt::Key_Down: |
|
794 break; |
|
795 case Qt::Key_Right: |
|
796 layoutDirection() == Qt::LeftToRight |
|
797 ? d->openSubmenu() |
|
798 : d->closeSubmenu(); |
|
799 break; |
|
800 case Qt::Key_Left: |
|
801 layoutDirection() == Qt::LeftToRight |
|
802 ? d->closeSubmenu() |
|
803 : d->openSubmenu(); |
|
804 break; |
|
805 case Qt::Key_Backspace: |
|
806 d->closeSubmenu(); |
|
807 break; |
|
808 case Qt::Key_Escape: |
|
809 close(); |
|
810 break; |
|
811 default: |
|
812 HbPopup::keyPressEvent( event ); |
|
813 break; |
|
814 } |
|
815 } |
|
816 |
|
817 /*! |
|
818 \reimp |
|
819 */ |
|
820 void HbMenu::keyReleaseEvent(QKeyEvent *event) |
|
821 { |
|
822 //TODO do we need this method? |
|
823 QGraphicsWidget::keyReleaseEvent( event ); |
|
824 } |
816 } |
825 |
817 |
826 /*! |
818 /*! |
827 \reimp |
819 \reimp |
828 */ |
820 */ |
844 d->actionChanged(actionEvent); |
836 d->actionChanged(actionEvent); |
845 return true; |
837 return true; |
846 } |
838 } |
847 } |
839 } |
848 if (event->type() == QEvent::LayoutRequest) { |
840 if (event->type() == QEvent::LayoutRequest) { |
849 resize(preferredSize()); |
|
850 if(d->menuItemView) |
841 if(d->menuItemView) |
851 d->menuItemView->contentWidget()->adjustSize(); |
842 d->menuItemView->contentWidget()->adjustSize(); |
|
843 } else if (event->type() == QEvent::GraphicsSceneResize){ |
852 if (d->mSubMenuItem) |
844 if (d->mSubMenuItem) |
853 d->setSubMenuPosition(); |
845 d->setSubMenuPosition(); |
854 } |
846 } |
855 |
847 |
856 return HbPopup::event(event); |
848 return HbPopup::event(event); |
879 } |
871 } |
880 } |
872 } |
881 |
873 |
882 QPainterPath HbMenu::shape() const |
874 QPainterPath HbMenu::shape() const |
883 { |
875 { |
884 QRectF sceneRect = mapRectToScene(boundingRect()); |
876 QRectF sceneRect = mapRectToScene(QRectF(-0.5, -0.5, boundingRect().width() + 0.5, boundingRect().height() + 0.5)); |
885 QRectF clipRect = sceneRect.intersected(geometry()); |
877 QRectF clipRect = sceneRect.intersected(QRectF(pos().x() - 0.5, pos().y() - 0.5, size().width() + 0.5, size().height() + 0.5)); |
886 QPainterPath path; |
878 |
|
879 QPainterPath path; |
887 path.addRect(mapRectFromScene(clipRect)); |
880 path.addRect(mapRectFromScene(clipRect)); |
888 return path; |
881 |
|
882 return path.intersected(HbPopup::shape()); |
889 } |
883 } |
890 |
884 |
891 /*! @alpha |
885 /*! @alpha |
892 * |
886 * |
893 * Opens the menu and returns immediately. |
887 * Opens the menu and returns immediately. |