29 #include <hbtoolbutton.h> |
29 #include <hbtoolbutton.h> |
30 #include <hbabstractbutton.h> |
30 #include <hbabstractbutton.h> |
31 #include <hbabstractedit.h> |
31 #include <hbabstractedit.h> |
32 #include <hbtextedit.h> |
32 #include <hbtextedit.h> |
33 #include <hblineedit.h> |
33 #include <hblineedit.h> |
34 #include <hbinputvirtualrocker.h> |
|
35 #include <hbabstractslidercontrol.h> |
34 #include <hbabstractslidercontrol.h> |
36 #include <hbprogressslider.h> |
35 #include <hbprogressslider.h> |
37 #include <hbscrollbar.h> |
36 #include <hbscrollbar.h> |
38 #include <hbabstractviewitem.h> |
37 #include <hbabstractviewitem.h> |
39 #include <hbabstractitemview.h> |
38 #include <hbabstractitemview.h> |
62 /*! |
61 /*! |
63 Finds out the graphics item type of the parent widget. |
62 Finds out the graphics item type of the parent widget. |
64 */ |
63 */ |
65 int HbFeedbackEffectUtils::parentItemType(const HbWidget *widget) |
64 int HbFeedbackEffectUtils::parentItemType(const HbWidget *widget) |
66 { |
65 { |
67 int graphicsItemType = 0; |
66 QGraphicsItem *parent = widget->parentItem(); |
68 if (const HbWidget *parent = dynamic_cast<const HbWidget *>(widget->parentItem())) { |
67 if(parent) |
69 graphicsItemType = parent->type(); |
68 return parent->type(); |
70 } |
69 else |
71 return graphicsItemType; |
70 return 0; |
72 } |
71 } |
73 |
72 |
74 /*! |
73 /*! |
75 Returns the widget family for a widget. |
74 Returns the widget family for a widget. |
76 */ |
75 */ |
266 if (widget->type() == HbPrivate::ItemType_TitlePane) { |
265 if (widget->type() == HbPrivate::ItemType_TitlePane) { |
267 if (isOptionsMenuEmpty(widget)) { |
266 if (isOptionsMenuEmpty(widget)) { |
268 effect = HbFeedback::None; |
267 effect = HbFeedback::None; |
269 } |
268 } |
270 } |
269 } |
|
270 |
|
271 if (widget->type() == Hb::ItemType_ComboBox) { |
|
272 effect = HbFeedback::BasicButton; |
|
273 } |
|
274 |
271 break; |
275 break; |
272 |
276 |
273 case HbFeedbackEffectUtils::List: |
277 case HbFeedbackEffectUtils::List: |
274 if (modifiers & (Hb::ModifierExpandedItem | Hb::ModifierCollapsedItem)) { |
278 if (modifiers & (Hb::ModifierExpandedItem | Hb::ModifierCollapsedItem)) { |
275 effect = HbFeedback::BasicItem; |
279 effect = HbFeedback::BasicItem; |
276 } |
280 } |
277 else { |
281 else { |
278 effect = HbFeedback::BasicItem; |
282 effect = HbFeedback::BasicItem; |
279 } |
283 } |
280 if (widget->type() == Hb::ItemType_DataFormViewItem) { |
284 if (widget->type() == Hb::ItemType_DataFormViewItem || |
281 effect = HbFeedback::SensitiveItem; |
285 widget->type() == HbPrivate::ItemType_DataGroup) { |
282 } |
|
283 else if (widget->type() == HbPrivate::ItemType_DataGroup) { |
|
284 effect = HbFeedback::None; |
286 effect = HbFeedback::None; |
285 } |
287 } |
286 |
|
287 break; |
288 break; |
288 |
289 |
289 case HbFeedbackEffectUtils::Grid: |
290 case HbFeedbackEffectUtils::Grid: |
290 effect = HbFeedback::BasicItem; |
291 effect = HbFeedback::BasicItem; |
291 break; |
292 break; |
324 effect = HbFeedback::None; |
325 effect = HbFeedback::None; |
325 } |
326 } |
326 break; |
327 break; |
327 |
328 |
328 case HbFeedbackEffectUtils::Editor: |
329 case HbFeedbackEffectUtils::Editor: |
329 effect = HbFeedback::Editor; |
330 if (const HbAbstractEdit* editor = qobject_cast<const HbAbstractEdit *>(widget)) { |
|
331 if(editor->isReadOnly() && (Hb::TextCursorHidden == editor->cursorVisibility())) { |
|
332 // cannot edit nor select |
|
333 effect = HbFeedback::None; |
|
334 } else { |
|
335 effect = HbFeedback::Editor; |
|
336 } |
|
337 } |
330 break; |
338 break; |
331 |
339 |
332 default: |
340 default: |
333 break; |
341 break; |
334 } |
342 } |
339 if (itemView) { |
347 if (itemView) { |
340 // Different press feedbacks for single and multiselection list items |
348 // Different press feedbacks for single and multiselection list items |
341 switch (itemView->selectionMode()) { |
349 switch (itemView->selectionMode()) { |
342 case HbAbstractItemView::SingleSelection: |
350 case HbAbstractItemView::SingleSelection: |
343 case HbAbstractItemView::MultiSelection: { |
351 case HbAbstractItemView::MultiSelection: { |
344 effect = HbFeedback::BasicButton; |
352 effect = HbFeedback::BasicItem; |
345 break; |
353 break; |
346 } |
354 } |
347 case HbAbstractItemView::NoSelection: |
355 case HbAbstractItemView::NoSelection: |
348 if (const HbListView * listView = qobject_cast<const HbListView *>(itemView)) { |
356 if (const HbListView * listView = qobject_cast<const HbListView *>(itemView)) { |
349 if (listView->arrangeMode() |
357 if (listView->arrangeMode() |
358 |
366 |
359 // radio button list behaves like an item view on press |
367 // radio button list behaves like an item view on press |
360 if (viewItem->type() == Hb::ItemType_RadioButtonListViewItem) { |
368 if (viewItem->type() == Hb::ItemType_RadioButtonListViewItem) { |
361 effect = HbFeedback::BasicItem; |
369 effect = HbFeedback::BasicItem; |
362 } |
370 } |
363 else if(viewItem->type() == Hb::ItemType_TumbleViewItem ) { |
371 else if(viewItem->type() == Hb::ItemType_DatePickerViewItem || |
364 effect = HbFeedback::BasicItem; |
372 viewItem->type() == Hb::ItemType_TumbleViewItem) { |
|
373 effect = HbFeedback::None; |
365 } |
374 } |
366 |
375 |
367 // expandable or collapsable items give a BasicItem feedback |
376 // expandable or collapsable items give a BasicItem feedback |
368 if (const HbTreeViewItem* treeItem = qobject_cast<const HbTreeViewItem *>(widget)) { |
377 if (const HbTreeViewItem* treeItem = qobject_cast<const HbTreeViewItem *>(widget)) { |
369 if (itemView->model()->rowCount(treeItem->modelIndex()) > 0) { |
378 if (itemView->model()->rowCount(treeItem->modelIndex()) > 0) { |
370 effect = HbFeedback::BasicItem; |
379 effect = HbFeedback::BasicItem; |
371 } |
380 } |
372 else { |
381 else { |
373 effect = HbFeedback::BasicItem; |
382 effect = HbFeedback::BasicItem; |
374 } |
383 } |
|
384 } |
|
385 // Combo box drop down list |
|
386 if (QString(widget->metaObject()->className()) == "HbComboListViewItem") { |
|
387 effect = HbFeedback::BasicItem; |
375 } |
388 } |
376 } |
389 } |
377 } |
390 } |
378 |
391 |
379 if (widget->type() == Hb::ItemType_VirtualTrackPoint || QString(widget->metaObject()->className()) == "HbSelectionControl") { |
392 if (widget->type() == Hb::ItemType_VirtualTrackPoint || QString(widget->metaObject()->className()) == "HbSelectionControl") { |
466 effect = HbFeedback::None; |
479 effect = HbFeedback::None; |
467 } |
480 } |
468 else if (widget->type() == Hb::ItemType_DataFormViewItem) { |
481 else if (widget->type() == Hb::ItemType_DataFormViewItem) { |
469 effect = HbFeedback::None; |
482 effect = HbFeedback::None; |
470 } |
483 } |
|
484 |
471 break; |
485 break; |
472 |
486 |
473 case HbFeedbackEffectUtils::Grid: |
487 case HbFeedbackEffectUtils::Grid: |
474 effect = HbFeedback::BasicItem; |
488 if (widget->type() == HbPrivate::ItemType_ColorGridViewItem) { |
|
489 effect = HbFeedback::None; |
|
490 } |
|
491 else { |
|
492 effect = HbFeedback::BasicItem; |
|
493 } |
475 break; |
494 break; |
476 |
495 |
477 case HbFeedbackEffectUtils::Slider: |
496 case HbFeedbackEffectUtils::Slider: |
478 |
497 |
479 // slider track default |
498 if (widget->type() == Hb::ItemType_ScrollBar) { |
480 effect = HbFeedback::BasicSlider; |
499 effect = HbFeedback::None; |
481 |
500 } |
|
501 else { // slider track default |
|
502 effect = HbFeedback::BasicSlider; |
|
503 } |
482 // slider handle |
504 // slider handle |
483 if (modifiers & Hb::ModifierSliderHandle) { |
505 if (modifiers & Hb::ModifierSliderHandle) { |
484 effect = HbFeedback::BasicSlider; |
506 effect = HbFeedback::BasicSlider; |
485 } |
507 } |
486 |
508 |
487 // slider elements |
509 // slider elements |
488 if (modifiers & Hb::ModifierSliderElement) { |
510 if (modifiers & Hb::ModifierSliderElement) { |
489 effect = HbFeedback::None; |
511 effect = HbFeedback::None; |
490 } |
512 } |
|
513 |
491 break; |
514 break; |
492 |
515 |
493 case HbFeedbackEffectUtils::Editor: |
516 case HbFeedbackEffectUtils::Editor: |
494 effect = HbFeedback::None; |
517 effect = HbFeedback::None; |
495 break; |
518 break; |
530 |
553 |
531 // radio button list has checkbox feedback behaviour on release |
554 // radio button list has checkbox feedback behaviour on release |
532 if (viewItem->type() == Hb::ItemType_RadioButtonListViewItem) { |
555 if (viewItem->type() == Hb::ItemType_RadioButtonListViewItem) { |
533 effect = HbFeedback::Checkbox; |
556 effect = HbFeedback::Checkbox; |
534 } |
557 } |
535 else if(viewItem->type() == Hb::ItemType_TumbleViewItem ) { |
558 else if(viewItem->type() == Hb::ItemType_DatePickerViewItem || |
|
559 viewItem->type() == Hb::ItemType_TumbleViewItem) { |
536 effect = HbFeedback::BasicItem; |
560 effect = HbFeedback::BasicItem; |
537 } |
561 } |
538 else if (widget->type() == Hb::ItemType_NotificationDialog) { |
562 else if (widget->type() == Hb::ItemType_NotificationDialog) { |
539 effect = HbFeedback::BasicItem; |
563 effect = HbFeedback::BasicItem; |
540 } |
564 } |
541 |
565 |
542 if (modifiers & Hb::ModifierExpandedItem || modifiers & Hb::ModifierCollapsedItem) { |
566 if (modifiers & Hb::ModifierExpandedItem || modifiers & Hb::ModifierCollapsedItem) { |
543 effect = HbFeedback::BasicItem; |
567 effect = HbFeedback::BasicItem; |
544 } |
568 } |
|
569 |
|
570 // Combo box drop down list |
|
571 if (QString(widget->metaObject()->className()) == "HbComboListViewItem") { |
|
572 effect = HbFeedback::None; |
|
573 } |
545 } |
574 } |
546 } |
575 } |
547 |
576 |
548 return effect; |
577 return effect; |
549 } |
578 } |
565 case HbFeedbackEffectUtils::Button: |
594 case HbFeedbackEffectUtils::Button: |
566 effect = HbFeedback::SensitiveButton; |
595 effect = HbFeedback::SensitiveButton; |
567 |
596 |
568 // input widget special case |
597 // input widget special case |
569 if (widget->type() == Hb::ItemType_InputButtonGroup && modifiers & Hb::ModifierInputFunctionButton) { |
598 if (widget->type() == Hb::ItemType_InputButtonGroup && modifiers & Hb::ModifierInputFunctionButton) { |
570 effect = HbFeedback::BasicKeypad; |
599 effect = HbFeedback::SensitiveKeypad; |
571 } |
600 } |
572 else if (widget->type() == Hb::ItemType_InputButtonGroup) { |
601 else if (widget->type() == Hb::ItemType_InputButtonGroup) { |
573 effect = HbFeedback::SensitiveKeypad; |
602 effect = HbFeedback::SensitiveKeypad; |
574 } |
603 } |
575 |
604 |
689 else { |
718 else { |
690 effect = HbFeedback::TextSelection; |
719 effect = HbFeedback::TextSelection; |
691 } |
720 } |
692 } |
721 } |
693 } |
722 } |
694 else if (const HbInputVirtualRocker *trackPoint = qobject_cast<const HbInputVirtualRocker *>(widget)) { |
723 |
695 |
|
696 QGraphicsItem* graphicsItem = trackPoint->mainWindow()->scene()->focusItem(); |
|
697 |
|
698 if (graphicsItem->isWidget() && (static_cast<QGraphicsWidget*>(graphicsItem)->inherits("QGraphicsWebView"))) { |
|
699 QVariant v; |
|
700 v = graphicsItem->scene()->inputMethodQuery( Qt::ImCursorPosition ); |
|
701 if ( v.isValid() && v.canConvert<int>()) { |
|
702 int index; |
|
703 index = v.toInt(); |
|
704 QVariant varSurrText; |
|
705 varSurrText = graphicsItem->scene()->inputMethodQuery( Qt::ImSurroundingText ); |
|
706 if ( varSurrText.isValid() ) { |
|
707 QString text = varSurrText.toString(); |
|
708 // Index (current cursor position) can be equal to the |
|
709 // length of the string (for e.g. when the cursor is at the end) |
|
710 // So we make sure we bring index within the bounds of the string |
|
711 if (!text.isEmpty() && index <= text.count()) { |
|
712 dist = abs(index - previousCursorPosition); |
|
713 |
|
714 if (previousCursorPosition < index || index == text.count()) { |
|
715 index--; |
|
716 } |
|
717 QChar character = text.at(index); |
|
718 emptyline = character.category() == QChar::Separator_Paragraph; |
|
719 |
|
720 if (emptyline) { |
|
721 effect = HbFeedback::EmptyLineSelection; |
|
722 } |
|
723 else if (dist > 1) { |
|
724 effect = HbFeedback::LineSelection; |
|
725 } |
|
726 else if (character.isSpace()) { |
|
727 effect = HbFeedback::BlankSelection; |
|
728 } |
|
729 else { |
|
730 effect = HbFeedback::TextSelection; |
|
731 } |
|
732 } |
|
733 } |
|
734 } |
|
735 } |
|
736 } |
|
737 return effect; |
724 return effect; |
738 } |
725 } |
739 |
726 |
740 /*! |
727 /*! |
741 Checks if feedback is allowed for certain types of popup widgets. |
728 Checks if feedback is allowed for certain types of popup widgets. |
818 // Single selection is handled with a release |
805 // Single selection is handled with a release |
819 effect = HbFeedback::None; |
806 effect = HbFeedback::None; |
820 break; |
807 break; |
821 } |
808 } |
822 case HbAbstractItemView::MultiSelection: { |
809 case HbAbstractItemView::MultiSelection: { |
823 effect = HbFeedback::Checkbox; |
810 if (modifiers & Hb::ModifierScrolling) { |
|
811 effect = HbFeedback::MultipleCheckbox; |
|
812 } |
|
813 else { |
|
814 effect = HbFeedback::Checkbox; |
|
815 } |
824 break; |
816 break; |
825 } |
817 } |
826 default: |
818 default: |
827 break; |
819 break; |
828 } |
820 } |
829 } |
|
830 } |
|
831 else if (const HbAbstractItemView* itemView = qobject_cast<const HbAbstractItemView*>(widget)) { |
|
832 if (itemView->selectionMode() == HbAbstractItemView::MultiSelection && (modifiers & Hb::ModifierScrolling)) { |
|
833 effect = HbFeedback::MultipleCheckbox; |
|
834 } |
821 } |
835 } |
822 } |
|
823 |
836 return effect; |
824 return effect; |
837 } |
825 } |
838 |
826 |
839 /*! |
827 /*! |
840 Returns the instant continuous feedback effect for a continuous interaction. |
828 Returns the instant continuous feedback effect for a continuous interaction. |
1015 |
1003 |
1016 case Hb::InstantSelectionChanged: |
1004 case Hb::InstantSelectionChanged: |
1017 modalities = HbFeedback::Tactile; |
1005 modalities = HbFeedback::Tactile; |
1018 break; |
1006 break; |
1019 |
1007 |
1020 case Hb::InstantMultitouchActivated: |
1008 case Hb::InstantAdvancedGestureActivated: |
1021 modalities = HbFeedback::Tactile | HbFeedback::Audio; |
1009 modalities = HbFeedback::Tactile | HbFeedback::Audio; |
1022 break; |
1010 break; |
1023 |
1011 |
1024 default: |
1012 default: |
1025 modalities = HbFeedback::Tactile; |
1013 modalities = HbFeedback::Tactile; |