30 #include "hbtoolbutton_p.h" |
30 #include "hbtoolbutton_p.h" |
31 #include "hbdialog_p.h" |
31 #include "hbdialog_p.h" |
32 #include "hbdeviceprofile.h" |
32 #include "hbdeviceprofile.h" |
33 #include "hbtoolbar_p.h" |
33 #include "hbtoolbar_p.h" |
34 #include "hbmainwindow.h" |
34 #include "hbmainwindow.h" |
|
35 #include "hbstyle_p.h" |
|
36 #include <hbframeitem.h> |
35 #ifdef HB_EFFECTS |
37 #ifdef HB_EFFECTS |
36 #include <hbeffect.h> |
38 #include <hbeffect.h> |
37 #include <hbeffectinternal_p.h> |
39 #include <hbeffectinternal_p.h> |
38 bool HbToolBarExtensionPrivate::extensionEffectsLoaded = false; |
40 bool HbToolBarExtensionPrivate::extensionEffectsLoaded = false; |
39 #endif |
41 #endif |
40 |
42 |
41 #include <QDebug> |
43 #include <QDebug> |
42 #include <QGraphicsGridLayout> |
44 #include <QGraphicsGridLayout> |
43 #include <QEventLoop> |
45 #include <QEventLoop> |
44 #include <QGraphicsLinearLayout> |
46 #include <QGraphicsLinearLayout> |
45 |
47 |
46 /*! |
48 /*! |
47 @stable |
49 @stable |
48 @hbcore |
50 @hbcore |
49 \class HbToolBarExtension |
51 \class HbToolBarExtension |
50 |
52 \brief The HbToolBarExtension class provides a popup extension to a toolbar. |
51 \brief HbToolBarExtension is a popup style component that adds |
53 |
52 extra functionality to an HbToolBar. A toolbar can contain more |
54 You can use a toolbar extension to extend the main toolbar |
53 than one toolbar extension. An extension popup is opened when a |
55 (HbToolBar class) in a view with additional actions that are placed |
54 toolbar button with associated with the extension is triggered. |
56 in a subsidiary toolbar. Alternatively, a toolbar extension can |
55 |
57 contain a widget, such as a list or grid. This is useful, for |
56 A toolbar extension uses the QGraphicsWidget action API to manage |
58 example, for providing navigation between views when there are more |
57 buttons. In addition the HbDialog API can be used to fill the |
59 views than can fit as actions on the toolbar itself. |
58 extension popup with custom widgets (e.g. list or line edit). If |
60 |
59 custom content widget is set, buttons generated based on actions |
61 A toolbar can contain more than one toolbar extension. A toolbar |
60 will not be visible. |
62 extension opens when the user triggers the toolbar action that is |
61 |
63 associated with the extension, usually by tapping it. The user |
62 An example of how to add a toolbar extension button to the toolbar: |
64 dismisses the toolbar extension by selecting an option (which runs a |
63 \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,27} |
65 command) or by tapping outside the extension. |
64 */ |
66 |
65 |
67 The following image shows a toolbar that has two extensions: the |
66 /*! |
68 leftmost one contains a list widget and the rightmost one contains |
67 \reimp |
69 three standard actions. |
68 \fn int HbToolBarExtension::type() const |
70 |
69 */ |
71 \image html toolbarextension.png A toolbar that has two extensions |
70 |
72 |
71 /*! |
73 Use addAction() to create an action and add it to the toolbar |
|
74 extension. There are several overloads of this function, which allow |
|
75 you to specify both a text and image or just a text and also to |
|
76 connect the action's \link HbAction::triggered() triggered()\endlink |
|
77 signal to a slot on a receiver object. Use the insertAction(), |
|
78 addActions() and insertActions() methods (which are inherited from |
|
79 QGraphicsWidget) to add existing actions to the toolbar |
|
80 extension. Use clearActions() to clear all of the actions and |
|
81 removeAction() to remove individual actions. |
|
82 |
|
83 The order of the actions within the toolbar extension controls the |
|
84 order of the buttons that the user sees. addAction() and |
|
85 addActions() append the actions to the end of the toolbar and |
|
86 insertAction() and insertActions() enable you to specify the |
|
87 required position. |
|
88 |
|
89 You can use the HbDialog API to fill the toolbar extension popup |
|
90 with widgets (such as a list, grid or line edit). If you do this, |
|
91 any actions that you add to the toolbar extension will not be |
|
92 visible. |
|
93 |
|
94 \section _usecases_hbtoolbarextension Using the HbToolBarExtension class |
|
95 |
|
96 \subsection _uc_001_hbtoolbarextension Creating a toolbar extension containing actions |
|
97 The following example demonstrates how to add a toolbar extension button to the toolbar |
|
98 and how to add actions to the toolbar extension. |
|
99 \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,27} |
|
100 |
|
101 \subsection _uc_002_hbtoolbarextension Creating a toolbar extension containing a widget |
|
102 |
|
103 The following example demonstrates creating a toolbar extension containing a single-selection |
|
104 list widget. |
|
105 |
|
106 \code |
|
107 // Create the toolbar. |
|
108 HbToolBar *toolBar = new HbToolBar(); |
|
109 |
|
110 // Add the action that will open the toolbar extension. |
|
111 HbAction *radioAction = toolBar->addAction("Channel"); |
|
112 |
|
113 // Create the toolbar extension. |
|
114 HbToolBarExtension *radioExtension = new HbToolBarExtension(); |
|
115 |
|
116 // Set the heading. |
|
117 HbLabel* heading = new HbLabel(QString("Channel")); |
|
118 radioExtension->setHeadingWidget(heading); |
|
119 |
|
120 // Create a list widget. |
|
121 HbListWidget *list = new HbListWidget(); |
|
122 list->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); |
|
123 |
|
124 // Make the list single selection. |
|
125 list->setSelectionMode(HbAbstractItemView::SingleSelection); |
|
126 |
|
127 // Add list items. |
|
128 list->addItem("574.7"); |
|
129 list->addItem("976.5"); |
|
130 list->addItem("108.67"); |
|
131 |
|
132 // Add the list widget to the toolbar extension object. |
|
133 radioExtension->setContentWidget(list); |
|
134 |
|
135 // Add the toolbar extension to the toolbar action that will open it. |
|
136 radioAction->setToolBarExtension(radioExtension); |
|
137 \endcode |
|
138 */ |
|
139 |
|
140 /*! |
|
141 \fn int HbToolBarExtension::type() const |
|
142 */ |
|
143 |
|
144 /* |
72 \primitives |
145 \primitives |
73 \primitive{background} HbFrameItem representing the extension background. |
146 \primitive{background} HbFrameItem representing the extension background. |
74 */ |
147 */ |
75 |
148 |
76 HbToolBarExtensionPrivate::HbToolBarExtensionPrivate() : |
149 HbToolBarExtensionPrivate::HbToolBarExtensionPrivate() : |
77 HbDialogPrivate(), |
150 HbDialogPrivate(), |
78 mToolButtons(), |
151 mToolButtons(), |
79 mLayout(0), |
152 mLayout(0), |
80 extensionAction(0), |
153 extensionAction(0), |
81 mAlignment(Qt::AlignTop), |
154 mAlignment(Qt::AlignTop), |
82 mDefaultContentWidget(false), |
155 mDefaultContentWidget(false), |
83 // default values, in case CSS parsing fails |
156 // default values, in case CSS parsing fails |
84 mMargins(0), |
157 mRowsPortrait(4), |
85 mRowsPortrait(4), |
158 mRowsLandscape(3), |
86 mRowsLandscape(3), |
159 mColsPortrait(3), |
87 mColsPortrait(3), |
160 mColsLandscape(4), |
88 mColsLandscape(4), |
161 lazyInitDone(false), |
89 lazyInitDone(false), |
162 orientationConnectDone(false), |
90 orientationConnectDone(false), |
163 mExtendedButton(0), |
91 // |
164 mToolBar(0) |
92 mExtendedButton(0), |
165 { |
93 mToolBar(0) |
166 frameType = HbPopup::Weak; |
94 { |
|
95 } |
167 } |
96 |
168 |
97 HbToolBarExtensionPrivate::~HbToolBarExtensionPrivate() |
169 HbToolBarExtensionPrivate::~HbToolBarExtensionPrivate() |
98 { |
170 { |
99 } |
171 } |
157 foreach (HbToolButton* button, mToolButtons) { |
235 foreach (HbToolButton* button, mToolButtons) { |
158 button->setVisible(HbToolButtonPrivate::d_ptr(button)->action->isVisible()); |
236 button->setVisible(HbToolButtonPrivate::d_ptr(button)->action->isVisible()); |
159 } |
237 } |
160 |
238 |
161 mLayout = new QGraphicsGridLayout(); |
239 mLayout = new QGraphicsGridLayout(); |
162 mLayout->setContentsMargins( mMargins, mMargins, mMargins, mMargins ); |
240 mLayout->setContentsMargins(0, 0, 0, 0); |
163 mLayout->setSpacing(0.0); // if non zero spacing needed, add to css |
241 mLayout->setSpacing(0.0); // if non zero spacing needed, add to css |
164 for ( int i(0), j(0), ie(mToolButtons.count()); i < ie; ++i ) { |
242 for ( int i(0), j(0), ie(mToolButtons.count()); i < ie; ++i ) { |
165 HbToolButton *button = mToolButtons.at(i); |
243 HbToolButton *button = mToolButtons.at(i); |
166 if ( HbToolButtonPrivate::d_ptr(button)->action->isVisible() ) { |
244 if ( HbToolButtonPrivate::d_ptr(button)->action->isVisible() ) { |
167 // Calculate the row and column indices |
245 // Calculate the row and column indices |
222 QObject::connect(event->action(), SIGNAL(triggered()), button, SLOT(_q_actionTriggered())); |
300 QObject::connect(event->action(), SIGNAL(triggered()), button, SLOT(_q_actionTriggered())); |
223 QObject::connect(event->action(), SIGNAL(changed()), button, SLOT(_q_actionChanged())); |
301 QObject::connect(event->action(), SIGNAL(changed()), button, SLOT(_q_actionChanged())); |
224 } |
302 } |
225 |
303 |
226 if ((hbAction && !hbAction->icon().isNull()) || !event->action()->icon().isNull()) { |
304 if ((hbAction && !hbAction->icon().isNull()) || !event->action()->icon().isNull()) { |
227 if (HbToolButtonPrivate::d_ptr(button)->action->text().isEmpty()) { |
305 q->setProperty("icon", true); |
228 button->setToolButtonStyle(HbToolButton::ToolButtonIcon); |
|
229 } else { |
|
230 button->setToolButtonStyle(HbToolButton::ToolButtonTextAndIcon); |
|
231 } |
|
232 } else { |
306 } else { |
233 button->setToolButtonStyle(HbToolButton::ToolButtonText); |
307 q->setProperty("icon", false); |
|
308 } |
|
309 if (!HbToolButtonPrivate::d_ptr(button)->action->text().isEmpty()) { |
|
310 q->setProperty("text", true); |
|
311 } else { |
|
312 q->setProperty("text", false); |
234 } |
313 } |
235 |
314 |
236 button->setProperty("toolbutton_extension_layout", true); |
315 button->setProperty("toolbutton_extension_layout", true); |
237 button->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, |
316 button->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, |
238 QSizePolicy::Preferred) ); |
317 QSizePolicy::Preferred) ); |
338 Destructor. |
421 Destructor. |
339 */ |
422 */ |
340 HbToolBarExtension::~HbToolBarExtension() |
423 HbToolBarExtension::~HbToolBarExtension() |
341 { |
424 { |
342 } |
425 } |
343 |
426 |
344 /*! |
427 |
345 \overload |
428 /*! |
346 |
429 Creates a new action with the given \a text and adds the action |
347 Creates a new action with the given \a text. |
430 to the end of the toolbar extension, provided space is |
348 This action is added to the end of the toolbar extension. |
431 available. The space available in a toolbar extension depends on the |
349 TODO: If the grid is already full, this call will be ignored. |
432 screen size and orientation. When there is no free space, this |
350 TODO: Find a way to notificate the caller. |
433 function does nothing. There is currently no notification when there |
|
434 is no free space. |
|
435 |
|
436 \overload |
|
437 \return The new action. |
351 */ |
438 */ |
352 HbAction *HbToolBarExtension::addAction( const QString &text ) |
439 HbAction *HbToolBarExtension::addAction( const QString &text ) |
353 { |
440 { |
354 HbAction *action = new HbAction( text, this ); |
441 HbAction *action = new HbAction( text, this ); |
355 addAction(action); |
442 addAction(action); |
356 return action; |
443 return action; |
357 } |
444 } |
358 |
445 |
359 /*! |
446 |
360 \overload |
447 /*! |
361 |
448 Creates a new action with the given \a icon and \a text and adds |
362 Creates a new action with the given \a icon and \a text. |
449 the action to the end of the toolbar extension, provided space is |
363 This action is added to the end of the toolbar extension. |
450 available. The space available in a toolbar extension depends on the |
364 TODO: If the grid is already full, this call will be ignored. |
451 screen size and orientation. When there is no free space, this |
365 TODO: Find a way to notificate the caller. |
452 function does nothing. There is currently no notification when there |
|
453 is no free space. |
|
454 |
|
455 \overload |
|
456 \return The new action. |
366 */ |
457 */ |
367 HbAction *HbToolBarExtension::addAction( const HbIcon &icon, |
458 HbAction *HbToolBarExtension::addAction( const HbIcon &icon, |
368 const QString &text ) |
459 const QString &text ) |
369 { |
460 { |
370 HbAction *action = new HbAction( icon, text, this ); |
461 HbAction *action = new HbAction( icon, text, this ); |
371 addAction(action); |
462 addAction(action); |
372 return action; |
463 return action; |
373 } |
464 } |
374 |
465 |
375 /*! |
466 |
376 \overload |
467 /*! |
377 |
468 Creates a new action with the given \a text, adds the action to |
378 Creates a new action with the given \a text. |
469 the end of the toolbar extension (provided space is available), and |
379 This action is added to the end of the toolbar extension. |
470 connects the action's \link HbAction::triggered() |
380 TODO: If the grid is already full, this call will be ignored. |
471 triggered()\endlink signal to a receiver object's slot. |
381 The action's \link HbAction::triggered() |
472 |
382 triggered()\endlink signal is connected to \a member in \a |
473 The space available in a toolbar extension depends on the screen |
383 receiver. |
474 size and orientation. When there is no free space, this function |
384 TODO: Find a way to notificate the caller. |
475 does not add the action to the toolbar extension. There is currently |
385 */ |
476 no notification when there is no free space. |
386 HbAction *HbToolBarExtension::addAction( const QString &text, |
477 |
387 const QObject *receiver, |
478 \overload |
|
479 \param text The text for the new action. |
|
480 \param receiver The object that is to receive the new action's signal. |
|
481 \param member The slot on the receiver to which the action's signal is to connect. |
|
482 \return The new action. |
|
483 */ |
|
484 HbAction *HbToolBarExtension::addAction( const QString &text, |
|
485 const QObject *receiver, |
388 const char *member ) |
486 const char *member ) |
389 { |
487 { |
390 HbAction *action = new HbAction( text, this ); |
488 HbAction *action = new HbAction( text, this ); |
391 QObject::connect( action, SIGNAL( triggered(bool) ), receiver, member ); |
489 QObject::connect( action, SIGNAL( triggered(bool) ), receiver, member ); |
392 addAction(action); |
490 addAction(action); |
393 return action; |
491 return action; |
394 } |
492 } |
395 |
493 |
396 /*! |
494 /*! |
397 \overload |
495 Creates a new action with the given \a icon and \a text, adds the |
398 |
496 action to the end of the toolbar extension (provided space is |
399 Creates a new action with the given \a icon and \a text. |
497 available), and connects the action's \link HbAction::triggered() |
400 This action is added to the end of the toolbar extension. |
498 triggered()\endlink signal to a receiver object's slot. |
401 TODO: If the grid is already full, this call will be ignored. |
499 |
402 The action's \link HbAction::triggered() |
500 The space available in a toolbar extension depends on the screen |
403 triggered()\endlink signal is connected to \a member in \a |
501 size and orientation. When there is no free space, this function |
404 receiver. |
502 does not add the action to the toolbar extension. There is currently |
405 TODO: Find a way to notificate the caller. |
503 no notification when there is no free space. |
|
504 |
|
505 \overload |
|
506 \param icon The image for the new action. |
|
507 \param text The text for the new action. |
|
508 \param receiver The object that is to receive the new action's signal. |
|
509 \param member The slot on the receiver to which the action's signal is to connect. |
|
510 \return The new action. |
406 */ |
511 */ |
407 HbAction *HbToolBarExtension::addAction( const HbIcon &icon, |
512 HbAction *HbToolBarExtension::addAction( const HbIcon &icon, |
408 const QString &text, |
513 const QString &text, |
409 const QObject *receiver, |
514 const QObject *receiver, |
410 const char *member ) |
515 const char *member ) |
453 } |
560 } |
454 return HbDialog::event(event); |
561 return HbDialog::event(event); |
455 } |
562 } |
456 |
563 |
457 /*! |
564 /*! |
458 \reimp |
565 |
459 */ |
566 */ |
460 void HbToolBarExtension::polish( HbStyleParameters ¶ms ) |
567 void HbToolBarExtension::polish( HbStyleParameters ¶ms ) |
461 { |
568 { |
462 Q_D(HbToolBarExtension); |
569 if (isVisible()) { |
463 d->doLazyInit(); |
570 Q_D(HbToolBarExtension); |
464 const QString Margins = "content-margins"; |
571 d->doLazyInit(); |
465 const QString RowsPortrait = "max-rows-portrait"; |
572 const QLatin1String RowsPortrait("max-rows-portrait"); |
466 const QString RowsLandscape = "max-rows-landscape"; |
573 const QLatin1String RowsLandscape("max-rows-landscape"); |
467 const QString ColsPortrait = "max-columns-portrait"; |
574 const QLatin1String ColsPortrait("max-columns-portrait"); |
468 const QString ColsLandscape = "max-columns-landscape"; |
575 const QLatin1String ColsLandscape("max-columns-landscape"); |
469 |
576 |
470 params.addParameter( Margins ); |
577 params.addParameter( RowsPortrait ); |
471 params.addParameter( RowsPortrait ); |
578 params.addParameter( RowsLandscape ); |
472 params.addParameter( RowsLandscape ); |
579 params.addParameter( ColsPortrait ); |
473 params.addParameter( ColsPortrait ); |
580 params.addParameter( ColsLandscape ); |
474 params.addParameter( ColsLandscape ); |
581 d->initialiseContent(); |
475 d->initialiseContent(); |
582 if (d->mDefaultContentWidget) { |
476 if (d->mDefaultContentWidget) { |
583 HbDialog::polish(params); |
477 HbDialog::polish(params); |
584 if ( params.value( RowsPortrait ).isValid() |
478 if ( params.value( Margins ).isValid() |
585 && params.value( RowsLandscape ).isValid() |
479 && params.value( RowsPortrait ).isValid() |
586 && params.value( ColsPortrait ).isValid() |
480 && params.value( RowsLandscape ).isValid() |
587 && params.value( ColsLandscape ).isValid() ) { |
481 && params.value( ColsPortrait ).isValid() |
588 d->mRowsPortrait = params.value( RowsPortrait ).toInt(); |
482 && params.value( ColsLandscape ).isValid() ) { |
589 d->mRowsLandscape = params.value( RowsLandscape ).toInt(); |
483 d->mMargins = params.value( Margins ).toReal(); |
590 d->mColsPortrait = params.value( ColsPortrait ).toInt(); |
484 d->mRowsPortrait = params.value( RowsPortrait ).toInt(); |
591 d->mColsLandscape = params.value( ColsLandscape ).toInt(); |
485 d->mRowsLandscape = params.value( RowsLandscape ).toInt(); |
592 d->doLayout(); |
486 d->mColsPortrait = params.value( ColsPortrait ).toInt(); |
593 } |
487 d->mColsLandscape = params.value( ColsLandscape ).toInt(); |
594 return; |
488 d->doLayout(); |
595 } |
489 } |
596 } |
490 } else { |
597 HbDialog::polish(params); |
491 HbDialog::polish(params); |
|
492 } |
|
493 } |
598 } |
494 |
599 |
495 QVariant HbToolBarExtension::itemChange(GraphicsItemChange change, |
600 QVariant HbToolBarExtension::itemChange(GraphicsItemChange change, |
496 const QVariant &value) |
601 const QVariant &value) |
497 { |
602 { |
498 Q_D(HbToolBarExtension); |
603 Q_D(HbToolBarExtension); |
499 if (change == QGraphicsItem::ItemVisibleHasChanged) { |
604 if (change == QGraphicsItem::ItemVisibleHasChanged) { |
500 if (value.toBool()) { |
605 if (value.toBool()) { |
501 HbMainWindow* w(mainWindow()); |
606 HbMainWindow* w(mainWindow()); |
502 if(w && !d->orientationConnectDone) { |
607 if(w && !d->orientationConnectDone) { |
503 QObject::connect(w,SIGNAL(orientationChanged(Qt::Orientation)), |
608 QObject::disconnect( w , SIGNAL(aboutToChangeOrientation()), this, SLOT(_q_orientationChanged())); |
504 this, SLOT(_q_orientationChanged())); |
609 QObject::connect( w , SIGNAL(aboutToChangeOrientation()), this, SLOT(_q_orientationChanged())); |
505 d->orientationConnectDone = true; |
610 d->orientationConnectDone = true; |
506 } |
611 } |
507 d->placeToolBarExtension(); |
612 d->placeToolBarExtension(); |
508 } |
613 } |
509 } |
614 } |
510 |
615 |
511 return HbDialog::itemChange(change, value); |
616 return HbDialog::itemChange(change, value); |
512 } |
617 } |
513 |
618 |
|
619 void HbToolBarExtension::initPrimitiveData(HbStylePrimitiveData *primitiveData, |
|
620 const QGraphicsObject *primitive) |
|
621 { |
|
622 Q_D(HbToolBarExtension); |
|
623 HbDialog::initPrimitiveData(primitiveData, primitive); |
|
624 QString itemName = HbStyle::itemName(primitive); |
|
625 if (itemName == QLatin1String("background")) { |
|
626 HbStyleFramePrimitiveData *data = hbstyleprimitivedata_cast<HbStyleFramePrimitiveData*>(primitiveData); |
|
627 data->frameGraphicsName = d->frameType == HbPopup::Strong ? |
|
628 QLatin1String("qtg_fr_popup") : |
|
629 QLatin1String("qtg_fr_popup_trans"); |
|
630 data->frameType = HbFrameDrawer::NinePieces; |
|
631 } |
|
632 } |
|
633 |
|
634 void HbToolBarExtensionPrivate::doSetFrameType(HbPopup::FrameType newFrameType) |
|
635 { |
|
636 Q_Q(HbToolBarExtension); |
|
637 switch( newFrameType ) { |
|
638 case HbPopup::Weak: |
|
639 q->setBackgroundItem(new HbFrameItem(QLatin1String("qtg_fr_popup_trans"), HbFrameDrawer::NinePieces), -1); |
|
640 break; |
|
641 case HbPopup::Strong: |
|
642 default: |
|
643 q->setBackgroundItem(new HbFrameItem(QLatin1String("qtg_fr_popup"), HbFrameDrawer::NinePieces), -1); |
|
644 break; |
|
645 } |
|
646 |
|
647 } |
514 #include "moc_hbtoolbarextension.cpp" |
648 #include "moc_hbtoolbarextension.cpp" |