--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bwins/ganeswidgetsu.def Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,83 @@
+EXPORTS
+ ?setScrollBar@HgWidget@@QAEXPAVHbScrollBar@@@Z @ 1 NONAME ; void HgWidget::setScrollBar(class HbScrollBar *)
+ ?setCurrentIndex@HgWidget@@QAEXABVQModelIndex@@V?$QFlags@W4SelectionFlag@QItemSelectionModel@@@@@Z @ 2 NONAME ; void HgWidget::setCurrentIndex(class QModelIndex const &, class QFlags<enum QItemSelectionModel::SelectionFlag>)
+ ?currentIndex@HgWidget@@QBE?AVQModelIndex@@XZ @ 3 NONAME ; class QModelIndex HgWidget::currentIndex(void) const
+ ?trUtf8@HgWidget@@SA?AVQString@@PBD0@Z @ 4 NONAME ; class QString HgWidget::trUtf8(char const *, char const *)
+ ?scrollTo@HgWidget@@QAEXABVQModelIndex@@@Z @ 5 NONAME ; void HgWidget::scrollTo(class QModelIndex const &)
+ ??1HgWidget@@UAE@XZ @ 6 NONAME ; HgWidget::~HgWidget(void)
+ ?selectionModel@HgWidget@@QBEPAVQItemSelectionModel@@XZ @ 7 NONAME ; class QItemSelectionModel * HgWidget::selectionModel(void) const
+ ?activated@HgWidget@@IAEXABVQModelIndex@@@Z @ 8 NONAME ; void HgWidget::activated(class QModelIndex const &)
+ ?eventFilter@HgWidget@@MAE_NPAVQObject@@PAVQEvent@@@Z @ 9 NONAME ; bool HgWidget::eventFilter(class QObject *, class QEvent *)
+ ?scrollBarPolicy@HgWidget@@QBE?AW4ScrollBarPolicy@1@XZ @ 10 NONAME ; enum HgWidget::ScrollBarPolicy HgWidget::scrollBarPolicy(void) const
+ ?selectAll@HgWidget@@QAEXXZ @ 11 NONAME ; void HgWidget::selectAll(void)
+ ?trUtf8@HgWidget@@SA?AVQString@@PBD0H@Z @ 12 NONAME ; class QString HgWidget::trUtf8(char const *, char const *, int)
+ ?tr@HgWidget@@SA?AVQString@@PBD0@Z @ 13 NONAME ; class QString HgWidget::tr(char const *, char const *)
+ ?getStaticMetaObject@HgWidget@@SAABUQMetaObject@@XZ @ 14 NONAME ; struct QMetaObject const & HgWidget::getStaticMetaObject(void)
+ ?qt_metacast@HgWidget@@UAEPAXPBD@Z @ 15 NONAME ; void * HgWidget::qt_metacast(char const *)
+ ?setSelectionModel@HgWidget@@QAEXPAVQItemSelectionModel@@@Z @ 16 NONAME ; void HgWidget::setSelectionModel(class QItemSelectionModel *)
+ ?d_func@HgWidget@@ABEPBVHgWidgetPrivate@@XZ @ 17 NONAME ; class HgWidgetPrivate const * HgWidget::d_func(void) const
+ ?setScrollBarPolicy@HgWidget@@QAEXW4ScrollBarPolicy@1@@Z @ 18 NONAME ; void HgWidget::setScrollBarPolicy(enum HgWidget::ScrollBarPolicy)
+ ?longPressEnabled@HgWidget@@QBE_NXZ @ 19 NONAME ; bool HgWidget::longPressEnabled(void) const
+ ?tr@HgWidget@@SA?AVQString@@PBD0H@Z @ 20 NONAME ; class QString HgWidget::tr(char const *, char const *, int)
+ ?setModel@HgWidget@@UAEXPAVQAbstractItemModel@@@Z @ 21 NONAME ; void HgWidget::setModel(class QAbstractItemModel *)
+ ?longPressed@HgWidget@@IAEXABVQModelIndex@@ABVQPointF@@@Z @ 22 NONAME ; void HgWidget::longPressed(class QModelIndex const &, class QPointF const &)
+ ?staticMetaObject@HgWidget@@2UQMetaObject@@B @ 23 NONAME ; struct QMetaObject const HgWidget::staticMetaObject
+ ?selectionMode@HgWidget@@QBE?AW4SelectionMode@1@XZ @ 24 NONAME ; enum HgWidget::SelectionMode HgWidget::selectionMode(void) const
+ ??_EHgWidget@@UAE@I@Z @ 25 NONAME ; HgWidget::~HgWidget(unsigned int)
+ ?qt_metacall@HgWidget@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 26 NONAME ; int HgWidget::qt_metacall(enum QMetaObject::Call, int, void * *)
+ ?d_func@HgWidget@@AAEPAVHgWidgetPrivate@@XZ @ 27 NONAME ; class HgWidgetPrivate * HgWidget::d_func(void)
+ ?metaObject@HgWidget@@UBEPBUQMetaObject@@XZ @ 28 NONAME ; struct QMetaObject const * HgWidget::metaObject(void) const
+ ?scrollBar@HgWidget@@QBEPAVHbScrollBar@@XZ @ 29 NONAME ; class HbScrollBar * HgWidget::scrollBar(void) const
+ ?model@HgWidget@@QBEPAVQAbstractItemModel@@XZ @ 30 NONAME ; class QAbstractItemModel * HgWidget::model(void) const
+ ?clearSelection@HgWidget@@QAEXXZ @ 31 NONAME ; void HgWidget::clearSelection(void)
+ ?setLongPressEnabled@HgWidget@@QAEX_N@Z @ 32 NONAME ; void HgWidget::setLongPressEnabled(bool)
+ ?dataChanged@HgWidget@@IAEXABVQModelIndex@@0@Z @ 33 NONAME ; void HgWidget::dataChanged(class QModelIndex const &, class QModelIndex const &)
+ ?setSelectionMode@HgWidget@@QAEXW4SelectionMode@1@_N@Z @ 34 NONAME ; void HgWidget::setSelectionMode(enum HgWidget::SelectionMode, bool)
+ ?event@HgWidget@@MAE_NPAVQEvent@@@Z @ 35 NONAME ; bool HgWidget::event(class QEvent *)
+ ?orientationChanged@HgWidget@@QAEXW4Orientation@Qt@@@Z @ 36 NONAME ; void HgWidget::orientationChanged(enum Qt::Orientation)
+ ?aboutToChangeOrientation@HgWidget@@QAEXXZ @ 37 NONAME ; void HgWidget::aboutToChangeOrientation(void)
+ ?getItemOutline@HgWidget@@QAE_NABVQModelIndex@@AAVQPolygonF@@@Z @ 38 NONAME ; bool HgWidget::getItemOutline(class QModelIndex const &, class QPolygonF &)
+ ?getVisibleItemIndices@HgWidget@@QBE?AV?$QList@VQModelIndex@@@@XZ @ 39 NONAME ; class QList<class QModelIndex> HgWidget::getVisibleItemIndices(void) const
+ ?scrollingEnded@HgWidget@@IAEXXZ @ 40 NONAME ; void HgWidget::scrollingEnded(void)
+ ?scrollingStarted@HgWidget@@IAEXXZ @ 41 NONAME ; void HgWidget::scrollingStarted(void)
+ ?scrollDirection@HgWidget@@QBE?AW4Orientation@Qt@@XZ @ 42 NONAME ; enum Qt::Orientation HgWidget::scrollDirection(void) const
+ ?tr@HgMediawall@@SA?AVQString@@PBD0@Z @ 43 NONAME ; class QString HgMediawall::tr(char const *, char const *)
+ ?qt_metacall@HgMediawall@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 44 NONAME ; int HgMediawall::qt_metacall(enum QMetaObject::Call, int, void * *)
+ ?d_func@HgMediawall@@ABEPBVHgMediawallPrivate@@XZ @ 45 NONAME ; class HgMediawallPrivate const * HgMediawall::d_func(void) const
+ ?tr@HgGrid@@SA?AVQString@@PBD0H@Z @ 46 NONAME ; class QString HgGrid::tr(char const *, char const *, int)
+ ?metaObject@HgMediawall@@UBEPBUQMetaObject@@XZ @ 47 NONAME ; struct QMetaObject const * HgMediawall::metaObject(void) const
+ ?d_func@HgGrid@@ABEPBVHgGridPrivate@@XZ @ 48 NONAME ; class HgGridPrivate const * HgGrid::d_func(void) const
+ ?tr@HgMediawall@@SA?AVQString@@PBD0H@Z @ 49 NONAME ; class QString HgMediawall::tr(char const *, char const *, int)
+ ?staticMetaObject@HgMediawall@@2UQMetaObject@@B @ 50 NONAME ; struct QMetaObject const HgMediawall::staticMetaObject
+ ??_EHgGrid@@UAE@I@Z @ 51 NONAME ; HgGrid::~HgGrid(unsigned int)
+ ?trUtf8@HgMediawall@@SA?AVQString@@PBD0@Z @ 52 NONAME ; class QString HgMediawall::trUtf8(char const *, char const *)
+ ?getStaticMetaObject@HgMediawall@@SAABUQMetaObject@@XZ @ 53 NONAME ; struct QMetaObject const & HgMediawall::getStaticMetaObject(void)
+ ?getStaticMetaObject@HgGrid@@SAABUQMetaObject@@XZ @ 54 NONAME ; struct QMetaObject const & HgGrid::getStaticMetaObject(void)
+ ?d_func@HgGrid@@AAEPAVHgGridPrivate@@XZ @ 55 NONAME ; class HgGridPrivate * HgGrid::d_func(void)
+ ?qt_metacall@HgGrid@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 56 NONAME ; int HgGrid::qt_metacall(enum QMetaObject::Call, int, void * *)
+ ??0HgGrid@@QAE@W4Orientation@Qt@@PAVQGraphicsItem@@@Z @ 57 NONAME ; HgGrid::HgGrid(enum Qt::Orientation, class QGraphicsItem *)
+ ??0HgMediawall@@QAE@PAVQGraphicsItem@@@Z @ 58 NONAME ; HgMediawall::HgMediawall(class QGraphicsItem *)
+ ?qt_metacast@HgGrid@@UAEPAXPBD@Z @ 59 NONAME ; void * HgGrid::qt_metacast(char const *)
+ ?trUtf8@HgGrid@@SA?AVQString@@PBD0H@Z @ 60 NONAME ; class QString HgGrid::trUtf8(char const *, char const *, int)
+ ??0HgWidget@@IAE@PAVHbWidgetPrivate@@PAVQGraphicsItem@@@Z @ 61 NONAME ; HgWidget::HgWidget(class HbWidgetPrivate *, class QGraphicsItem *)
+ ?trUtf8@HgMediawall@@SA?AVQString@@PBD0H@Z @ 62 NONAME ; class QString HgMediawall::trUtf8(char const *, char const *, int)
+ ?trUtf8@HgGrid@@SA?AVQString@@PBD0@Z @ 63 NONAME ; class QString HgGrid::trUtf8(char const *, char const *)
+ ?tr@HgGrid@@SA?AVQString@@PBD0@Z @ 64 NONAME ; class QString HgGrid::tr(char const *, char const *)
+ ??1HgGrid@@UAE@XZ @ 65 NONAME ; HgGrid::~HgGrid(void)
+ ?qt_metacast@HgMediawall@@UAEPAXPBD@Z @ 66 NONAME ; void * HgMediawall::qt_metacast(char const *)
+ ?staticMetaObject@HgGrid@@2UQMetaObject@@B @ 67 NONAME ; struct QMetaObject const HgGrid::staticMetaObject
+ ??1HgMediawall@@UAE@XZ @ 68 NONAME ; HgMediawall::~HgMediawall(void)
+ ?metaObject@HgGrid@@UBEPBUQMetaObject@@XZ @ 69 NONAME ; struct QMetaObject const * HgGrid::metaObject(void) const
+ ??_EHgMediawall@@UAE@I@Z @ 70 NONAME ; HgMediawall::~HgMediawall(unsigned int)
+ ?d_func@HgMediawall@@AAEPAVHgMediawallPrivate@@XZ @ 71 NONAME ; class HgMediawallPrivate * HgMediawall::d_func(void)
+ ?descriptionPosition@HgMediawall@@QBE?AW4LabelPosition@1@XZ @ 72 NONAME ; enum HgMediawall::LabelPosition HgMediawall::descriptionPosition(void) const
+ ?setDescriptionFontSpec@HgMediawall@@QAEXABVHbFontSpec@@@Z @ 73 NONAME ; void HgMediawall::setDescriptionFontSpec(class HbFontSpec const &)
+ ?titleFontSpec@HgMediawall@@QBE?AVHbFontSpec@@XZ @ 74 NONAME ; class HbFontSpec HgMediawall::titleFontSpec(void) const
+ ?setDescriptionPosition@HgMediawall@@QAEXW4LabelPosition@1@@Z @ 75 NONAME ; void HgMediawall::setDescriptionPosition(enum HgMediawall::LabelPosition)
+ ?titlePosition@HgMediawall@@QBE?AW4LabelPosition@1@XZ @ 76 NONAME ; enum HgMediawall::LabelPosition HgMediawall::titlePosition(void) const
+ ?setTitleFontSpec@HgMediawall@@QAEXABVHbFontSpec@@@Z @ 77 NONAME ; void HgMediawall::setTitleFontSpec(class HbFontSpec const &)
+ ?setTitlePosition@HgMediawall@@QAEXW4LabelPosition@1@@Z @ 78 NONAME ; void HgMediawall::setTitlePosition(enum HgMediawall::LabelPosition)
+ ?descriptionFontSpec@HgMediawall@@QBE?AVHbFontSpec@@XZ @ 79 NONAME ; class HbFontSpec HgMediawall::descriptionFontSpec(void) const
+ ?setIndexFeedbackPolicy@HgWidget@@QAEXW4IndexFeedbackPolicy@1@@Z @ 80 NONAME ; void HgWidget::setIndexFeedbackPolicy(enum HgWidget::IndexFeedbackPolicy)
+ ?indexFeedbackPolicy@HgWidget@@QBE?AW4IndexFeedbackPolicy@1@XZ @ 81 NONAME ; enum HgWidget::IndexFeedbackPolicy HgWidget::indexFeedbackPolicy(void) const
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/eabi/ganeswidgetsu.def Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,89 @@
+EXPORTS
+ _ZN11HgMediawall11qt_metacallEN11QMetaObject4CallEiPPv @ 1 NONAME
+ _ZN11HgMediawall11qt_metacastEPKc @ 2 NONAME
+ _ZN11HgMediawall16staticMetaObjectE @ 3 NONAME DATA 16
+ _ZN11HgMediawall19getStaticMetaObjectEv @ 4 NONAME
+ _ZN11HgMediawallC1EP13QGraphicsItem @ 5 NONAME
+ _ZN11HgMediawallC2EP13QGraphicsItem @ 6 NONAME
+ _ZN11HgMediawallD0Ev @ 7 NONAME
+ _ZN11HgMediawallD1Ev @ 8 NONAME
+ _ZN11HgMediawallD2Ev @ 9 NONAME
+ _ZN6HgGrid11qt_metacallEN11QMetaObject4CallEiPPv @ 10 NONAME
+ _ZN6HgGrid11qt_metacastEPKc @ 11 NONAME
+ _ZN6HgGrid16staticMetaObjectE @ 12 NONAME DATA 16
+ _ZN6HgGrid19getStaticMetaObjectEv @ 13 NONAME
+ _ZN6HgGridC1EN2Qt11OrientationEP13QGraphicsItem @ 14 NONAME
+ _ZN6HgGridC2EN2Qt11OrientationEP13QGraphicsItem @ 15 NONAME
+ _ZN6HgGridD0Ev @ 16 NONAME
+ _ZN6HgGridD1Ev @ 17 NONAME
+ _ZN6HgGridD2Ev @ 18 NONAME
+ _ZN8HgWidget11dataChangedERK11QModelIndexS2_ @ 19 NONAME
+ _ZN8HgWidget11eventFilterEP7QObjectP6QEvent @ 20 NONAME
+ _ZN8HgWidget11longPressedERK11QModelIndexRK7QPointF @ 21 NONAME
+ _ZN8HgWidget11qt_metacallEN11QMetaObject4CallEiPPv @ 22 NONAME
+ _ZN8HgWidget11qt_metacastEPKc @ 23 NONAME
+ _ZN8HgWidget12setScrollBarEP11HbScrollBar @ 24 NONAME
+ _ZN8HgWidget14clearSelectionEv @ 25 NONAME
+ _ZN8HgWidget14getItemOutlineERK11QModelIndexR9QPolygonF @ 26 NONAME
+ _ZN8HgWidget14scrollingEndedEv @ 27 NONAME
+ _ZN8HgWidget15setCurrentIndexERK11QModelIndex6QFlagsIN19QItemSelectionModel13SelectionFlagEE @ 28 NONAME
+ _ZN8HgWidget16scrollingStartedEv @ 29 NONAME
+ _ZN8HgWidget16setSelectionModeENS_13SelectionModeEb @ 30 NONAME
+ _ZN8HgWidget16staticMetaObjectE @ 31 NONAME DATA 16
+ _ZN8HgWidget17setSelectionModelEP19QItemSelectionModel @ 32 NONAME
+ _ZN8HgWidget18orientationChangedEN2Qt11OrientationE @ 33 NONAME
+ _ZN8HgWidget18setScrollBarPolicyENS_15ScrollBarPolicyE @ 34 NONAME
+ _ZN8HgWidget19getStaticMetaObjectEv @ 35 NONAME
+ _ZN8HgWidget19setLongPressEnabledEb @ 36 NONAME
+ _ZN8HgWidget24aboutToChangeOrientationEv @ 37 NONAME
+ _ZN8HgWidget5eventEP6QEvent @ 38 NONAME
+ _ZN8HgWidget8scrollToERK11QModelIndex @ 39 NONAME
+ _ZN8HgWidget8setModelEP18QAbstractItemModel @ 40 NONAME
+ _ZN8HgWidget9activatedERK11QModelIndex @ 41 NONAME
+ _ZN8HgWidget9selectAllEv @ 42 NONAME
+ _ZN8HgWidgetC1EP15HbWidgetPrivateP13QGraphicsItem @ 43 NONAME
+ _ZN8HgWidgetC2EP15HbWidgetPrivateP13QGraphicsItem @ 44 NONAME
+ _ZN8HgWidgetD0Ev @ 45 NONAME
+ _ZN8HgWidgetD1Ev @ 46 NONAME
+ _ZN8HgWidgetD2Ev @ 47 NONAME
+ _ZNK11HgMediawall10metaObjectEv @ 48 NONAME
+ _ZNK6HgGrid10metaObjectEv @ 49 NONAME
+ _ZNK8HgWidget10metaObjectEv @ 50 NONAME
+ _ZNK8HgWidget12currentIndexEv @ 51 NONAME
+ _ZNK8HgWidget13selectionModeEv @ 52 NONAME
+ _ZNK8HgWidget14selectionModelEv @ 53 NONAME
+ _ZNK8HgWidget15scrollBarPolicyEv @ 54 NONAME
+ _ZNK8HgWidget15scrollDirectionEv @ 55 NONAME
+ _ZNK8HgWidget16longPressEnabledEv @ 56 NONAME
+ _ZNK8HgWidget21getVisibleItemIndicesEv @ 57 NONAME
+ _ZNK8HgWidget5modelEv @ 58 NONAME
+ _ZNK8HgWidget9scrollBarEv @ 59 NONAME
+ _ZTI11HgMediawall @ 60 NONAME
+ _ZTI6HgGrid @ 61 NONAME
+ _ZTI8HgWidget @ 62 NONAME
+ _ZTV11HgMediawall @ 63 NONAME
+ _ZTV6HgGrid @ 64 NONAME
+ _ZTV8HgWidget @ 65 NONAME
+ _ZThn16_N11HgMediawallD0Ev @ 66 NONAME
+ _ZThn16_N11HgMediawallD1Ev @ 67 NONAME
+ _ZThn16_N6HgGridD0Ev @ 68 NONAME
+ _ZThn16_N6HgGridD1Ev @ 69 NONAME
+ _ZThn16_N8HgWidgetD0Ev @ 70 NONAME
+ _ZThn16_N8HgWidgetD1Ev @ 71 NONAME
+ _ZThn8_N11HgMediawallD0Ev @ 72 NONAME
+ _ZThn8_N11HgMediawallD1Ev @ 73 NONAME
+ _ZThn8_N6HgGridD0Ev @ 74 NONAME
+ _ZThn8_N6HgGridD1Ev @ 75 NONAME
+ _ZThn8_N8HgWidgetD0Ev @ 76 NONAME
+ _ZThn8_N8HgWidgetD1Ev @ 77 NONAME
+ _ZN11HgMediawall16setTitleFontSpecERK10HbFontSpec @ 78 NONAME
+ _ZN11HgMediawall16setTitlePositionENS_13LabelPositionE @ 79 NONAME
+ _ZN11HgMediawall22setDescriptionFontSpecERK10HbFontSpec @ 80 NONAME
+ _ZN11HgMediawall22setDescriptionPositionENS_13LabelPositionE @ 81 NONAME
+ _ZNK11HgMediawall13titleFontSpecEv @ 82 NONAME
+ _ZNK11HgMediawall13titlePositionEv @ 83 NONAME
+ _ZNK11HgMediawall19descriptionFontSpecEv @ 84 NONAME
+ _ZNK11HgMediawall19descriptionPositionEv @ 85 NONAME
+ _ZN8HgWidget22setIndexFeedbackPolicyENS_19IndexFeedbackPolicyE @ 86 NONAME
+ _ZNK8HgWidget19indexFeedbackPolicyEv @ 87 NONAME
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/data/ganeswidgets.qrc Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/mark.svg</file>
+ <file>hgwidget.css</file>
+ <file>hgwidget.widgetml</file>
+ <file>hgindexfeedback.css</file>
+ </qresource>
+</RCC>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/data/hgindexfeedback.css Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,7 @@
+HgIndexFeedback
+{
+ one-char-height:18un;
+ three-char-height:12un;
+ three-char-width:36un;
+ string-offset:8un;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/data/hgwidget.css Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,40 @@
+HgWidget
+{
+ layout:default_layout;
+}
+
+HgWidget::scrollbar-vertical
+{
+ left:0un;
+ right:0un;
+ top:-0.8un;
+ bottom:expr(var(hb-param-widget-scroll-bar-interactive-width)+0.8un);
+}
+
+HgWidget::scrollbar-horizontal
+{
+ left:0un;
+ right:var(hb-param-widget-scroll-bar-interactive-width);
+ top:0un;
+ bottom:0un;
+}
+
+HgWidget::continuation-indicator-bottom
+{
+ fixed-height:2.0un;
+}
+
+HgWidget::continuation-indicator-top
+{
+ fixed-height:2.0un;
+}
+
+HgWidget::continuation-indicator-left
+{
+ fixed-width:2.0un;
+}
+
+HgWidget::continuation-indicator-right
+{
+ fixed-width:2.0un;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/data/hgwidget.widgetml Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,27 @@
+<hbwidget version="0.1" type="HgWidget">
+ <layout name="default_layout" type="mesh">
+ <meshitem src="scrollbar-vertical" srcEdge="RIGHT" dst="" dstEdge="RIGHT" />
+ <meshitem src="scrollbar-vertical" srcEdge="TOP" dst="" dstEdge="TOP" />
+ <meshitem src="scrollbar-vertical" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM" />
+
+ <meshitem src="scrollbar-horizontal" srcEdge="RIGHT" dst="" dstEdge="RIGHT" />
+ <meshitem src="scrollbar-horizontal" srcEdge="LEFT" dst="" dstEdge="LEFT" />
+ <meshitem src="scrollbar-horizontal" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM" />
+
+ <meshitem src="continuation-indicator-top" srcEdge="RIGHT" dst="" dstEdge="RIGHT" />
+ <meshitem src="continuation-indicator-top" srcEdge="LEFT" dst="" dstEdge="LEFT" />
+ <meshitem src="continuation-indicator-top" srcEdge="TOP" dst="" dstEdge="TOP" />
+
+ <meshitem src="continuation-indicator-bottom" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM" />
+ <meshitem src="continuation-indicator-bottom" srcEdge="LEFT" dst="" dstEdge="LEFT" />
+ <meshitem src="continuation-indicator-bottom" srcEdge="RIGHT" dst="" dstEdge="RIGHT" />
+
+ <meshitem src="continuation-indicator-left" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM" />
+ <meshitem src="continuation-indicator-left" srcEdge="LEFT" dst="" dstEdge="LEFT" />
+ <meshitem src="continuation-indicator-left" srcEdge="TOP" dst="" dstEdge="TOP" />
+
+ <meshitem src="continuation-indicator-right" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM" />
+ <meshitem src="continuation-indicator-right" srcEdge="TOP" dst="" dstEdge="TOP" />
+ <meshitem src="continuation-indicator-right" srcEdge="RIGHT" dst="" dstEdge="RIGHT" />
+ </layout>
+</hbwidget>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/data/images/mark.svg Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generator: Mobile Designer 3.0 2.0 -->
+<svg width="40" height="40" viewBox="-20 -20 40 40"
+ stroke-miterlimit="2" enable-background="new" zoomAndPan="disable"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ev="http://www.w3.org/2001/xml-events"
+ xml:space="preserve" version="1.1" baseProfile="Normal">
+
+<!-- Definitions -->
+<defs>
+<style type="text/css"><![CDATA[
+ .st0 { fill:none; stroke:#fff; stroke-width:3; stroke-miterlimit:4;}
+]]>
+</style>
+</defs>
+
+<!-- Movie Background -->
+<rect fill="none" x="-20" y="-20" width="40" height="40"/>
+
+<!-- Scene 1 -->
+<g id="Scene_1">
+ <rect x="-19.5" y="-19.5" width="38.75" height="38.75" fill="none" stroke="#fff" stroke-width="3" stroke-linejoin="bevel" stroke-miterlimit="4"/>
+ <polyline class="st0"
+ points="-14.5,4.75 -0.75,16.5"/>
+ <polyline class="st0"
+ points="-0.75,16.5 8.25,-16.25"/>
+</g>
+
+</svg>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/ganeswidgets.pro Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,78 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+# Contributors:
+# Description:
+
+symbian:TARGET.UID3 = 0x10207C66
+TEMPLATE = lib
+CONFIG += hb
+TARGET = ganeswidgets
+DEFINES += BUILD_HG_WIDGETS
+TARGET.CAPABILITY = All \
+ -TCB
+DEPENDPATH += .
+INCLUDEPATH += . \
+ inc \
+ $$MW_LAYER_SYSTEMINCLUDE \
+ /sf/mw/hb/src/hbcore/gui
+LIBS += -lestor.dll \
+ -lmpxcommon.dll \
+ -lhbcore \
+ -lhbwidgets \
+ -llibOpenVG.dll \
+ -llibOpenVGU.dll
+symbian {
+ TARGET.EPOCALLOWDLLDATA = 1
+}
+
+# Input
+SOURCES += src/hgwidgets.cpp \
+ src/hgwidgets_p.cpp \
+ src/hgcontainer.cpp \
+ src/hgwidgetitem.cpp \
+ src/hgscrollbuffermanager.cpp \
+ src/hgquad.cpp \
+ src/hgquadrenderer.cpp \
+ src/hgvgquadrenderer.cpp \
+ src/hgvgimage.cpp \
+ src/hgmediawallrenderer.cpp \
+ src/hgspring.cpp \
+ src/hgdrag.cpp \
+ src/hgimagefader.cpp \
+ src/hglongpressvisualizer.cpp \
+ src/hgcoverflowcontainer.cpp \
+ src/hggridcontainer.cpp \
+ src/hgindexfeedback.cpp \
+ src/hgindexfeedback_p.cpp \
+ src/hggrid.cpp \
+ src/hggrid_p.cpp \
+ src/hgmediawall.cpp \
+ src/hgmediawall_p.cpp
+HEADERS = inc/trace.h \
+ ../hgwidgets_plat/ganeswidgets_api/inc/hgwidgets.h \
+ ../hgwidgets_plat/ganeswidgets_api/inc/hggrid.h \
+ ../hgwidgets_plat/ganeswidgets_api/inc/hgmediawall.h \
+ inc/hgwidgets_p.h \
+ inc/hggrid_p.h \
+ inc/hgmediawall_p.h \
+ inc/hgmediawallrenderer.h \
+ inc/hgcontainer.h \
+ inc/hgspring.h \
+ inc/hgdrag.h \
+ inc/hgscrollbuffermanager.h \
+ inc/hgimagefader.h \
+ inc/hglongpressvisualizer.h \
+ inc/hgcoverflowcontainer.h \
+ inc/hggridcontainer.h \
+ inc/hgindexfeedback.h
+RESOURCES += data/ganeswidgets.qrc
+
+
+include(rom/rom.pri)
+include(sis/stub.pri)
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/HgContainer.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,200 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGCONTAINER_H
+#define HGCONTAINER_H
+
+#include <QTime>
+#include <hbwidget.h>
+#include <hgwidgets/hgwidgets.h>
+
+#include "hgmediawalldataprovider.h"
+#include "hgdrag.h"
+#include "hgspring.h"
+
+class HgWidgetItem;
+class HgQuadRenderer;
+class HgMediaWallRenderer;
+class QPanGesture;
+class HbAbstractViewItem;
+class HbGestureSceneFilter;
+class HgLongPressVisualizer;
+
+class HgContainer: public HbWidget, public HgMediaWallDataProvider
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(HgContainer)
+
+public:
+ explicit HgContainer(QGraphicsItem* parent = 0);
+ virtual ~HgContainer();
+
+ void setItemCount(int count);
+ int itemCount() const;
+ int rowCount() const;
+
+ QList<HgWidgetItem*> items() const;
+ HgWidgetItem* itemByIndex(const QModelIndex &index) const;
+ HgWidgetItem* itemByIndex(const int &index) const;
+
+ void setSelectionModel(QItemSelectionModel *selectionModel);
+ QItemSelectionModel *selectionModel() const;
+ void setSelectionMode(HgWidget::SelectionMode mode, bool resetSelection);
+ HgWidget::SelectionMode selectionMode() const;
+
+ void dimensions(qreal &screenSize, qreal &worldSize);
+ Qt::Orientation orientation() const;
+ void setOrientation(Qt::Orientation orientation, bool animate=true);
+
+ // new size for the widget. calls resize.
+ void scrollToPosition(qreal value, bool animate = false);
+ virtual void scrollToPosition(const QPointF& pos, bool animate);
+ void scrollTo(const QModelIndex &index);
+
+ void itemDataChanged(const QModelIndex &firstIndex, const QModelIndex &lastIndex);
+
+ void addItems(int start, int end);
+ void removeItems(int start, int end);
+ void moveItems(int start, int end, int destination);
+
+ bool getItemPoints(int index, QPolygonF& points);
+
+ QList<QModelIndex> getVisibleItemIndices() const;
+
+ virtual void itemDataChanged(const int &firstIndex, const int &lastIndex);
+
+ void init(Qt::Orientation scrollDirection);
+
+signals:
+
+ // emit this signal when scrolling. for example scrollbar can be connected to this signal.
+ void scrollPositionChanged(qreal value, bool scrollBarAnimation);
+ void centerItemChanged(const QModelIndex &index);
+ void activated(const QModelIndex &index);
+ void longPressed(const QModelIndex &index, const QPointF &coords);
+ void scrollingStarted();
+ void scrollingEnded();
+
+private slots:
+
+ void updateBySpringPosition();
+ void redraw();
+ void updateLongPressVisualizer();
+ void updateByCurrentIndex(const QModelIndex ¤t);
+ void onScrollingEnded();
+
+protected: // from HgMediaWallDataProvider
+
+ int imageCount() const;
+ const HgImage *image(int index) const;
+ int flags(int index) const;
+ const HgImage *indicator(int flags) const;
+
+protected: // events
+
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ virtual void resizeEvent(QGraphicsSceneResizeEvent *event);
+
+ // this needs to be implemented for gesture framework to work
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ // From HbWidget for gestures.
+ virtual void gestureEvent(QGestureEvent *event);
+protected:
+
+ virtual HgMediaWallRenderer* createRenderer()=0;
+ virtual qreal getCameraDistance(qreal springVelocity);
+ virtual qreal getCameraRotationY(qreal springVelocity);
+ virtual void handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex);
+ virtual void handleLongTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex);
+ virtual void onScrollPositionChanged(qreal pos);
+ virtual void handleCurrentChanged(const QModelIndex ¤t);
+
+protected:
+
+ enum ItemActionType
+ {
+ LongTap = 1,
+ DoubleTap,
+ NormalTap,
+ TapStart,
+ LongTapStart
+ };
+
+ qreal worldWidth() const;
+ void initSpringForScrollBar();
+ void initSpringForScrolling();
+ void boundSpring();
+ void handlePanning(QPanGesture *gesture);
+ void handleTap(Qt::GestureState state, const QPointF &pos);
+ void handleLongTap(Qt::GestureState state, const QPointF &pos);
+ void handleItemAction(const QPointF &pos, ItemActionType action);
+
+ void selectItem();
+ void updateSelectedItem();
+ void unselectItem();
+
+ HgWidgetItem* getItemAt(const QPointF& pos, int& index);
+ void startLongPressWatcher(const QPointF& pos);
+ void stopLongPressWatcher();
+ bool updateSelectionModel(HgWidgetItem* item);
+
+ QTransform qtToVgTransform() const;
+ QPointF mapQtToVg(const QPointF& p) const;
+
+protected: // data
+
+ QList<HgWidgetItem *> mItems;
+ //int mRowCount;
+ //int mColumnCount;
+
+ //HbLabel *mLabel;
+ HgQuadRenderer *mQuadRenderer;
+ HgMediaWallRenderer *mRenderer;
+
+ HgSpring mSpring;
+ HgDrag mDrag;
+
+ QTime mTapDuration; // Temp hack until HbTapGesture is available
+ QTime mDoubleTapDuration;
+ int mTapCount;
+
+ bool mAnimateUsingScrollBar;
+
+ HgWidget::SelectionMode mSelectionMode;
+ QItemSelectionModel *mSelectionModel;
+ HgImage *mMarkImage;
+
+ qreal mSpringVelAtDragStart;
+ bool mDragged;
+ int mFramesDragged;
+
+ HbAbstractViewItem* mHitItemView;
+ QPixmap mHitItemPixmap;
+
+ HgLongPressVisualizer* mLongPressVisualizer;
+ QTimer* mLongPressTimer;
+ HgWidgetItem* mHitItem;
+ int mHitItemIndex;
+
+ QPointF mOffsetAtDragStart;
+ QTime mLongTapDuration;
+ bool mScrollBarPressed;
+
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/HgImageFader.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGIMAGEFADER_H_
+#define HGIMAGEFADER_H_
+
+#include <qobject>
+#include <qtimer>
+#include <qlinkedlist>
+
+class HgImage;
+
+class HgImageFader : public QObject
+{
+ Q_OBJECT
+public:
+ HgImageFader();
+ virtual ~HgImageFader();
+ void addImage(HgImage* image);
+ void removeImage(HgImage* image);
+ void fadeImages();
+signals:
+ void doUpdate();
+private slots:
+ void doFading();
+private:
+ QTimer mTimer;
+ QLinkedList<HgImage*> mImages;
+};
+
+#endif /* HGIMAGEFADER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/HgScrollBufferManager.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef HGSCROLLBUFFERMANAGER_H_
+#define HGSCROLLBUFFERMANAGER_H_
+
+#include <qobject>
+#include <QTimer>
+
+class HgScrollBufferManager: public QObject
+ {
+ Q_OBJECT
+public:
+
+ HgScrollBufferManager(
+ int bufferSize,
+ int bufferTreshold,
+ int initialPosition,
+ int totalCount);
+
+ virtual ~HgScrollBufferManager();
+
+ void resetBuffer(int aPosition, int aTotalCount);
+
+ void scrollPositionChanged(int newPosition);
+
+ bool positionInsideBuffer(int position);
+
+ void removeItems(int start, int end, int totalCount);
+ void addItems(int start, int end, int totalCount);
+ void moveItems(int start, int end, int target, int totalCount);
+
+ void currentBuffer(int& bufferStart, int& bufferEnd);
+
+signals:
+
+ void releaseItems(int releaseStart, int releaseEnd);
+ void requestItems(int requestStart, int requestEnd);
+
+protected slots:
+
+ void timeout();
+
+protected:
+
+ void init();
+ void asyncUpdate();
+ bool isInsideBuffer(int pos);
+ bool isInsideBuffer(int start, int end);
+
+private:
+
+ int mBufferSize;
+ int mBufferTreshold;
+ int mBufferPosition;
+ int mDiff;
+ int mTotalCount;
+
+ bool mResetOrdered;
+
+ int mRequestStart;
+ int mRequestCount;
+ int mReleaseStart;
+ int mReleaseCount;
+ QTimer mTimer;
+
+private:
+ Q_DISABLE_COPY(HgScrollBufferManager)
+ };
+
+#endif /*HGSCROLLBUFFERMANAGER_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgcoverflowcontainer.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGCOVERFLOWCONTAINER_H
+#define HGCOVERFLOWCONTAINER_H
+
+#include <hgwidgets/hgmediawall.h>
+#include "HgContainer.h"
+
+class HbLabel;
+
+class HgCoverflowContainer: public HgContainer
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(HgCoverflowContainer)
+
+public:
+ explicit HgCoverflowContainer(QGraphicsItem* parent = 0);
+ virtual ~HgCoverflowContainer();
+
+ // events
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ virtual void resizeEvent(QGraphicsSceneResizeEvent *event);
+
+ // from HgContainer
+ virtual HgMediaWallRenderer* createRenderer();
+ virtual qreal getCameraDistance(qreal springVelocity);
+ virtual qreal getCameraRotationY(qreal springVelocity);
+ virtual void handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex);
+ virtual void handleLongTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex);
+ virtual void onScrollPositionChanged(qreal pos);
+ virtual void handleCurrentChanged(const QModelIndex & current);
+ virtual void itemDataChanged(const int &firstIndex, const int &lastIndex);
+ virtual void scrollToPosition(const QPointF& pos, bool animate);
+
+ void setTitlePosition(HgMediawall::LabelPosition position);
+ HgMediawall::LabelPosition titlePosition() const;
+ void setDescriptionPosition(HgMediawall::LabelPosition position);
+ HgMediawall::LabelPosition descriptionPosition() const;
+ void setTitleFontSpec(const HbFontSpec &fontSpec);
+ HbFontSpec titleFontSpec() const;
+ void setDescriptionFontSpec(const HbFontSpec &fontSpec);
+ HbFontSpec descriptionFontSpec() const;
+
+private:
+ void positionLabels();
+ void updateLabels(int itemIndex);
+
+private:
+ HbLabel *mTitleLabel;
+ HbLabel *mDescriptionLabel;
+ HgMediawall::LabelPosition mTitlePosition;
+ HgMediawall::LabelPosition mDescriptionPosition;
+ int mCenterIconTop;
+ int mPrevPos;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgdrag.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Container for pan (drag) gesture -related data and logic.
+*
+*/
+
+#ifndef HGDRAG_H
+#define HGDRAG_H
+
+#include <QTime>
+
+class HgDrag
+{
+public:
+ HgDrag();
+ void reset(const qreal delta, const qreal viewPos);
+ qreal update(const qreal delta, const qreal viewPos, const qreal itemWidth);
+ bool finish(const qreal viewPos, bool stopToFullItem, qreal &newPos);
+ qreal viewPosAtStart() const;
+
+private:
+ QTime mDuration;
+ qreal mViewPosAtStart;
+ qreal mLength;
+ qreal mCumulatedDelta;
+ int mDirection;
+ int mDirectionChange;
+};
+
+#endif // HGDRAG_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hggrid_p.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGGRID_P_H
+#define HGGRID_P_H
+
+#include <hgwidgets/hggrid.h>
+#include "hgwidgets_p.h"
+
+class HgGridPrivate : public HgWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(HgGrid)
+
+public:
+
+ HgGridPrivate();
+ virtual ~HgGridPrivate();
+
+ void init(Qt::Orientation scrollDirection);
+
+private:
+
+};
+
+#endif //HGGRID_P_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hggridcontainer.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGGRIDCONTAINER_H
+#define HGGRIDCONTAINER_H
+
+#include "HgContainer.h"
+
+class HbLabel;
+class HgWidgetItem;
+class HgMediaWallRenderer;
+
+class HgGridContainer : public HgContainer
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(HgGridContainer)
+
+public:
+ explicit HgGridContainer(QGraphicsItem *parent = 0);
+
+ virtual ~HgGridContainer();
+
+protected:
+
+ // events
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ // from HgContainer
+ virtual HgMediaWallRenderer* createRenderer();
+ virtual qreal getCameraDistance(qreal springVelocity);
+ virtual qreal getCameraRotationY(qreal springVelocity);
+ virtual void handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex);
+ virtual void handleLongTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemindex);
+
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgimage.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGIMAGE_H
+#define HGIMAGE_H
+
+class QImage;
+
+/**
+ * Interface class for Images provided to HgQuadRenderer.
+ */
+class HgImage
+{
+public:
+ virtual ~HgImage() {}
+ virtual void setAlpha(qreal alpha) { mAlpha = alpha; }
+ virtual qreal alpha() const { return mAlpha; }
+ virtual void setImage(QImage& image)=0;
+ virtual void releaseImage()=0;
+private:
+ qreal mAlpha;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgindexfeedback.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGINDEXFEEDBACK_H
+#define HGINDEXFEEDBACK_H
+
+#include <hbglobal.h>
+#include <hbwidget.h>
+#include <hgwidgets/hgwidgets.h>
+
+class HbScrollBar;
+class HgIndexFeedbackPrivate;
+class HbStyleOptionIndexFeedback;
+class HgWidget;
+
+QT_BEGIN_NAMESPACE
+class QGraphicsItem;
+QT_END_NAMESPACE
+
+class HgIndexFeedback : public HbWidget
+{
+ Q_OBJECT
+
+public:
+
+ explicit HgIndexFeedback(QGraphicsItem *parent=0);
+ virtual ~HgIndexFeedback();
+
+ enum { Type = Hb::ItemType_IndexFeedback };
+ int type() const { return Type; }
+
+ void setIndexFeedbackPolicy( HgWidget::IndexFeedbackPolicy policy);
+ HgWidget::IndexFeedbackPolicy indexFeedbackPolicy() const;
+
+ void setWidget(HgWidget *itemView);
+ HgWidget* widget() const;
+
+ virtual QGraphicsItem *primitive(HbStyle::Primitive primitive) const;
+
+protected:
+ virtual void polish( HbStyleParameters& params);
+ virtual bool sceneEventFilter(QGraphicsItem* watched, QEvent* event);
+ virtual bool eventFilter(QObject *obj, QEvent *event);
+ void initStyleOption(HbStyleOptionIndexFeedback *option) const;
+
+private:
+ Q_DECLARE_PRIVATE_D(d_ptr, HgIndexFeedback)
+ Q_DISABLE_COPY(HgIndexFeedback)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_scrollPositionChanged(qreal, Qt::Orientation))
+ Q_PRIVATE_SLOT(d_func(), void _q_hideIndexFeedback())
+ Q_PRIVATE_SLOT(d_func(), void _q_itemViewDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_hideIndexFeedbackNow())
+ Q_PRIVATE_SLOT(d_func(), void _q_currentModelIndexChanged(QModelIndex, QModelIndex))
+};
+
+#endif // HGINDEXFEEDBACK_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgindexfeedback_p.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGINDEXFEEDBACKPRIVATE_H
+#define HGINDEXFEEDBACKPRIVATE_H
+
+#include "hgindexfeedback.h"
+#include <hbwidget_p.h>
+
+#define HB_INDEXFEEDBACK_TYPE "indexfeedback"
+#define EFFECT_IFAPPEAR "appear"
+#define EFFECT_IFDISAPPEAR "disappear"
+
+QT_BEGIN_NAMESPACE
+class QGraphicsWidget;
+class QGraphicsItem;
+class QRectF;
+class QItemSelectionModel;
+QT_END_NAMESPACE
+
+class HgIndexFeedbackPrivate : public HbWidgetPrivate
+{
+ Q_DECLARE_PUBLIC( HgIndexFeedback )
+
+public:
+ HgIndexFeedbackPrivate();
+ virtual ~HgIndexFeedbackPrivate();
+ void init();
+
+ void showIndexFeedback();
+ void updateIndex();
+
+ void scrollBarPressed();
+ void scrollBarReleased();
+
+ void connectScrollBarToIndexFeedback(HbScrollBar* scrollBar);
+ void disconnectItemView();
+ void connectModelToIndexFeedback(QItemSelectionModel* model);
+
+ void _q_scrollPositionChanged(qreal value, Qt::Orientation orientation);
+ void _q_hideIndexFeedback();
+ void _q_itemViewDestroyed();
+ void _q_hideIndexFeedbackNow();
+ void _q_currentModelIndexChanged(const QModelIndex& current, const QModelIndex& previous);
+
+ void updatePrimitives();
+ void createPrimitives();
+
+ void calculatePopupRects();
+ qreal textHeight() const;
+ qreal textWidth() const;
+
+ QString displayText(const QVariant &data) const;
+
+public:
+ int mIndexFeedbackPressTimeout;
+ int mIndexFeedbackDwellTimeout;
+ int mIndexFeedbackReleaseTimeout;
+ HgWidget::IndexFeedbackPolicy mIndexFeedbackPolicy;
+
+ // TODO::The values are storred here is a work around for a bug in hbscrollbar.
+ // the bug is that the value changed signal is emitted when the thumb
+ // is pressed, and again when it is released, regaurdless of if there was a value change.
+ // once that bug is fixed, this should be removed.
+ qreal mScrollBarValue;
+
+ QTimer *mIndexFeedbackTimer;
+ QTimer *mDisappearTimer;
+
+ QString mPopupContent;
+ QGraphicsItem *mTextItem;
+ QGraphicsItem *mPopupItem;
+
+ QRectF mPopupTextRect;
+ QRectF mPopupBackgroundRect;
+ QRectF mItemViewContentsRect;
+
+ qreal mOneCharHeight;
+ qreal mThreeCharHeight;
+ qreal mThreeCharWidth;
+ qreal mStringOffset;
+
+ HgWidget* mWidget;
+ QList<QGraphicsItem*> mPopupItemList;
+ bool mScrollBarPressed;
+};
+
+#endif //HBINDEXFEEDBACKPRIVATE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hglongpressvisualizer.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGLONGPRESSVISUALIZER_H
+#define HGLONGPRESSVISUALIZER_H
+
+#include <QTime>
+#include <hbwidget.h>
+#include <hgwidgets/hgwidgets.h>
+
+#include "hgmediawalldataprovider.h"
+#include "hgdrag.h"
+#include "hgspring.h"
+
+class HgLongPressVisualizer : public HbWidget
+{
+public:
+ HgLongPressVisualizer(QGraphicsItem* parent=0);
+ virtual ~HgLongPressVisualizer();
+
+ void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget=0);
+ QRectF boundingRect() const;
+
+ void start(const QPointF& pos);
+ void stop();
+ void setFrame(int frame);
+private:
+ QRectF rect;
+ bool active;
+ qreal spanAngle;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgmediawall_p.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGMEDIAWALL_P_H
+#define HGMEDIAWALL_P_H
+
+#include <hgwidgets/hgmediawall.h>
+#include "hgwidgets_p.h"
+
+class HgCoverflowContainer;
+
+class HgMediawallPrivate : public HgWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(HgMediawall)
+
+public:
+
+ HgMediawallPrivate();
+ virtual ~HgMediawallPrivate();
+
+ void init();
+
+ void setTitlePosition(HgMediawall::LabelPosition position);
+ HgMediawall::LabelPosition titlePosition() const;
+ void setDescriptionPosition(HgMediawall::LabelPosition position);
+ HgMediawall::LabelPosition descriptionPosition() const;
+ void setTitleFontSpec(const HbFontSpec &fontSpec);
+ HbFontSpec titleFontSpec() const;
+ void setDescriptionFontSpec(const HbFontSpec &fontSpec);
+ HbFontSpec descriptionFontSpec() const;
+
+private:
+ HgCoverflowContainer *container();
+ const HgCoverflowContainer *container() const;
+};
+
+#endif //HGMEDIAWALL_P_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgmediawalldataprovider.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGMEDIAWALLDATAPROVIDER_H
+#define HGMEDIAWALLDATAPROVIDER_H
+
+class HgImage;
+
+/**
+ * Data Provider interface for HgMediWallRenderer.
+ */
+class HgMediaWallDataProvider
+{
+public:
+ virtual ~HgMediaWallDataProvider() {}
+ /**
+ * Gets the number of images the model contains.
+ * @return number of images the model contains.
+ */
+ virtual int imageCount() const=0;
+ /**
+ * Gets the image at given index.
+ * @param index of the image in the model
+ * @return pointer to HgImage-object.
+ */
+ virtual const HgImage* image(int index) const=0;
+ /**
+ * Gets the the flags associated to the item at index
+ * @param index of the item
+ * @return flags of the item
+ */
+ virtual int flags(int index) const=0;
+ /**
+ * Gets the image associated to given flags.
+ * @param flags.
+ * @return pointer HgImage-object.
+ */
+ virtual const HgImage* indicator(int flags) const=0;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgmediawallrenderer.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,269 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#ifndef HGMEDIAWALLRENDERER_H
+#define HGMEDIAWALLRENDERER_H
+
+#include <qmatrix4x4>
+#include <qobject>
+
+class HgQuadRenderer;
+class HgMediaWallDataProvider;
+class QPointF;
+class QPainter;
+class QTimer;
+class QStateMachine;
+class HgAnimatedQuad;
+class HgQuad;
+class HgImageFader;
+class HgImage;
+class QPolygonF;
+
+/**
+ * MediaWall rendering engine class.
+ */
+class HgMediaWallRenderer : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal animationAlpha READ animationAlpha WRITE setAnimationAlpha)
+ Q_PROPERTY(qreal stateAnimationAlpha READ stateAnimationAlpha WRITE setStateAnimationAlpha)
+public:
+
+ enum OpeningAnimationType
+ {
+ OpeningAnimationFlip,
+ OpeningAnimationZoomIn,
+ OpeningAnimationZoomOver
+ };
+
+ explicit HgMediaWallRenderer(HgMediaWallDataProvider* provider);
+
+ virtual ~HgMediaWallRenderer();
+
+ void setCameraDistance(qreal distance);
+ qreal getCameraDistance() const;
+ void setCameraRotationY(qreal angle);
+ qreal getCameraRotationY() const;
+ void setCameraRotationZ(qreal angle);
+ qreal getCameraRotationZ() const;
+
+ void draw(
+ const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter);
+
+ void setFlipAnimationAngle(qreal angleInDegrees);
+
+ void setOpeningAnimationType(OpeningAnimationType type);
+
+ void setOpeningAnimationDuration(int msecs);
+
+ void setOrientation(Qt::Orientation orientation, bool animate=false);
+ Qt::Orientation getOrientation() const;
+
+ void enableCoverflowMode(bool enabled);
+ bool coverflowModeEnabled() const;
+
+ void setRowCount(int rowCount, const QSizeF& newImageSize, bool animate=false);
+ int getRowCount() const;
+
+ HgQuad* getQuadAt(const QPointF& position) const;
+
+ void setRect(const QRectF& windowRect);
+ const QRectF& getRect() const;
+ void setSpacing(const QSizeF& spacing);
+ const QSizeF& getSpacing() const;
+ void setImageSize(const QSizeF& imageSize);
+ const QSizeF& getImageSize() const;
+
+ void setFrontCoverElevationFactor(qreal elevation);
+ qreal getFrontCoverElevationFactor() const;
+
+ void openItem(int index, bool animate);
+ void closeItem(bool animate);
+ bool isItemOpen() const;
+
+ void enableReflections(bool enabled);
+ bool reflectionsEnabled() const;
+
+ qreal getWorldWidth() const;
+
+ void beginRemoveRows(int start, int end);
+ void endRemoveRows();
+
+ int getSelectedItem() const;
+
+ void initialize(QPainter* painter);
+ bool initialized() const;
+
+ HgQuadRenderer* getRenderer();
+
+ bool getItemPoints(int index, QPolygonF& points) const;
+
+ QList<HgQuad*> getVisibleQuads() const;
+
+signals:
+ void renderingNeeded();
+ void itemOpened(int index);
+ void itemClosed(int index);
+ void itemMarked(int index);
+ void toggleItem();
+ void toggleState();
+ void itemsRemoved(int start, int end);
+private slots:
+ void onIdleState();
+ void onOpenedState();
+ void emitUpdate();
+protected:
+
+ struct State
+ {
+ QList<HgQuad*> mQuads;
+ };
+
+ void setAnimationAlpha(qreal alpha);
+ qreal animationAlpha() const;
+
+ void createStateMachine();
+ void recordState(State& state);
+
+ void updateStateAnimation(qreal alpha);
+ void setStateAnimationAlpha(qreal alpha);
+ qreal stateAnimationAlpha() const;
+ void setupStateAnimation(QPainter* painter);
+
+ void setupRows(
+ const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter);
+
+ void drawQuads(QPainter* painter);
+ void resetQuads();
+ void updateCameraMatrices();
+ void updateSpacingAndImageSize();
+ qreal getRowPosY(int row);
+ qreal getColumnPosX(int column);
+ QPointF mapFromWindow(const QPointF& point) const;
+ void applyOpeningAnimation(HgQuad* quad);
+ void startStateAnimation(QPainter* painter);
+
+
+ void setupCoverflow(const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter);
+
+ void setupGridPortrait(const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter);
+
+ void setupGridLandscape(const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter);
+
+ void setupGridRow(qreal posY, int itemIndex, int& quadIndex);
+ void setupGridColumn(qreal posX, int itemIndex, int& quadIndex);
+ void setupDefaultQuad(const QVector3D& pos, int itemIndex, bool reflectionsEnabled, int& quadIndex);
+ void setupIndicator(HgQuad* parent,
+ HgQuad* indicator, const HgImage* indicatorImage, int itemIndex);
+ bool initializeRenderer(QPainter* painter);
+
+protected:
+
+ enum ItemState
+ {
+ ItemClosed,
+ ItemOpening,
+ ItemOpened,
+ ItemClosing
+ };
+
+ HgMediaWallDataProvider* mDataProvider;
+ HgQuadRenderer* mRenderer;
+ HgQuadRenderer* mIndicatorRenderer;
+ bool mRendererInitialized;
+
+ Qt::Orientation mOrientation;
+ Qt::Orientation mNextOrientation;
+
+ qreal mStateAnimationAlpha;
+ bool mStateAnimationOnGoing;
+
+ qreal mAnimationAlpha;
+
+ OpeningAnimationType mOpeningAnimationType;
+ int mOpeningAnimationDuration;
+ int mOpenedItem;
+ int mSelectedItem;
+ qreal mFlipAngle;
+ QTimer* mAnimationTimer;
+ QMatrix4x4 mViewMatrix;
+ QMatrix4x4 mProjMatrix;
+ QStateMachine* mStateMachine;
+ qreal mZoomAmount;
+ bool mCoverflowMode;
+ int mRowCount;
+ int mNextRowCount;
+
+ QList<HgAnimatedQuad*> mAnimatedQuads;
+ int mStateAnimationDuration;
+ qreal mStep;
+ qreal mZfar;
+ QRectF mRect;
+
+ QSizeF mSpacing2D;
+ QSizeF mSpacing3D;
+ QSizeF mImageSize2D;
+ QSizeF mImageSize3D;
+
+ qreal mCameraDistance;
+ qreal mCameraRotationY;
+ qreal mCameraRotationZ;
+
+ qreal mFrontCoverElevation;
+
+ State mOldState;
+ State mNextState;
+
+
+ bool mReflectionsEnabled;
+ HgImageFader* mImageFader;
+
+ QSizeF mNextImageSize;
+
+ bool mItemCountChanged;
+ int mRemoveStart;
+ int mRemoveEnd;
+ int mInsertStart;
+ int mInsertEnd;
+ int mColumnCount;
+
+ ItemState mOpenedItemState;
+
+private:
+ Q_DISABLE_COPY(HgMediaWallRenderer)
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgquad.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,161 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGQUAD_H
+#define HGQUAD_H
+
+#include <qvector3d>
+#include <qvector2d>
+#include <qquaternion>
+#include <qvariant>
+
+class HgImage;
+
+/**
+ * Quad class to be used by HgQuadRenderer.
+ */
+class HgQuad
+{
+public:
+ /**
+ * Constructor.
+ */
+ HgQuad();
+ /**
+ * Destructor.
+ */
+ virtual ~HgQuad();
+ /**
+ * Sets the position of the quad.
+ * @param position in 3D space.
+ */
+ void setPosition(const QVector3D& position);
+ /**
+ * Sets the rotation of the quad.
+ * @param rotation as quaternion.
+ */
+ void setRotation(const QQuaternion& rotation);
+ /**
+ * Sets the image to use in this quad.
+ * @param image to use in this quad.
+ */
+ void setImage(const HgImage* image);
+ /**
+ * Toggles quads visible/hidden.
+ * @param visible true to make quad visible.
+ */
+ void setVisible(bool visible);
+ /**
+ * Sets the pivot point of the quad.
+ * @pivot to set for this quad. Quads are considered unit quads so to set pivot for example,
+ * to bottom left corner you would use QVector2D(-0.5f, -0.5f).
+ */
+ void setPivot(const QVector2D& pivot);
+ /**
+ * Sets the scale of the quad.
+ * @param scale scaling 2d vector (appliend before rotation but after pivot is transformed)
+ */
+ void setScale(const QVector2D& scale);
+ /**
+ * Sets user data to this quad.
+ * @param userdata to be carried in this quad. This can be for example to identify object that is represented by this specific quad instance.
+ */
+ void setUserData(const QVariant& data);
+ /**
+ * Gets the image in this quad.
+ * @return pointer HgImage-object carried by this quad.
+ */
+ const HgImage* image() const;
+ /**
+ * Gets the position of this quad.
+ * @return position vector.
+ */
+ const QVector3D& position() const;
+ /**
+ * Gets the roation of this quad.
+ * @return rotation quaternion.
+ */
+ const QQuaternion& rotation() const;
+ /**
+ * Tells whether or not this quad is visible and should be rendered.
+ * @return true if this quad is visible and should be rendered.
+ */
+ bool visible() const;
+ /**
+ * Gets the pivot point of this quad.
+ * @return pivot point applied to this quads trasformation.
+ */
+ const QVector2D& pivot() const;
+ /**
+ * Gets the scale of this quad.
+ * @return scaling applied to this quads transformation.
+ */
+ const QVector2D& scale() const;
+ /**
+ * Gets the user data associated in to this quad.
+ * @return user data carriend by this quad.
+ */
+ const QVariant& userData() const;
+ /**
+ *
+ */
+ HgQuad* copy() const;
+ /**
+ *
+ */
+ void copyFrom(const HgQuad& quad);
+ /*
+ *
+ */
+ void setOuterRotation(const QQuaternion& rot);
+ /*
+ *
+ */
+ const QQuaternion outerRotation() const;
+ /**
+ *
+ */
+ void enableMirrorImage(bool enabled);
+ /**
+ *
+ */
+ bool mirrorImageEnabled() const;
+ /**
+ *
+ */
+ void setAlpha(qreal alpha);
+ /**
+ *
+ */
+ qreal alpha() const;
+private:
+ QVector3D mPosition;
+ QQuaternion mRotation;
+ const HgImage* mImage;
+ bool mVisible;
+ QVector2D mPivot;
+ QVector2D mScale;
+ QVariant mUserData;
+ QQuaternion mOuterRotation;
+ bool mDrawMirror;
+ qreal mAlpha;
+private:
+ Q_DISABLE_COPY(HgQuad)
+};
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgquadrenderer.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,108 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGQUADRENDERER_H
+#define HGQUADRENDERER_H
+
+#include <qlist>
+
+class HgQuad;
+class QPointF;
+class QPainter;
+class QRectF;
+class QMatrix4x4;
+class QPolygonF;
+class HgImage;
+class QImage;
+class HgImageFader;
+/**
+ *
+ * Abstract class to be inherited by differend quad renderer implementations.
+ * One could for example implement this in OpenGL instead of OpenVG.
+ */
+class HgQuadRenderer
+{
+public:
+ /**
+ * Destructor.
+ */
+ virtual ~HgQuadRenderer();
+ /**
+ * Gets the quad at given index.
+ * @return HgQuad-object at index.
+ */
+ virtual HgQuad* quad(int index);
+ /**
+ * Gets the max amount of quads this renderer can draw.
+ * @return max amount of quads.
+ */
+ virtual int quadCount() const;
+ /**
+ * Gets quads index at pointer position.
+ * @param pointer position.
+ * @return quad under the pointer position or -1 if nothing is there.
+ */
+ virtual HgQuad* getQuadAt(const QPointF& point) const = 0;
+ /**
+ * Transform quads with view and projection transformation for rendering.
+ * @param view view transformation matrix.
+ * @param projection transformation matrix.
+ * @rect window rectangle.
+ */
+ virtual void transformQuads(const QMatrix4x4& view, const QMatrix4x4& proj,
+ const QRectF& rect)=0;
+ /**
+ * Draw transformed quads using painter or underlying Native graphics API.
+ * This should be called inside Widgets draw method.
+ * @param rect window rectangle.
+ * @param painter QPainter-object.
+ */
+ virtual void drawQuads(const QRectF& rect, QPainter* painter)=0;
+
+ /**
+ *
+ */
+ virtual bool getQuadTranformedPoints(QPolygonF& points, int index) const=0;
+
+ /**
+ *
+ */
+ virtual void setMirroringPlaneY(qreal mirroringPlaneY);
+
+ /**
+ *
+ */
+ virtual HgImage* createNativeImage()=0;
+
+ /**
+ *
+ */
+ virtual void setImageFader(HgImageFader* fader);
+
+ /**
+ *
+ */
+ virtual QList<HgQuad*> getVisibleQuads(const QRectF& rect) const=0;
+protected:
+ HgQuadRenderer(int maxQuads);
+
+ QList<HgQuad*> mQuads;
+ qreal mMirroringPlaneY;
+ HgImageFader* mImageFader;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgspring.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGSPRING_H
+#define HGSPRING_H
+
+#include <qpoint>
+#include <qobject>
+#include <qtime>
+
+class QTimer;
+
+/**
+ * Spring physics class.
+ */
+class HgSpring : public QObject
+{
+ Q_OBJECT
+public:
+
+ explicit HgSpring();
+ virtual ~HgSpring();
+
+ void setK(qreal K);
+ void setDamping(qreal damping);
+
+ void animateToPos(const QPointF& pos);
+ void gotoPos(const QPointF& pos);
+ void cancel();
+ bool isActive() const;
+
+ const QPointF& startPos() const;
+ const QPointF& pos() const;
+ const QPointF& endPos() const;
+ const QPointF& velocity() const;
+
+ bool updatePositionIfNeeded();
+
+signals:
+ void updated();
+ void started();
+ void ended();
+private slots:
+ void update();
+private:
+ Q_DISABLE_COPY(HgSpring)
+
+ QPointF mStartPos;
+ QPointF mPos;
+ QPointF mEndPos;
+ QPointF mVelocity;
+ qreal mK;
+ qreal mDamping;
+ int mAccumulator;
+ QTimer* mTimer;
+ QTime mPrevTime;
+ bool mDoNotUpdate;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgvgimage.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGVGIMAGE_H
+#define HGVGIMAGE_H
+
+#include <qstring>
+#include <qimage>
+#include <VG/openvg.h>
+#include "HgImage.h"
+
+class HgVgImagePool;
+class HgImageFader;
+class HgVgQuadRenderer;
+/**
+ * Implements HgImage for HgVgQuadRenderer implementation.
+ */
+class HgVgImage : public HgImage
+{
+public:
+ HgVgImage(HgVgQuadRenderer* renderer);
+ virtual ~HgVgImage();
+
+ int width() const;
+ int height() const;
+
+ VGImage image() const;
+
+ int mirrorImageWidth() const;
+ int mirrorImageHeight() const;
+
+ VGImage mirrorImage() const;
+
+ void setImage(QImage& image);
+ void releaseImage();
+
+ void upload(bool mirror=false);
+
+private:
+ VGImage mVgImage;
+ VGImage mMirrorImage;
+ QSize mMirrorSize;
+ QImage mQImage;
+ HgVgQuadRenderer* mRenderer;
+private:
+ Q_DISABLE_COPY(HgVgImage)
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgvgimagepool.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGVGIMAGEPOOL_H_
+#define HGVGIMAGEPOOL_H_
+
+#include <VG/openvg.h>
+#include <qlinkedlist>
+
+class HgVgImagePool
+{
+public:
+ HgVgImagePool(int numImages, int imgWidth, int imgHeight, bool alpha);
+ ~HgVgImagePool();
+ void releaseImage(VGImage image);
+ VGImage getImage();
+private:
+ QLinkedList<VGImage> mFreeImages;
+ QLinkedList<VGImage> mUsedImages;
+};
+
+
+#endif /* HGVGIMAGEPOOL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgvgquadrenderer.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGVGQUADRENDERER_H
+#define HGVGQUADRENDERER_H
+
+#include "hgquadrenderer.h"
+#include <qlist>
+#include <VG/openvg.h>
+#include <qimage>
+
+class QPoint;
+class QPainter;
+class QRectF;
+class QMatrix4x4;
+class HgVgQuad;
+class HgVgImage;
+class HgImageFader;
+class QSize;
+/**
+ * OpenVG implementation of the HgQuadRenderer.
+ */
+class HgVgQuadRenderer: public HgQuadRenderer
+{
+public:
+ HgVgQuadRenderer(int maxQuads);
+ virtual ~HgVgQuadRenderer();
+ virtual HgQuad* getQuadAt(const QPointF& point) const;
+ virtual void transformQuads(const QMatrix4x4& view, const QMatrix4x4& proj,
+ const QRectF& rect);
+ virtual void drawQuads(const QRectF& rect, QPainter* painter);
+ virtual bool getQuadTranformedPoints(QPolygonF& points, int index) const;
+ virtual HgImage* createNativeImage();
+ virtual QList<HgQuad*> getVisibleQuads(const QRectF& rect) const;
+
+ // new functions
+ HgVgImage* defaultImage();
+ QSize imageSize(bool mirror=false) const;
+ HgImageFader* imageFader();
+private:
+
+ QList<HgVgQuad*> mTransformedQuads;
+
+ QList<HgVgQuad*> mSortedQuads;
+
+ HgVgImage* mDefaultVgImage;
+
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgwidgetitem.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: HgWidget private class definition
+*
+*/
+
+
+#ifndef HGWIDGETITEM_H
+#define HGWIDGETITEM_H
+
+#include <QString>
+#include <QPixmap>
+#include <QModelIndex>
+#include <qobject>
+#include <hgvgimage.h>
+
+class HgQuadRenderer;
+class HgImage;
+
+class HgWidgetItem
+{
+public:
+
+ HgWidgetItem(HgQuadRenderer* renderer);
+ HgWidgetItem( HgQuadRenderer* renderer, QImage image, QString title, QString description );
+ virtual ~HgWidgetItem();
+
+ void setImage( QImage image );
+
+ void setTitle( QString title );
+ QString title() const;
+
+ const HgImage* image() const;
+
+ void setDescription( QString description );
+ QString description() const;
+
+ void setModelIndex( const QModelIndex& index);
+ QModelIndex modelIndex() const;
+
+ bool validData() const;
+ bool updateItemData();
+ void releaseItemData();
+
+ bool visibility() const;
+ void setVisibility(bool visible);
+
+private:
+
+ QString mTitle;
+ QString mDescription;
+ QModelIndex mModelIndex;
+ bool mValidData;
+ HgImage* mHgImage;
+ HgQuadRenderer* mRenderer;
+ bool mVisibility;
+
+ Q_DISABLE_COPY(HgWidgetItem)
+};
+
+#endif //HGWIDGETITEM_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/hgwidgets_p.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,127 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGWIDGET_P_H
+#define HGWIDGET_P_H
+
+#include <hgwidgets/hgwidgets.h>
+#include <hbwidget_p.h>
+#include <QTimer>
+#include <QTime>
+
+class QAbstractItemModel;
+class HgContainer;
+class HgScrollBufferManager;
+class QGraphicsLinearLayout;
+class HgIndexFeedback;
+
+class HgWidgetPrivate : public HbWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(HgWidget)
+
+public:
+
+ HgWidgetPrivate();
+ virtual ~HgWidgetPrivate();
+
+ void init(HgContainer *container);
+
+ void setModel(QAbstractItemModel *model);
+
+ void setSelectionModel(QItemSelectionModel *selectionModel);
+ QItemSelectionModel *selectionModel() const;
+
+ void setSelectionMode(HgWidget::SelectionMode mode, bool resetSelection);
+ HgWidget::SelectionMode selectionMode() const;
+ void selectAll();
+ void clearSelection();
+
+ QModelIndex currentIndex() const;
+ void setCurrentIndex(const QModelIndex &index,
+ QItemSelectionModel::SelectionFlags selectionFlag=QItemSelectionModel::NoUpdate);
+
+ void scrollTo(const QModelIndex &index);
+
+ bool getItemOutline(const QModelIndex& index, QPolygonF& points);
+ void aboutToChangeOrientation();
+ void orientationChanged(Qt::Orientation orientation);
+
+ QList<QModelIndex> getVisibleItemIndices() const;
+ Qt::Orientation scrollDirection() const;
+
+ void setIndexFeedbackPolicy( HgWidget::IndexFeedbackPolicy policy);
+ HgWidget::IndexFeedbackPolicy indexFeedbackPolicy() const;
+
+private:
+
+ void clearCurrentModel();
+ void initializeNewModel();
+
+ void adjustGeometry();
+
+ void createScrollBar(Qt::Orientation orientation);
+
+ void setScrollBarPolicy(HgWidget::ScrollBarPolicy policy);
+ void replaceScrollBar(HbScrollBar *scrollBar);
+
+ virtual void updateScrollMetrics( qreal pos = 0 );
+ void prepareScrollBars( qreal pos = 0);
+
+ virtual void updateScrollBar(qreal pos = 0);
+ void displayScrollBar(qreal pos = 0);
+ void setScrollBarMetrics(qreal pos = 0);
+
+ void lostForeground();
+ void gainedForeground();
+
+ // private slot functions
+ void _q_scrollPositionChanged(qreal index, bool scrollBarAnimation);
+ void _q_releaseItems( int releaseStart, int releaseEnd );
+ void _q_requestItems( int requestStart, int requestEnd );
+ void _q_hideScrollBars();
+ void _q_thumbPositionChanged(qreal value, Qt::Orientation orientation);
+ void _q_insertRows(const QModelIndex &parent, int start, int end);
+ void _q_removeRows(const QModelIndex &parent, int start, int end);
+ void _q_moveRows(const QModelIndex &sourceParent, int sourceStart,
+ int sourceEnd, const QModelIndex &destinationParent,
+ int destinationRow);
+ void _q_groovePressed(qreal value, Qt::Orientation orientation);
+
+protected:
+
+ QGraphicsLinearLayout *mLayout;
+
+ HgContainer *mContainer;
+ HgScrollBufferManager *mBufferManager;
+
+ QAbstractItemModel *mModel;
+ QItemSelectionModel *mSelectionModel;
+ QItemSelectionModel *mDefaultSelectionModel;
+
+ HbScrollBar *mScrollBar;
+ HgWidget::ScrollBarPolicy mScrollBarPolicy;
+ bool mAbleToScroll;
+ QTimer mScrollBarHideTimer;
+
+ bool mHandleLongPress;
+ bool mForeground;
+ int mBufferSize;
+ HgIndexFeedback *mIndexFeedback;
+};
+
+#endif //HGWIDGET_p_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/inc/trace.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,148 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Tracing macros, 2nd generation
+*
+*/
+
+#ifndef TRACE_H
+#define TRACE_H
+
+#include <QDebug>
+
+//-----------------------------------------------------------------------------
+// Trace definitions
+//-----------------------------------------------------------------------------
+//
+
+/**
+* Error trace enabled
+*/
+#ifdef _DEBUG
+//#ifdef __WINS__
+ #define ERROR_TRACE
+ #define INFO_TRACE
+ #define TIMESTAMP_TRACE
+ #define FUNC_TRACE
+#else
+ #undef ERROR_TRACE
+ #undef INFO_TRACE
+ #undef TIMESTAMP_TRACE
+ #undef FUNC_TRACE
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+//
+
+/**
+* Trace prefixes for macros with component name.
+*/
+#define _TRACE_PREFIX "[HG]:"
+
+/**
+* Prefix error trace
+*/
+#define _ERROR_PREFIX _TRACE_PREFIX " [ERROR]:"
+
+/**
+* Prefix info trace.
+*/
+#define _INFO_PREFIX _TRACE_PREFIX " [INFO]:"
+
+/**
+* Prefix timestamp trace.
+*/
+#define _TIMESTAMP_PREFIX _TRACE_PREFIX " [TIMESTAMP]:"
+
+//-----------------------------------------------------------------------------
+// Error trace macros
+// Usage: wrap traces in ERROR() macro to allow disabling them in release builds.
+// Use normal stream object operations.
+// Examples:
+// ERROR( "xxx failed" );
+// ERROR( "Test trace arg =" << 999 << "arg2 =" << title() );
+//-----------------------------------------------------------------------------
+//
+#ifdef ERROR_TRACE
+ #define ERROR(trace) {qDebug() << _ERROR_PREFIX << trace;}
+ #define ERROR_PARAM(param) param
+ #define HANDLE_ERROR(trace) {ERROR(trace << "File:" << __FILE__ << ", line:" << __LINE__); __BREAKPOINT();}
+ #define HANDLE_ERROR_BOOL(x) {if (!x) {ERROR(#x << "is false" << "File:" << __FILE__ << ", line:" << __LINE__); __BREAKPOINT();}}
+ #define HANDLE_ERROR_NULL(x) {if (!x) {ERROR(#x << "is NULL" << "File:" << __FILE__ << ", line:" << __LINE__); __BREAKPOINT();}}
+ #define HANDLE_ERROR_NEG(x) {if (x < 0) {ERROR(#x << "=" << x << "File:" << __FILE__ << ", line:" << __LINE__); __BREAKPOINT();}}
+ #define CHECK_ERROR(err, trace) {if (err < 0) ERROR(trace << err);}
+#else //ERROR_TRACE not defined
+ #define ERROR(trace)
+ #define ERROR_PARAM(param)
+ #define HANDLE_ERROR(trace)
+ #define HANDLE_ERROR_BOOL(x)
+ #define HANDLE_ERROR_NULL(x)
+ #define HANDLE_ERROR_NEG(x)
+ #define CHECK_ERROR(err,trace)
+#endif //ERROR_TRACE
+
+//-----------------------------------------------------------------------------
+// Info trace macros
+// Usage: wrap traces in INFO() macro to allow disabling them in release builds.
+// Use normal stream object operations.
+// Examples:
+// INFO( "Test trace" );
+// INFO( "Test trace arg =" << 999 << "arg2 =" << title() );
+//-----------------------------------------------------------------------------
+//
+#ifdef INFO_TRACE
+ #define INFO(trace) {qDebug() << _INFO_PREFIX << trace;}
+ #define INFO_PARAM(param) param
+#else //INFO_TRACE not defined
+ #define INFO(trace)
+ #define INFO_PARAM(param)
+#endif //INFO_TRACE
+
+//-----------------------------------------------------------------------------
+// Function trace macros
+//-----------------------------------------------------------------------------
+//
+#ifdef FUNC_TRACE
+
+ class FuncLog
+ {
+ public:
+ inline FuncLog( const char* func ) : m_func( func )
+ { qDebug() << _TRACE_PREFIX << m_func << "-START"; }
+ inline ~FuncLog() { qDebug() << _TRACE_PREFIX << m_func << "-END"; }
+ private: // Data
+ QString m_func;
+ };
+
+ #define FUNC_LOG FuncLog _fl( __PRETTY_FUNCTION__ );
+#else //FUNC_TRACE not defined
+ #define FUNC_LOG
+#endif //FUNC_TRACE
+
+//-----------------------------------------------------------------------------
+// Timestamp trace macros
+//-----------------------------------------------------------------------------
+//
+#ifdef TIMESTAMP_TRACE
+ #include <QTime>
+ #define TIMESTAMP(trace)\
+ {qDebug() << _TIMESTAMP_PREFIX << "(" << \
+ QTime::currentTime().toString("HH:mm:ss:zzz") << ")" << trace;}
+#else //TIMESTAMP_TRACE not defined
+ #define TIMESTAMP(trace)
+#endif //TIMESTAMP_TRACE
+
+#endif // TRACE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/rom/ganeswidgets.iby Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef GANESWIDGETS_IBY
+#define GANESWIDGETS_IBY
+
+#include <bldvariant.hrh>
+
+#include <data_caging_paths_for_iby.hrh>
+
+file=ABI_DIR\BUILD_DIR\ganeswidgets.dll SHARED_LIB_DIR\ganeswidgets.dll
+data=ZSYSTEM\install\ganeswidgetsstub.sis System\Install\ganeswidgetsstub.sis
+
+#endif //GANESWIDGETS_IBY
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/rom/rom.pri Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+symbian {
+ HGWIDGETS_IBY_DIR = $$section(PWD,":",1)
+
+ exists(/epoc32/include/platform_paths.hrh) {
+ BLD_INF_RULES.prj_exports += "$${LITERAL_HASH}include <platform_paths.hrh>"
+ } else {
+ BLD_INF_RULES.prj_exports += "$${LITERAL_HASH}include <domain\osextensions\platform_paths.hrh>"
+ }
+
+ BLD_INF_RULES.prj_exports += "$$HGWIDGETS_IBY_DIR/ganeswidgets.iby CORE_MW_LAYER_IBY_EXPORT_PATH(ganeswidgets.iby)"
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/sis/ganeswidgets.pkg Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,35 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; Installation file for ganeswidgets DLL
+;
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"GanesWidgets"},(0x10207C66),10,10,0, TYPE=SA, RU
+
+;Localised Vendor name
+%{"Nokia"}
+
+;Unique Vendor name
+:"Nokia"
+
+;Supports Series 60 v 5.0
+[0x1028315F], 0, 0, 0, {"S60ProductID"}
+
+;Files to install
+;GanesWidgets
+"\epoc32\release\armv5\urel\ganeswidgets.dll" -"c:\sys\bin\ganeswidgets.dll"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/sis/ganeswidgetsstub.pkg Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,32 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; Installation file for ganeswidgets library stub for IAD
+;
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"ganeswidgets"},(0x10207C66),10,0,0, TYPE=SA
+
+;Localised Vendor name
+%{"Nokia"}
+
+;Unique Vendor name
+:"Nokia"
+
+;Files to install
+;ganeswidgets
+"" - "z:\sys\bin\ganeswidgets.dll"
Binary file ganeswidgets/sis/ganeswidgetsstub.sis has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/sis/stub.pri Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+symbian {
+ GANESWIDGETS_STUB_DIR = $$section(PWD,":",1)
+
+ BLD_INF_RULES.prj_exports += "$$GANESWIDGETS_STUB_DIR/ganeswidgetsstub.sis /epoc32/data/z/system/install/ganeswidgetsstub.sis"
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/HgContainer.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,960 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QGesture>
+#include <QPainter>
+#include <QTimer>
+#include <hbgridviewitem>
+#include <hbmainwindow>
+#include "hgcontainer.h"
+#include "hgmediawallrenderer.h"
+#include "hgquad.h"
+#include "hgvgquadrenderer.h"
+#include "hgvgimage.h"
+#include "hgwidgetitem.h"
+#include "trace.h"
+
+#include <hbgridviewitem>
+#include <hbgridview>
+#include <hbiconitem>
+#include <qabstractitemmodel>
+#include "hglongpressvisualizer.h"
+
+static const qreal KSpringKScrolling(50.0);
+static const qreal KSpringKScrollBar(10.0);
+static const qreal KSpringDampingScrolling(20.0);
+static const qreal KSpringDampingScrollBar(5.0);
+static const qreal KFramesToZeroVelocity(60.0);
+static const int KLongTapDuration(400);
+
+
+HgContainer::HgContainer(QGraphicsItem* parent) :
+ HbWidget(parent),
+ mQuadRenderer(0),
+ mRenderer(0),
+ mTapCount(0),
+ mAnimateUsingScrollBar(false),
+ mSelectionMode(HgWidget::NoSelection),
+ mSelectionModel(0),
+ mMarkImage(0),
+ mSpringVelAtDragStart(0),
+ mDragged(false),
+ mFramesDragged(0),
+ mHitItemView(NULL),
+ mLongPressVisualizer(NULL),
+ mLongPressTimer(NULL),
+ mHitItemIndex(NULL)
+{
+ FUNC_LOG;
+
+ grabGesture(Qt::PanGesture);
+ grabGesture(Qt::TapGesture);
+ grabGesture(Qt::TapAndHoldGesture);
+}
+
+HgContainer::~HgContainer()
+{
+ FUNC_LOG;
+
+ for (QList<HgWidgetItem*>::iterator i = mItems.begin(); i != mItems.end(); ++i) {
+ delete (*i);
+ }
+ mItems.clear();
+ delete mMarkImage;
+ delete mRenderer;
+}
+
+void HgContainer::setItemCount(int itemCount)
+{
+ FUNC_LOG;
+
+ mItems.clear();
+ for (int i=0; i<itemCount; i++) {
+ HgWidgetItem* item = new HgWidgetItem(mQuadRenderer);
+ mItems.append(item);
+ }
+}
+
+int HgContainer::itemCount() const
+{
+ return mItems.count();
+}
+
+int HgContainer::rowCount() const
+{
+ return mRenderer ? mRenderer->getRowCount() : 0;
+}
+
+QList<HgWidgetItem*> HgContainer::items() const
+{
+ return mItems;
+}
+
+HgWidgetItem* HgContainer::itemByIndex(const QModelIndex& index) const
+{
+ foreach (HgWidgetItem* item, mItems) {
+ if (item->modelIndex() == index)
+ return item;
+ }
+
+ return 0;
+}
+
+HgWidgetItem* HgContainer::itemByIndex(const int& index) const
+{
+ if (mItems.count() > index && index >= 0)
+ return mItems.at(index);
+ else
+ return 0;
+}
+
+/*!
+ Changes the selection model of the container.
+ Ownership is not transferred.
+ Widget is redrawn to make new selection visible.
+*/
+void HgContainer::setSelectionModel(QItemSelectionModel *selectionModel)
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(selectionModel); // Parameter is always a valid QItemSelectionModel
+
+ if (mSelectionModel != selectionModel) {
+ if (mSelectionModel) { // mSelectionModel is 0 when called first time
+ mSelectionModel->disconnect(SIGNAL(currentChanged(QModelIndex,QModelIndex)), this);
+
+ if (mSelectionModel->currentIndex().isValid() &&
+ !(selectionModel->currentIndex().isValid())) {
+ selectionModel->setCurrentIndex(mSelectionModel->currentIndex(),
+ QItemSelectionModel::Current);
+ }
+ }
+ mSelectionModel = selectionModel;
+ connect(mSelectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ SLOT(updateByCurrentIndex(QModelIndex)));
+ update();
+ }
+}
+
+/*!
+ Returns the selection model of the container.
+ Ownership is not transferred.
+*/
+QItemSelectionModel *HgContainer::selectionModel() const
+{
+ FUNC_LOG;
+
+ return mSelectionModel;
+}
+
+/*!
+ Changes the selection mode of the container (no selection/multiselection).
+*/
+void HgContainer::setSelectionMode(HgWidget::SelectionMode mode, bool resetSelection)
+{
+ FUNC_LOG;
+
+ if (mSelectionMode != mode) {
+ mSelectionMode = mode;
+
+ if (mSelectionModel && resetSelection) {
+ mSelectionModel->clearSelection();
+ update();
+ }
+ }
+}
+
+/*!
+ Returns the selection mode of the container (no selection/multiselection).
+*/
+HgWidget::SelectionMode HgContainer::selectionMode() const
+{
+ FUNC_LOG;
+
+ return mSelectionMode;
+}
+
+void HgContainer::dimensions(qreal &screenSize, qreal &worldSize)
+{
+ const QRectF containerRect(rect());
+
+ // TODO, fix logic
+ if (containerRect.height() > containerRect.width()) {
+ // assume we are in portrait mode, ofcource this might not be the case
+ screenSize = containerRect.height()/(mRenderer->getImageSize().height() + mRenderer->getSpacing().height());
+ worldSize = worldWidth();
+ }
+ else{
+ screenSize = containerRect.width()/(mRenderer->getImageSize().width() + mRenderer->getSpacing().width());
+ worldSize = worldWidth();
+ }
+}
+
+Qt::Orientation HgContainer::orientation() const
+{
+ FUNC_LOG;
+
+ return mRenderer->getOrientation();
+}
+
+void HgContainer::setOrientation(Qt::Orientation orientation, bool animate)
+{
+ FUNC_LOG;
+
+ mRenderer->setOrientation(orientation, animate);
+}
+
+void HgContainer::scrollToPosition(qreal value, bool animate)
+{
+ FUNC_LOG;
+
+ scrollToPosition(QPointF(value*worldWidth(), 0), animate);
+}
+
+void HgContainer::scrollToPosition(const QPointF& pos, bool animate)
+{
+ FUNC_LOG;
+
+ mAnimateUsingScrollBar = animate;
+ initSpringForScrollBar();
+
+ if (animate)
+ mSpring.animateToPos(pos);
+ else
+ mSpring.gotoPos(pos);
+}
+
+void HgContainer::scrollTo(const QModelIndex &index)
+{
+ FUNC_LOG;
+
+ if (index.isValid()) {
+ scrollToPosition(QPointF(index.row(), index.column()), false);
+ }
+}
+
+void HgContainer::itemDataChanged(const QModelIndex &firstIndex, const QModelIndex &lastIndex)
+{
+ FUNC_LOG;
+
+ // TODO, fix this
+ int columns = firstIndex.model()->columnCount(QModelIndex());
+
+ // Check this!!
+ int index = columns*firstIndex.row()+firstIndex.column();
+ int index2 = columns*lastIndex.row()+lastIndex.column();
+
+ // convert indeces to match one dimensional item array
+ itemDataChanged( index, index2 );
+}
+
+void HgContainer::addItems(int start, int end)
+{
+ FUNC_LOG;
+
+ int first = qBound(0, start, mItems.count()-1);
+ int last = qBound(0, end, mItems.count()-1);
+ for (int i = 0; i <= end-start; i++) {
+ HgWidgetItem* item = new HgWidgetItem(mQuadRenderer);
+ mItems.insert(start, item);
+ }
+}
+
+void HgContainer::removeItems(int start, int end)
+{
+ FUNC_LOG;
+
+ int first = qBound(0, start, mItems.count()-1);
+ int last = qBound(0, end, mItems.count()-1);
+ for (int i = last; i >= first; i--) {
+ delete mItems.at(i);
+ mItems.removeAt(i);
+ }
+}
+
+void HgContainer::moveItems(int start, int end, int destination)
+{
+ FUNC_LOG;
+
+ int first = qBound(0, start, mItems.count()-1);
+ int last = qBound(0, end, mItems.count()-1);
+ int target = qBound(0, destination, mItems.count()-1);
+
+ if (target < first) {
+ for (int i = 0; i <= last-first; i++) {
+ mItems.move(first+i, target+i);
+ }
+ }
+ else if (target > last) {
+ for (int i = 0; i <= last-first; i++) {
+ mItems.move(last-i, target);
+ }
+ }
+ // else do nothing
+}
+
+int HgContainer::imageCount() const
+{
+ return mItems.count();
+}
+
+const HgImage *HgContainer::image(int index) const
+{
+ return mItems[index]->image();
+}
+
+int HgContainer::flags(int index) const
+{
+ if (index >= 0 && index < itemCount()) {
+ if (mSelectionModel && mSelectionModel->isSelected(mSelectionModel->model()->index(index, 0))) {
+ return 1; // TODO: Assign flag to mark indicator
+ }
+ }
+ return 0;
+}
+
+const HgImage *HgContainer::indicator(int flags) const
+{
+ if (flags & 1) {
+ return mMarkImage;
+ }
+
+ return 0;
+}
+
+void HgContainer::updateBySpringPosition()
+{
+ update();
+
+ // spring works always in one dimension, that is, x coord.
+ qreal pos = mSpring.pos().x();
+
+ onScrollPositionChanged(pos);
+
+ emit scrollPositionChanged(pos, mAnimateUsingScrollBar);
+}
+
+void HgContainer::redraw()
+{
+ update();
+}
+
+void HgContainer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
+
+ if (mSpring.updatePositionIfNeeded())
+ {
+ // spring works always in one dimension, that is, x coord.
+ qreal pos = mSpring.pos().x();
+ onScrollPositionChanged(pos);
+ emit scrollPositionChanged(pos, mAnimateUsingScrollBar);
+ }
+
+ QRectF vp = painter->viewport();
+ QRectF rts = mapRectToScene(rect());
+ QRectF r;
+
+ // transform rectangle to vg space &
+ // rotate rendering according to orientation
+ if (mainWindow()->orientation() == Qt::Horizontal) {
+ r = QRectF(vp.width()-(rts.height()+rts.top()), rts.left(), rts.height(), rts.width());
+ mRenderer->setCameraRotationZ(-90);
+ }
+ else {
+ r = QRectF(rts.left(), vp.height()-(rts.height()+rts.top()), rts.width(), rts.height());
+ mRenderer->setCameraRotationZ(0);
+ }
+
+ // interpolate spring velocity towards zero, this is done
+ // so that spring velocity for rendering doesn't drop directly to
+ // zero when dragging starts
+ qreal springVel = mSpring.velocity().x();
+ if (mDragged) {
+ qreal t = qBound(mFramesDragged / KFramesToZeroVelocity, 0.0f, 1.0f);
+ springVel = mSpringVelAtDragStart * (1.0f - t);
+ mFramesDragged++;
+ }
+
+ // setup rendering and draw the current view
+ mRenderer->setCameraDistance(getCameraDistance(springVel));
+ mRenderer->setCameraRotationY(getCameraRotationY(springVel));
+ mRenderer->setRect(r);
+ mRenderer->draw(mSpring.startPos(), mSpring.pos(), mSpring.endPos(),
+ springVel, painter);
+
+}
+
+void HgContainer::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ FUNC_LOG;
+
+ HbWidget::resizeEvent(event);
+}
+
+// this needs to be implemented for gesture framework to work
+void HgContainer::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+void HgContainer::gestureEvent(QGestureEvent *event)
+{
+ FUNC_LOG;
+
+ // Event may contain more than one gesture type
+ if (QGesture *gesture = event->gesture(Qt::TapAndHoldGesture)) {
+ QTapAndHoldGesture *tapAndHold = static_cast<QTapAndHoldGesture *>(gesture);
+ handleLongTap(tapAndHold->state(),
+ mapFromScene(event->mapToGraphicsScene(tapAndHold->position())));
+ }
+ else if (QGesture *gesture = event->gesture(Qt::TapGesture)) {
+ // Tap and hold is not working yet in HW, tap gesture is delivered instead
+ QTapGesture *tap = static_cast<QTapGesture *>(gesture);
+ handleTap(tap->state(),
+ mapFromScene(event->mapToGraphicsScene(tap->position())));
+ }
+ else if (QGesture *pan = event->gesture(Qt::PanGesture)) {
+ handlePanning(static_cast<QPanGesture*>(pan));
+ }
+}
+
+void HgContainer::init(Qt::Orientation scrollDirection)
+{
+ FUNC_LOG;
+
+ mRenderer = createRenderer();
+ if (mRenderer->coverflowModeEnabled())
+ mRenderer->setOrientation(Qt::Horizontal, false);
+ else
+ mRenderer->setOrientation(scrollDirection, false);
+
+ mQuadRenderer = mRenderer->getRenderer();
+
+ QImage markImage(":/images/mark.svg");
+ if (markImage.isNull()) {
+ ERROR("Failed to load :/images/mark.svg");
+ }
+ mMarkImage = mQuadRenderer->createNativeImage();
+ HANDLE_ERROR_NULL(mMarkImage);
+ if (mMarkImage) {
+ mMarkImage->setImage(markImage);
+ }
+
+ connect(&mSpring, SIGNAL(updated()), SLOT(updateBySpringPosition()));
+ connect(&mSpring, SIGNAL(ended()), SLOT(onScrollingEnded()));
+ connect(&mSpring, SIGNAL(ended()), SIGNAL(scrollingEnded()));
+ connect(&mSpring, SIGNAL(started()), SIGNAL(scrollingStarted()));
+ connect(mRenderer, SIGNAL(renderingNeeded()), SLOT(redraw()));
+
+}
+
+qreal HgContainer::worldWidth() const
+{
+ return (qreal)mRenderer->getWorldWidth();
+}
+
+void HgContainer::initSpringForScrollBar()
+{
+ FUNC_LOG;
+
+ mSpring.setDamping(KSpringDampingScrollBar);
+ mSpring.setK(KSpringKScrollBar);
+}
+
+void HgContainer::initSpringForScrolling()
+{
+ FUNC_LOG;
+
+ mSpring.setDamping(KSpringDampingScrolling);
+ mSpring.setK(KSpringKScrolling);
+}
+
+void HgContainer::boundSpring()
+{
+ FUNC_LOG;
+
+ qreal x = mSpring.endPos().x();
+ x = qBound(qreal(0), x, worldWidth());
+ if (mRenderer->coverflowModeEnabled()) {
+ qreal i = floorf(x);
+ x = (x - i > 0.5f) ? ceilf(x) : i;
+ mSpring.animateToPos(QPointF(x, 0));
+ }
+
+ mSpring.animateToPos(QPointF(x, 0));
+
+}
+
+void HgContainer::handlePanning(QPanGesture *gesture)
+{
+ mAnimateUsingScrollBar = false;
+ initSpringForScrolling();
+
+ qreal pos = mSpring.pos().x();
+ qreal delta(0);
+ qreal itemSide(0);
+
+ if (mRenderer->getOrientation() == mainWindow()->orientation()) {
+ delta = gesture->delta().y();
+ }
+ else {
+ delta = gesture->delta().x();
+ }
+
+ if (mRenderer->getOrientation() == Qt::Vertical)
+ itemSide = mRenderer->getImageSize().height()+mRenderer->getSpacing().height();
+ else
+ itemSide = mRenderer->getImageSize().width()+mRenderer->getSpacing().width();
+
+ if (gesture->state() == Qt::GestureStarted) {
+ mOffsetAtDragStart = gesture->offset();
+ }
+ else if (gesture->state() == Qt::GestureUpdated) {
+ QPointF offset = gesture->offset();
+ QPointF offsetDelta = offset - mOffsetAtDragStart;
+ if (!mDragged && (qAbs(offsetDelta.x()) > 8 ||
+ qAbs(offsetDelta.y()) > 8)) {
+ mDragged = true;
+ mDrag.reset(delta, mSpring.pos().x());
+ mDragged = true;
+ mSpringVelAtDragStart = mSpring.velocity().x();
+ mFramesDragged = 0;
+ }
+
+ if (mDragged)
+ {
+ emit scrollingStarted();
+
+ qreal newPosition = mDrag.update(delta, pos, itemSide);
+ if (qAbs(newPosition - mSpring.pos().x()) > 0.01f)
+ {
+ mSpring.gotoPos(QPointF(newPosition, 0));
+ update();
+ }
+ }
+ }
+ else if (mDragged && gesture->state() == Qt::GestureFinished) {
+ mDrag.update(delta, pos, itemSide);
+ mDragged = false;
+ qreal newPos(0);
+ if (mDrag.finish(pos, mRenderer->coverflowModeEnabled(), newPos)) {
+ mSpring.animateToPos(QPointF(qBound(qreal(0), newPos, worldWidth()), 0));
+ HgWidgetItem* item = itemByIndex(newPos);
+ if (item && item->modelIndex() != mSelectionModel->currentIndex()) {
+ // mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
+ }
+ }
+ else {
+ boundSpring();
+ }
+ }
+ else if (gesture->state() == Qt::GestureCanceled) {
+ boundSpring();
+ }
+}
+
+
+
+void HgContainer::handleTap(Qt::GestureState state, const QPointF &pos)
+{
+ FUNC_LOG;
+
+ if (state == Qt::GestureStarted) {
+ mTapDuration.start();
+
+ startLongPressWatcher(pos);
+ }
+ else if (state == Qt::GestureCanceled)
+ {
+ stopLongPressWatcher();
+ }
+ else if (state == Qt::GestureFinished) {
+
+ stopLongPressWatcher();
+ handleItemAction(pos, mTapDuration.elapsed() > KLongTapDuration ? LongTap : NormalTap);
+ }
+}
+
+void HgContainer::handleLongTap(Qt::GestureState state, const QPointF &pos)
+{
+ FUNC_LOG;
+
+ mAnimateUsingScrollBar = false;
+ initSpringForScrolling();
+
+ if (state == Qt::GestureFinished) {
+ handleItemAction(pos, LongTap);
+ }
+}
+
+/*!
+ Handle tap, lang tap and double tap action.
+ Finds out the item in the tap position and sends out suitable signal,
+ Sets the item as the current item and in multiselection mode toggles the
+ item selection status.
+*/
+void HgContainer::handleItemAction(const QPointF &pos, ItemActionType action)
+{
+ FUNC_LOG;
+
+ // If there is content, mSelectionModel must always exist - either default or client-provided
+ if (!mSelectionModel) return;
+
+ mHitItem = getItemAt(pos, mHitItemIndex);
+ if (mHitItem)
+ {
+ int index = mHitItemIndex;
+
+
+ HgWidgetItem* item = itemByIndex(index);
+ if (item && action != DoubleTap) {
+ mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
+
+ if (action == LongTap) {
+ INFO("Long tap:" << item->modelIndex().row());
+
+ if (!mRenderer->coverflowModeEnabled())
+ selectItem();
+
+ emit longPressed(item->modelIndex(), pos);
+ }
+ else if (mSelectionMode == HgWidget::MultiSelection) {
+ INFO("Select:" << item->modelIndex().row());
+ mSelectionModel->select(item->modelIndex(), QItemSelectionModel::Toggle);
+ update(); // It would be enough to update the item
+ }
+ else if (mSelectionMode == HgWidget::SingleSelection) {
+ INFO("Select:" << item->modelIndex().row());
+ mSelectionModel->select(item->modelIndex(), QItemSelectionModel::ClearAndSelect);
+ update(); // It would be enough to update the item
+ }
+ else if (mSelectionMode == HgWidget::ContiguousSelection) {
+ QModelIndex newSelected = item->modelIndex();
+ QModelIndexList oldSelection = mSelectionModel->selectedIndexes();
+ INFO("Select:" << newSelected.row());
+ if (oldSelection.count() > 0 && !mSelectionModel->isSelected(newSelected)) {
+ if (newSelected.row() < oldSelection.front().row()) {
+ mSelectionModel->select(QItemSelection(newSelected, oldSelection.back()),
+ QItemSelectionModel::Select);
+ }
+ else { // newSelected.row() > oldSelection.back().row()
+ mSelectionModel->select(QItemSelection(oldSelection.front(), newSelected),
+ QItemSelectionModel::Select);
+ }
+ }
+ else {
+ mSelectionModel->select(newSelected, QItemSelectionModel::Select);
+ }
+ update(); // It would be enough to update the item
+ }
+ else {
+ INFO("Tap:" << item->modelIndex().row());
+
+ if (mRenderer->coverflowModeEnabled())
+ {
+ if (qAbs(qreal(index) - mSpring.pos().x()) < 0.01f)
+ {
+ emit activated(item->modelIndex());
+ }
+ else
+ {
+ mSpring.animateToPos(QPointF(index, 0));
+ }
+ }
+ else
+ {
+ selectItem();
+ emit activated(item->modelIndex());
+ }
+
+ }
+ }
+ }
+ else {
+ INFO("No quad at pos:" << pos);
+
+ unselectItem();
+ }
+}
+
+bool HgContainer::getItemPoints(int index, QPolygonF& points)
+{
+ QPolygonF poly;
+ if (!mRenderer->getItemPoints(index, poly))
+ return false;
+
+ bool invertible;
+ QTransform t = qtToVgTransform().inverted(&invertible);
+
+ points = t.map(poly);
+ return true;
+}
+
+QList<QModelIndex> HgContainer::getVisibleItemIndices() const
+{
+ QList<HgQuad*> quads = mRenderer->getVisibleQuads();
+ QList<QModelIndex> result;
+ for (int i = 0; i < quads.count(); i++) {
+ bool ok;
+ int index = quads.at(i)->userData().toInt(&ok);
+ result.append(itemByIndex(index)->modelIndex());
+ }
+ qSort(result);
+ return result;
+}
+
+void HgContainer::itemDataChanged(const int &firstIndex, const int &lastIndex)
+{
+ FUNC_LOG;
+
+ // TODO FIX THIS FUNCTION!!!!!!!!!!!!!!!!!!!!!!
+
+ int firstItemOnScreen = 0, lastItemOnScreen = 0;
+ firstItemOnScreen = mSpring.pos().x();
+ firstItemOnScreen *= rowCount();
+
+ // This code doesnt take into count if there is some empty space at the
+ // beginning or at the end of the widget
+
+ int itemsOnScreen = 0;
+ if (mRenderer->getOrientation() == Qt::Vertical) {
+ itemsOnScreen = this->rect().height()/mRenderer->getImageSize().height();
+ itemsOnScreen += rowCount();
+ }
+ else {
+ // Doesnt work here. Use some magic for now.
+ itemsOnScreen = this->rect().width()/mRenderer->getImageSize().width();
+ itemsOnScreen += 4;
+ }
+ itemsOnScreen *= rowCount();
+ lastItemOnScreen = firstItemOnScreen+itemsOnScreen;
+
+ if ((firstIndex >= firstItemOnScreen && firstIndex <= lastItemOnScreen) ||
+ (lastIndex >= firstItemOnScreen && lastIndex <= lastItemOnScreen)) {
+ update( this->rect() );
+ }
+}
+
+void HgContainer::selectItem()
+{
+ // TODO: replace this with own selection implementation
+
+ if (mHitItemView)
+ {
+ delete mHitItemView;
+ mHitItemView = NULL;
+ }
+
+ mHitItemView = new HbGridViewItem(this);
+ mHitItemView->setVisible(false);
+
+ QModelIndex modelIndex = mItems[mHitItemIndex]->modelIndex();
+ const QAbstractItemModel* model = modelIndex.model();
+ mHitItemView->resize(mRenderer->getImageSize().width() + 10,
+ mRenderer->getImageSize().height() + 10);
+
+ QVariant iconVariant = model->data(modelIndex, Qt::DecorationRole);
+ mHitItemPixmap = iconVariant.value<QPixmap>();
+ HbIcon icon(mHitItemPixmap);
+
+ QGraphicsItem* item = mHitItemView->style()->createPrimitive(HbStyle::P_GridViewItem_icon, mHitItemView);
+ HbIconItem *iconItem = static_cast<HbIconItem*>(item);
+ iconItem->setIcon(icon);
+ iconItem->setAlignment(Qt::AlignCenter);
+ iconItem->setAspectRatioMode(Qt::KeepAspectRatio);
+
+ mHitItemView->setModelIndex(modelIndex);
+ mHitItemView->setPos(QPointF(-10,-10));
+ mHitItemView->setPressed(true, false);
+ mHitItemView->updatePrimitives();
+
+}
+
+void HgContainer::updateSelectedItem()
+{
+ if (!mHitItemView || mHitItemIndex == -1)
+ return;
+
+ QPolygonF points;
+ if (!getItemPoints(mHitItemIndex, points))
+ {
+ // the item was not rendered, we must hide
+ // our qt item
+ mHitItemView->setVisible(false);
+ }
+
+ if (mHitItemPixmap.isNull())
+ {
+ mHitItemView->setVisible(false);
+ return;
+ }
+
+ QPolygonF img;
+ img.append(QPointF(0,mHitItemPixmap.height()));
+ img.append(QPointF(mHitItemPixmap.width(),mHitItemPixmap.height()));
+ img.append(QPointF(mHitItemPixmap.width(),0));
+ img.append(QPointF(0,0));
+
+ QTransform t;
+ QTransform::quadToQuad(img, points, t);
+
+ mHitItemView->setTransform(t);
+ mHitItemView->setVisible(true);
+}
+
+void HgContainer::unselectItem()
+{
+ mHitItemIndex = -1;
+ if (mHitItemView)
+ {
+ mHitItemView->setPressed(false, false);
+ mHitItemView->setVisible(false);
+ }
+}
+
+void HgContainer::updateLongPressVisualizer()
+{
+ int elapsed = mLongTapDuration.elapsed();
+
+ if (elapsed > 80)
+ {
+ int frame = 100.0f * qreal(elapsed - 80) / qreal(KLongTapDuration - 80);
+ mLongPressVisualizer->setFrame(frame);
+ }
+}
+
+void HgContainer::updateByCurrentIndex(const QModelIndex ¤t)
+{
+ handleCurrentChanged(current);
+}
+
+HgWidgetItem* HgContainer::getItemAt(const QPointF& pos, int& index)
+{
+ QPointF p = mapQtToVg(pos);
+ HgQuad* quad = mRenderer->getQuadAt(p);
+ if (quad)
+ {
+ bool ok;
+ index = quad->userData().toInt(&ok);
+
+ HgWidgetItem* item = itemByIndex(index);
+ return item;
+ }
+ return NULL;
+}
+
+void HgContainer::startLongPressWatcher(const QPointF& pos)
+{
+ if (!mLongPressVisualizer)
+ {
+ mLongPressVisualizer = new HgLongPressVisualizer(this);
+ mLongPressVisualizer->setZValue(zValue()+1);
+ }
+
+ mLongPressVisualizer->start(pos);
+
+ if (!mLongPressTimer)
+ {
+ mLongPressTimer = new QTimer(this);
+ QObject::connect(mLongPressTimer, SIGNAL(timeout()), this, SLOT(updateLongPressVisualizer()));
+ }
+
+ mLongPressTimer->start(20);
+
+ mLongTapDuration.start();
+}
+
+void HgContainer::stopLongPressWatcher()
+{
+ if (mLongPressTimer && mLongPressVisualizer)
+ {
+ mLongPressTimer->stop();
+ mLongPressVisualizer->stop();
+ }
+}
+
+QTransform HgContainer::qtToVgTransform() const
+{
+ QTransform t;
+ if (mainWindow()->orientation() == Qt::Vertical)
+ {
+ t.translate(0, rect().height());
+ t.scale(1, -1);
+ }
+ else // horizontal
+ {
+ t.translate(rect().height(), 0);
+ t.scale(-1, 1);
+ t.translate(0, rect().width());
+ t.rotate(-90, Qt::ZAxis);
+ }
+ return t;
+}
+
+QPointF HgContainer::mapQtToVg(const QPointF& p) const
+{
+ QTransform t = qtToVgTransform();
+ return t.map(p);
+}
+
+qreal HgContainer::getCameraDistance(qreal springVelocity)
+{
+ Q_UNUSED(springVelocity)
+ return 0;
+}
+
+qreal HgContainer::getCameraRotationY(qreal springVelocity)
+{
+ Q_UNUSED(springVelocity)
+ return 0;
+}
+
+void HgContainer::handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex)
+{
+ Q_UNUSED(pos)
+ Q_UNUSED(hitItem)
+ Q_UNUSED(hitItemIndex)
+}
+
+void HgContainer::handleLongTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex)
+{
+ Q_UNUSED(pos)
+ Q_UNUSED(hitItem)
+ Q_UNUSED(hitItemIndex)
+}
+
+void HgContainer::onScrollPositionChanged(qreal pos)
+{
+ Q_UNUSED(pos)
+}
+
+void HgContainer::handleCurrentChanged(const QModelIndex ¤t)
+{
+ Q_UNUSED(current)
+ // By default do nothing
+}
+
+void HgContainer::onScrollingEnded()
+{
+/* int index;
+ HgWidgetItem* item = getItemAt(rect().center(), index);
+ if (item && item->modelIndex() != mSelectionModel->currentIndex()) {
+ mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
+ }*/
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/HgImageFader.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+/*
+ * HgImageFader.cpp
+ *
+ * Created on: Feb 10, 2010
+ * Author: anpentti
+ */
+
+#include "HgImageFader.h"
+#include "hgimage.h"
+
+HgImageFader::HgImageFader()
+{
+ QObject::connect(&mTimer, SIGNAL(timeout()), this, SLOT(doFading()));
+}
+
+HgImageFader::~HgImageFader()
+{
+ if (mTimer.isActive())
+ mTimer.stop();
+}
+
+void HgImageFader::addImage(HgImage* image)
+{
+ mImages.push_back(image);
+}
+
+void HgImageFader::removeImage(HgImage* image)
+{
+ mImages.removeOne(image);
+}
+
+void HgImageFader::fadeImages()
+{
+ if (!mImages.empty() && !mTimer.isActive())
+ {
+ mTimer.start(10);
+ }
+}
+
+void HgImageFader::doFading()
+{
+ QLinkedList<HgImage*>::iterator i = mImages.begin();
+ while (i != mImages.end())
+ {
+ HgImage* image = (*i);
+ image->setAlpha(image->alpha() + 0.1f);
+ if (image->alpha() >= 1.0f)
+ {
+ image->setAlpha(1.0f);
+ i = mImages.erase(i);
+ }
+ else
+ {
+ i++;
+ }
+ }
+
+ //emit doUpdate();
+
+ if (mImages.empty())
+ {
+ mTimer.stop();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/HgScrollBufferManager.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,360 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <QTimer>
+
+#include "HgScrollBufferManager.h"
+#include "trace.h"
+
+// -----------------------------------------------------------------------------
+// HgScrollBufferManager::HgScrollBufferManager()
+// -----------------------------------------------------------------------------
+//
+HgScrollBufferManager::HgScrollBufferManager(
+ int bufferSize,
+ int bufferTreshold,
+ int initialPosition,
+ int totalCount )
+: mBufferSize( bufferSize ),
+ mBufferTreshold( bufferTreshold ),
+ mBufferPosition( initialPosition ),
+ mDiff(0),
+ mTotalCount( totalCount ),
+ mResetOrdered(false),
+ mRequestStart(0),
+ mRequestCount(0),
+ mReleaseStart(0),
+ mReleaseCount(0)
+ {
+ init();
+ }
+
+// -----------------------------------------------------------------------------
+// HgScrollBufferManager::init()
+// -----------------------------------------------------------------------------
+//
+void HgScrollBufferManager::init()
+ {
+ mResetOrdered = ETrue;
+ mTimer.setSingleShot(true);
+ connect(&mTimer, SIGNAL(timeout()), this, SLOT(timeout()));
+ }
+
+// -----------------------------------------------------------------------------
+// HgScrollBufferManager::~HgScrollBufferManager()
+// -----------------------------------------------------------------------------
+//
+HgScrollBufferManager::~HgScrollBufferManager()
+ {
+ mTimer.stop();
+ }
+
+// -----------------------------------------------------------------------------
+// HgScrollBufferManager::resetBuffer()
+// -----------------------------------------------------------------------------
+//
+void HgScrollBufferManager::resetBuffer( int aPosition, int totalCount )
+ {
+ if( !mResetOrdered )
+ {
+ // release Old buffer
+ mReleaseStart = mBufferPosition;
+ mReleaseCount = mBufferSize;
+ }
+
+ // set position and count
+ mBufferPosition = aPosition - (mBufferSize / 2);
+ mTotalCount = totalCount;
+ mDiff = 0;
+
+ if( mBufferPosition + mBufferSize > mTotalCount - 1 )
+ {
+ mBufferPosition = mTotalCount - mBufferSize;
+ }
+
+ if(mBufferPosition < 0 )
+ {
+ mBufferPosition = 0;
+ }
+
+ //request new Buffer
+ mRequestStart = mBufferPosition;
+ mRequestCount = mBufferSize;
+ mResetOrdered = ETrue;
+ asyncUpdate();
+ }
+
+void HgScrollBufferManager::scrollPositionChanged( int newPosition )
+ {
+ // If all the items fit in the buffer no need to move the buffer.
+ if( mTotalCount <= mBufferSize ) return;
+
+ bool forceUpdate = EFalse;
+ newPosition -= mBufferSize / 2; // normalize index to Buffer start
+
+ if(newPosition < 0)
+ {
+ newPosition = 0;
+ forceUpdate = ETrue;
+ }
+ else if( newPosition > mTotalCount - mBufferSize )
+ {
+ newPosition = mTotalCount - mBufferSize;
+ forceUpdate = ETrue;
+ }
+
+ mDiff = mBufferPosition - newPosition;
+
+ // Too large change reset whole buffer
+ if( mDiff >= mBufferSize || -mDiff >= mBufferSize || mResetOrdered )
+ {
+ resetBuffer(newPosition + (mBufferSize/2), mTotalCount );
+ }
+ // Move Up
+ else if( mDiff >= mBufferTreshold )
+ {
+ mRequestCount = mDiff;
+ mReleaseCount = mDiff;
+ asyncUpdate();
+ }
+ // Move Down
+ else if( -mDiff >= mBufferTreshold )
+ {
+ mRequestCount = -mDiff;
+ mReleaseCount = -mDiff;
+ asyncUpdate();
+ }
+ // Top or bottom has been reached
+ else if( forceUpdate && mDiff )
+ {
+ int diff = mDiff < 0 ? -mDiff : mDiff;
+ mRequestCount = diff;
+ mReleaseCount = diff;
+ asyncUpdate();
+ }
+ }
+
+void HgScrollBufferManager::timeout()
+{
+ if(mResetOrdered)
+ {
+ mResetOrdered = EFalse;
+ }
+ else
+ {
+ if(mDiff < 0)
+ {
+ mReleaseStart = mBufferPosition;
+ mRequestStart = mBufferPosition + mBufferSize;
+ }
+ else if( mDiff > 0)
+ {
+ mReleaseStart = mBufferPosition + mBufferSize - mDiff;
+ mRequestStart = mBufferPosition - mDiff;
+ }
+ }
+
+ // Release
+ int end = mReleaseStart + mReleaseCount < mTotalCount ?
+ mReleaseStart + mReleaseCount: mTotalCount;
+ end--;
+ if(end >= mReleaseStart )
+ {
+ emit releaseItems( mReleaseStart, end );
+ }
+
+ mReleaseCount = 0;
+
+ // Request
+ end = mRequestStart + mRequestCount < mTotalCount ?
+ mRequestStart + mRequestCount : mTotalCount;
+
+ end--;
+ if(end >= mRequestStart )
+ {
+ emit requestItems( mRequestStart, end );
+ }
+
+ mRequestCount = 0;
+
+ // Move Buffer
+ mBufferPosition -= mDiff;
+ // Reset Diff
+ mDiff = 0;
+}
+
+bool HgScrollBufferManager::positionInsideBuffer( int position )
+{
+ return position >= mBufferPosition && position <= (mBufferPosition+mBufferSize);
+}
+
+void HgScrollBufferManager::asyncUpdate()
+{
+ if( !mTimer.isActive())
+ mTimer.start(0);
+}
+
+void HgScrollBufferManager::currentBuffer(int& bufferStart, int& bufferEnd)
+{
+ bufferStart = mBufferPosition;
+ bufferEnd = mBufferPosition+mBufferSize > mTotalCount-1 ?
+ mTotalCount-1 : mBufferPosition+mBufferSize;
+}
+
+void HgScrollBufferManager::removeItems(int start, int end, int totalCount)
+{
+ int oldTotalCount = mTotalCount;
+ mTotalCount = totalCount;
+
+ if (isInsideBuffer(start, end)) {
+ if (mTotalCount > mBufferSize && mBufferPosition+mBufferSize == oldTotalCount) {
+ // We are at the end of items, move buffer
+ int oldBufferPos = mBufferPosition;
+ mBufferPosition = qMax(0, totalCount-mBufferSize);
+
+ if (start < oldBufferPos) { // Removed items are partially inside buffer
+ emit requestItems(mBufferPosition, start-1);
+ }
+ else {
+ emit requestItems(mBufferPosition, oldBufferPos-1);
+ }
+ }
+ else {
+ int first = qBound(mBufferPosition, start, mBufferPosition+mBufferSize-1);
+ int last = qBound(mBufferPosition, end, mBufferPosition+mBufferSize-1);
+
+ // Requested from the end
+ emit requestItems(mBufferPosition+mBufferSize-(last-first+1),
+ qMin(mBufferPosition+mBufferSize-1, mTotalCount));
+ }
+ }
+}
+
+void HgScrollBufferManager::addItems(int start, int end, int totalCount)
+{
+ int oldTotalCount = mTotalCount;
+ mTotalCount = totalCount;
+
+ if (isInsideBuffer(start, end)) {
+ int first = start;
+ int last = end;
+
+ if (mTotalCount > mBufferSize && mBufferPosition+mBufferSize == oldTotalCount) {
+ // We are at the end of items, keep it that way
+ int oldBufferPos = mBufferPosition;
+ mBufferPosition = qMin(mBufferPosition+(end-start+1), totalCount-mBufferSize);
+
+ if (oldBufferPos < mBufferPosition) {
+ // Release from the beginning
+ emit releaseItems(oldBufferPos, mBufferPosition-1);
+ }
+
+ // Added items may fall outside the buffer as the buffer is moved
+ if (isInsideBuffer(start, end)) {
+ first = qBound(mBufferPosition, start, mBufferPosition+mBufferSize-1);
+ last = qBound(mBufferPosition, end, mBufferPosition+mBufferSize-1);
+ emit requestItems(first, last);
+ }
+ }
+ else {
+ first = qBound(mBufferPosition, start, mBufferPosition+mBufferSize-1);
+ last = qBound(mBufferPosition, end, mBufferPosition+mBufferSize-1);
+
+ if (mTotalCount > mBufferSize) {
+ // Release from the end
+ emit releaseItems(mBufferPosition+mBufferSize,
+ mBufferPosition+mBufferSize+(last-first+1)-1);
+ }
+ // If all the items fit in the buffer no need to release items
+
+ emit requestItems(first, last);
+ }
+ }
+}
+
+void HgScrollBufferManager::moveItems(int start, int end, int target, int totalCount)
+{
+ if (isInsideBuffer(start) && isInsideBuffer(end) && isInsideBuffer(target)) {
+ return;
+ }
+
+ if (!isInsideBuffer(start, end) && !isInsideBuffer(target)) {
+ return;
+ }
+
+ if (!isInsideBuffer(target)) {
+ if (isInsideBuffer(start) && isInsideBuffer(end)) {
+ if (mBufferPosition+mBufferSize == mTotalCount) {
+ // Fetch from beginning
+ emit requestItems(mBufferPosition, mBufferPosition+end-start);
+ }
+ else {
+ // Fetch from end
+ emit requestItems(mBufferPosition+mBufferSize-(end-start+1),
+ qMin(mBufferPosition+mBufferSize-1, mTotalCount));
+ }
+ }
+ else if (isInsideBuffer(start) && end >= mBufferPosition+mBufferSize-1) {
+ emit requestItems(start, mBufferPosition+mBufferSize-1);
+ }
+ else if (start <= mBufferPosition && isInsideBuffer(end)) {
+ emit requestItems(mBufferPosition, end);
+ }
+ else {
+ emit requestItems(mBufferPosition, mBufferPosition+mBufferSize-1);
+ }
+ }
+
+ if (isInsideBuffer(target)) {
+ // start-end may be partially inside buffer
+ if (!isInsideBuffer(start, end)) {
+ addItems(target, target+end-start, totalCount);
+ }
+ else if (isInsideBuffer(start)) {
+ addItems(target+(mBufferPosition+mBufferSize-start), target+end-start, totalCount);
+ }
+ else { // end is inside buffer
+ addItems(target, target+mBufferPosition-start-1, totalCount);
+ }
+ }
+}
+
+bool HgScrollBufferManager::isInsideBuffer(int pos)
+{
+ return (pos >= mBufferPosition && pos < mBufferPosition+mBufferSize);
+}
+
+bool HgScrollBufferManager::isInsideBuffer(int start, int end)
+{
+ INFO("Buffer:" << mBufferPosition << "-" << mBufferPosition+mBufferSize-1);
+ INFO("Change:" << start << "-" << end);
+
+ if (isInsideBuffer(start)) {
+ return true;
+ }
+ if (isInsideBuffer(end)) {
+ return true;
+ }
+ if (start < mBufferPosition && end >= mBufferPosition+mBufferSize) {
+ return true;
+ }
+
+ INFO("Buffer not affected");
+ return false;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgcoverflowcontainer.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,319 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QGesture>
+#include <QPainter>
+#include <hblabel.h>
+#include "hgcoverflowcontainer.h"
+#include "hgmediawallrenderer.h"
+#include "hgwidgetitem.h"
+#include "trace.h"
+
+
+static const qreal KCameraMaxYAngle(20);
+static const qreal KSpringVelocityToCameraYAngleFactor(2);
+static const int KLabelMargin(4);
+
+HgCoverflowContainer::HgCoverflowContainer(
+ QGraphicsItem* parent) : HgContainer(parent),
+ mTitleLabel(0),
+ mDescriptionLabel(0),
+ mTitlePosition(HgMediawall::PositionAboveImage),
+ mDescriptionPosition(HgMediawall::PositionNone),
+ mCenterIconTop(0),
+ mPrevPos(-1)
+{
+ mTitleLabel = new HbLabel(this);
+ mTitleLabel->setZValue(zValue()+1);
+ mTitleLabel->setAlignment(Qt::AlignCenter);
+ mTitleLabel->setVisible(false);
+
+ mDescriptionLabel = new HbLabel(this);
+ mDescriptionLabel->setZValue(zValue()+1);
+ mDescriptionLabel->setAlignment(Qt::AlignCenter);
+ mDescriptionLabel->setVisible(false);
+}
+
+HgCoverflowContainer::~HgCoverflowContainer()
+{
+}
+
+// events
+void HgCoverflowContainer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ HgContainer::paint(painter, option, widget);
+}
+
+void HgCoverflowContainer::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ FUNC_LOG;
+
+ HbWidget::resizeEvent(event);
+
+ QSizeF s(size());
+ qreal side = qMin(s.height()/1.8, s.width()/1.8);
+ INFO("Setting image size to:" << side << "," << side);
+ mRenderer->setImageSize(QSizeF(side, side));
+ mCenterIconTop = (s.height()-side)/2;
+
+ positionLabels();
+}
+
+// from HgContainer
+HgMediaWallRenderer* HgCoverflowContainer::createRenderer()
+{
+ HgMediaWallRenderer* renderer = new HgMediaWallRenderer(this);
+ renderer->setImageSize(QSizeF(200, 200));
+ renderer->enableCoverflowMode(true);
+ renderer->setRowCount(1, renderer->getImageSize(), false);
+ renderer->enableReflections(true);
+ renderer->setSpacing(QSizeF(1,1));
+ renderer->setFrontCoverElevationFactor(0.5);
+ return renderer;
+}
+
+qreal HgCoverflowContainer::getCameraDistance(qreal springVelocity)
+{
+ return qAbs(springVelocity * 0.01f);
+}
+
+qreal HgCoverflowContainer::getCameraRotationY(qreal springVelocity)
+{
+ return qBound(-KCameraMaxYAngle, springVelocity * KSpringVelocityToCameraYAngleFactor, KCameraMaxYAngle);
+}
+
+void HgCoverflowContainer::handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex)
+{
+ Q_UNUSED(pos)
+
+ if (qAbs(qreal(hitItemIndex) - mSpring.pos().x()) < 0.01f)
+ {
+ emit activated(hitItem->modelIndex());
+ }
+ else
+ {
+ mSpring.animateToPos(QPointF(hitItemIndex, 0));
+ }
+}
+
+void HgCoverflowContainer::handleLongTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex)
+{
+ Q_UNUSED(hitItemIndex)
+
+ emit longPressed(hitItem->modelIndex(), pos);
+}
+
+void HgCoverflowContainer::onScrollPositionChanged(qreal pos)
+{
+ HgContainer::onScrollPositionChanged(pos);
+
+ if (mPrevPos != (int)pos) {
+ mPrevPos = (int)pos;
+ HgWidgetItem* item = itemByIndex((int)pos);
+ if (item && item->modelIndex() != mSelectionModel->currentIndex()) {
+ mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
+ }
+ }
+}
+
+void HgCoverflowContainer::handleCurrentChanged(const QModelIndex ¤t)
+{
+ FUNC_LOG;
+
+ if (current.isValid()) {
+ updateLabels(current.row());
+ }
+}
+
+void HgCoverflowContainer::itemDataChanged(const int &firstIndex, const int &lastIndex)
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(mSelectionModel); // If model has been set, also is selection model
+
+ HgContainer::itemDataChanged(firstIndex, lastIndex);
+
+ if (mSelectionModel->currentIndex().isValid()) {
+ int current = mSelectionModel->currentIndex().row();
+ if (firstIndex <= current && current <= lastIndex) {
+ updateLabels(current);
+ }
+ }
+}
+
+void HgCoverflowContainer::setTitlePosition(HgMediawall::LabelPosition position)
+{
+ FUNC_LOG;
+
+ if (mTitlePosition != position) {
+ mTitlePosition = position;
+ positionLabels();
+ }
+}
+
+HgMediawall::LabelPosition HgCoverflowContainer::titlePosition() const
+{
+ FUNC_LOG;
+
+ return mTitlePosition;
+}
+
+void HgCoverflowContainer::setDescriptionPosition(HgMediawall::LabelPosition position)
+{
+ FUNC_LOG;
+
+ if (mDescriptionPosition != position) {
+ mDescriptionPosition = position;
+ positionLabels();
+ }
+}
+
+HgMediawall::LabelPosition HgCoverflowContainer::descriptionPosition() const
+{
+ FUNC_LOG;
+
+ return mDescriptionPosition;
+}
+
+void HgCoverflowContainer::setTitleFontSpec(const HbFontSpec &fontSpec)
+{
+ FUNC_LOG;
+
+ if (!mTitleLabel) return;
+ if (mTitleLabel->fontSpec() != fontSpec) {
+ mTitleLabel->setFontSpec(fontSpec);
+ positionLabels();
+ }
+}
+
+HbFontSpec HgCoverflowContainer::titleFontSpec() const
+{
+ FUNC_LOG;
+
+ if (!mTitleLabel) return HbFontSpec();
+ return mTitleLabel->fontSpec();
+}
+
+void HgCoverflowContainer::setDescriptionFontSpec(const HbFontSpec &fontSpec)
+{
+ FUNC_LOG;
+
+ if (!mDescriptionLabel) return;
+ if (mDescriptionLabel->fontSpec() != fontSpec) {
+ mDescriptionLabel->setFontSpec(fontSpec);
+ positionLabels();
+ }
+}
+
+HbFontSpec HgCoverflowContainer::descriptionFontSpec() const
+{
+ FUNC_LOG;
+
+ if (!mDescriptionLabel) return HbFontSpec();
+ return mDescriptionLabel->fontSpec();
+}
+
+void HgCoverflowContainer::positionLabels()
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(mTitleLabel);
+ HANDLE_ERROR_NULL(mDescriptionLabel);
+ HANDLE_ERROR_NULL(mSelectionModel);
+
+ int height = size().height();
+ int width = size().width();
+ int titleHeight = QFontMetrics(mTitleLabel->effectiveFontSpec().font()).height();
+ int descriptionHeight = QFontMetrics(mDescriptionLabel->effectiveFontSpec().font()).height();
+
+ if (mTitlePosition == HgMediawall::PositionAboveImage &&
+ mDescriptionPosition == HgMediawall::PositionAboveImage) {
+ mTitleLabel->setGeometry(QRectF(
+ 0,
+ qMax(KLabelMargin, mCenterIconTop-2*KLabelMargin-titleHeight-descriptionHeight),
+ width, titleHeight));
+ mDescriptionLabel->setGeometry(QRectF(
+ 0,
+ mTitleLabel->geometry().bottom()+KLabelMargin,
+ width, descriptionHeight));
+ }
+ else if (mTitlePosition == HgMediawall::PositionBelowImage &&
+ mDescriptionPosition == HgMediawall::PositionBelowImage) {
+ mDescriptionLabel->setGeometry(QRectF(
+ 0,
+ height-descriptionHeight-KLabelMargin,
+ width, descriptionHeight));
+ mTitleLabel->setGeometry(QRectF(
+ 0,
+ mDescriptionLabel->geometry().top()-titleHeight-KLabelMargin,
+ width, titleHeight));
+ }
+ else {
+ if (mTitlePosition == HgMediawall::PositionAboveImage) {
+ mTitleLabel->setGeometry(QRectF(
+ 0,
+ qMax(KLabelMargin, mCenterIconTop-KLabelMargin-titleHeight),
+ width, titleHeight));
+ }
+ else if (mTitlePosition == HgMediawall::PositionBelowImage) {
+ mTitleLabel->setGeometry(QRectF(
+ 0,
+ height-titleHeight-KLabelMargin,
+ width, titleHeight));
+ }
+
+ if (mDescriptionPosition == HgMediawall::PositionAboveImage) {
+ mDescriptionLabel->setGeometry(QRectF(
+ 0,
+ qMax(KLabelMargin, mCenterIconTop-KLabelMargin-descriptionHeight),
+ width, descriptionHeight));
+ }
+ else if (mDescriptionPosition == HgMediawall::PositionBelowImage) {
+ mDescriptionLabel->setGeometry(QRectF(
+ 0,
+ height-descriptionHeight-KLabelMargin,
+ width, descriptionHeight));
+ }
+ }
+
+ mTitleLabel->setVisible(mTitlePosition != HgMediawall::PositionNone);
+ mDescriptionLabel->setVisible(mDescriptionPosition != HgMediawall::PositionNone);
+
+ INFO("Title geometry:" << mTitleLabel->geometry() << "visible:" << mTitleLabel->isVisible());
+ INFO("Description geometry:" << mDescriptionLabel->geometry() << "visible:" << mDescriptionLabel->isVisible());
+
+ if (mSelectionModel->currentIndex().isValid()) {
+ updateLabels(mSelectionModel->currentIndex().row());
+ }
+}
+
+void HgCoverflowContainer::updateLabels(int itemIndex)
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(mTitleLabel);
+ HANDLE_ERROR_NULL(mDescriptionLabel);
+
+ if (itemIndex >= 0 && itemIndex < mItems.count()) {
+ mTitleLabel->setPlainText(mItems.at(itemIndex)->title());
+ mDescriptionLabel->setPlainText(mItems.at(itemIndex)->description());
+ }
+}
+
+void HgCoverflowContainer::scrollToPosition(const QPointF& pos, bool animate)
+{
+ QPointF p = pos;
+ p.setX((int)pos.x());
+ HgContainer::scrollToPosition(p,animate);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgdrag.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Container for pan (drag) gesture -related data and logic.
+*
+*/
+
+#include "hgdrag.h"
+#include "trace.h"
+
+HgDrag::HgDrag()
+{
+}
+
+void HgDrag::reset(const qreal delta, const qreal viewPos)
+{
+ mViewPosAtStart = viewPos;
+ mDuration.start();
+ mLength = 0;
+ mCumulatedDelta = 0;
+ mDirection = delta;
+ mDirectionChange = 0;
+ INFO("Drag reset at view pos:" << mViewPosAtStart);
+}
+
+qreal HgDrag::update(const qreal delta, const qreal viewPos, const qreal itemWidth)
+{
+// INFO("delta:" << delta << ", direction:" << mDirection);
+ if ((delta > 0 && mDirection < 0) || (delta < 0 && mDirection > 0))
+ {
+ if (mDirectionChange > 2)
+ {
+ mDirectionChange = 0;
+ reset(delta, viewPos);
+ }
+ else
+ {
+ mDirectionChange++;
+ }
+ }
+ else
+ {
+ mDirection = delta;
+ mDirectionChange = 0;
+ }
+
+ mCumulatedDelta = (mCumulatedDelta+delta)/2;
+ mLength += delta/itemWidth;
+ qreal pos = mViewPosAtStart-mLength;
+// INFO("Drag len:" << mLength << ", new pos:" << pos);
+ return pos;
+}
+
+bool HgDrag::finish(const qreal viewPos, bool stopToFullItem, qreal &newPos)
+{
+ int dt = mDuration.elapsed();
+ if (dt > 10)
+ {
+ qreal t = (qreal)dt/1000;
+ INFO("Drag len:" << mLength << ", duration:" << t << ", cumulated:" << mCumulatedDelta);
+ if (qAbs(mCumulatedDelta) > 4)
+ {
+ newPos = viewPos-mLength/t * 0.5f;
+ }
+ else
+ {
+ newPos = mViewPosAtStart-mLength;
+ }
+ if (stopToFullItem)
+ {
+ qreal i = floorf(newPos);
+ newPos = (newPos - i > 0.5f) ? ceilf(newPos) : i;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+qreal HgDrag::viewPosAtStart() const
+{
+ return mViewPosAtStart;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hggrid.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <hgwidgets/hggrid.h>
+#include "hggrid_p.h"
+#include "hggridcontainer.h"
+
+HgGrid::HgGrid( Qt::Orientation scrollDirection, QGraphicsItem *parent ):
+ HgWidget(new HgGridPrivate, parent)
+{
+ Q_D(HgGrid);
+ d->q_ptr = this;
+
+ d->init(scrollDirection);
+}
+
+HgGrid::~HgGrid()
+{
+}
+
+// EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hggrid_p.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "hggrid_p.h"
+#include "hggridcontainer.h"
+
+static const int BUFFERSIZE(120);
+
+HgGridPrivate::HgGridPrivate()
+{
+
+}
+
+HgGridPrivate::~HgGridPrivate()
+{
+
+}
+
+void HgGridPrivate::init(Qt::Orientation scrollDirection)
+{
+ Q_Q(HgGrid);
+ HgGridContainer *container = new HgGridContainer(q);
+ container->init(scrollDirection);
+
+ // Use a little larger buffer for the grid than the default one.
+ mBufferSize = BUFFERSIZE;
+
+ HgWidgetPrivate::init(container);
+}
+
+// EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hggridcontainer.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,104 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QGesture>
+#include <QPainter>
+#include <QTimer>
+#include <hblabel.h>
+#include <hbgridviewitem>
+#include <hbmainwindow>
+#include "hggridcontainer.h"
+#include "hgmediawallrenderer.h"
+#include "hgquad.h"
+#include "hgvgquadrenderer.h"
+#include "hgvgimage.h"
+#include "hgwidgetitem.h"
+#include "trace.h"
+
+#include <hbgridviewitem>
+#include <hbgridview>
+#include <hbiconitem>
+#include <qabstractitemmodel>
+#include "hglongpressvisualizer.h"
+
+
+static const qreal KCameraMaxYAngle(20);
+static const qreal KSpringVelocityToCameraYAngleFactor(2);
+
+HgGridContainer::HgGridContainer(QGraphicsItem *parent) : HgContainer(parent)
+{
+
+}
+
+HgGridContainer::~HgGridContainer()
+{
+
+}
+
+void HgGridContainer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ HgContainer::paint(painter, option, widget);
+
+ updateSelectedItem();
+}
+
+HgMediaWallRenderer* HgGridContainer::createRenderer()
+{
+
+ HgMediaWallRenderer* renderer = new HgMediaWallRenderer(this);
+ renderer->enableCoverflowMode(false);
+ renderer->setImageSize(QSizeF(105, 80));
+ renderer->setRowCount(3, renderer->getImageSize(), false);
+ renderer->enableReflections(false);
+ renderer->setSpacing(QSizeF(1,1));
+ renderer->setFrontCoverElevationFactor(0.5);
+
+ return renderer;
+}
+
+qreal HgGridContainer::getCameraDistance(qreal springVelocity)
+{
+ if (mRenderer->getOrientation() == Qt::Vertical)
+ return 0;
+
+ return qAbs(springVelocity * 0.01f);
+}
+
+qreal HgGridContainer::getCameraRotationY(qreal springVelocity)
+{
+ if (mRenderer->getOrientation() == Qt::Vertical)
+ return 0;
+
+ return qBound(-KCameraMaxYAngle, springVelocity * KSpringVelocityToCameraYAngleFactor, KCameraMaxYAngle);
+}
+
+void HgGridContainer::handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex)
+{
+ Q_UNUSED(pos)
+ Q_UNUSED(hitItemIndex)
+
+ selectItem();
+ emit activated(hitItem->modelIndex());
+}
+
+void HgGridContainer::handleLongTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex)
+{
+ Q_UNUSED(hitItemIndex)
+
+ selectItem();
+ emit longPressed(hitItem->modelIndex(), pos);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgindexfeedback.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,329 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "hgindexfeedback.h"
+#include "hgindexfeedback_p.h"
+
+#include <hbscrollbar.h>
+#include <hbstyleoptionindexfeedback.h>
+#include <hbstyleparameters.h>
+#include <hbstyle.h>
+#include <hbdeviceprofile.h>
+#include <hgwidgets/hgwidgets.h>
+#include <hbstyleloader.h>
+
+#include <QEvent>
+#include <QObject>
+#include <QGraphicsScene>
+
+
+/* rather than magic numbers, let's define some constants. */
+namespace {
+/*
+ string name from the index feedback .css for the single character height parameter.
+*/
+static const QString ONE_CHAR_HEIGHT = QLatin1String("one-char-height");
+
+/*
+ string name from the index feedback .css for the three character height parameter.
+*/
+static const QString THREE_CHAR_HEIGHT = QLatin1String("three-char-height");
+
+/*
+ string name from the index feedback .css for the three character width parameter.
+*/
+static const QString THREE_CHAR_WIDTH = QLatin1String("three-char-width");
+
+/*
+ string name from the index feedback .css for the string mode offest parameter.
+*/
+static const QString STRING_OFFSET = QLatin1String("string-offset");
+}
+
+/*!
+ Constructs a new HgIndexFeedback with a parent.
+*/
+HgIndexFeedback::HgIndexFeedback(QGraphicsItem *parent)
+ : HbWidget( *new HgIndexFeedbackPrivate, parent, 0)
+
+{
+ Q_D( HgIndexFeedback );
+ d->q_ptr = this;
+
+ HbStyleLoader::registerFilePath(":/hgindexfeedback.css");
+
+ d->init();
+}
+
+/*!
+ Destructs the index feedback.
+*/
+HgIndexFeedback::~HgIndexFeedback()
+{
+ HbStyleLoader::unregisterFilePath(":/hgindexfeedback.css");
+}
+
+/*!
+ \brief sets the index feedback policy.
+
+ \param policy - The HgIndexFeedback::IndexFeedbackPolicy to use.
+
+ \sa HgIndexFeedback::IndexFeedbackPolicy
+*/
+void HgIndexFeedback::setIndexFeedbackPolicy(HgWidget::IndexFeedbackPolicy policy)
+{
+ Q_D( HgIndexFeedback );
+
+ if (policy != d->mIndexFeedbackPolicy) {
+ d->_q_hideIndexFeedbackNow();
+ d->mIndexFeedbackPolicy = policy;
+ d->calculatePopupRects();
+ d->updatePrimitives();
+ }
+}
+
+/*!
+ \brief Returns the index feedback policy.
+
+ \return The HgIndexFeedback::IndexFeedbackPolicy that's currently in use.
+*/
+HgWidget::IndexFeedbackPolicy HgIndexFeedback::indexFeedbackPolicy() const
+{
+ Q_D( const HgIndexFeedback );
+
+ return d->mIndexFeedbackPolicy;
+}
+
+/*!
+ \brief sets the item view for the index feedback.
+
+ Disconnects from the existing item view, then connects to the specified one.
+
+ If set to NULL the index feedback is simply disconnected.
+
+ \param itemView The HbAbstractItemView* to provide index feedback for.
+*/
+void HgIndexFeedback::setWidget(HgWidget *widget)
+{
+ Q_D( HgIndexFeedback );
+
+ if (widget == d->mWidget) {
+ return;
+ }
+
+ d->disconnectItemView();
+
+ d->mWidget = widget;
+
+ if (!d->mWidget) {
+ return;
+ }
+
+ d->connectModelToIndexFeedback(d->mWidget->selectionModel());
+
+ d->connectScrollBarToIndexFeedback(d->mWidget->scrollBar());
+
+ connect(d->mWidget, SIGNAL(destroyed(QObject*)),
+ this, SLOT(_q_itemViewDestroyed()));
+
+ if (d->mWidget->scene()) {
+ d->mWidget->scene()->addItem(this);
+ d->mWidget->installSceneEventFilter(this);
+ }
+
+ d->calculatePopupRects();
+ updatePrimitives();
+}
+
+/*!
+ Returns the HbAbstractItemView which the index feedback currently monitors.
+
+ \return HbAbstractItemView*.
+*/
+HgWidget* HgIndexFeedback::widget() const
+{
+ Q_D( const HgIndexFeedback );
+
+ return d->mWidget;
+}
+
+/*!
+ Returns the primitives used in HgIndexFeedback.
+
+ \param primitive The primitive type requested.
+
+ \return A pointer for the primitive requested.
+*/
+QGraphicsItem* HgIndexFeedback::primitive(HbStyle::Primitive primitive) const
+{
+ Q_D( const HgIndexFeedback );
+
+ QGraphicsItem* retVal = HbWidget::primitive(primitive);
+
+ switch (primitive) {
+ case HbStyle::P_IndexFeedback_popup_text:
+ retVal = d->mTextItem;
+ break;
+
+ case HbStyle::P_IndexFeedback_popup_background:
+ retVal = d->mPopupItem;
+ break;
+
+ default:
+ qt_noop();
+ break;
+ }
+
+ return retVal;
+}
+
+
+/*
+ A scene event filter. It's purpose is to call calculatePopupRects on
+ a resize event for the item view.
+*/
+bool HgIndexFeedback::sceneEventFilter(QGraphicsItem *watched, QEvent *ev)
+{
+ Q_D( HgIndexFeedback );
+
+ if (ev->type() == QEvent::GraphicsSceneResize) {
+ d->calculatePopupRects();
+ }
+
+ return QGraphicsItem::sceneEventFilter(watched, ev);
+}
+
+/*
+ Rather than adding signals to HbScrollBar specifically to implement
+ index feedback, an event filter is used.
+
+ Specifically, if a scrollbar which is interactive is pressed or released
+ this function will call the appropriate function in HgIndexFeedbackPrivate.
+*/
+bool HgIndexFeedback::eventFilter(QObject *obj, QEvent *ev)
+{
+ Q_D( HgIndexFeedback );
+ HbScrollBar* scrollBar = qobject_cast<HbScrollBar*>(obj);
+
+ if (d->mIndexFeedbackPolicy != HgWidget::IndexFeedbackNone
+ && scrollBar) {
+ switch (ev->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::MouseButtonPress:
+ if (scrollBar->isInteractive()) {
+ d->scrollBarPressed();
+ }
+ break;
+
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::MouseButtonRelease:
+ if (scrollBar->isInteractive()) {
+ d->scrollBarReleased();
+ }
+ break;
+
+ case QEvent::GraphicsSceneResize:
+ case QEvent::Resize:
+ d->_q_hideIndexFeedbackNow();
+ d->calculatePopupRects();
+ d->updatePrimitives();
+ break;
+
+ default:
+ // do nothing, ignore other events.
+ break;
+ }
+ }
+
+ return QObject::eventFilter(obj, ev);
+}
+
+/*
+ For use with HbStyle.
+
+ Provide the correct data to use in the 'model.'
+*/
+void HgIndexFeedback::initStyleOption(HbStyleOptionIndexFeedback *option) const
+{
+ Q_D( const HgIndexFeedback );
+
+ HbWidget::initStyleOption(option);
+
+ if (!d->mWidget) {
+ return;
+ }
+
+ HbFontSpec fontSpec;
+ qreal margin = 0;
+
+ style()->parameter(QLatin1String("hb-param-margin-gene-popup"), margin);
+
+ switch (d->mIndexFeedbackPolicy) {
+ case HgWidget::IndexFeedbackSingleCharacter:
+ {
+ fontSpec = HbFontSpec(HbFontSpec::Primary);
+ fontSpec.setTextPaneHeight(d->textHeight());
+ }
+ break;
+
+ case HgWidget::IndexFeedbackThreeCharacter:
+ {
+ fontSpec = HbFontSpec(HbFontSpec::Primary);
+ fontSpec.setTextPaneHeight(d->textHeight());
+ }
+ break;
+
+ case HgWidget::IndexFeedbackString:
+ {
+ fontSpec = HbFontSpec(HbFontSpec::Primary);
+ qreal textPaneHeight = 0;
+ style()->parameter(QLatin1String("hb-param-text-height-primary"), textPaneHeight);
+ fontSpec.setTextPaneHeight( textPaneHeight );
+ }
+ break;
+
+ case HgWidget::IndexFeedbackNone:
+ // leave the HbStyleOption uninitialized
+ return;
+ }
+
+ option->text = d->mPopupContent;
+ option->fontSpec = fontSpec;
+ option->textRect = d->mPopupTextRect;
+ option->popupRect = d->mPopupBackgroundRect;
+}
+
+void HgIndexFeedback::polish(HbStyleParameters& params)
+{
+ Q_D( HgIndexFeedback );
+
+ params.addParameter( ONE_CHAR_HEIGHT );
+ params.addParameter( THREE_CHAR_HEIGHT );
+ params.addParameter( THREE_CHAR_WIDTH );
+ params.addParameter( STRING_OFFSET );
+
+ HbWidget::polish( params );
+
+ d->mOneCharHeight = params.value( ONE_CHAR_HEIGHT ).toDouble();
+ d->mThreeCharHeight = params.value( THREE_CHAR_HEIGHT ).toDouble();
+ d->mThreeCharWidth = params.value( THREE_CHAR_WIDTH ).toDouble();
+ d->mStringOffset = params.value( STRING_OFFSET ).toDouble();
+
+ d->calculatePopupRects();
+}
+
+#include "moc_hgindexfeedback.cpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgindexfeedback_p.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,566 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "hgindexfeedback.h"
+#include "hgindexfeedback_p.h"
+
+#include <hbscrollbar.h>
+#include <hbstyle.h>
+#include <hbapplication.h>
+#include <hbeffect.h>
+#include <hbstyleoptionindexfeedback.h>
+#include <hgwidgets/hgwidgets.h>
+
+#include <QTimer>
+#include <QSize>
+#include <QGraphicsScene>
+#include <qitemselectionmodel>
+
+// rather than having magic numbers
+// defaults and constants are defined here.
+namespace {
+/*
+ Press timeout is the duration after the scrollbar is
+ pressed to when the index feedback will be dismissed.
+
+ In the case that the press timeout has not yet passed
+ and the timer should be fired with the release timeout,
+ the timer with the press timeout will continue running.
+*/
+static const int DEFAULT_INDEX_FEEDBACK_PRESS_TIMEOUT = 1000;
+
+/*
+ Dwell timeout is the duration after which if there is not a change
+ in the scrollbar's value the index feedback will be dismissed.
+*/
+static const int DEFAULT_INDEX_FEEDBACK_DWELL_TIMEOUT = 2000;
+
+/*
+ Release timeout is the duration after which the user has lifted
+ their finger from the scrollbar to when the index feedback will be dismissed.
+*/
+static const int DEFAULT_INDEX_FEEDBACK_RELEASE_TIMEOUT = 250;
+
+/*
+ The default value for the index feedback policy.
+*/
+static const HgWidget::IndexFeedbackPolicy DEFAULT_INDEX_FEEDBACK_POLICY = HgWidget::IndexFeedbackNone;
+
+/*
+ The value of the index feedback's disappear animation
+*/
+static const int INDEX_FEEDBACK_DISAPPEAR_DURATION = 300;
+}
+
+/*
+ constructor
+*/
+HgIndexFeedbackPrivate::HgIndexFeedbackPrivate() :
+ mIndexFeedbackPressTimeout(DEFAULT_INDEX_FEEDBACK_PRESS_TIMEOUT),
+ mIndexFeedbackDwellTimeout(DEFAULT_INDEX_FEEDBACK_DWELL_TIMEOUT),
+ mIndexFeedbackReleaseTimeout(DEFAULT_INDEX_FEEDBACK_RELEASE_TIMEOUT),
+ mIndexFeedbackPolicy(DEFAULT_INDEX_FEEDBACK_POLICY),
+ mScrollBarValue(-1.0),
+ mIndexFeedbackTimer(0),
+ mDisappearTimer(0),
+ mTextItem(0),
+ mPopupItem(0),
+ mOneCharHeight(1.0),
+ mThreeCharHeight(1.0),
+ mThreeCharWidth(1.0),
+ mStringOffset(0.0),
+ mWidget(0)
+{
+
+}
+
+/*
+ Destructor
+*/
+HgIndexFeedbackPrivate::~HgIndexFeedbackPrivate()
+{
+
+}
+
+/*
+ 2ndary construction, called from public's constructor.
+*/
+void HgIndexFeedbackPrivate::init()
+{
+ Q_Q( HgIndexFeedback );
+
+ //mItemView = 0; // double check that this is safe.
+
+ HbEffect::add(HB_INDEXFEEDBACK_TYPE, "indexfeedback_appear", EFFECT_IFAPPEAR);
+ if (!HbEffect::add(HB_INDEXFEEDBACK_TYPE, "indexfeedback_disappear", EFFECT_IFDISAPPEAR)) {
+ mDisappearTimer = new QTimer(q);
+ mDisappearTimer->setSingleShot(true);
+ mDisappearTimer->setInterval(INDEX_FEEDBACK_DISAPPEAR_DURATION);
+ q->connect(mDisappearTimer, SIGNAL(timeout()),
+ q, SLOT(_q_hideIndexFeedbackNow()));
+ }
+
+ mIndexFeedbackTimer = new QTimer(q);
+ mIndexFeedbackTimer->setSingleShot(true);
+ q->connect(mIndexFeedbackTimer, SIGNAL(timeout()),
+ q, SLOT(_q_hideIndexFeedback()));
+
+ createPrimitives();
+}
+
+/*
+ Update the data for, and show the index feedback (if it's not already shown)
+*/
+void HgIndexFeedbackPrivate::showIndexFeedback()
+{
+ if (!mWidget
+ || mIndexFeedbackPolicy == HgWidget::IndexFeedbackNone) {
+ return;
+ }
+
+ QModelIndex targetIndex = mWidget->currentIndex();
+
+ if (targetIndex.isValid()) {
+ QVariant data = targetIndex.data(Hb::IndexFeedbackRole);
+ if (data.canConvert<QString>()) {
+
+ QString testString = displayText(data);
+ if (testString != mPopupContent) {
+ mPopupContent = testString;
+ updatePrimitives();
+ }
+
+ if (mTextItem->opacity() == 0.0) {
+ HbEffect::start(mPopupItemList, HB_INDEXFEEDBACK_TYPE, EFFECT_IFAPPEAR);
+ }
+ if (mTextItem) {
+ mTextItem->show();
+ }
+
+ if (mPopupItem) {
+ mPopupItem->show();
+ }
+
+ if (mDisappearTimer) {
+ mDisappearTimer->stop();
+ }
+ } else {
+ _q_hideIndexFeedback();
+ }
+ }
+}
+
+void HgIndexFeedbackPrivate::updateIndex()
+{
+ QModelIndex targetIndex = mWidget->currentIndex();
+
+ if (targetIndex.isValid()) {
+ QVariant data = targetIndex.data(Hb::IndexFeedbackRole);
+ if (data.canConvert<QString>()) {
+ QString testString = displayText(data);
+ if (testString != mPopupContent) {
+ mPopupContent = testString;
+ updatePrimitives();
+ }
+ }
+ }
+}
+
+
+/*
+ Returns the qstring which will be the text in the index feedback.
+*/
+QString HgIndexFeedbackPrivate::displayText(const QVariant &data) const
+{
+ QString retVal = QString();
+
+ switch (mIndexFeedbackPolicy) {
+ case HgWidget::IndexFeedbackSingleCharacter:
+ retVal = data.toString().left(1);
+ break;
+
+ case HgWidget::IndexFeedbackThreeCharacter:
+ retVal = data.toString().left(3);
+ break;
+
+ case HgWidget::IndexFeedbackString:
+ retVal = data.toString();
+ break;
+
+ default:
+ qt_noop();
+ break;
+ }
+
+ return retVal;
+}
+
+/*
+ Handle the case of the scrollbar being pressed.
+
+ This is show the index feedback and start the dismissal timer with the
+ press timeout.
+*/
+void HgIndexFeedbackPrivate::scrollBarPressed()
+{
+ showIndexFeedback();
+
+ // need to record the scrollbar values
+
+ // TODO::The values are storred here is a work around for a bug in hbscrollbar.
+ // the bug is that the value changed signal is emitted when the thumb
+ // is pressed, and again when it is released, regaurdless of if there was a value change.
+ // once that bug is fixed, this should be removed.
+ mScrollBarValue = mWidget->scrollBar()->value();
+ mScrollBarPressed = true;
+}
+
+/*
+ Handle the case of the scrollbar being released.
+
+ This is to start the dismissal timer with the release timeout.
+ ...but not if the timer is still running with the press timeout...
+*/
+void HgIndexFeedbackPrivate::scrollBarReleased()
+{
+ // record the scrollbar values in case position changed is emitted after us w/o a real change
+
+ // TODO::The values are storred here is a work around for a bug in hbscrollbar.
+ // the bug is that the value changed signal is emitted when the thumb
+ // is pressed, and again when it is released, regaurdless of if there was a value change.
+ // once that bug is fixed, this should be removed.
+ mScrollBarValue = mWidget->scrollBar()->value();
+
+ // start this timer.
+ if (!(mIndexFeedbackTimer->isActive()
+ && mIndexFeedbackTimer->interval() == mIndexFeedbackPressTimeout)) {
+ mIndexFeedbackTimer->setInterval(mIndexFeedbackReleaseTimeout);
+ mIndexFeedbackTimer->start();
+ }
+
+ mScrollBarPressed = false;
+
+}
+
+/*
+ Handle the case of the scrollbar being moved.
+
+ This is to stop any existing timers (only if the scrollbar actually moved),
+ and start a timer with the dwell timeout.
+
+ NOTE:: this should be much simpler once the valueChanged signal from hbscrollbar
+ is emitted at the correct times.
+*/
+void HgIndexFeedbackPrivate::_q_scrollPositionChanged(qreal value, Qt::Orientation orientation )
+{
+ // using 3 timers. If the press timer is active, stop it, assuming the value actually changed.
+
+ // TODO::The value check here is a work around for a bug in hbscrollbar.
+ // the bug is that the value changed signal is emitted when the thumb
+ // is pressed, and again when it is released, regaurdless of if there was a value change.
+ // once that bug is fixed, This should be just setting the dwell interval,
+ // starting the timer, and showing the index feedback.
+ if (value != mScrollBarValue && orientation == mWidget->scrollDirection()) {
+ showIndexFeedback();
+ }
+}
+
+/*
+ The private slot for hiding the index feedback.
+
+ If effects are active, use the disappear effect to hide the index feedback's
+ primitives. Otherwise simply hide them.
+*/
+void HgIndexFeedbackPrivate::_q_hideIndexFeedback()
+{
+ if (qFuzzyCompare(mTextItem->opacity(), (qreal) 1.0)) {
+ HbEffect::start(mPopupItemList, HB_INDEXFEEDBACK_TYPE, EFFECT_IFDISAPPEAR);
+ }
+
+ if (mDisappearTimer) {
+ mDisappearTimer->start();
+ }
+}
+
+/*
+ A private slot for actually calling hide on the index feedback.
+
+ This should happen after the index feedback's hide animation is completed
+ regardless of if it went successfully.
+*/
+void HgIndexFeedbackPrivate::_q_hideIndexFeedbackNow()
+{
+ if (mTextItem) {
+ mTextItem->hide();
+ }
+
+ if (mPopupItem) {
+ mPopupItem->hide();
+ }
+}
+
+/*
+ Do the appropriate thing if the item view we're pointing at is destroyed
+*/
+void HgIndexFeedbackPrivate::_q_itemViewDestroyed()
+{
+ mWidget = 0;
+}
+
+/*
+ Update the primitives for the index feedback.
+*/
+void HgIndexFeedbackPrivate::updatePrimitives()
+{
+ Q_Q( HgIndexFeedback );
+
+ HbStyleOptionIndexFeedback option;
+ q->initStyleOption(&option);
+ if (mTextItem) {
+ q->style()->updatePrimitive(mTextItem, HbStyle::P_IndexFeedback_popup_text, &option);
+ }
+ if (mPopupItem) {
+ q->style()->updatePrimitive(mPopupItem, HbStyle::P_IndexFeedback_popup_background, &option);
+ }
+}
+
+/*
+ Create the primitives for the index feedback.
+*/
+void HgIndexFeedbackPrivate::createPrimitives()
+{
+ Q_Q( HgIndexFeedback );
+
+ mPopupItemList.clear();
+
+ if (!mTextItem) {
+ mTextItem = q->style()->createPrimitive(HbStyle::P_IndexFeedback_popup_text, q);
+ mTextItem->hide();
+ mPopupItemList.append(mTextItem);
+ }
+
+ if (!mPopupItem) {
+ mPopupItem = q->style()->createPrimitive(HbStyle::P_IndexFeedback_popup_background, q);
+ mPopupItem->hide();
+ mPopupItemList.append(mPopupItem);
+ }
+}
+
+/*
+ disconnects the current item view from HgIndexFeedback's slots & event filters.
+*/
+void HgIndexFeedbackPrivate::disconnectItemView()
+{
+ Q_Q( HgIndexFeedback );
+
+ if (mWidget) {
+ // disconnect from the existing itemView's scrollbars
+ mWidget->disconnect(q);
+ // uninstall the event filters;
+ mWidget->scrollBar()->removeEventFilter(q);
+
+ mWidget->removeSceneEventFilter(q);
+ if (mWidget->scene()) {
+ mWidget->scene()->removeItem(q);
+ }
+ }
+
+ mWidget = 0;
+}
+
+/*
+ Hooks up the private slots & event filter to a scrollbar.
+*/
+void HgIndexFeedbackPrivate::connectScrollBarToIndexFeedback(HbScrollBar* scrollBar)
+{
+ Q_Q( HgIndexFeedback );
+
+ if (scrollBar) {
+ //q->connect(scrollBar, SIGNAL(valueChanged(qreal, Qt::Orientation)),
+ // q, SLOT(_q_scrollPositionChanged(qreal, Qt::Orientation)));
+ scrollBar->installEventFilter(q);
+ }
+}
+
+/*
+ Calculates the rects for the popup text and background.
+
+ Does nothing if the rect is the same as the last time it was called.
+*/
+void HgIndexFeedbackPrivate::calculatePopupRects()
+{
+ Q_Q( HgIndexFeedback );
+
+ if (!mWidget) {
+ return;
+ }
+
+ QRectF contentRect = mWidget->rect();
+
+ HbScrollBar *scrollBar = mWidget->scrollBar();
+ if (scrollBar->isInteractive() && mWidget->scrollDirection() == Qt::Vertical) {
+ contentRect.setWidth( contentRect.width() - scrollBar->rect().width() );
+ if (HbApplication::layoutDirection() == Qt::RightToLeft) {
+ contentRect.setLeft( contentRect.left() + scrollBar->rect().width() );
+ }
+ }
+ else if (scrollBar->isInteractive()) {
+ contentRect.setHeight( contentRect.height() - scrollBar->rect().height() );
+ }
+
+ if (contentRect == mItemViewContentsRect) {
+ return;
+ }
+
+ qreal margin = 0;
+ q->style()->parameter(QLatin1String("hb-param-margin-gene-popup"), margin);
+
+ QSizeF backgroundSize;
+ QSizeF textSize;
+
+ switch (mIndexFeedbackPolicy) {
+ case HgWidget::IndexFeedbackSingleCharacter:
+ case HgWidget::IndexFeedbackThreeCharacter:
+ {
+ textSize.setHeight( textHeight() );
+ textSize.setWidth ( textWidth() );
+
+ backgroundSize.setHeight( textSize.height() + 2 * margin );
+ backgroundSize.setWidth ( textSize.width() + 2 * margin );
+
+ mPopupBackgroundRect.setLeft( contentRect.left() + (contentRect.width() -
+ backgroundSize.width()) / 2.0 );
+ mPopupBackgroundRect.setTop ( contentRect.top() + (contentRect.height() -
+ backgroundSize.height()) / 2.0 );
+
+ mPopupTextRect.setLeft( mPopupBackgroundRect.left() + margin );
+ mPopupTextRect.setTop ( mPopupBackgroundRect.top() + margin );
+
+ mPopupBackgroundRect.setSize(backgroundSize);
+ mPopupTextRect.setSize(textSize);
+ }
+ break;
+
+ case HgWidget::IndexFeedbackString:
+ {
+ textSize.setHeight( textHeight() );
+ backgroundSize.setHeight( textSize.height() + 2 * margin );
+
+ backgroundSize.setWidth( contentRect.width() - 2 * mStringOffset );
+ textSize.setWidth( backgroundSize.width() - 2 * margin );
+
+ mPopupBackgroundRect.setLeft( contentRect.left() + mStringOffset );
+ mPopupBackgroundRect.setTop( contentRect.top() + (contentRect.height() -
+ backgroundSize.height()) / 2.0 );
+
+ mPopupTextRect.setLeft( mPopupBackgroundRect.left() + margin );
+ mPopupTextRect.setTop ( mPopupBackgroundRect.top() + margin );
+
+ mPopupBackgroundRect.setSize(backgroundSize);
+ mPopupTextRect.setSize(textSize);
+ }
+ break;
+
+ case HgWidget::IndexFeedbackNone:
+ {
+ mPopupTextRect = QRectF();
+ mPopupBackgroundRect = QRectF();
+ }
+ break;
+ }
+}
+
+/*
+ Returns the text height in pixels.
+*/
+qreal HgIndexFeedbackPrivate::textHeight() const
+{
+ Q_Q( const HgIndexFeedback );
+
+ qreal retVal;
+
+ switch (mIndexFeedbackPolicy) {
+ case HgWidget::IndexFeedbackNone:
+ retVal = 0.0;
+ break;
+
+ case HgWidget::IndexFeedbackSingleCharacter:
+ retVal = mOneCharHeight;
+ break;
+
+ case HgWidget::IndexFeedbackThreeCharacter:
+ retVal = mThreeCharHeight;
+ break;
+
+ case HgWidget::IndexFeedbackString:
+ q->style()->parameter(QLatin1String("hb-param-text-height-primary"), retVal);
+ break;
+ }
+
+ return retVal;
+}
+
+/*
+ Returns the text width in units.
+*/
+qreal HgIndexFeedbackPrivate::textWidth() const
+{
+ qreal retVal = 0.0;
+
+ switch (mIndexFeedbackPolicy) {
+ case HgWidget::IndexFeedbackString:
+ case HgWidget::IndexFeedbackNone:
+ retVal = 0.0;
+ break;
+
+ case HgWidget::IndexFeedbackSingleCharacter:
+ retVal = mOneCharHeight;
+ break;
+
+ case HgWidget::IndexFeedbackThreeCharacter:
+ retVal = mThreeCharWidth;
+ break;
+ }
+
+ return retVal;
+}
+
+/*
+ Connects model currentSelectionChanged slot to index feedback.
+ */
+void HgIndexFeedbackPrivate::connectModelToIndexFeedback(QItemSelectionModel* model)
+{
+ Q_Q(HgIndexFeedback);
+
+ if (!model)
+ return;
+
+ q->connect(model, SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
+ q, SLOT(_q_currentModelIndexChanged(const QModelIndex&, const QModelIndex&)));
+
+}
+
+void HgIndexFeedbackPrivate::_q_currentModelIndexChanged(const QModelIndex& current, const QModelIndex& previous)
+{
+ Q_UNUSED(current)
+ Q_UNUSED(previous)
+
+ if (mScrollBarPressed)
+ updateIndex();
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hglongpressvisualizer.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QGesture>
+#include <QPainter>
+#include <QTimer>
+#include <hblabel.h>
+#include <hbgridviewitem>
+#include <hbmainwindow>
+#include "hglongpressvisualizer.h"
+
+HgLongPressVisualizer::HgLongPressVisualizer(QGraphicsItem* parent) : HbWidget(parent),
+ active(false),
+ spanAngle(0)
+{
+
+}
+
+HgLongPressVisualizer::~HgLongPressVisualizer()
+{
+
+}
+
+
+void HgLongPressVisualizer::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ if (active) {
+ QPen pen( Qt::lightGray );
+ pen.setWidth(5);
+ painter->setPen(pen);
+ painter->drawArc(rect, 90*16, -spanAngle*16);
+ }
+}
+
+void HgLongPressVisualizer::start(const QPointF& scenePos)
+{
+ prepareGeometryChange();
+ rect = QRect( 0, 0, 30, 30);
+
+ if (scenePos.y() < 60 ) {
+ //Draw the animation below of the touch point
+ rect.moveCenter( QPointF(scenePos.x(), scenePos.y()+50));
+ }
+ else {
+ //Draw the animation above of the touch point
+ rect.moveCenter( QPointF(scenePos.x(), scenePos.y()-50));
+ }
+
+ setFrame(0);
+ active = true;
+}
+
+void HgLongPressVisualizer::stop()
+{
+ active = false;
+ update();
+}
+
+void HgLongPressVisualizer::setFrame(int frame)
+{
+ spanAngle = frame*360/100;
+ update();
+}
+
+QRectF HgLongPressVisualizer::boundingRect() const
+{
+ return rect;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgmediawall.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,113 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <hgwidgets/hgmediawall.h>
+#include "hgmediawall_p.h"
+#include "hgwidgets_p.h"
+#include "hgcoverflowcontainer.h"
+
+HgMediawall::HgMediawall(QGraphicsItem *parent ):
+ HgWidget(new HgMediawallPrivate, parent)
+{
+ Q_D(HgMediawall);
+ d->q_ptr = this;
+ d->init();
+}
+
+HgMediawall::~HgMediawall()
+{
+}
+
+/*!
+ Sets the placement of the title.
+*/
+void HgMediawall::setTitlePosition(LabelPosition position)
+{
+ Q_D(HgMediawall);
+ d->setTitlePosition(position);
+}
+
+/*!
+ Returns the placement of the title.
+*/
+HgMediawall::LabelPosition HgMediawall::titlePosition() const
+{
+ Q_D(const HgMediawall);
+ return d->titlePosition();
+}
+
+/*!
+ Sets the placement of the description.
+*/
+void HgMediawall::setDescriptionPosition(LabelPosition position)
+{
+ Q_D(HgMediawall);
+ d->setDescriptionPosition(position);
+}
+
+/*!
+ Returns the placement of the description.
+*/
+HgMediawall::LabelPosition HgMediawall::descriptionPosition() const
+{
+ Q_D(const HgMediawall);
+ return d->descriptionPosition();
+}
+
+/*!
+ Sets the fontSpec property of the title.
+
+ The font specification defines the font with a font role and optional
+ other parameters.
+*/
+void HgMediawall::setTitleFontSpec(const HbFontSpec &fontSpec)
+{
+ Q_D(HgMediawall);
+ d->setTitleFontSpec(fontSpec);
+}
+
+/*!
+ Returns the fontSpec property of the title.
+*/
+HbFontSpec HgMediawall::titleFontSpec() const
+{
+ Q_D(const HgMediawall);
+ return d->titleFontSpec();
+}
+
+/*!
+ Sets the fontSpec property of the description.
+
+ The font specification defines the font with a font role and optional
+ other parameters.
+*/
+void HgMediawall::setDescriptionFontSpec(const HbFontSpec &fontSpec)
+{
+ Q_D(HgMediawall);
+ d->setDescriptionFontSpec(fontSpec);
+}
+
+/*!
+ Returns the fontSpec property of the description.
+*/
+HbFontSpec HgMediawall::descriptionFontSpec() const
+{
+ Q_D(const HgMediawall);
+ return d->descriptionFontSpec();
+}
+
+// EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgmediawall_p.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,111 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "hgmediawall_p.h"
+#include "hgcoverflowcontainer.h"
+#include "trace.h"
+
+HgMediawallPrivate::HgMediawallPrivate()
+{
+ FUNC_LOG;
+}
+
+HgMediawallPrivate::~HgMediawallPrivate()
+{
+ FUNC_LOG;
+}
+
+void HgMediawallPrivate::init()
+{
+ FUNC_LOG;
+
+ Q_Q(HgMediawall);
+ HgCoverflowContainer* container = new HgCoverflowContainer(q);
+ // Mediawall supports only horizontal scrolling.
+ container->init(Qt::Horizontal);
+ HgWidgetPrivate::init(container);
+}
+
+void HgMediawallPrivate::setTitlePosition(HgMediawall::LabelPosition position)
+{
+ FUNC_LOG;
+
+ container()->setTitlePosition(position);
+}
+
+HgMediawall::LabelPosition HgMediawallPrivate::titlePosition() const
+{
+ FUNC_LOG;
+
+ return container()->titlePosition();
+}
+
+void HgMediawallPrivate::setDescriptionPosition(HgMediawall::LabelPosition position)
+{
+ FUNC_LOG;
+
+ container()->setDescriptionPosition(position);
+}
+
+HgMediawall::LabelPosition HgMediawallPrivate::descriptionPosition() const
+{
+ FUNC_LOG;
+
+ return container()->descriptionPosition();
+}
+
+void HgMediawallPrivate::setTitleFontSpec(const HbFontSpec &fontSpec)
+{
+ FUNC_LOG;
+
+ container()->setTitleFontSpec(fontSpec);
+}
+
+HbFontSpec HgMediawallPrivate::titleFontSpec() const
+{
+ FUNC_LOG;
+
+ return container()->titleFontSpec();
+}
+
+void HgMediawallPrivate::setDescriptionFontSpec(const HbFontSpec &fontSpec)
+{
+ FUNC_LOG;
+
+ container()->setDescriptionFontSpec(fontSpec);
+}
+
+HbFontSpec HgMediawallPrivate::descriptionFontSpec() const
+{
+ FUNC_LOG;
+
+ return container()->descriptionFontSpec();
+}
+
+HgCoverflowContainer *HgMediawallPrivate::container()
+{
+ HANDLE_ERROR_NULL(mContainer);
+ return qobject_cast<HgCoverflowContainer *>(mContainer);
+}
+
+const HgCoverflowContainer *HgMediawallPrivate::container() const
+{
+ HANDLE_ERROR_NULL(mContainer);
+ return qobject_cast<const HgCoverflowContainer *>(mContainer);
+}
+
+// EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgmediawallrenderer.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,977 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "HgMediaWallRenderer.h"
+#include "hgmediawalldataprovider.h"
+#include "hgquadrenderer.h"
+#include "hgquad.h"
+#include "hgimage.h"
+#include "HgImageFader.h"
+#include "hgvgquadrenderer.h"
+#include <qvector3d>
+#include <qtimer>
+#include <qpropertyanimation>
+#include <qstate.h>
+#include <qabstracttransition>
+#include <qstatemachine>
+#include <qsignaltransition>
+#include <qsequentialanimationgroup>
+#include <qparallelanimationgroup>
+#include <qvariantanimation>
+#include <qpolygon>
+#include <qpainter>
+#include <qpaintengine>
+
+const Qt::Orientation KDefaultOrientation(Qt::Vertical);
+const qreal KPi = 3.1415926535897932384626433832795;
+
+static qreal lerp(qreal start, qreal end, qreal t)
+{
+ return start * (1.0f - t) + end * t;
+}
+
+class MyVectorAnimation : public QVariantAnimation
+{
+public:
+ virtual void updateCurrentValue(const QVariant& value)
+ {
+ mValue = value.value<QVector3D>();
+ }
+ QVector3D getValue() const
+ {
+ return mValue;
+ }
+private:
+ QVector3D mValue;
+};
+
+class HgAnimatedQuad
+{
+public:
+
+ HgAnimatedQuad(HgQuad* start, HgQuad* end,
+ int duration) : mQuad(start)
+ {
+ mPositionAnimation.setDuration(duration);
+ mPositionAnimation.setKeyValueAt(0, start->position());
+ mPositionAnimation.setKeyValueAt(1.0, end->position());
+ mPositionAnimation.setEasingCurve(QEasingCurve::Linear);
+
+ mScaleAnimation.setDuration(duration);
+ mScaleAnimation.setKeyValueAt(0, QVector3D(start->scale().x(), start->scale().y(), 0));
+ mScaleAnimation.setKeyValueAt(1, QVector3D(end->scale().x(), end->scale().y(), 0));
+ mScaleAnimation.setEasingCurve(QEasingCurve::Linear);
+
+ }
+
+ ~HgAnimatedQuad()
+ {
+ }
+
+ void start()
+ {
+ mPositionAnimation.start();
+ mScaleAnimation.start();
+ }
+
+ void update()
+ {
+ mQuad->setPosition(mPositionAnimation.currentValue().value<QVector3D>());
+ QVector3D scale = mScaleAnimation.currentValue().value<QVector3D>();
+ mQuad->setScale(QVector2D(scale.x(), scale.y()));
+ }
+
+ HgQuad* mQuad;
+ MyVectorAnimation mPositionAnimation;
+ MyVectorAnimation mScaleAnimation;
+};
+
+HgMediaWallRenderer::HgMediaWallRenderer(HgMediaWallDataProvider* provider) :
+ mDataProvider(provider),
+ mRenderer(NULL),
+ mIndicatorRenderer(NULL),
+ mRendererInitialized(false),
+ mOrientation(KDefaultOrientation),
+ mNextOrientation(KDefaultOrientation),
+ mStateAnimationAlpha(0),
+ mStateAnimationOnGoing(false),
+ mAnimationAlpha(0),
+ mOpeningAnimationDuration(500),
+ mOpenedItem(-1),
+ mFlipAngle(qreal(360)),
+ mZoomAmount(qreal(0.5)),
+ mCoverflowMode(false),
+ mRowCount(1),
+ mNextRowCount(1),
+ mStateAnimationDuration(300),
+ mStep(1.1),
+ mZfar(-2),
+ mSpacing2D(10,10),
+ mImageSize2D(100, 60),
+ mCameraDistance(0),
+ mCameraRotationY(0),
+ mCameraRotationZ(0),
+ mFrontCoverElevation(0.4),
+ mReflectionsEnabled(true),
+ mItemCountChanged(false),
+ mOpenedItemState(ItemClosed)
+{
+ createStateMachine();
+ mImageFader = new HgImageFader();
+ mRenderer = new HgVgQuadRenderer(256);
+ mRendererInitialized = true;
+}
+
+HgMediaWallRenderer::~HgMediaWallRenderer()
+{
+ delete mRenderer;
+ delete mImageFader;
+ delete mStateMachine;
+}
+
+
+void HgMediaWallRenderer::setCameraDistance(qreal distance)
+{
+ mCameraDistance = distance;
+}
+
+void HgMediaWallRenderer::setCameraRotationY(qreal angle)
+{
+ mCameraRotationY = angle;
+}
+
+void HgMediaWallRenderer::setCameraRotationZ(qreal angle)
+{
+ mCameraRotationZ = angle;
+}
+
+qreal HgMediaWallRenderer::getCameraDistance() const
+{
+ return mCameraDistance;
+}
+
+qreal HgMediaWallRenderer::getCameraRotationY() const
+{
+ return mCameraRotationY;
+}
+
+qreal HgMediaWallRenderer::getCameraRotationZ() const
+{
+ return mCameraRotationZ;
+}
+
+void HgMediaWallRenderer::draw(
+ const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter)
+{
+ // if still not initialized we cant draw anything
+ if (!mRendererInitialized)
+ return;
+
+ if (mOrientation != mNextOrientation ||
+ mRowCount != mNextRowCount)
+ {
+
+ // save old state of the quads
+ recordState(mOldState);
+
+ // goto wanted orientation / rowcount
+ mOrientation = mNextOrientation;
+ mRowCount = mNextRowCount;
+ setImageSize(mNextImageSize);
+
+ // setup quads to new state
+ setupRows(startPosition, position, targetPosition, springVelocity, painter);
+
+ // record state for animation
+ recordState(mNextState);
+
+ startStateAnimation(painter);
+ }
+ else
+ {
+ if (!mStateAnimationOnGoing)
+ {
+ setupRows(startPosition, position, targetPosition, springVelocity, painter);
+ }
+ else
+ {
+ setupStateAnimation(painter);
+ }
+ }
+
+ updateCameraMatrices();
+ drawQuads(painter);
+}
+
+void HgMediaWallRenderer::setupRows(const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter)
+{
+ // draw the state for it
+ resetQuads();
+ updateSpacingAndImageSize();
+
+ if (mCoverflowMode)
+ {
+ //setupRow(startPosition, position, targetPosition, springVelocity, painter, 0);
+ setupCoverflow(startPosition, position, targetPosition, springVelocity, painter);
+ }
+ else
+ {
+ if (mOrientation == Qt::Vertical)
+ {
+ setupGridPortrait(startPosition, position, targetPosition,
+ springVelocity, painter);
+ }
+ else
+ {
+ setupGridLandscape(startPosition, position, targetPosition,
+ springVelocity, painter);
+ }
+ }
+}
+
+void HgMediaWallRenderer::setFlipAnimationAngle(qreal angleInDegrees)
+{
+ mFlipAngle = angleInDegrees;
+}
+
+void HgMediaWallRenderer::setOpeningAnimationType(HgMediaWallRenderer::OpeningAnimationType type)
+{
+ mOpeningAnimationType = type;
+}
+
+void HgMediaWallRenderer::setOpeningAnimationDuration(int msecs)
+{
+ mOpeningAnimationDuration = msecs;
+}
+
+qreal HgMediaWallRenderer::animationAlpha() const
+{
+ return mAnimationAlpha;
+}
+
+void HgMediaWallRenderer::setAnimationAlpha(qreal alpha)
+{
+ mAnimationAlpha = alpha;
+
+ if (mOpenedItemState == ItemClosing && alpha == 0.0f)
+ mOpenedItemState = ItemClosed;
+
+ if (mOpenedItemState == ItemOpening && alpha == 1.0f)
+ mOpenedItemState = ItemOpened;
+
+ emit renderingNeeded();
+}
+
+qreal HgMediaWallRenderer::stateAnimationAlpha() const
+{
+ return mStateAnimationAlpha;
+}
+
+void HgMediaWallRenderer::setStateAnimationAlpha(qreal alpha)
+{
+ mStateAnimationAlpha = alpha;
+ if (alpha == 1 && mStateAnimationOnGoing)
+ {
+ mStateAnimationOnGoing = false;
+ }
+ emit renderingNeeded();
+}
+
+void HgMediaWallRenderer::createStateMachine()
+{
+ mStateMachine = new QStateMachine(this);
+ mStateMachine->setAnimated(true);
+
+ QState* root = new QState(QState::ParallelStates);
+ QState* p1 = new QState(root);
+ QState* p2 = new QState(root);
+
+ // create idle/opened states
+ {
+ QState* idle = new QState(p1);
+ QState* opened = new QState(p1);
+
+ idle->assignProperty(this, "animationAlpha", qreal(0));
+ opened->assignProperty(this, "animationAlpha", qreal(1));
+
+ // add opening animation
+ QPropertyAnimation* anim1 = new QPropertyAnimation(this, "animationAlpha");
+ anim1->setDuration(mOpeningAnimationDuration);
+ idle->addTransition(this, SIGNAL(toggleItem()), opened)->addAnimation(anim1);
+
+ // add closing animation
+ QPropertyAnimation* anim2 = new QPropertyAnimation(this, "animationAlpha");
+ anim2->setDuration(mOpeningAnimationDuration);
+ opened->addTransition(this, SIGNAL(toggleItem()), idle)->addAnimation(anim2);
+
+ QObject::connect(idle, SIGNAL(entered()), this, SLOT(onIdleState()));
+ QObject::connect(opened, SIGNAL(entered()), this, SLOT(onOpenedState()));
+
+ p1->setInitialState(idle);
+ }
+
+ // create two states to animate between
+ {
+ QState* s1 = new QState(p2);
+ QState* s2 = new QState(p2);
+
+ s1->assignProperty(this, "stateAnimationAlpha", qreal(0));
+ s2->assignProperty(this, "stateAnimationAlpha", qreal(0));
+
+ QPropertyAnimation* anim = new QPropertyAnimation(this, "stateAnimationAlpha");
+ anim->setStartValue(qreal(0));
+ anim->setEndValue(qreal(1));
+ anim->setDuration(mStateAnimationDuration);
+
+ s1->addTransition(this, SIGNAL(toggleState()), s2)->addAnimation(anim);
+ s2->addTransition(this, SIGNAL(toggleState()), s1)->addAnimation(anim);
+
+ p2->setInitialState(s1);
+ }
+
+ root->setInitialState(p1);
+ mStateMachine->addState(root);
+ mStateMachine->setInitialState(root);
+ mStateMachine->start();
+
+}
+
+void HgMediaWallRenderer::onIdleState()
+{
+ emit itemClosed(mOpenedItem);
+}
+
+void HgMediaWallRenderer::onOpenedState()
+{
+ emit itemOpened(mOpenedItem);
+}
+
+void HgMediaWallRenderer::setOrientation(Qt::Orientation orientation, bool animate)
+{
+ if (mOrientation != orientation)
+ {
+ mStateMachine->setAnimated(animate);
+ mNextOrientation = orientation;
+
+ if (!animate)
+ mOrientation = orientation;
+ else
+ {
+ emit renderingNeeded();
+ }
+ }
+}
+
+Qt::Orientation HgMediaWallRenderer::getOrientation() const
+{
+ return mOrientation;
+}
+
+void HgMediaWallRenderer::drawQuads(QPainter* painter)
+{
+ mRenderer->transformQuads(mViewMatrix, mProjMatrix, mRect);
+
+ mRenderer->drawQuads(mRect, painter);
+}
+
+
+void HgMediaWallRenderer::enableCoverflowMode(bool enabled)
+{
+ mCoverflowMode = enabled;
+}
+
+bool HgMediaWallRenderer::coverflowModeEnabled() const
+{
+ return mCoverflowMode;
+}
+
+void HgMediaWallRenderer::setRowCount(int rowCount, const QSizeF& newImageSize, bool animate)
+{
+ if (rowCount != mRowCount)
+ {
+ mStateMachine->setAnimated(animate);
+
+ mNextRowCount = rowCount;
+ mNextImageSize = newImageSize;
+
+ mColumnCount = rowCount;
+
+ if (!animate)
+ {
+ mRowCount = rowCount;
+ }
+ else
+ {
+ emit renderingNeeded();
+ }
+
+ }
+
+}
+
+int HgMediaWallRenderer::getRowCount() const
+{
+ return mRowCount;
+}
+
+void HgMediaWallRenderer::recordState(HgMediaWallRenderer::State& state)
+{
+ // cleanup old quads
+ for (int i = 0; i < state.mQuads.size(); i++)
+ {
+ delete state.mQuads[i];
+ }
+
+ state.mQuads.clear();
+
+ // record new quads
+ for (int i = 0; i < mRenderer->quadCount(); i++)
+ {
+ HgQuad* quad = mRenderer->quad(i);
+ if (!quad->visible())
+ continue;
+
+ state.mQuads.append(quad->copy());
+ }
+}
+
+void HgMediaWallRenderer::setupStateAnimation(QPainter* painter)
+{
+ Q_UNUSED(painter)
+
+ resetQuads();
+ // setup quads from animated state
+ for (int i = 0; i < mOldState.mQuads.size(); i++)
+ {
+ mAnimatedQuads[i]->update();
+ mRenderer->quad(i)->copyFrom(*mOldState.mQuads[i]);
+ }
+}
+
+void HgMediaWallRenderer::resetQuads()
+{
+ for (int i = 0; i < mRenderer->quadCount(); i++)
+ mRenderer->quad(i)->setVisible(false);
+}
+
+HgQuad* HgMediaWallRenderer::getQuadAt(const QPointF& position) const
+{
+ if (!mRendererInitialized)
+ return NULL;
+
+ return mRenderer->getQuadAt(position);//mapFromWindow(position));
+}
+
+bool HgMediaWallRenderer::isItemOpen() const
+{
+ return (mOpenedItem != -1 && mAnimationAlpha > 0);
+}
+
+void HgMediaWallRenderer::setRect(const QRectF& windowRect)
+{
+ mRect = windowRect;
+}
+
+const QRectF& HgMediaWallRenderer::getRect() const
+{
+ return mRect;
+}
+
+void HgMediaWallRenderer::updateCameraMatrices()
+{
+ QMatrix4x4 view;
+
+ view.setToIdentity();
+
+ view.lookAt(QVector3D(0.0, 0.0, 1.0f + mCameraDistance),
+ QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0f, 1.0f, 0.0f));
+
+ QMatrix4x4 rot;
+ rot.rotate(mCameraRotationZ, QVector3D(0,0,1));
+ rot.rotate(mCameraRotationY, QVector3D(0,1,0));
+ view *= rot;
+
+ qreal aspect = mRect.width() / mRect.height();
+
+ QMatrix4x4 proj;
+ proj.setToIdentity();
+
+ if (mRect.width() <= mRect.height())
+ {
+ qreal aspect = mRect.height() / mRect.width();
+ proj.frustum(-0.5f, 0.5f, -0.5f*aspect, 0.5f*aspect, 1.0f, 1000.0f);
+ }
+ else
+ {
+ qreal aspect = mRect.width() / mRect.height();
+ proj.frustum(-0.5f*aspect, 0.5f*aspect, -0.5f, 0.5f, 1.0f, 1000.0f);
+ }
+
+ mViewMatrix = view;
+ mProjMatrix = proj;
+
+ qreal mirrorPlaneY = getRowPosY(mRowCount-1)-mImageSize3D.height()/2;
+ mRenderer->setMirroringPlaneY(mirrorPlaneY);
+}
+
+void HgMediaWallRenderer::updateSpacingAndImageSize()
+{
+ qreal div = mRect.width() <= mRect.height() ? mRect.width() : mRect.height();
+
+ mSpacing3D = mSpacing2D / div;
+ mImageSize3D = mImageSize2D / div;
+}
+
+void HgMediaWallRenderer::setSpacing(const QSizeF& spacing)
+{
+ mSpacing2D = spacing;
+}
+
+void HgMediaWallRenderer::setImageSize(const QSizeF& imageSize)
+{
+ mImageSize2D = imageSize;
+ mNextImageSize = imageSize;
+}
+
+const QSizeF& HgMediaWallRenderer::getSpacing() const
+{
+ return mSpacing2D;
+}
+
+const QSizeF& HgMediaWallRenderer::getImageSize() const
+{
+ return mImageSize2D;
+}
+
+void HgMediaWallRenderer::setFrontCoverElevationFactor(qreal elevation)
+{
+ mFrontCoverElevation = elevation;
+}
+
+qreal HgMediaWallRenderer::getFrontCoverElevationFactor() const
+{
+ return mFrontCoverElevation;
+}
+
+void HgMediaWallRenderer::openItem(int index, bool animate)
+{
+ if (isItemOpen())
+ return;
+
+ mOpenedItem = index;
+ mOpenedItemState = animate ? ItemOpening : ItemOpened;
+
+ mStateMachine->setAnimated(animate);
+ emit toggleItem();
+
+}
+
+void HgMediaWallRenderer::closeItem(bool animate)
+{
+ if (!isItemOpen())
+ return;
+
+ mOpenedItemState = animate ? ItemClosing : ItemClosed;
+ if (!animate)
+ mOpenedItem = -1;
+
+ mStateMachine->setAnimated(animate);
+ emit toggleItem();
+}
+
+qreal HgMediaWallRenderer::getRowPosY(int row)
+{
+ qreal step = mSpacing3D.height() + mImageSize3D.height();
+ return mRowCount == 1 ? qreal(0) : (((qreal)mRowCount/qreal(2)-qreal(0.5)) - (qreal)row) * step;
+}
+
+qreal HgMediaWallRenderer::getColumnPosX(int col)
+{
+ qreal step = -(mSpacing3D.width() + mImageSize3D.width());
+ return mColumnCount == 1 ? qreal(0) : (((qreal)mColumnCount/qreal(2)-qreal(0.5)) - (qreal)col) * step;
+}
+
+
+void HgMediaWallRenderer::enableReflections(bool enabled)
+{
+ mReflectionsEnabled = enabled;
+}
+
+bool HgMediaWallRenderer::reflectionsEnabled() const
+{
+ return mReflectionsEnabled;
+}
+
+QPointF HgMediaWallRenderer::mapFromWindow(const QPointF& point) const
+{
+ return QPointF(point.x(), mRect.height() - point.y());
+}
+
+void HgMediaWallRenderer::emitUpdate()
+{
+ emit renderingNeeded();
+}
+
+void HgMediaWallRenderer::applyOpeningAnimation(HgQuad* quad)
+{
+ QQuaternion rot(0,0,0,1);
+ qreal rotAngle = mAnimationAlpha * mFlipAngle;
+ rot = QQuaternion::fromAxisAndAngle(QVector3D(0,1,0), rotAngle);
+ quad->setRotation(rot);
+ quad->setPosition(quad->position() + QVector3D(0,0,mAnimationAlpha * mZoomAmount));
+}
+
+
+qreal HgMediaWallRenderer::getWorldWidth() const
+{
+ qreal width = (qreal)mDataProvider->imageCount() / (qreal)mRowCount - 1.0f;
+
+ if (mOrientation == Qt::Vertical)
+ {
+ qreal step = mSpacing2D.height() + mImageSize2D.height();
+ width -= (mRect.height() / step - 1.0f);
+ }
+
+ return width;
+}
+
+void HgMediaWallRenderer::beginRemoveRows(int start, int end)
+{
+ mRemoveStart = start;
+ mRemoveEnd = end;
+ mItemCountChanged = true;
+
+ recordState(mOldState);
+
+}
+
+void HgMediaWallRenderer::endRemoveRows()
+{
+
+ mStateMachine->setAnimated(true);
+
+ emit renderingNeeded();
+
+}
+
+void HgMediaWallRenderer::startStateAnimation(QPainter* painter)
+{
+
+ // clear previous animation quads
+ for (int i = 0; i < mAnimatedQuads.size(); i++)
+ {
+ delete mAnimatedQuads[i];
+ }
+ mAnimatedQuads.clear();
+
+ // setup animated quads
+ HgQuad* defaultQuad = new HgQuad();
+ defaultQuad->setPosition(QVector3D(100,100,-100));
+ int n = mOldState.mQuads.count() < mNextState.mQuads.count() ? mNextState.mQuads.count() : mOldState.mQuads.count();
+ for (int i = 0; i < n; i++)
+ {
+ HgQuad* qA = (i >= mOldState.mQuads.count()) ? defaultQuad : mOldState.mQuads[i];
+ HgQuad* qB = (i >= mNextState.mQuads.count()) ? defaultQuad : mNextState.mQuads[i];
+
+ HgAnimatedQuad* q = new HgAnimatedQuad(qA, qB, mStateAnimationDuration);
+ mAnimatedQuads.append(q);
+ q->start();
+ }
+
+ mStateAnimationOnGoing = true;
+
+ // setup first frame of the animation
+ setupStateAnimation(painter);
+
+ // toggle state animation on
+ toggleState();
+
+}
+
+void HgMediaWallRenderer::setupCoverflow(const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter)
+{
+ Q_UNUSED(startPosition)
+ Q_UNUSED(targetPosition)
+ Q_UNUSED(springVelocity)
+ Q_UNUSED(painter)
+
+ // save selected item for coverflow
+ mSelectedItem = ceil(position.x());
+
+ int quadsVisible = (mRect.width() / mImageSize2D.width() + 1) * 4;
+ int selectedItemIndex = quadsVisible / 2;
+
+ qreal step = mSpacing3D.width() + mImageSize3D.width();
+ qreal ipos = floorf(position.x());
+ qreal frac = (position.x() - ipos) * step;
+ qreal posX = -(qreal)(selectedItemIndex + 0) * step - frac;
+ qreal zFar = -mFrontCoverElevation;
+ qreal posY = 0;
+
+ int count = mDataProvider->imageCount();
+ int quadIndex = 0;
+ int itemIndex = ((int)(ipos - (qreal)selectedItemIndex));
+ int index = 0;
+
+ while (1)
+ {
+ if (itemIndex < 0)
+ {
+ itemIndex++;
+ posX += step;
+ index++;
+ continue;
+ }
+ else if (itemIndex >= count || index >= quadsVisible || quadIndex >= mRenderer->quadCount())
+ {
+ break;
+ }
+
+ qreal posZ = zFar;
+
+ // if this is center item modify its z
+ qreal p = posX / step;
+ if (p > -1.0f && p < 1.0f)
+ {
+ qreal d = lerp(-zFar, 0, qBound(qreal(0), qAbs(springVelocity)/6.0f, qreal(1)));
+ posZ = zFar + sin((p+1.0f) * KPi / 2) * d;
+ }
+
+ // modify z also for sorting
+ posZ -= 0.001f * abs(posX/step);
+
+ // setup quad for this item
+ HgQuad* quad = mRenderer->quad(quadIndex);
+ setupDefaultQuad(QVector3D(posX, posY, posZ), itemIndex, mReflectionsEnabled, quadIndex);
+
+ // step to next item
+ posX += step;
+ itemIndex++;
+ index++;
+ }
+
+}
+
+
+void HgMediaWallRenderer::setupGridPortrait(const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter)
+{
+ Q_UNUSED(startPosition)
+ Q_UNUSED(targetPosition)
+ Q_UNUSED(springVelocity)
+ Q_UNUSED(painter)
+
+ int rowCount = (mRect.height() / mImageSize2D.height() + 1) * 4;
+ int rowsUp = rowCount/2;
+
+ qreal stepY = mSpacing3D.height() + mImageSize3D.height();
+ qreal ipos = floorf(position.x());
+ qreal frac = (position.x() - ipos) * stepY;
+ qreal posY = -(qreal)rowsUp * stepY - frac;
+
+ // adjust height so that we begin from top
+ qreal div = mRect.width() <= mRect.height() ? mRect.width() : mRect.height();
+ posY -= mRect.height() / div / 2.0 - stepY / 2.0;
+
+ int count = mDataProvider->imageCount();
+ int itemIndex = ((int)(ipos - (qreal)rowsUp)) * mColumnCount;
+ int row = 0;
+ int quadIndex = 0;
+
+ while (1)
+ {
+ if (itemIndex < 0)
+ {
+ itemIndex+=mColumnCount;
+ posY += stepY;
+ row++;
+ continue;
+ }
+ else if (itemIndex >= count || quadIndex >= mRenderer->quadCount() || row >= rowCount)
+ {
+ break;
+ }
+
+ setupGridRow(-posY, itemIndex, quadIndex);
+
+ posY += stepY;
+ row++;
+ itemIndex+=mColumnCount;
+ }
+
+}
+
+void HgMediaWallRenderer::setupGridLandscape(const QPointF& startPosition,
+ const QPointF& position,
+ const QPointF& targetPosition,
+ qreal springVelocity,
+ QPainter* painter)
+{
+ Q_UNUSED(startPosition)
+ Q_UNUSED(targetPosition)
+ Q_UNUSED(springVelocity)
+ Q_UNUSED(painter)
+
+ int colCount = (mRect.width() / mImageSize2D.width() + 1) * 3;
+ int colsLeft = colCount/2;
+
+ qreal stepX = mSpacing3D.width() + mImageSize3D.width();
+ qreal ipos = floorf(position.x());
+ qreal frac = (position.x() - ipos) * stepX;
+ qreal posX = -(qreal)colsLeft * stepX - frac;
+
+ int count = mDataProvider->imageCount();
+ int itemIndex = ((int)(ipos - (qreal)colsLeft)) * mRowCount;
+ int col = 0;
+ int quadIndex = 0;
+
+ while (1)
+ {
+ if (itemIndex < 0)
+ {
+ itemIndex+=mColumnCount;
+ posX += stepX;
+ col++;
+ continue;
+ }
+ else if (itemIndex >= count || col >= colCount || quadIndex >= mRenderer->quadCount())
+ {
+ break;
+ }
+
+ setupGridColumn(posX, itemIndex, quadIndex);
+
+ posX += stepX;
+ col++;
+ itemIndex+=mRowCount;
+ }
+}
+
+void HgMediaWallRenderer::setupGridColumn(qreal posX, int itemIndex, int& quadIndex)
+{
+ for (int i = 0; i < mRowCount; i++)
+ {
+ qreal posY = getRowPosY(i);
+
+ // enable reflections for the last row needed
+ bool reflections = (i == (mRowCount-1) && mReflectionsEnabled);
+
+ setupDefaultQuad(QVector3D(posX, posY, 0), itemIndex++, reflections, quadIndex);
+
+ if (itemIndex >= mDataProvider->imageCount())
+ return;
+ }
+}
+
+void HgMediaWallRenderer::setupGridRow(qreal posY, int itemIndex, int& quadIndex)
+{
+ for (int i = 0; i < mColumnCount; i++)
+ {
+ qreal posX = getColumnPosX(i);
+ setupDefaultQuad(QVector3D(posX, posY, 0), itemIndex++, false, quadIndex);
+ if (itemIndex >= mDataProvider->imageCount())
+ return;
+ }
+}
+
+void HgMediaWallRenderer::setupDefaultQuad(const QVector3D& pos, int itemIndex, bool reflectionsEnabled, int& quadIndex)
+{
+ HgQuad* quad = mRenderer->quad(quadIndex++);
+ quad->setPosition(pos);
+ quad->setImage(mDataProvider->image(itemIndex));
+ quad->setVisible(true);
+ quad->setScale(QVector2D(mImageSize3D.width(),mImageSize3D.height()));
+ quad->setPivot(QVector2D(0,0));
+ quad->setUserData(QVariant(itemIndex));
+ quad->setRotation(QQuaternion(1,0,0,0));
+ quad->setOuterRotation(QQuaternion(1,0,0,0));
+ quad->enableMirrorImage(reflectionsEnabled);
+ quad->setAlpha(1.0f);
+
+ // apply opening animation if needed
+ /* if (itemIndex == mOpenedItem)
+ applyOpeningAnimation(quad);
+*/
+ // setup indicator/decorator for the item if needed
+ int flags = mDataProvider->flags(itemIndex);
+ const HgImage* indicatorImage = mDataProvider->indicator(flags);
+ if (flags != 0 && indicatorImage)
+ {
+ HgQuad* indicator = mRenderer->quad(quadIndex++);
+ setupIndicator(quad, indicator, indicatorImage,
+ itemIndex);
+ indicator->enableMirrorImage(reflectionsEnabled);
+ }
+
+
+}
+
+void HgMediaWallRenderer::setupIndicator(HgQuad* parent,
+ HgQuad* indicator, const HgImage* indicatorImage, int itemIndex)
+{
+ indicator->setPosition(parent->position()+
+ QVector3D(0.25*mImageSize3D.width(), -0.25*mImageSize3D.height(), 0.0001f));
+ indicator->setImage(indicatorImage);
+ indicator->setVisible(true);
+ indicator->setScale(QVector2D(0.25f*mImageSize3D.width(), 0.25f*mImageSize3D.height()));
+ indicator->setPivot(QVector2D(0.0, 0.0));
+ indicator->setUserData(QVariant(itemIndex));
+ indicator->setRotation(parent->rotation());
+ indicator->setOuterRotation(parent->outerRotation());
+ indicator->enableMirrorImage(false);
+ indicator->setAlpha(parent->alpha());
+
+ // apply opening animation to indicator if needed
+ if (itemIndex == mOpenedItem)
+ applyOpeningAnimation(indicator);
+}
+
+HgQuadRenderer* HgMediaWallRenderer::getRenderer()
+{
+ return mRenderer;
+}
+
+bool HgMediaWallRenderer::getItemPoints(int index, QPolygonF& points) const
+{
+ QPolygonF poly;
+ if (!mRenderer->getQuadTranformedPoints(poly, index))
+ return false;
+
+ points = poly;
+ return true;
+}
+
+QList<HgQuad*> HgMediaWallRenderer::getVisibleQuads() const
+{
+ return mRenderer->getVisibleQuads(QRectF(0, 0, mRect.width(), mRect.height()));
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgquad.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,155 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "HgQuad.h"
+
+HgQuad::HgQuad() :
+mRotation(QQuaternion(1,0,0,0)),
+mImage(NULL),
+mVisible(false),
+mPivot(0, 0),
+mScale(1, 1),
+mOuterRotation(QQuaternion(1,0,0,0)),
+mDrawMirror(false),
+mAlpha(1)
+{
+}
+
+HgQuad::~HgQuad()
+{
+}
+
+void HgQuad::setPosition(const QVector3D& position)
+{
+ mPosition = position;
+}
+
+void HgQuad::setRotation(const QQuaternion& rotation)
+{
+ mRotation = rotation;
+}
+
+const QVector3D& HgQuad::position() const
+{
+ return mPosition;
+}
+
+const QQuaternion& HgQuad::rotation() const
+{
+ return mRotation;
+}
+
+void HgQuad::setImage(const HgImage* image)
+{
+ mImage = image;
+}
+
+const HgImage* HgQuad::image() const
+{
+ return mImage;
+}
+
+void HgQuad::setVisible(bool visible)
+{
+ mVisible = visible;
+}
+
+bool HgQuad::visible() const
+{
+ return mVisible;
+}
+
+void HgQuad::setPivot(const QVector2D& pivot)
+{
+ mPivot = pivot;
+}
+
+void HgQuad::setScale(const QVector2D& scale)
+{
+ mScale = scale;
+}
+
+void HgQuad::setUserData(const QVariant& userData)
+{
+ mUserData = userData;
+}
+
+const QVector2D& HgQuad::pivot() const
+ {
+ return mPivot;
+ }
+
+const QVector2D& HgQuad::scale() const
+ {
+ return mScale;
+ }
+
+const QVariant& HgQuad::userData() const
+ {
+ return mUserData;
+ }
+
+HgQuad* HgQuad::copy() const
+ {
+ HgQuad* q = new HgQuad();
+ q->copyFrom(*this);
+ return q;
+ }
+
+
+void HgQuad::copyFrom(const HgQuad& quad)
+ {
+ mPosition = quad.mPosition;
+ mRotation = quad.mRotation;
+ mScale = quad.mScale;
+ mPivot = quad.mPivot;
+ mImage = quad.mImage;
+ mUserData = quad.mUserData;
+ mVisible = quad.mVisible;
+ }
+
+void HgQuad::setOuterRotation(const QQuaternion& rot)
+{
+ mOuterRotation = rot;
+}
+
+const QQuaternion HgQuad::outerRotation() const
+{
+ return mOuterRotation;
+}
+
+void HgQuad::enableMirrorImage(bool enabled)
+{
+ mDrawMirror = enabled;
+}
+
+bool HgQuad::mirrorImageEnabled() const
+{
+ return mDrawMirror;
+}
+
+void HgQuad::setAlpha(qreal alpha)
+{
+ mAlpha = alpha;
+}
+
+qreal HgQuad::alpha() const
+{
+ return mAlpha;
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgquadrenderer.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "hgquadrenderer.h"
+#include "hgquad.h"
+
+HgQuadRenderer::HgQuadRenderer(int maxQuads)
+{
+ for (int i = 0; i < maxQuads; i++)
+ {
+ mQuads.append(new HgQuad());
+ }
+}
+
+HgQuadRenderer::~HgQuadRenderer()
+{
+ for (int i = 0; i < mQuads.size(); i++)
+ {
+ delete mQuads[i];
+ }
+}
+
+int HgQuadRenderer::quadCount() const
+ {
+ return mQuads.size();
+ }
+
+HgQuad* HgQuadRenderer::quad(int index)
+{
+ return mQuads[index];
+}
+
+void HgQuadRenderer::setMirroringPlaneY(qreal mirroringPlaneY)
+{
+ mMirroringPlaneY = mirroringPlaneY;
+}
+
+void HgQuadRenderer::setImageFader(HgImageFader* fader)
+{
+ mImageFader = fader;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgspring.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,167 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "HgSpring.h"
+#include <qtimer>
+#include "trace.h"
+
+const int KTimeDelta(10);
+const qreal KTimeDeltaF(0.01f);
+//const qreal KVelocitySnap(0.05f);
+const qreal KPositionSnap(0.01f);
+const int KTimerInterval(10);
+
+HgSpring::HgSpring() :
+mStartPos(QPointF(0,0)),
+mPos(QPointF(0,0)),
+mEndPos(QPointF(0,0)),
+mVelocity(QPointF(0,0)),
+mK(30.1),
+mDamping(10.1),
+mAccumulator(0.0),
+mDoNotUpdate(false)
+{
+ mTimer = new QTimer(this);
+
+ QObject::connect( mTimer, SIGNAL( timeout() ), this, SLOT( update() ) );
+
+}
+
+HgSpring::~HgSpring()
+{
+
+}
+
+void HgSpring::setK(qreal k)
+{
+ mK = k;
+}
+
+void HgSpring::setDamping(qreal damping)
+{
+ mDamping = damping;
+}
+
+void HgSpring::animateToPos(const QPointF& pos)
+{
+ mStartPos = mPos;
+ mEndPos = pos;
+
+ emit started();
+
+ if (!mTimer->isActive())
+ {
+ mTimer->start(KTimerInterval);
+ mPrevTime.start();
+ }
+}
+
+void HgSpring::gotoPos(const QPointF& pos)
+{
+ if (mTimer->isActive())
+ {
+ mTimer->stop();
+ }
+
+ mPos = pos;
+ mEndPos = pos;
+}
+
+void HgSpring::cancel()
+{
+ if (mTimer->isActive())
+ mTimer->stop();
+}
+
+const QPointF& HgSpring::startPos() const
+{
+ return mStartPos;
+}
+
+const QPointF& HgSpring::pos() const
+{
+ return mPos;
+}
+
+const QPointF& HgSpring::endPos() const
+{
+ return mEndPos;
+}
+
+const QPointF& HgSpring::velocity() const
+{
+return mVelocity;
+}
+
+
+void HgSpring::update()
+{
+ int deltaTime = mPrevTime.elapsed();
+
+ mPrevTime.start();
+
+ mAccumulator += deltaTime;
+
+ bool stopped = false;
+ while (mAccumulator >= KTimeDelta)
+ {
+ QPointF delta = mEndPos - mPos;
+ QPointF force = delta * mK - mVelocity * mDamping;
+ mVelocity += force * KTimeDeltaF;
+ mPos += mVelocity * KTimeDeltaF;
+ if ( (qAbs(mPos.x() - mEndPos.x()) < KPositionSnap &&
+ qAbs(mPos.y() - mEndPos.y()) < KPositionSnap) )
+ {
+ mPos = mEndPos;
+ mAccumulator = 0;
+ mVelocity = QPointF(0,0);
+ mTimer->stop();
+ stopped = true;
+ break;
+ }
+
+ mAccumulator -= KTimeDelta;
+ }
+
+ if (!mDoNotUpdate)
+ emit updated();
+
+ if (stopped)
+ emit ended();
+
+}
+
+bool HgSpring::isActive() const
+{
+ return mTimer->isActive();
+}
+
+bool HgSpring::updatePositionIfNeeded()
+{
+ if (isActive() && mPrevTime.elapsed() > KTimeDelta) {
+ mDoNotUpdate = true;
+ update();
+ mDoNotUpdate = false;
+ mTimer->stop();
+ mTimer->start(KTimerInterval);
+ return true;
+ }
+ return false;
+}
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgvgimage.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,179 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "HgVgImage.h"
+#include "HgImageFader.h"
+#include "hgvgquadrenderer.h"
+
+const int KMaxMirrorWidth(128);
+const int KMaxMirrorHeight(64);
+
+static QSize getMirrorSize(const QImage& image)
+{
+ return QSize(
+ qMin(image.width() / 2, KMaxMirrorWidth),
+ qMin(image.height() / 4, KMaxMirrorHeight)
+ );
+}
+
+HgVgImage::HgVgImage(HgVgQuadRenderer* renderer) :
+ mVgImage(VG_INVALID_HANDLE),
+ mMirrorImage(VG_INVALID_HANDLE),
+ mMirrorSize(0,0),
+ mRenderer(renderer)
+{
+ setAlpha(1.0);
+}
+
+HgVgImage::~HgVgImage()
+{
+ releaseImage();
+}
+
+int HgVgImage::width() const
+{
+ return mQImage.width();
+}
+
+int HgVgImage::height() const
+{
+ return mQImage.height();
+}
+
+VGImage HgVgImage::image() const
+{
+ return mVgImage;
+}
+
+int HgVgImage::mirrorImageWidth() const
+{
+ return mMirrorSize.width();
+}
+
+int HgVgImage::mirrorImageHeight() const
+{
+ return mMirrorSize.height();
+}
+
+VGImage HgVgImage::mirrorImage() const
+{
+ return mMirrorImage;
+}
+
+
+void HgVgImage::setImage(QImage& image)
+{
+ if (image.isNull())
+ return;
+
+ // release previous images vg data
+ releaseImage();
+
+ mQImage = image;
+
+ mMirrorSize = getMirrorSize(mQImage);
+
+}
+
+void HgVgImage::releaseImage()
+{
+ if (mVgImage != VG_INVALID_HANDLE)
+ {
+ vgDestroyImage(mVgImage);
+ mVgImage = VG_INVALID_HANDLE;
+ }
+ if (mMirrorImage != VG_INVALID_HANDLE)
+ {
+ vgDestroyImage(mMirrorImage);
+ mMirrorImage = VG_INVALID_HANDLE;
+ }
+
+ // TODO, check that this will free all the previously reserved image resources.
+ mQImage = QImage();
+}
+
+void HgVgImage::upload(bool mirror)
+{
+
+ if (mVgImage == VG_INVALID_HANDLE)
+ {
+
+ VGImageFormat format;
+
+ switch (mQImage.format())
+ {
+ case QImage::Format_ARGB32_Premultiplied:
+ format = VG_sARGB_8888_PRE;
+ break;
+ case QImage::Format_ARGB32:
+ format = VG_sARGB_8888;
+ break;
+ case QImage::Format_RGB16:
+ format = VG_sRGB_565;
+ break;
+ default:
+ mQImage = mQImage.convertToFormat(QImage::Format_RGB16);
+ format = VG_sRGB_565;
+ break;
+ }
+
+
+ mVgImage = vgCreateImage(format,
+ mQImage.width(), mQImage.height(),VG_IMAGE_QUALITY_NONANTIALIASED);
+ if (mVgImage == VG_INVALID_HANDLE)
+ {
+ qWarning("HgMediaWall run out of video memory for images!");
+ return;
+ }
+
+ vgImageSubData(mVgImage, mQImage.bits(), mQImage.bytesPerLine(),
+ format, 0, 0, mQImage.width(), mQImage.height() );
+ }
+
+ if (mirror && mMirrorImage == VG_INVALID_HANDLE)
+ {
+ mMirrorImage = vgCreateImage(VG_sARGB_8888_PRE, mMirrorSize.width(), mMirrorSize.height(), VG_IMAGE_QUALITY_NONANTIALIASED);
+ if (mMirrorImage == VG_INVALID_HANDLE)
+ {
+ qWarning("HgMediaWall run out of video memory for images!");
+ return;
+ }
+
+ // cut half of the image, then scale to desired width/height if needed
+ QImage mirrorImage = mQImage.copy(0, mQImage.height()/2, mQImage.width(), mQImage.height()/2).scaled(mMirrorSize).convertToFormat(QImage::Format_ARGB32);
+
+ // apply gradient to alpha channel so that mirror image looks like
+ // it fades under the floor
+ for (int i = 0; i < mirrorImage.height(); i++)
+ {
+ qreal t = qreal(i) / qreal(mirrorImage.height());
+ int a = (int)(t * 255.0);
+ for (int j = 0; j < mirrorImage.width(); j++)
+ {
+ QRgb rgb = mirrorImage.pixel(j, i);
+ mirrorImage.setPixel(j, i, qRgba(qRed(rgb), qGreen(rgb), qBlue(rgb), a));
+ }
+ }
+
+ // copy data to vg image
+ vgImageSubData(mMirrorImage, mirrorImage.bits(), mirrorImage.bytesPerLine(),
+ VG_sARGB_8888, 0, 0, mirrorImage.width(), mirrorImage.height() );
+
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgvgimagepool.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "hgvgimagepool.h"
+#include "trace.h"
+
+HgVgImagePool::HgVgImagePool(int numImages, int imgWidth, int imgHeight, bool alpha)
+{
+ for (int i = 0; i < numImages; i++)
+ {
+ VGImage vgimage = vgCreateImage(alpha ? VG_sARGB_8888 : VG_sRGB_565,
+ imgWidth, imgHeight,VG_IMAGE_QUALITY_NONANTIALIASED);
+
+ mFreeImages.push_back(vgimage);
+ }
+}
+HgVgImagePool::~HgVgImagePool()
+{
+ QLinkedList<VGImage>::const_iterator it = mUsedImages.begin();
+ while (it != mUsedImages.end())
+ {
+ vgDestroyImage((*it));
+ it++;
+ }
+
+ QLinkedList<VGImage>::const_iterator it2 = mFreeImages.begin();
+ while (it2 != mFreeImages.end())
+ {
+ vgDestroyImage((*it2));
+ it2++;
+ }
+
+}
+void HgVgImagePool::releaseImage(VGImage image)
+{
+ if (image == VG_INVALID_HANDLE)
+ return;
+
+ for (QLinkedList<VGImage>::iterator it = mUsedImages.begin();
+ it != mUsedImages.end(); ++it)
+ {
+ if ((*it) == image)
+ {
+ mUsedImages.erase(it);
+ break;
+ }
+ }
+ vgClearImage(image, 0, 0, vgGetParameteri(image, VG_IMAGE_WIDTH), vgGetParameteri(image, VG_IMAGE_HEIGHT));
+ mFreeImages.push_back(image);
+}
+
+VGImage HgVgImagePool::getImage()
+{
+ FUNC_LOG
+
+ if (mFreeImages.empty())
+ {
+ INFO("Hg: Run out of images!");
+
+ // if no free images left, use the one which was allocated
+ // longer ago
+ QLinkedList<VGImage>::iterator i = mUsedImages.begin();
+ VGImage img = *i;
+ mUsedImages.erase(i);
+ mUsedImages.push_back(img);
+ return img;
+ }
+
+ QLinkedList<VGImage>::iterator i = mFreeImages.begin();
+ VGImage img = *i;
+ mUsedImages.push_back(img);
+ mFreeImages.erase(i);
+
+ return img;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgvgquadrenderer.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,471 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "hgvgquadrenderer.h"
+#include "hgquad.h"
+#include "hgvgimage.h"
+#include "trace.h"
+#include "HgImageFader.h"
+
+#include <VG/openvg.h>
+#include <VG/vgu.h>
+#include <qvector2d>
+#include <qpolygon>
+#include <qmatrix4x4>
+#include <qpainter>
+
+
+class HgVgQuad
+{
+public:
+ HgVgQuad(HgVgQuadRenderer* renderer);
+ ~HgVgQuad();
+
+ int index() const;
+ bool isPointInside(const QPointF& point) const;
+ void transformQuad(int index, const QMatrix4x4& matrix, HgQuad* quad,
+ const QRectF& rect, qreal mirroringPlaneY);
+ void draw();
+
+ void getTransformedPoints(QPolygonF& polygon) const;
+
+ void computeMirrorMatrix(const QMatrix4x4& tm, const QMatrix4x4& projView,
+ const QRectF& rect, qreal mirroringPlaneY);
+
+ bool perspectiveTransformPoints(QVector2D* points, const QMatrix4x4& matrix,
+ const QRectF& rect);
+
+ void computeWarpMatrix(VGfloat* matrix, int pxWidth, int pxHeight, const QVector2D* points);
+
+ void drawImage(HgVgImage* image, qreal alpha);
+
+ int mIndex;
+ HgQuad* mQuad;
+ QVector2D mTransformedPoints[4];
+ VGfloat mMatrix[9];
+ VGfloat mMirrorMatrix[9];
+ HgVgQuadRenderer* mRenderer;
+ bool mDegenerate;
+private:
+ HgVgQuad(const HgVgQuad&);
+ HgVgQuad& operator=(const HgVgQuad&);
+};
+
+static bool quadSorter(HgVgQuad* a, HgVgQuad* b)
+{
+ return a->mQuad->position().z() < b->mQuad->position().z();
+}
+
+HgVgQuad::HgVgQuad(HgVgQuadRenderer* renderer) : mRenderer(renderer)
+{
+
+}
+
+HgVgQuad::~HgVgQuad()
+{
+
+}
+
+int HgVgQuad::index() const
+ {
+ return mIndex;
+ }
+
+bool HgVgQuad::isPointInside(const QPointF& point) const
+{
+ QPolygonF poly;
+ getTransformedPoints(poly);
+ QRectF rect = poly.boundingRect();
+ if (rect.contains(point))
+ {
+ return true;
+ }
+ return false;
+}
+
+
+void HgVgQuad::computeMirrorMatrix(const QMatrix4x4& trans, const QMatrix4x4& projView,
+ const QRectF& rect, qreal mirroringPlaneY)
+{
+ HgQuad* quad = mQuad;
+
+ QMatrix4x4 mirror = trans;
+
+ qreal distToPlane = qAbs(quad->position().y() - mirroringPlaneY);
+
+ mirror.translate(quad->position().x(), mirroringPlaneY - distToPlane/2, quad->position().z());
+ mirror.scale(quad->scale().x(), -quad->scale().y()/2);
+ mirror.rotate(quad->rotation());
+
+ QMatrix4x4 modelViewProjMatrix = projView * mirror;
+
+ QVector2D temp[4];
+
+ perspectiveTransformPoints(temp, modelViewProjMatrix, rect);
+
+ HgVgImage* image = (HgVgImage*)mQuad->image();
+
+ if (image == NULL)
+ {
+ image = mRenderer->defaultImage();
+ }
+
+ int pxWidth = image->mirrorImageWidth();
+ int pxHeight = image->mirrorImageHeight();
+
+ computeWarpMatrix(mMirrorMatrix, pxWidth, pxHeight, temp);
+}
+
+void HgVgQuad::transformQuad(int index, const QMatrix4x4& projView, HgQuad* quad,
+ const QRectF& rect, qreal mirroringPlaneY)
+{
+ mIndex = index;
+ mQuad = quad;
+
+ QMatrix4x4 tm;
+ tm.setToIdentity();
+ tm.rotate(quad->outerRotation());
+
+ if (mQuad->mirrorImageEnabled())
+ {
+ computeMirrorMatrix(tm, projView, rect, mirroringPlaneY);
+ }
+
+ tm.translate(quad->position());
+ tm.rotate(quad->rotation());
+ tm.scale(quad->scale().x(), quad->scale().y());
+
+ tm = projView * tm;
+ //QMatrix4x4 tmt = tm.transposed();
+
+ mDegenerate = false;
+ if (!perspectiveTransformPoints(mTransformedPoints, tm, rect))
+ {
+ mDegenerate = true;
+ }
+
+ HgVgImage* image = (HgVgImage*)mQuad->image();
+
+ if (image == NULL)
+ {
+ image = mRenderer->defaultImage();
+ }
+
+ int pxWidth = image->width();
+ int pxHeight = image->height();
+
+ computeWarpMatrix(mMatrix, pxWidth, pxHeight, mTransformedPoints);
+
+}
+
+bool HgVgQuad::perspectiveTransformPoints(QVector2D* outPoints, const QMatrix4x4& matrix,
+ const QRectF& rect)
+{
+ const QVector4D points[] =
+ {
+ QVector4D(-0.5f, -0.5f, 0.0f, 1.0f),
+ QVector4D( 0.5f, -0.5f, 0.0f, 1.0f),
+ QVector4D( 0.5f, 0.5f, 0.0f, 1.0f),
+ QVector4D(-0.5f, 0.5f, 0.0f, 1.0f)
+ };
+
+ qreal hw = rect.width() * 0.5f;
+ qreal hh = rect.height() * 0.5f;
+
+ for (int i = 0; i < 4; i++)
+ {
+ QVector4D temp = matrix * points[i];
+
+ outPoints[i] = QVector2D(
+ hw + temp.x() / temp.w() * hw,
+ hh + temp.y() / temp.w() * hh);
+
+ }
+
+ return true;
+}
+
+void HgVgQuad::computeWarpMatrix(VGfloat* matrix, int pxWidth, int pxHeight, const QVector2D* points)
+{
+ vguComputeWarpQuadToQuad(
+ points[0].x(), points[0].y(),
+ points[1].x(), points[1].y(),
+ points[2].x(), points[2].y(),
+ points[3].x(), points[3].y(),
+ 0, pxHeight,
+ pxWidth, pxHeight,
+ pxWidth, 0,
+ 0, 0,
+ matrix);
+/*
+ INFO("P0 x:" << points[0].x() << " y:" << points[0].y());
+ INFO("P1 x:" << points[1].x() << " y:" << points[1].y());
+ INFO("P2 x:" << points[2].x() << " y:" << points[2].y());
+ INFO("P3 x:" << points[3].x() << " y:" << points[3].y());*/
+}
+
+
+void HgVgQuad::draw()
+{
+ if (!mQuad->visible())
+ return;
+
+ if (mDegenerate)
+ return;
+
+ HgVgImage* image = (HgVgImage*)mQuad->image();
+
+
+ if (image == NULL || image->alpha() == 0)
+ {
+ return;
+ //drawImage(mRenderer->defaultImage(), 1.0f);
+ }
+ else
+ {
+ image->upload(mQuad->mirrorImageEnabled());
+
+ if (image->image() == VG_INVALID_HANDLE)
+ {
+ drawImage(mRenderer->defaultImage(), 1.0f);
+ }
+ else
+ {
+
+ if ( mQuad->alpha() < 1.0f )
+ {
+ drawImage(mRenderer->defaultImage(), 1.0f - mQuad->alpha());
+ }
+
+ drawImage(image, mQuad->alpha());
+ }
+ }
+
+
+}
+
+void HgVgQuad::drawImage(HgVgImage* image, qreal alpha)
+{
+ Q_UNUSED(alpha)
+
+ //VGfloat values[] = { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 };
+ //values[3] = alpha;
+
+ //vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
+
+ VGImage vgImage = image->image();
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+
+ VGfloat m[9];
+ vgGetMatrix(m);
+
+ vgMultMatrix(mMatrix);
+ vgDrawImage(vgImage);
+
+ vgLoadMatrix(m);
+
+ if (mQuad->mirrorImageEnabled())
+ {
+ VGImage mirrorImage = image->mirrorImage();
+ if (mirrorImage == VG_INVALID_HANDLE)
+ return;
+
+ vgMultMatrix(mMirrorMatrix);
+
+ vgDrawImage(mirrorImage);
+ vgLoadMatrix(m);
+ }
+
+}
+
+
+void HgVgQuad::getTransformedPoints(QPolygonF& poly) const
+{
+ poly.append(mTransformedPoints[0].toPointF());
+ poly.append(mTransformedPoints[1].toPointF());
+ poly.append(mTransformedPoints[2].toPointF());
+ poly.append(mTransformedPoints[3].toPointF());
+}
+
+
+HgVgQuadRenderer::HgVgQuadRenderer(int maxQuads) :
+ HgQuadRenderer(maxQuads),
+ mDefaultVgImage(NULL)
+{
+ for (int i = 0; i < maxQuads; i++)
+ {
+ mTransformedQuads.append(new HgVgQuad(this));
+ }
+ mImageFader = new HgImageFader();
+}
+
+HgVgQuadRenderer::~HgVgQuadRenderer()
+{
+ delete mDefaultVgImage;
+}
+
+HgQuad* HgVgQuadRenderer::getQuadAt(const QPointF& point) const
+{
+ FUNC_LOG
+
+ // TODO: need to use sorted quads here, in reversed order.
+ QList<HgVgQuad*>::const_iterator i = mSortedQuads.begin();
+ while(i != mSortedQuads.end())
+ {
+ HgVgQuad* q = (*i);
+ if (q->isPointInside(point))
+ {
+ return q->mQuad;
+ }
+ i++;
+ }
+
+ return NULL;
+}
+
+
+void HgVgQuadRenderer::transformQuads(const QMatrix4x4& view, const QMatrix4x4& proj,
+ const QRectF& rect)
+{
+ QMatrix4x4 pv = proj * view;
+
+ mSortedQuads.clear();
+
+ for (int i = 0; i < mQuads.size(); i++)
+ {
+ HgQuad* q = mQuads[i];
+
+ HgVgQuad* tq = mTransformedQuads[i];
+
+ if (q->visible())
+ {
+ tq->transformQuad(i, pv, q, rect, mMirroringPlaneY);
+ mSortedQuads.append(tq);
+ }
+ }
+
+ qSort(mSortedQuads.begin(), mSortedQuads.end(), quadSorter);
+}
+
+void HgVgQuadRenderer::drawQuads(const QRectF& rect, QPainter* painter)
+{
+ Q_UNUSED(rect)
+
+
+ painter->beginNativePainting();
+
+ // need to save old scissoring rects, otherwise hb
+ // screws up with rendering
+/* VGint oldScissoring = vgGeti(VG_SCISSORING);
+ VGint numRects = 32;//vgGeti(VG_MAX_SCISSOR_RECTS);
+ VGint oldRects[32*4];
+ vgGetiv(VG_SCISSOR_RECTS, numRects, oldRects);
+
+ // setup our new scissoring rects
+ VGint sRect[4];
+ sRect[0] = rect.left();
+ sRect[1] = rect.top();
+ sRect[2] = rect.width();
+ sRect[3] = rect.height();
+ vgSeti(VG_SCISSORING, VG_TRUE);
+ vgSetiv(VG_SCISSOR_RECTS, 4, sRect);
+ */
+ // setup root transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadIdentity();
+ vgTranslate(rect.left(), rect.top());
+
+ vgSeti(VG_COLOR_TRANSFORM, VG_FALSE);
+ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+
+ // draw quads
+ for (int i = 0; i < mSortedQuads.size(); i++)
+ {
+ mSortedQuads[i]->draw();
+ }
+
+ // set back old scissor rects
+ // vgSeti(VG_SCISSORING, oldScissoring);
+ // vgSetiv(VG_SCISSOR_RECTS, numRects, oldRects);
+
+ painter->endNativePainting();
+
+}
+
+bool HgVgQuadRenderer::getQuadTranformedPoints(QPolygonF& points, int index) const
+{
+ for (int i = 0; i < mSortedQuads.count(); i++)
+ {
+ HgVgQuad* quad = mSortedQuads[i];
+ if (quad->mQuad)
+ {
+ bool bOk;
+ if (quad->mQuad->userData().toInt(&bOk) == index)
+ {
+ quad->getTransformedPoints(points);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+HgImage* HgVgQuadRenderer::createNativeImage()
+{
+ return new HgVgImage(this);
+}
+
+HgVgImage* HgVgQuadRenderer::defaultImage()
+{
+ if (mDefaultVgImage == NULL)
+ {
+ QImage defaultImage(64,64,QImage::Format_RGB16);
+ defaultImage.fill(qRgb(255,0,0));
+ mDefaultVgImage = static_cast<HgVgImage*>(createNativeImage());
+ mDefaultVgImage->setImage(defaultImage);
+ mDefaultVgImage->upload(true);
+ }
+ return mDefaultVgImage;
+}
+
+HgImageFader* HgVgQuadRenderer::imageFader()
+{
+ return mImageFader;
+}
+
+QList<HgQuad*> HgVgQuadRenderer::getVisibleQuads(const QRectF& rect) const
+{
+ FUNC_LOG;
+
+ // this implementation isn't 100% precise
+ QList<HgQuad*> result;
+ for (int i = 0; i < mSortedQuads.count(); i++) {
+ QPolygonF poly;
+ mSortedQuads[i]->getTransformedPoints(poly);
+ QRectF bounds = poly.boundingRect();
+ if (bounds.intersects(rect) || rect.contains(bounds)) {
+ result.append(mSortedQuads[i]->mQuad);
+ }
+ }
+
+ return result;
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgwidgetitem.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,190 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "hgwidgetitem.h"
+#include "hgquadrenderer.h"
+#include <hgwidgets/hgwidgets.h>
+#include <QStringList>
+#include <HbIcon>
+
+HgWidgetItem::HgWidgetItem(HgQuadRenderer* renderer):
+mTitle(""),
+mDescription(""),
+mValidData(false),
+mHgImage(NULL),
+mRenderer(renderer)
+{
+}
+
+HgWidgetItem::HgWidgetItem(HgQuadRenderer* renderer, QImage image, QString title, QString description ) :
+mTitle(""),
+mDescription(""),
+mValidData(false),
+mHgImage(NULL),
+mRenderer(renderer),
+mVisibility(true)
+{
+ Q_UNUSED(image)
+ setTitle(title);
+ setDescription(description);
+}
+
+HgWidgetItem::~HgWidgetItem()
+{
+ releaseItemData();
+ delete mHgImage;
+}
+
+void HgWidgetItem::setImage( QImage image )
+{
+ if (!mHgImage)
+ {
+ mHgImage = mRenderer->createNativeImage();
+ }
+ mHgImage->setImage(image);
+ if (!mVisibility)
+ mHgImage->setAlpha(0);
+
+}
+
+void HgWidgetItem::setTitle( QString title )
+{
+ mTitle = title;
+}
+
+QString HgWidgetItem::title() const
+{
+ return mTitle;
+}
+
+void HgWidgetItem::setDescription( QString description )
+{
+ mDescription = description;
+}
+
+QString HgWidgetItem::description() const
+{
+ return mDescription;
+}
+
+void HgWidgetItem::setModelIndex(const QModelIndex& index)
+{
+ mModelIndex = index;
+}
+
+QModelIndex HgWidgetItem::modelIndex() const
+{
+ return mModelIndex;
+}
+
+bool HgWidgetItem::updateItemData()
+{
+ mValidData = false;
+ if( mModelIndex.isValid() ){
+ QVariant image = mModelIndex.data(Qt::DecorationRole);
+ QVariant texts = mModelIndex.data(Qt::DisplayRole);
+
+ QVariant vis = mModelIndex.data(HgWidget::HgVisibilityRole);
+ if (vis.canConvert<bool>())
+ {
+ setVisibility(vis.toBool());
+ }
+
+ // Convert data to correct format if possible.
+ if(image.canConvert<QImage>()){
+ setImage(image.value<QImage>());
+ mValidData = true;
+ }
+ else if(image.canConvert<HbIcon>()){
+ // This is heavy operation but we need to support
+ // HbIcon too.
+ HbIcon hbIcon = image.value<HbIcon>();
+ if (!hbIcon.isNull()){
+ QIcon &qicon = hbIcon.qicon();
+ QList<QSize> sizes = qicon.availableSizes();
+ QSize size;
+ foreach(size, sizes){
+ if (size.width() != 0 && size.height() != 0 ){
+ QPixmap pixmap = qicon.pixmap(size);
+ if (!pixmap.isNull()){
+ setImage(pixmap.toImage());
+ mValidData = true;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else if (image.canConvert<QIcon>()){
+ // This is heavy operation but we need to support
+ // QIcon too.
+ QIcon tempIcon = image.value<QIcon>();
+ QList<QSize> sizes = tempIcon.availableSizes();
+ QSize size;
+ foreach(size, sizes){
+ if (size.width() != 0 && size.height() != 0 ){
+ QPixmap pixmap = tempIcon.pixmap(size);
+ if (!pixmap.isNull()){
+ setImage(pixmap.toImage());
+ mValidData = true;
+ }
+ break;
+ }
+ }
+ }
+ if( texts.canConvert<QStringList>() ){
+ QStringList list(texts.toStringList() );
+ if( list.count() >= 2 ){
+ setTitle(list.at(0));
+ setDescription(list.at(1));
+ mValidData = true;
+ }
+ }
+
+ }
+ return mValidData;
+}
+
+void HgWidgetItem::releaseItemData()
+{
+ mTitle = "";
+ mDescription = "";
+ mValidData = false;
+ if (mHgImage)
+ mHgImage->releaseImage();
+}
+
+bool HgWidgetItem::validData() const
+{
+ return mValidData;
+}
+
+const HgImage* HgWidgetItem::image() const
+{
+ return mHgImage;
+}
+
+void HgWidgetItem::setVisibility(bool visibility)
+{
+ mVisibility = visibility;
+ if (mHgImage)
+ {
+ if (!mVisibility)
+ mHgImage->setAlpha(0);
+ else
+ mHgImage->setAlpha(1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgwidgets.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,325 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QGraphicsSceneResizeEvent>
+#include <hbmainwindow>
+#include <hbscrollbar.h>
+#include <qapplication.h>
+#include <hgwidgets/hgwidgets.h>
+#include <hbstyleloader.h>
+
+#include "hgwidgets_p.h"
+#include "hgcontainer.h"
+#include "hgwidgetitem.h"
+#include "hgscrollbuffermanager.h"
+#include "hgcoverflowcontainer.h"
+#include "hggridcontainer.h"
+#include "trace.h"
+
+HgWidget::HgWidget(HbWidgetPrivate* widgetPrivate, QGraphicsItem *parent ):
+ HbWidget(*widgetPrivate, parent)
+{
+ Q_D(HgWidget);
+ d->q_ptr = this;
+
+ HbStyleLoader::registerFilePath(":/hgwidget.css");
+ HbStyleLoader::registerFilePath(":/hgwidget.widgetml");
+}
+
+HgWidget::~HgWidget()
+{
+ HbStyleLoader::unregisterFilePath(":/hgwidget.css");
+ HbStyleLoader::unregisterFilePath(":/hgwidget.widgetml");
+}
+
+/*!
+ Returns model that view is currently presenting.
+*/
+QAbstractItemModel *HgWidget::model() const
+{
+ Q_D(const HgWidget);
+ return d->mModel;
+}
+
+/*!
+ Sets the model to \a model and replaces current item prototype with \a prototype.
+ Ownership of the model is not taken. Ownership of the prototype is taken.
+ If no prototype has been passed, default prototype is used.
+ */
+void HgWidget::setModel(QAbstractItemModel *model )
+{
+ Q_D(HgWidget);
+ d->setModel(model);
+}
+
+void HgWidget::setSelectionModel(QItemSelectionModel *selectionModel)
+{
+ Q_D(HgWidget);
+ d->setSelectionModel(selectionModel);
+}
+
+QItemSelectionModel *HgWidget::selectionModel() const
+{
+ Q_D(const HgWidget);
+ return d->selectionModel();
+}
+
+HgWidget::SelectionMode HgWidget::selectionMode() const
+{
+ Q_D(const HgWidget);
+ return d->selectionMode();
+}
+
+/*!
+ If newMode is not same as current selection mode of view, updates
+ selection mode and all viewitems. If resetSelection is true (the default),
+ it clears all existing selections.
+*/
+void HgWidget::setSelectionMode(SelectionMode mode, bool resetSelection)
+{
+ Q_D(HgWidget);
+ d->setSelectionMode(mode, resetSelection);
+}
+
+void HgWidget::selectAll()
+{
+ Q_D(HgWidget);
+ d->selectAll();
+}
+
+void HgWidget::clearSelection()
+{
+ Q_D(HgWidget);
+ d->clearSelection();
+}
+
+QModelIndex HgWidget::currentIndex() const
+{
+ Q_D(const HgWidget);
+ return d->currentIndex();
+}
+
+void HgWidget::setCurrentIndex(
+ const QModelIndex &index, QItemSelectionModel::SelectionFlags selectionFlag)
+{
+ Q_D(HgWidget);
+ d->setCurrentIndex(index, selectionFlag);
+}
+
+void HgWidget::scrollTo(const QModelIndex &index)
+{
+ Q_D(HgWidget);
+ d->scrollTo(index);
+}
+
+void HgWidget::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ Q_D( HgWidget);
+ // TODO,take columns into count
+ for( int i = topLeft.row(); i <= bottomRight.row(); i++ ){
+ // if data for item outside our current buffer has changed
+ // we just have to ignore it since we dont have resources
+ // to handle it(or we dont want to waste resources).
+ if(d->mBufferManager->positionInsideBuffer(i)){
+ HgWidgetItem* item = d->mContainer->itemByIndex( i );
+ if( item ){
+ item->updateItemData();
+ }
+ }
+ }
+ d->mContainer->itemDataChanged( topLeft, bottomRight );
+}
+
+/*!
+ * Returns true if the scroll area handles
+ * long press gestures, false otherwise
+ *
+ * \sa HbScrollArea::setHandleLongPress()
+ */
+bool HgWidget::longPressEnabled() const
+{
+ Q_D( const HgWidget );
+
+ return d->mHandleLongPress;
+}
+
+/*!
+ * Sets the value of the handleLongPress property. This value is set
+ * to true if the widget is to respond to long press gestures, false otherwise.
+ *
+ * The default value is false.
+ *
+ * \sa HbScrollArea::handleLongPress()
+ */
+void HgWidget::setLongPressEnabled (bool value)
+{
+ Q_D( HgWidget );
+
+ if (d->mHandleLongPress != value)
+ {
+ d->mHandleLongPress = value;
+ if (value)
+ {
+ grabGesture(Qt::TapAndHoldGesture);
+ }
+ else
+ {
+ ungrabGesture(Qt::TapAndHoldGesture);
+ }
+ }
+
+ // TODO, should we do something like this?????
+// if (isChanged) {
+// d->updateGestures();
+// emit gestureSceneFilterChanged( d->mGestureFilter );
+// }
+}
+
+HgWidget::ScrollBarPolicy HgWidget::scrollBarPolicy() const
+{
+ Q_D(const HgWidget);
+ return d->mScrollBarPolicy;
+}
+
+/*!
+ Sets the policy for vertical scrollbar
+
+ The default policy is HgWidget::ScrollBarAutoHide.
+
+ \sa setHorizontalScrollBarPolicy(), verticalScrollBarPolicy()
+*/
+void HgWidget::setScrollBarPolicy(ScrollBarPolicy policy)
+{
+ Q_D(HgWidget);
+ d->setScrollBarPolicy(policy);
+}
+
+/*!
+ Returns the vertical scroll bar.
+
+ \sa verticalScrollBarPolicy(), horizontalScrollBar()
+ */
+HbScrollBar *HgWidget::scrollBar() const
+{
+ Q_D(const HgWidget);
+ return d->mScrollBar;
+}
+
+/*!
+ Replaces the existing vertical scroll bar with \a scrollBar. The former
+ scroll bar is deleted.
+
+ HgWidget already provides vertical and horizontal scroll bars by
+ default. You can call this function to replace the default vertical
+ scroll bar with your own custom scroll bar.
+
+ \sa verticalScrollBar(), setHorizontalScrollBar()
+*/
+void HgWidget::setScrollBar(HbScrollBar *scrollBar)
+{
+ Q_D(HgWidget);
+ if (!scrollBar) {
+ qWarning("HgWidget::setVerticalScrollBar: Cannot set a null scroll bar");
+ return;
+ }
+
+ d->replaceScrollBar(scrollBar);
+}
+
+bool HgWidget::eventFilter(QObject *obj,QEvent *event)
+{
+ Q_D(HgWidget);
+ switch (event->type() )
+ {
+ case QEvent::ApplicationActivate:
+ {
+ d->gainedForeground();
+ break;
+ }
+ case QEvent::ApplicationDeactivate:
+ {
+ d->lostForeground();
+ break;
+ }
+ case QEvent::GraphicsSceneResize:
+ {
+ d->adjustGeometry();
+ break;
+ }
+ default:
+ break;
+ }
+ return QObject::eventFilter(obj, event);
+}
+
+bool HgWidget::event(QEvent *event)
+{
+ Q_D(HgWidget);
+
+ bool value(false);
+ if (event){
+ value = HbWidget::event(event);
+ if (event->type() == QEvent::GraphicsSceneResize){
+ d->adjustGeometry();
+ }
+ }
+ return value;
+}
+
+bool HgWidget::getItemOutline(const QModelIndex& index, QPolygonF& points)
+{
+ Q_D(HgWidget);
+
+ return d->getItemOutline(index, points);
+}
+
+void HgWidget::aboutToChangeOrientation()
+{
+
+}
+
+void HgWidget::orientationChanged(Qt::Orientation orientation)
+{
+ Q_D(HgWidget);
+ d->orientationChanged(orientation);
+}
+
+Qt::Orientation HgWidget::scrollDirection() const
+{
+ Q_D(const HgWidget);
+ return d->scrollDirection();
+}
+
+QList<QModelIndex> HgWidget::getVisibleItemIndices() const
+{
+ Q_D(const HgWidget);
+ return d->getVisibleItemIndices();
+}
+
+void HgWidget::setIndexFeedbackPolicy(IndexFeedbackPolicy policy)
+{
+ Q_D(HgWidget);
+ d->setIndexFeedbackPolicy(policy);
+}
+
+HgWidget::IndexFeedbackPolicy HgWidget::indexFeedbackPolicy() const
+{
+ Q_D(const HgWidget);
+ return d->indexFeedbackPolicy();
+}
+
+// EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgwidgets_p.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,693 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QGraphicsLinearLayout>
+#include <QApplication>
+#include <hbscrollbar_p.h>
+#include <hgwidgets/hgwidgets.h>
+
+#include "hgwidgets_p.h"
+#include "hgcontainer.h"
+#include "hgcoverflowcontainer.h"
+#include "hgscrollbuffermanager.h"
+#include "hgwidgetitem.h"
+#include "trace.h"
+#include "hgindexfeedback.h"
+
+static const int INITIAL_SCROLLBAR_HIDE_TIMEOUT(4000);
+static const int DEFAULT_BUFFER_SIZE(40);
+
+HgWidgetPrivate::HgWidgetPrivate() :
+ mLayout(0),
+ mContainer(0),
+ mBufferManager(0),
+ mModel(0),
+ mSelectionModel(0),
+ mDefaultSelectionModel(0),
+ mScrollBar(0),
+ mAbleToScroll(false),
+ mHandleLongPress(false),
+ mBufferSize(DEFAULT_BUFFER_SIZE)
+{
+ FUNC_LOG;
+}
+
+HgWidgetPrivate::~HgWidgetPrivate()
+{
+ FUNC_LOG;
+
+ delete mDefaultSelectionModel;
+ delete mBufferManager;
+}
+
+void HgWidgetPrivate::init(HgContainer *container)
+{
+ FUNC_LOG;
+ Q_Q(HgWidget);
+
+ mScrollBarHideTimer.setParent(q);
+ mScrollBarHideTimer.setSingleShot(true);
+
+ q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ q->setFlag( QGraphicsItem::ItemClipsChildrenToShape, true );
+ q->setFocusPolicy(Qt::StrongFocus);
+
+ createScrollBar(container->orientation());
+
+ QObject::connect(&(mScrollBarHideTimer), SIGNAL(timeout()), q, SLOT(_q_hideScrollBars()));
+
+ mContainer = container;
+
+ mScrollBarPolicy = HgWidget::ScrollBarAutoHide;
+
+ q->connect(mContainer, SIGNAL(scrollPositionChanged(qreal,bool)),
+ q, SLOT(_q_scrollPositionChanged(qreal,bool)));
+ q->connect(mContainer, SIGNAL(activated(const QModelIndex&)),
+ q, SIGNAL(activated(const QModelIndex&)));
+ q->connect(mContainer, SIGNAL(longPressed(const QModelIndex&, const QPointF &)),
+ q, SIGNAL(longPressed(const QModelIndex&, const QPointF &)));
+ q->connect(mContainer, SIGNAL(scrollingStarted()), q, SIGNAL(scrollingStarted()));
+ q->connect(mContainer, SIGNAL(scrollingEnded()), q, SIGNAL(scrollingEnded()));
+
+ mIndexFeedback = new HgIndexFeedback(q);
+ mIndexFeedback->setWidget(q);
+
+}
+
+void HgWidgetPrivate::setModel( QAbstractItemModel *model )
+{
+ FUNC_LOG;
+
+ if (model != mModel) {
+ clearCurrentModel();
+ mModel = model;
+ initializeNewModel();
+ }
+}
+
+void HgWidgetPrivate::setSelectionModel(QItemSelectionModel *selectionModel)
+{
+ FUNC_LOG;
+
+ Q_Q(HgWidget);
+
+ if (mContainer) {
+ if (selectionModel == 0) {
+ QItemSelectionModel *oldSelectionModel = mDefaultSelectionModel;
+ mDefaultSelectionModel = 0;
+ mDefaultSelectionModel = new QItemSelectionModel(mModel);
+ mContainer->setSelectionModel(mDefaultSelectionModel);
+ delete oldSelectionModel;
+ }
+ else if (selectionModel != mContainer->selectionModel()) {
+ QItemSelectionModel *oldSelectionModel = mDefaultSelectionModel;
+ mDefaultSelectionModel = 0;
+ mContainer->setSelectionModel(selectionModel);
+ delete oldSelectionModel;
+ }
+ if (mContainer->selectionModel()) {
+ if (mIndexFeedback) {
+ delete mIndexFeedback;
+ mIndexFeedback = 0;
+ }
+ mIndexFeedback = new HgIndexFeedback(q);
+ mIndexFeedback->setWidget(q);
+ }
+ }
+}
+
+QItemSelectionModel *HgWidgetPrivate::selectionModel() const
+{
+ FUNC_LOG;
+
+ if (mContainer) {
+ return mContainer->selectionModel();
+ }
+ return 0;
+}
+
+HgWidget::SelectionMode HgWidgetPrivate::selectionMode() const
+{
+ FUNC_LOG;
+
+ if (mContainer) {
+ return mContainer->selectionMode();
+ }
+ return HgWidget::NoSelection;
+}
+
+void HgWidgetPrivate::setSelectionMode(HgWidget::SelectionMode mode, bool resetSelection)
+{
+ FUNC_LOG;
+
+ if (mContainer) {
+ mContainer->setSelectionMode(mode, resetSelection);
+ }
+}
+
+void HgWidgetPrivate::selectAll()
+{
+ FUNC_LOG;
+ Q_Q(HgWidget);
+
+ if (mContainer &&
+ (mContainer->selectionMode() == HgWidget::MultiSelection ||
+ mContainer->selectionMode() == HgWidget::ContiguousSelection) &&
+ mModel && mModel->columnCount() > 0 && mModel->rowCount() > 0) {
+ QItemSelection selection(
+ mModel->index(0, 0),
+ mModel->index(mModel->rowCount()-1, mModel->columnCount()-1));
+ mContainer->selectionModel()->select(selection, QItemSelectionModel::Select);
+ q->update();
+ }
+}
+
+void HgWidgetPrivate::clearSelection()
+{
+ FUNC_LOG;
+ Q_Q(HgWidget);
+
+ if (mContainer) {
+ mContainer->selectionModel()->clearSelection();
+ q->update();
+ }
+}
+
+QModelIndex HgWidgetPrivate::currentIndex() const
+{
+ FUNC_LOG;
+
+ if (mContainer && mContainer->selectionModel()) {
+ return mContainer->selectionModel()->currentIndex();
+ }
+ return QModelIndex();
+}
+
+void HgWidgetPrivate::setCurrentIndex(
+ const QModelIndex &index, QItemSelectionModel::SelectionFlags selectionFlag)
+{
+ FUNC_LOG;
+
+ if (mContainer && mContainer->selectionModel()) {
+ mContainer->selectionModel()->setCurrentIndex(index, selectionFlag);
+ }
+}
+
+void HgWidgetPrivate::scrollTo(const QModelIndex &index)
+{
+ FUNC_LOG;
+
+ if (index.isValid()) {
+ if (mContainer) {
+ mContainer->scrollTo(index);
+ }
+ if (mBufferManager) {
+ mBufferManager->scrollPositionChanged(index.row());
+ }
+ }
+}
+
+void HgWidgetPrivate::initializeNewModel()
+{
+ FUNC_LOG;
+ Q_Q(HgWidget);
+
+ if (mModel) {
+ // These asserts do basic sanity checking of the model
+ Q_ASSERT_X(mModel->index(0,0) == mModel->index(0,0),
+ "HbAbstractItemView::setModel",
+ "A model should return the exact same index "
+ "(including its internal id/pointer) when asked for it twice in a row.");
+ Q_ASSERT_X(mModel->index(0,0).parent() == QModelIndex(),
+ "HbAbstractItemView::setModel",
+ "The parent of a top level index should be invalid");
+
+ q->connect(mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ SLOT( dataChanged(QModelIndex,QModelIndex)));
+ q->connect(mModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
+ SLOT(_q_insertRows(QModelIndex, int, int)));
+ q->connect(mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)),
+ SLOT(_q_removeRows(QModelIndex, int, int)));
+ q->connect(mModel, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)),
+ SLOT(_q_moveRows(QModelIndex, int, int, QModelIndex, int)));
+
+ mContainer->setItemCount(mModel->rowCount(QModelIndex()));
+ QList<HgWidgetItem*> items = mContainer->items();
+
+ // set model indexes for the items firsts
+ int itemCount = items.count();
+ for( int i=0; i<itemCount; i++)
+ {
+ items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex()));
+ }
+
+ if( mBufferManager )
+ {
+ delete mBufferManager;
+ mBufferManager = 0;
+ }
+
+ mBufferManager = new HgScrollBufferManager(mBufferSize,mBufferSize/4,0,itemCount);
+ q->connect( mBufferManager, SIGNAL(releaseItems(int,int)), q, SLOT(_q_releaseItems(int,int)));
+ q->connect( mBufferManager, SIGNAL(requestItems(int,int)), q, SLOT(_q_requestItems(int,int)));
+ mBufferManager->resetBuffer(0, itemCount);
+
+ setSelectionModel(0); // Default
+
+ if (mModel->rowCount() > 0)
+ {
+ setCurrentIndex(mModel->index(0, 0));
+ scrollTo(mModel->index(0, 0));
+ }
+ }
+}
+
+void HgWidgetPrivate::clearCurrentModel()
+{
+ FUNC_LOG;
+ Q_Q(HgWidget);
+
+ if (mModel) {
+ mModel->disconnect(q, SLOT(dataChanged(QModelIndex, QModelIndex)));
+ mModel->disconnect(q, SLOT(_q_insertRows(QModelIndex, int, int)));
+ mModel->disconnect(q, SLOT(_q_removeRows(QModelIndex, int, int)));
+ mModel->disconnect(q, SLOT(_q_moveRows(QModelIndex, int, int, QModelIndex, int)));
+ mModel = 0;
+ }
+
+// TODO: setSelectionModel(0);
+
+}
+void HgWidgetPrivate::_q_releaseItems( int releaseStart, int releaseEnd )
+{
+ FUNC_LOG;
+
+ QList<HgWidgetItem*> items = mContainer->items();
+ const int itemCount = items.count();
+
+ int start = qBound(0, releaseStart, itemCount-1);
+ int end = qBound(0, releaseEnd, itemCount-1);
+
+ INFO("Release items:" << start << "-" << end);
+ // request data for items
+ for (int i = start; i <= end; i++) {
+ HgWidgetItem* item = items.at(i);
+ if (item) {
+ item->releaseItemData();
+ }
+ }
+}
+
+void HgWidgetPrivate::_q_requestItems(int requestStart, int requestEnd)
+{
+ FUNC_LOG;
+
+ QList<HgWidgetItem*> items = mContainer->items();
+ const int itemCount = items.count();
+
+ int start = qBound(0, requestStart, itemCount-1);
+ int end = qBound(0, requestEnd, itemCount-1);
+
+ // variables to track which items are really updated.
+ int firstUpdated = -1;
+ int lastUpdated = -1;
+
+ INFO("Request items:" << start << "-" << end);
+ // request data for items
+ for (int i = start; i <= end; i++) {
+ HgWidgetItem* item = items.at(i);
+ if (item && item->updateItemData()) {
+ if (firstUpdated == -1) firstUpdated = i;
+ lastUpdated = i;
+ }
+ }
+
+ // notify container which items have updated data available.
+ // container is responsible to redraw view if some of the items
+ // is visible.
+ if (firstUpdated != -1 && lastUpdated != -1) {
+ mContainer->itemDataChanged(firstUpdated, lastUpdated);
+ }
+}
+
+void HgWidgetPrivate::_q_scrollPositionChanged(qreal index,bool scrollBarAnimation)
+{
+ int newPos = index;
+ newPos *= mContainer->rowCount();
+ if (mBufferManager) {
+ mBufferManager->scrollPositionChanged(newPos);
+ }
+
+ if (!scrollBarAnimation)
+ updateScrollMetrics(index);
+}
+
+void HgWidgetPrivate::replaceScrollBar(HbScrollBar *scrollBar)
+{
+ Q_Q(HgWidget);
+ delete mScrollBar;
+ mScrollBar = scrollBar;
+
+ scrollBar->setParentItem(q);
+
+ // make sure the scrollbar is on top
+ scrollBar->setZValue(q->zValue() + 1);
+
+ prepareScrollBars();
+
+ QObject::connect(scrollBar, SIGNAL(valueChanged(qreal, Qt::Orientation)), q, SLOT(_q_thumbPositionChanged(qreal, Qt::Orientation)));
+}
+
+void HgWidgetPrivate::prepareScrollBars( qreal pos )
+{
+ Q_Q( HgWidget );
+
+ QRectF boundingRect = q->boundingRect();
+
+ bool scrollBarsVisible(false);
+
+ if ((mAbleToScroll && mScrollBarPolicy != HgWidget::ScrollBarAlwaysOff) ||
+ mScrollBarPolicy == HgWidget::ScrollBarAlwaysOn) {
+
+ displayScrollBar(pos );
+ scrollBarsVisible = true;
+ }
+ else if((!mAbleToScroll || mScrollBarPolicy == HgWidget::ScrollBarAlwaysOff)
+ && mScrollBar->isVisible()){
+ mScrollBar->setVisible(false);
+ }
+
+ if (scrollBarsVisible && !mScrollBarHideTimer.isActive()) {
+ mScrollBarHideTimer.start(INITIAL_SCROLLBAR_HIDE_TIMEOUT);
+ }
+}
+
+void HgWidgetPrivate::displayScrollBar(qreal pos)
+{
+ Q_Q(HgWidget);
+ // Layout the scrollbar
+ setScrollBarMetrics(pos);
+
+ // Activate the scrollbar
+ if ( !mScrollBar->isVisible() && q->isVisible()) {
+ mScrollBar->setVisible(true);
+ }
+}
+
+void HgWidgetPrivate::setScrollBarPolicy(HgWidget::ScrollBarPolicy policy)
+{
+ mScrollBarPolicy = policy;
+
+ if (mScrollBarPolicy == HgWidget::ScrollBarAlwaysOff &&
+ mScrollBar->isVisible()){
+ mScrollBar->setVisible(false);
+ }
+
+ if(policy != HgWidget::ScrollBarAlwaysOff){
+ updateScrollMetrics();
+ }
+}
+
+void HgWidgetPrivate::_q_hideScrollBars()
+{
+ if (mScrollBar && mScrollBarPolicy == HgWidget::ScrollBarAutoHide) {
+
+ // TODO, do we need to know if scrollbar was pressed? we cannot access the private methods, since
+ // only scrollareaprivate is a friend class.
+ if (false/*scrollBarPressed(mHorizontalScrollBar) ||
+ scrollBarPressed(mVerticalScrollBar)*/) {
+ mScrollBarHideTimer.start();
+ } else if(mScrollBarPolicy != HgWidget::ScrollBarAlwaysOn
+ && mScrollBar->isVisible()){
+ mScrollBar->setVisible(false);
+
+ }
+ }
+}
+
+/**
+ *
+ */
+void HgWidgetPrivate::_q_thumbPositionChanged(qreal value, Qt::Orientation orientation)
+{
+ Q_UNUSED(orientation)
+
+ mContainer->scrollToPosition( value, true );
+
+ // TODO, stop all scrolling and animations
+
+ if (mScrollBarHideTimer.isActive()) {
+ mScrollBarHideTimer.stop();
+ mScrollBarHideTimer.start();
+ }
+}
+
+void HgWidgetPrivate::_q_insertRows(const QModelIndex &parent, int start, int end)
+{
+ FUNC_LOG;
+ INFO("Insert rows" << start << "-" << end);
+ Q_UNUSED(parent)
+ Q_Q(HgWidget);
+
+ if (mContainer) {
+ mContainer->addItems(start, end);
+ // re-set model indexes for the items including and after the added indexes
+ QList<HgWidgetItem *> items = mContainer->items();
+ int newItemCount = items.count();
+ for (int i = start; i < newItemCount; i++) {
+ items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex()));
+ }
+ mBufferManager->addItems(start, end, newItemCount);
+ q->update();
+ }
+}
+
+void HgWidgetPrivate::_q_removeRows(const QModelIndex &parent, int start, int end)
+{
+ FUNC_LOG;
+ INFO("Remove rows" << start << "-" << end);
+ Q_UNUSED(parent)
+ Q_Q(HgWidget);
+
+ if (mContainer && mBufferManager) {
+ mContainer->removeItems(start, end);
+ // re-set model indexes for the items after the removed indexes
+ QList<HgWidgetItem *> items = mContainer->items();
+ int newItemCount = items.count();
+ for (int i = start; i < newItemCount; i++) {
+ items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex()));
+ }
+ mBufferManager->removeItems(start, end, newItemCount);
+ q->update();
+ }
+}
+
+void HgWidgetPrivate::_q_moveRows(const QModelIndex &sourceParent,
+ int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent, int destinationRow)
+{
+ FUNC_LOG;
+ INFO("Move rows" << sourceStart << "-" << sourceEnd << "to" << destinationRow);
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(destinationParent)
+ Q_Q(HgWidget);
+
+ if (mContainer) {
+ mContainer->moveItems(sourceStart, sourceEnd, destinationRow);
+ // re-set model indexes for the items after the removed indexes
+ QList<HgWidgetItem *> items = mContainer->items();
+ int itemCount = items.count();
+ for (int i = qMin(sourceStart, destinationRow); i < itemCount; i++) {
+ items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex()));
+ }
+ mBufferManager->moveItems(sourceStart, sourceEnd, destinationRow, itemCount);
+ q->update();
+ }
+}
+
+void HgWidgetPrivate::setScrollBarMetrics(qreal pos)
+{
+ Q_Q( HgWidget );
+
+ if (!mContainer)
+ return;
+
+ qreal screenSize, worldSize;
+ mContainer->dimensions(screenSize,worldSize);
+
+ const qreal start(0.0);
+ const qreal end(1.0);
+ const qreal page(screenSize/worldSize);
+
+ // Set handle size
+ mScrollBar->setPageSize( qBound(start,page,end ) );
+
+ updateScrollBar(pos);
+}
+
+void HgWidgetPrivate::updateScrollBar(qreal pos)
+{
+ Q_Q( HgWidget );
+
+ if (pos < 0.0)
+ pos = 0.0;
+ else if (pos > 1.0)
+ pos = 1.0;
+ // The scrollbar "thumb" position is the current position of the contents widget divided
+ // by the difference between the height of the contents widget and the height of the scroll area.
+ // This formula assumes that the "thumb" of the the scroll bar is sized proportionately to
+ // the height of the contents widget.
+ mScrollBar->setValue(pos);
+}
+
+/*
+ * updateScrollMetrics() is a private function called when
+ * scrolling starts to set the metrics needed in scrolling.
+ */
+void HgWidgetPrivate::updateScrollMetrics( qreal pos)
+{
+ Q_Q(HgWidget);
+
+ QRectF scrollAreaBoundingRect = q->boundingRect();
+
+ if (!mContainer || scrollAreaBoundingRect.isNull() ||
+ !scrollAreaBoundingRect.isValid())
+ return;
+
+ qreal screenSize, worldSize;
+ mContainer->dimensions(screenSize,worldSize);
+
+ mAbleToScroll = false;
+ if (worldSize > screenSize) {
+ mAbleToScroll = true;
+ }
+
+ prepareScrollBars( pos/worldSize );
+}
+
+void HgWidgetPrivate::adjustGeometry()
+{
+ Q_Q(HgWidget);
+
+ QRectF scrollAreaBoundingRect = q->boundingRect();
+ if( scrollAreaBoundingRect.isNull() ||
+ !scrollAreaBoundingRect.isValid() ||
+ !mContainer ||
+ scrollAreaBoundingRect == mContainer->boundingRect() )
+ return;
+
+ mContainer->resize(scrollAreaBoundingRect.size());
+
+ updateScrollMetrics(0);
+}
+
+
+void HgWidgetPrivate::lostForeground()
+{
+ if( !mForeground ) return;
+
+ mForeground = false;
+ QList<HgWidgetItem*> list = mContainer->items();
+ foreach(HgWidgetItem* item, list){
+ item->releaseItemData();
+ }
+}
+
+void HgWidgetPrivate::gainedForeground()
+{
+ if( mForeground ) return;
+
+ mForeground = true;
+ QList<HgWidgetItem*> list = mContainer->items();
+ int bufferStart = 0;
+ int bufferEnd = 0;
+ mBufferManager->currentBuffer(bufferStart,bufferEnd);
+ for(;bufferStart<=bufferEnd;bufferStart++){
+ list.at(bufferStart)->updateItemData();
+ }
+}
+
+bool HgWidgetPrivate::getItemOutline(const QModelIndex& index, QPolygonF& points)
+{
+ return mContainer->getItemPoints(index.row(), points);
+}
+
+void HgWidgetPrivate::aboutToChangeOrientation()
+{
+
+}
+
+void HgWidgetPrivate::orientationChanged(Qt::Orientation orientation)
+{
+ Q_Q(HgWidget);
+ if (mContainer->orientation() != orientation) {
+ createScrollBar(orientation);
+ q->repolish();
+ mContainer->setOrientation(orientation);
+ adjustGeometry();
+ }
+}
+
+void HgWidgetPrivate::_q_groovePressed(qreal value, Qt::Orientation orientation)
+{
+ Q_UNUSED(value);
+ Q_UNUSED(orientation);
+}
+
+Qt::Orientation HgWidgetPrivate::scrollDirection() const
+{
+ return mContainer->orientation();
+}
+
+void HgWidgetPrivate::createScrollBar(Qt::Orientation orientation)
+{
+ Q_Q(HgWidget);
+
+ delete mScrollBar;
+ mScrollBar = 0;
+ mScrollBar = new HbScrollBar(orientation,q);
+ if (orientation == Qt::Vertical) {
+ HbStyle::setItemName(mScrollBar, "scrollbar-vertical");
+ }
+ else {
+ HbStyle::setItemName(mScrollBar, "scrollbar-horizontal");
+ }
+
+ mScrollBar->setZValue(q->zValue() + 1);
+ QObject::connect(mScrollBar, SIGNAL(valueChanged(qreal, Qt::Orientation)),
+ q, SLOT(_q_thumbPositionChanged(qreal, Qt::Orientation)));
+ QObject::connect(mScrollBar, SIGNAL(valueChangeRequested(qreal, Qt::Orientation)),
+ q, SLOT(_q_groovePressed(qreal, Qt::Orientation)));
+ mScrollBar->setVisible(false);
+}
+
+QList<QModelIndex> HgWidgetPrivate::getVisibleItemIndices() const
+{
+ return mContainer->getVisibleItemIndices();
+}
+
+void HgWidgetPrivate::setIndexFeedbackPolicy( HgWidget::IndexFeedbackPolicy policy)
+{
+ mIndexFeedback->setIndexFeedbackPolicy(policy);
+}
+
+HgWidget::IndexFeedbackPolicy HgWidgetPrivate::indexFeedbackPolicy() const
+{
+ return mIndexFeedback->indexFeedbackPolicy();
+}
+
+#include "moc_hgwidgets.cpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/data/hgwidgettest.qrc Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>images/default.svg</file>
+ </qresource>
+</RCC>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/data/images/default.svg Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generator: Mobile Designer 3.0 2.0 -->
+<svg width="40" height="40" viewBox="-20 -20 40 40"
+ stroke-miterlimit="2" enable-background="new" zoomAndPan="disable"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ev="http://www.w3.org/2001/xml-events"
+ xml:space="preserve" version="1.1" baseProfile="Normal">
+
+<!-- Definitions -->
+<defs>
+<style type="text/css"><![CDATA[
+ .st0 { fill:none; stroke:#ffffff; stroke-width:3; stroke-miterlimit:4;}
+]]>
+</style>
+</defs>
+
+<!-- Movie Background -->
+<rect fill="none" x="-20" y="-20" width="40" height="40"/>
+
+<!-- Scene 1 -->
+<g id="Scene_1">
+ <rect x="-19" y="-19" width="38" height="38" fill="none" stroke="#ffffff" stroke-width="3" stroke-linejoin="bevel" stroke-miterlimit="4"/>
+ <polyline class="st0"
+ points="-19,19 19,-19"/>
+ <polyline class="st0"
+ points="-19,-19 19,19"/>
+</g>
+
+</svg>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/hgwidgettest.pro Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,46 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+# Contributors:
+# Description:
+
+
+TEMPLATE = app
+CONFIG += hb
+TARGET = hgwidgettest
+DEPENDPATH += .
+INCLUDEPATH += .
+INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE $$APP_LAYER_SYSTEMINCLUDE
+TARGET.CAPABILITY = All -TCB
+
+INCLUDEPATH += /sf/mw/hb/src/hbwidgets/itemviews /sf/mw/hb/src/hbcore/gui
+
+symbian {
+ TARGET.EPOCHEAPSIZE = 0x10000 0x2000000
+ BLD_INF_RULES.prj_exports += "rom/hgwidgettest.iby CORE_APP_LAYER_IBY_EXPORT_PATH(hgwidgettest.iby)" \
+ "rom/hgwidgettestresource.iby LANGUAGE_APP_LAYER_IBY_EXPORT_PATH(hgwidgettestresource.iby)"
+}
+
+SOURCES += src/main.cpp \
+ src/hgwidgettestdatamodel.cpp \
+ src/hgwidgettestalbumartmanager.cpp \
+ src/hgwidgettestview.cpp \
+ src/hgtestview.cpp \
+ src/hgselectiondialog.cpp \
+ src/hgflipwidget.cpp
+HEADERS += inc/hgwidgettestdatamodel.h \
+ inc/hgwidgettestalbumartmanager.h \
+ inc/hgwidgettestview.h \
+ inc/hgtestview.h \
+ inc/hgselectiondialog.h \
+ inc/hgflipwidget.h
+LIBS += -lganeswidgets.dll \
+ -lthumbnailmanagerqt.dll
+
+RESOURCES += data/hgwidgettest.qrc
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/inc/hgflipwidget.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Another view for test application.
+*
+*/
+#ifndef HGFLIPWIDGET_H_
+#define HGFLIPWIDGET_H_
+
+#include <hbwidget.h>
+#include <hbstackedwidget.h>
+
+class HbAction;
+class HbLabel;
+class QPropertyAnimation;
+
+class HgFlipWidget : public HbWidget
+{
+ Q_PROPERTY(qreal yRotation READ yRotation WRITE setYRotation)
+ Q_OBJECT
+public:
+ enum State
+ {
+ StateClosed,
+ StateOpening1,
+ StateOpening2,
+ StateOpened,
+ StateClosing1,
+ StateClosing2
+ };
+
+ HgFlipWidget(const QString &title1, const QString &title2, const QPixmap &pixmap, QGraphicsItem *parent=0);
+
+ qreal yRotation();
+ void setYRotation(qreal a);
+
+ void close();
+signals:
+ void closed();
+private slots:
+ void animationFinished();
+ void buttonClicked(bool checked=false);
+private:
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+ void togglePage();
+private:
+ QPixmap mPixmap;
+ HbStackedWidget *mStack;
+ qreal mYRotation;
+ QPropertyAnimation* mAnimation;
+ State mState;
+ HbLabel* mIconLabel;
+};
+
+#endif /* HGTESTVIEW_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/inc/hgselectiondialog.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Multiselection dialog
+*
+*/
+
+#ifndef HGSELECTIONDIALOG_H
+#define HGSELECTIONDIALOG_H
+
+#include <hbdialog.h>
+
+class HbPushButton;
+class HbLabel;
+class HgWidget;
+
+class HgSelectionDialog : public HbDialog
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(HgSelectionDialog)
+
+public:
+ HgSelectionDialog(const QString &title, const QString &primaryText, HgWidget *content, QGraphicsItem *parent=0);
+ ~HgSelectionDialog();
+
+private slots:
+ void updateItems();
+ void selectAll();
+
+private:
+ HgWidget *mHgWidget;
+ HbPushButton *mSelectAll;
+ HbLabel *mCountLabel;
+};
+
+#endif //HGSELECTIONDIALOG_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/inc/hgtestview.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Another view for test application.
+*
+*/
+#ifndef HGTESTVIEW_H_
+#define HGTESTVIEW_H_
+
+#include <hbview.h>
+
+class HbAction;
+class HbLabel;
+
+class HgTestView : public HbView
+{
+ Q_OBJECT
+
+public:
+ HgTestView(const QString &title1, const QString &title2, const QPixmap &pixmap, QGraphicsItem *parent=0);
+
+private slots:
+ void closeView();
+
+private:
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+
+private:
+ HbAction *mBackAction;
+ HbLabel *mIconLabel;
+ QPixmap mPixmap;
+};
+
+#endif /* HGTESTVIEW_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/inc/hgwidgettestalbumartmanager.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef HGWIDGETTESTALBUMARTMANAGER_H
+#define HGWIDGETTESTALBUMARTMANAGER_H
+
+#include <QObject>
+#include <QHash>
+#include <QMap>
+#include <QQueue>
+#include <QPair>
+#include <QBitmap>
+#include <hbicon.h>
+#include <thumbnailmanager_qt.h>
+
+class HgWidgetTestAlbumArtManager : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ explicit HgWidgetTestAlbumArtManager(QObject *parent=0);
+ virtual ~HgWidgetTestAlbumArtManager();
+
+ void setThumbnailSize(ThumbnailManager::ThumbnailSize size);
+
+ QImage albumArt( const QString &albumArtUri, int index );
+ bool cacheAlbumArt( const QStringList albumArtList );
+ void cancel();
+
+signals:
+
+ void albumArtReady( int index );
+ void albumCacheReady();
+
+public slots:
+
+ void thumbnailReady( const QPixmap& pixmap, void *data, int id, int error );
+ void thumbnailReady( const QImage& image, void* data, int id, int error );
+ void executeNext();
+
+private:
+
+ void applyMask( QPixmap &pixmap );
+
+private:
+
+ ThumbnailManager *mThumbnailManager;
+ QHash<QString, QImage> mImageCache;
+ QMap<int, QString> mTnmReqMap;
+ bool mCachingInProgress;
+
+ QQueue< QPair<QString, int> > mRequestQueue;
+ int mRequestCount;
+ QBitmap mMask;
+
+};
+
+#endif // HGWIDGETTESTALBUMARTMANAGER_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/inc/hgwidgettestdatamodel.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGWIDGETTESTDATAMODEL_H
+#define HGWIDGETTESTDATAMODEL_H
+
+#include <QAbstractListModel>
+#include <QItemSelection>
+#include <QStringList>
+#include <hbicon>
+#include <thumbnailmanager_qt.h>
+
+class HgWidgetTestAlbumArtManager;
+
+
+class HgWidgetTestDataModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+
+ explicit HgWidgetTestDataModel(QObject *parent=0);
+ virtual ~HgWidgetTestDataModel();
+
+ void setThumbnailSize(ThumbnailManager::ThumbnailSize size);
+
+ int rowCount(const QModelIndex &parent=QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
+ bool setData(const QModelIndex& index, const QVariant& value, int role=Qt::EditRole);
+
+ void refreshModel();
+
+ void remove(const QItemSelection &selection);
+ void move(const QItemSelection &selection, const QModelIndex &target);
+ void add(const QModelIndex &target, int count);
+
+ enum ImageType{TypeQIcon, TypeHbIcon, TypeQImage};
+
+ void setImageDataType(ImageType type);
+
+ void enableLowResImages(bool enabled);
+ bool lowResImagesEnabled() const;
+
+private:
+
+ void init();
+
+public slots:
+
+ void updateAlbumArt( int index );
+ void albumCacheReady();
+
+private:
+
+ HgWidgetTestAlbumArtManager *mAlbumArtManager; // Own
+ bool mCachingInProgress;
+ QStringList mFiles;
+ ImageType mImageType;
+ HbIcon mHbIcon;
+ QIcon mQIcon;
+ QImage mDefaultIcon;
+ QList<bool> mVisibility;
+ bool mUseLowResImages;
+};
+
+#endif // HgWidgetTestDataModel_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/inc/hgwidgettestview.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,100 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGWIDGETTESTVIEW_H_
+#define HGWIDGETTESTVIEW_H_
+
+#include <hbview.h>
+#include <hgwidgets/hgwidgets.h>
+
+class HbAction;
+class QGraphicsLinearLayout;
+class HgWidgetTestDataModel;
+class HbListWidget;
+class HgFlipWidget;
+class HbLabel;
+
+class HgWidgetTestView : public HbView
+{
+ Q_OBJECT
+
+public:
+
+ HgWidgetTestView(QGraphicsItem *parent = 0);
+ ~HgWidgetTestView();
+
+private slots:
+
+ void switchWidget(HbAction* action);
+ void toggleScrollDirection();
+ void openDialog(const QModelIndex &index);
+ void openView(const QModelIndex& index);
+ void openDeleteItemsDialog();
+ void openMoveItemsDialog();
+ void openAddItemsDialog();
+ void autoHideScrollBar();
+ void scrollBarAlwaysOn();
+ void scrollBarAlwaysOff();
+ void interactiveScrollBar();
+ void unInteractiveScrollBar();
+ void feedqimages();
+ void feedqicons();
+ void feedhbicons();
+ void flipClosed();
+ void orientationChanged();
+ void onScrollingStarted();
+ void onScrollingEnded();
+ void setDescriptionAboveImage();
+ void setDescriptionBelowImage();
+ void setDescriptionHidden();
+ void setTitleAboveImage();
+ void setTitleBelowImage();
+ void setTitleHidden();
+ void toggleLowResForCoverflow();
+
+private:
+
+ enum WidgetType {
+ HgWidgetGrid,
+ HgWidgetCoverflow
+ };
+
+ void createMenu();
+ void initWidget( WidgetType type );
+ void setScrollBarPolicy( HgWidget::ScrollBarPolicy policy );
+ void setScrollBarInteractive( bool value );
+ HgWidget *createWidget(WidgetType type) const;
+ HgWidget *copyWidget() const;
+
+private: // data
+
+ HgWidget *mWidget;
+ QGraphicsLinearLayout *mLayout;
+ HgWidgetTestDataModel *mModel;
+ WidgetType mWidgetType;
+ HbListWidget *mListWidget;
+ bool mToggleOrientation;
+ bool mTBone;
+ QItemSelectionModel *mSelectionModel;
+ HgFlipWidget* mFlipWidget;
+ QModelIndex mFlippedIndex;
+ HbLabel* mFrontItem;
+ HbAction* mUseLowResAction;
+};
+
+
+#endif /* HGWIDGETTESTVIEW_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/inc/trace.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,147 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Tracing macros, 2nd generation
+*
+*/
+
+#ifndef TRACE_H
+#define TRACE_H
+
+#include <QDebug>
+
+//-----------------------------------------------------------------------------
+// Trace definitions
+//-----------------------------------------------------------------------------
+//
+
+/**
+* Error trace enabled
+*/
+//#ifdef _DEBUG
+#ifdef __WINS__
+ #define ERROR_TRACE
+ #define TIMESTAMP_TRACE
+ #define FUNC_TRACE
+ #define INFO_TRACE
+#else
+ #undef ERROR_TRACE
+ #undef TIMESTAMP_TRACE
+ #undef FUNC_TRACE
+ #undef INFO_TRACE
+#endif
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+//
+
+/**
+* Trace prefixes for macros with component name.
+*/
+#define _TRACE_PREFIX "[TEST]:"
+
+/**
+* Prefix error trace
+*/
+#define _ERROR_PREFIX _TRACE_PREFIX " [ERROR]:"
+
+/**
+* Prefix info trace.
+*/
+#define _INFO_PREFIX _TRACE_PREFIX " [INFO]:"
+
+/**
+* Prefix timestamp trace.
+*/
+#define _TIMESTAMP_PREFIX _TRACE_PREFIX " [TIMESTAMP]:"
+
+//-----------------------------------------------------------------------------
+// Error trace macros
+// Usage: wrap traces in ERROR() macro to allow disabling them in release builds.
+// Use normal stream object operations.
+// Examples:
+// ERROR( "xxx failed" );
+// ERROR( "Test trace arg =" << 999 << "arg2 =" << title() );
+//-----------------------------------------------------------------------------
+//
+#ifdef ERROR_TRACE
+ #define ERROR(trace) {qDebug() << _ERROR_PREFIX << trace;}
+ #define ERROR_PARAM(param) param
+ #define HANDLE_ERROR(trace) {ERROR(trace); __BREAKPOINT();}
+ #define HANDLE_ERROR_BOOL(x) {if (!x) {ERROR(#x << "is false"); __BREAKPOINT();}}
+ #define HANDLE_ERROR_NULL(x) {if (!x) {ERROR(#x << "is NULL"); __BREAKPOINT();}}
+ #define HANDLE_ERROR_NEG(x) {if (x < 0) {ERROR(#x << "=" << x << "File:" << __FILE__ << ", line:" << __LINE__); __BREAKPOINT();}}
+ #define CHECK_ERROR(err, trace) {if (err < 0) ERROR(trace << err);}
+#else //ERROR_TRACE not defined
+ #define ERROR(trace)
+ #define ERROR_PARAM(param)
+ #define HANDLE_ERROR(trace)
+ #define HANDLE_ERROR_BOOL(x)
+ #define HANDLE_ERROR_NULL(x)
+ #define HANDLE_ERROR_NEG(x)
+ #define CHECK_ERROR(err,trace)
+#endif //ERROR_TRACE
+
+//-----------------------------------------------------------------------------
+// Info trace macros
+// Usage: wrap traces in INFO() macro to allow disabling them in release builds.
+// Use normal stream object operations.
+// Examples:
+// INFO( "Test trace" );
+// INFO( "Test trace arg =" << 999 << "arg2 =" << title() );
+//-----------------------------------------------------------------------------
+//
+#ifdef INFO_TRACE
+ #define INFO(trace) {qDebug() << _INFO_PREFIX << trace;}
+ #define INFO_PARAM(param) param
+#else //INFO_TRACE not defined
+ #define INFO(trace)
+ #define INFO_PARAM(param)
+#endif //INFO_TRACE
+
+//-----------------------------------------------------------------------------
+// Function trace macros
+//-----------------------------------------------------------------------------
+//
+#ifdef FUNC_TRACE
+
+ class FuncLog
+ {
+ public:
+ inline FuncLog( const char* func ) : m_func( func )
+ { qDebug() << _TRACE_PREFIX << m_func << "-START"; }
+ inline ~FuncLog() { qDebug() << _TRACE_PREFIX << m_func << "-END"; }
+ private: // Data
+ QString m_func;
+ };
+
+ #define FUNC_LOG FuncLog _fl( __PRETTY_FUNCTION__ );
+#else //FUNC_TRACE not defined
+ #define FUNC_LOG
+#endif //FUNC_TRACE
+
+//-----------------------------------------------------------------------------
+// Timestamp trace macros
+//-----------------------------------------------------------------------------
+//
+#ifdef TIMESTAMP_TRACE
+ #include <QTime>
+ #define TIMESTAMP(trace)\
+ {qDebug() << _TIMESTAMP_PREFIX << "(" << \
+ QTime::currentTime().toString("HH:mm:ss:zzz") << ")" << trace;}
+#else //TIMESTAMP_TRACE not defined
+ #define TIMESTAMP(trace)
+#endif //TIMESTAMP_TRACE
+
+#endif // TRACE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/rom/hgwidgettest.iby Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: ROM include file for test application.
+*
+*/
+
+#ifndef __HGWIDGETTEST_IBY__
+#define __HGWIDGETTEST_IBY__
+
+#include <data_caging_paths_for_iby.hrh>
+
+file=ABI_DIR\BUILD_DIR\hgwidgettest.exe \sys\bin\hgwidgettest.exe
+data=DATAZ_\private\10003a3f\import\apps\hgwidgettest_reg.rsc \private\10003a3f\import\apps\hgwidgettest_reg.rsc
+
+#endif // __HGWIDGETTEST_IBY__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/rom/hgwidgettestresource.iby Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: ROM include file for test application.
+*
+*/
+
+#ifndef __HGWIDGETTESTRESOURCE_IBY__
+#define __HGWIDGETTESTRESOURCE_IBY__
+
+#include <data_caging_paths_for_iby.hrh>
+
+S60_APP_RESOURCE(hgwidgettest)
+
+#endif // __HGWIDGETTESTRESOURCE_IBY__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/sis/hgwidgettest.pkg Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,39 @@
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+; Contributors:
+; Description: pkg file for ganeswidgets and test application
+
+; Language
+&EN
+
+; SIS header: name, uid, version
+#{"hgwidgettest"},(0xE321b788),1,0,0
+
+; Localised Vendor name
+%{"Vendor"}
+
+; Unique Vendor name
+:"Vendor"
+
+; Manual PKG pre-rules from PRO files
+; Default HW/platform dependencies
+[0x101F7961],0,0,0,{"S60ProductID"}
+[0x102032BE],0,0,0,{"S60ProductID"}
+[0x102752AE],0,0,0,{"S60ProductID"}
+[0x1028315F],0,0,0,{"S60ProductID"}
+
+; Default dependency to Qt libraries
+(0x2001E61C), 4, 5, 2, {"Qt"}
+
+; Executable and default resource files
+"/epoc32/release/$(PLATFORM)/$(TARGET)/hgwidgettest.exe" - "!:\sys\bin\hgwidgettest.exe"
+"/epoc32/data/z/resource/apps/hgwidgettest.rsc" - "!:\resource\apps\hgwidgettest.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/hgwidgettest_reg.rsc" - "!:\private\10003a3f\import\apps\hgwidgettest_reg.rsc"
+
+; Manual PKG post-rules from PRO files
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgflipwidget.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,178 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Another view for test application.
+*
+*/
+#include "hgflipwidget.h"
+
+#include <qgraphicslinearlayout.h>
+#include <qgraphicssceneresizeevent>
+#include <hbaction.h>
+#include <hbinstance.h>
+#include <hblabel.h>
+#include <hbmainwindow.h>
+#include <hblistwidget.h>
+#include <hbpushbutton.h>
+#include <qpropertyanimation>
+#include <qstate.h>
+#include <qabstracttransition>
+#include <qstatemachine>
+#include <qsignaltransition>
+#include "trace.h"
+
+HgFlipWidget::HgFlipWidget(const QString &title1, const QString &title2, const QPixmap &pixmap, QGraphicsItem *parent) :
+ HbWidget(parent), mPixmap(pixmap), mYRotation(0)
+{
+ FUNC_LOG;
+
+ Q_UNUSED(title1)
+ Q_UNUSED(title2)
+
+ mStack = new HbStackedWidget();
+
+ HbWidget* front = new HbWidget();
+ {
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical);
+ mIconLabel = new HbLabel;
+ HANDLE_ERROR_NULL(mIconLabel);
+ if (mIconLabel)
+ {
+ mIconLabel->setIcon(HbIcon(mPixmap));
+ mIconLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
+ layout->setContentsMargins(0,0,0,0);
+ layout->addItem(mIconLabel);
+ }
+ front->setLayout(layout);
+ }
+
+ HbWidget* back = new HbWidget();
+ {
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical);
+ HbListWidget* widget = new HbListWidget;
+ widget->addItem(QString("1. First item"));
+ widget->addItem(QString("2. Second item"));
+ widget->addItem(QString("3. Third item"));
+ widget->addItem(QString("4. Fourth item"));
+ HbPushButton* button = new HbPushButton("close");
+ layout->addItem(widget);
+ layout->addItem(button);
+ QObject::connect(button, SIGNAL(clicked(bool)), this, SLOT(buttonClicked(bool)));
+ layout->setContentsMargins(0,0,0,0);
+ back->setLayout(layout);
+ }
+
+ mStack->addWidget(front);
+ mStack->addWidget(back);
+
+ QGraphicsLinearLayout* layout = new QGraphicsLinearLayout(this);
+ layout->addItem(mStack);
+ layout->setAlignment(mStack, Qt::AlignHCenter|Qt::AlignVCenter);
+ layout->setContentsMargins(0,0,0,0);
+ setLayout(layout);
+
+
+ mState = StateOpening1;
+ mAnimation = new QPropertyAnimation(this, "yRotation");
+ mAnimation->setDuration(500);
+ mAnimation->setStartValue(qreal(0));
+ mAnimation->setEndValue(qreal(90));
+ QObject::connect(mAnimation, SIGNAL(finished()), this, SLOT(animationFinished()));
+
+ mAnimation->start();
+
+}
+
+void HgFlipWidget::togglePage()
+{
+ FUNC_LOG;
+
+ mStack->setCurrentIndex(mStack->currentIndex() ^ 1);
+}
+
+void HgFlipWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ FUNC_LOG;
+
+ if (mIconLabel && event)
+ {
+ QSize iconSize(event->newSize().width(), event->newSize().height());
+ mIconLabel->setIcon(HbIcon(mPixmap.scaled(iconSize, Qt::IgnoreAspectRatio)));
+ }
+
+}
+
+void HgFlipWidget::setYRotation(qreal a)
+{
+ mYRotation = a;
+ qreal s = 1.0f + (qAbs(a) / 90.0f * 0.5f);
+ QTransform t;
+ t.translate(rect().width()/2, rect().height()/2);
+ t.scale(s, s);
+ t.rotate(a, Qt::YAxis);
+ t.translate(-rect().width()/2, -rect().height()/2);
+ setTransform(t);
+ mStack->setTransform(t);
+}
+
+qreal HgFlipWidget::yRotation()
+{
+ return mYRotation;
+}
+
+void HgFlipWidget::animationFinished()
+{
+ if (mState == StateOpening1)
+ {
+ mAnimation->setStartValue(qreal(-90));
+ mAnimation->setEndValue(qreal(0));
+ mAnimation->start();
+ mState = StateOpening2;
+ togglePage();
+ }
+ else if (mState == StateOpening2)
+ {
+ mState = StateOpened;
+ }
+ else if (mState == StateClosing1)
+ {
+ mAnimation->setStartValue(-90);
+ mAnimation->setEndValue(0);
+ mAnimation->start();
+ mState = StateClosing2;
+ togglePage();
+ }
+ else if (mState == StateClosing2)
+ {
+ mState = StateClosed;
+ emit closed();
+ }
+}
+
+void HgFlipWidget::close()
+{
+ if (mState == StateOpened)
+ {
+ mState = StateClosing1;
+ mAnimation->setStartValue(0);
+ mAnimation->setEndValue(90);
+ mAnimation->start();
+ }
+}
+
+void HgFlipWidget::buttonClicked(bool checked)
+{
+ Q_UNUSED(checked)
+
+ close();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgselectiondialog.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,135 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Multiselection dialog
+*
+*/
+
+#include <hbaction.h>
+#include <hblabel.h>
+#include <hbpushbutton.h>
+#include <hgwidgets/hgwidgets.h>
+#include <QGraphicsLinearLayout>
+#include "hgselectiondialog.h"
+#include "trace.h"
+
+HgSelectionDialog::HgSelectionDialog(
+ const QString &title, const QString &primaryText,
+ HgWidget *content, QGraphicsItem *parent) :
+ HbDialog(parent),
+ mHgWidget(content),
+ mSelectAll(new HbPushButton("---")),
+ mCountLabel(new HbLabel("--/--"))
+{
+ FUNC_LOG;
+
+ setDismissPolicy(HbDialog::NoDismiss);
+ setTimeout(HbDialog::NoTimeout);
+ setHeadingWidget(new HbLabel(title, this));
+ setPrimaryAction(new HbAction(primaryText, this));
+ primaryAction()->setDisabled(true);
+ setSecondaryAction(new HbAction("Cancel", this));
+
+ connect(content->selectionModel(),
+ SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
+ SLOT(updateItems()));
+ connect(content->model(),
+ SIGNAL(rowsInserted(QModelIndex, int, int)),
+ SLOT(updateItems()));
+ connect(content->model(),
+ SIGNAL(rowsRemoved(QModelIndex, int, int)),
+ SLOT(updateItems()));
+
+ HbWidget *contentWidget = new HbWidget;
+ HANDLE_ERROR_NULL(contentWidget);
+ if (contentWidget) {
+ QGraphicsLinearLayout *contentLayout = new QGraphicsLinearLayout(Qt::Vertical);
+ HANDLE_ERROR_NULL(contentLayout);
+ if (contentLayout) {
+ QGraphicsLinearLayout *topLayout = new QGraphicsLinearLayout(Qt::Horizontal);
+ HANDLE_ERROR_NULL(topLayout);
+ if (topLayout) {
+ HANDLE_ERROR_NULL(mSelectAll);
+ if (mSelectAll) {
+ topLayout->addItem(mSelectAll);
+ connect(mSelectAll, SIGNAL(clicked()), SLOT(selectAll()));
+ }
+ if (mCountLabel) {
+ mCountLabel->setAlignment(Qt::AlignRight);
+ topLayout->addItem(mCountLabel);
+ }
+
+ contentLayout->addItem(topLayout);
+ }
+
+ contentLayout->addItem(mHgWidget);
+ contentWidget->setLayout(contentLayout);
+ }
+ setContentWidget(contentWidget);
+ }
+
+ updateItems();
+}
+
+HgSelectionDialog::~HgSelectionDialog()
+{
+ FUNC_LOG;
+}
+
+void HgSelectionDialog::updateItems()
+{
+ FUNC_LOG;
+
+ if (mHgWidget) {
+ QItemSelectionModel *selectionModel = mHgWidget->selectionModel();
+ QAbstractItemModel *model = mHgWidget->model();
+ if (selectionModel && model) {
+ primaryAction()->setEnabled(selectionModel->hasSelection());
+
+ int selectedCount = selectionModel->selectedIndexes().count();
+ int itemCount = model->rowCount();
+
+ if (selectedCount == itemCount) {
+ mSelectAll->setText("Unselect all");
+ mSelectAll->setChecked(false);
+ }
+ else {
+ mSelectAll->setText("Select all");
+ mSelectAll->setChecked(false);
+ }
+
+ mCountLabel->setPlainText(tr("%1/%2").arg(selectedCount).arg(itemCount));
+ }
+ }
+}
+
+void HgSelectionDialog::selectAll()
+{
+ FUNC_LOG;
+
+ if (mHgWidget) {
+ QItemSelectionModel *selectionModel = mHgWidget->selectionModel();
+ QAbstractItemModel *model = mHgWidget->model();
+ if (selectionModel && model) {
+ int selectedCount = selectionModel->selectedIndexes().count();
+ int itemCount = model->rowCount();
+
+ if (selectedCount == itemCount) {
+ mHgWidget->clearSelection();
+ }
+ else {
+ mHgWidget->selectAll();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgtestview.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Another view for test application.
+*
+*/
+#include <qgraphicslinearlayout.h>
+#include <qgraphicssceneresizeevent>
+#include <hbaction.h>
+#include <hbinstance.h>
+#include <hblabel.h>
+#include <hbmainwindow.h>
+#include "hgtestview.h"
+#include "trace.h"
+
+HgTestView::HgTestView(const QString &title1, const QString &title2, const QPixmap &pixmap, QGraphicsItem *parent) :
+ HbView(parent), mPixmap(pixmap)
+{
+ FUNC_LOG;
+
+ QList<HbMainWindow *> mainWindows = hbInstance->allMainWindows();
+ if (mainWindows.count() > 0)
+ {
+ HbMainWindow *primaryWindow = mainWindows[0];
+
+ setTitle(primaryWindow->currentView()->title());
+ setItemVisible(Hb::AllItems, true); // ensure that all needed view items stay visible
+
+ // set view as parent because action will be removed on view exit
+ mBackAction = new HbAction(Hb::BackAction, this);
+ primaryWindow->addSoftKeyAction(Hb::SecondarySoftKey, mBackAction);
+ connect(mBackAction, SIGNAL(triggered()), SLOT(closeView()));
+
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical);
+ HANDLE_ERROR_NULL(layout);
+ if (layout)
+ {
+ HbLabel *title1Label = new HbLabel(title1);
+ title1Label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
+ layout->addItem(title1Label);
+
+ HbLabel *title2Label = new HbLabel(title2);
+ title2Label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
+ layout->addItem(title2Label);
+
+ mIconLabel = new HbLabel;
+ HANDLE_ERROR_NULL(mIconLabel);
+ if (mIconLabel)
+ {
+ mIconLabel->setIcon(HbIcon(mPixmap));
+ mIconLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
+ layout->addItem(mIconLabel);
+ }
+ setLayout(layout);
+ }
+ }
+}
+
+void HgTestView::closeView()
+{
+ FUNC_LOG;
+
+ QList<HbMainWindow *> mainWindows = hbInstance->allMainWindows();
+ if (mainWindows.count() > 0)
+ {
+ HbMainWindow *primaryWindow = mainWindows[0];
+ primaryWindow->removeView(this);
+ primaryWindow->setViewSwitchingEnabled(true);
+ primaryWindow->removeSoftKeyAction(Hb::SecondarySoftKey, mBackAction); // restores original action
+ }
+ delete this; // ownership transferred back from HbMainWindow
+}
+
+void HgTestView::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ FUNC_LOG;
+
+ if (mIconLabel && event)
+ {
+ QSize iconSize(event->newSize().width()-5, event->newSize().height()-20);
+ mIconLabel->setIcon(HbIcon(mPixmap.scaled(iconSize, Qt::KeepAspectRatio)));
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgettestalbumartmanager.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,301 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <thumbnailmanager_qt.h>
+#include <QTimer>
+
+#include "hgwidgettestalbumartmanager.h"
+
+const int KMaxThumbnailReq = 1;
+
+/*!
+ \class HgWidgetTestAlbumArtManager
+ \brief Music Player collection album art manager.
+
+ Collection album art manager provides access to album art needed for
+ display in certain collection views. It hides interface to the thumbnail
+ manager and also implements a caching mechanism for performance reasons.
+*/
+
+/*!
+ \fn void albumArtReady( int index )
+
+ This signal is emitted when album art for \a index is ready.
+
+ \sa getAlbumArt()
+ */
+
+/*!
+ \fn void albumCacheReady()
+
+ This signal is emitted when album art cache is ready.
+
+ \sa cacheAlbumArt()
+ */
+
+/*!
+ Constructs the album art manager.
+ */
+HgWidgetTestAlbumArtManager::HgWidgetTestAlbumArtManager(QObject *parent)
+ : QObject(parent),
+ mCachingInProgress(false),
+ mRequestCount(0),
+ mMask()
+{
+ mThumbnailManager = new ThumbnailManager(this);
+ mThumbnailManager->setMode(ThumbnailManager::Default);
+ mThumbnailManager->setQualityPreference(ThumbnailManager::OptimizeForQuality);
+// mThumbnailManager->setMode(ThumbnailManager::CreateQImages);
+ QPixmap qpixmap(":/icons/teardrop_mask.png");
+ mMask = QBitmap(qpixmap);
+
+// connect( mThumbnailManager, SIGNAL(thumbnailReady(QImage, void *, int, int)),
+// this, SLOT(thumbnailReady(QImage, void *, int, int)) );
+ connect( mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void *, int, int)),
+ this, SLOT(thumbnailReady(QPixmap, void *, int, int)) );
+}
+
+/*!
+ Destructs the album art manager.
+ */
+HgWidgetTestAlbumArtManager::~HgWidgetTestAlbumArtManager()
+{
+ cancel();
+ mImageCache.clear();
+}
+
+void HgWidgetTestAlbumArtManager::setThumbnailSize(ThumbnailManager::ThumbnailSize size)
+{
+ cancel();
+ mImageCache.clear();
+ mThumbnailManager->setThumbnailSize(size);
+}
+
+/*!
+ Returns the album art for the given \a albumArtUri. If the album art is not
+ available in its cache, an asynchronous request is made to the thumbnail manager
+ and a null icon is returned.
+
+ \sa signal albumArtReady
+ */
+QImage HgWidgetTestAlbumArtManager::albumArt( const QString& albumArtUri, int index )
+{
+ QImage icon;
+ if ( mImageCache.contains(albumArtUri) ) {
+ icon = mImageCache.value(albumArtUri);
+ // If you want to cache all images disable this line. However, with large
+ // amount of items OOM will occure.
+// mImageCache.remove(albumArtUri);
+ }
+ else {
+ if ( mRequestCount < KMaxThumbnailReq ) {
+ // Using negative index as priority will ensure that thumbnail requests
+ // are processed in the order they were requested.
+ int *clientData = new int(index);
+ int reqId = mThumbnailManager->getThumbnail( albumArtUri, clientData, -1 );
+ if ( reqId != -1 ) {
+ mTnmReqMap.insert( reqId, albumArtUri );
+ mRequestCount++;
+ }
+ else {
+ }
+ }
+ else {
+ mRequestQueue.enqueue( qMakePair(albumArtUri, index) );
+ }
+ }
+ return icon;
+}
+
+/*!
+ Request to cache the album art for the items specified in \a albumArtList.
+ Returns 'true' if caching is started. If all items already exist in cache,
+ 'false' is returned.
+
+ \sa signal albumCacheReady
+ */
+bool HgWidgetTestAlbumArtManager::cacheAlbumArt( const QStringList albumArtList )
+{
+ int allAvailable = true;
+ if ( !albumArtList.empty() ) {
+ QString albumArtUri;
+ int reqId;
+ QStringListIterator iter(albumArtList);
+ while ( iter.hasNext() ) {
+ albumArtUri = iter.next();
+ if ( !mImageCache.contains(albumArtUri) ) {
+ reqId = mThumbnailManager->getThumbnail( albumArtUri );
+ if ( reqId != -1 ) {
+ mTnmReqMap.insert( reqId, albumArtUri );
+ mRequestCount++;
+ allAvailable = false;
+ }
+ else {
+ }
+ }
+ }
+ }
+
+ if ( allAvailable ) {
+ return false;
+ }
+ else {
+ mCachingInProgress = true;
+ return true;
+ }
+}
+
+/*!
+ Cancels all outstanding album art requests.
+
+ \sa getAlbumArt, cacheAlbumArt
+ */
+void HgWidgetTestAlbumArtManager::cancel()
+{
+ if ( !mTnmReqMap.empty() ) {
+ QMapIterator<int, QString> iter(mTnmReqMap);
+ while ( iter.hasNext() ) {
+ iter.next();
+ bool result = mThumbnailManager->cancelRequest(iter.key());
+ }
+ }
+ mTnmReqMap.clear();
+ mRequestQueue.clear();
+ mRequestCount = 0;
+ mCachingInProgress = false;
+}
+
+
+/*!
+ Slot to be called when thumbnail bitmap generation or loading is complete.
+ */
+void HgWidgetTestAlbumArtManager::thumbnailReady( const QPixmap& pixmap, void *data, int id, int error )
+{
+ // Find the index
+ if ( mTnmReqMap.contains(id) ) {
+ // Remove the request whether it completed successfully or with error.
+ QString albumArtUri = mTnmReqMap[id];
+ mTnmReqMap.remove( id );
+ mRequestCount--;
+
+ if ( mCachingInProgress ) {
+ if ( error == 0 ) {
+// QPixmap art(pixmap);
+// applyMask(art);
+// QIcon qicon(art);
+// mImageCache.insert(albumArtUri, pixmap);
+ }
+ else {
+ }
+ if ( mTnmReqMap.empty() ) {
+ mCachingInProgress = false;
+ emit albumCacheReady();
+ return;
+ }
+ }
+ else {
+ if ( error == 0 ) {
+ int *clientData = (int *)data;
+ int index = *clientData;
+ delete clientData;
+ QImage image = pixmap.toImage().convertToFormat(QImage::Format_RGB16);
+ mImageCache.insert(albumArtUri, image);
+ emit albumArtReady(index);
+ QTimer::singleShot(0, this, SLOT(executeNext()));
+ }
+ else {
+ }
+ }
+ }
+}
+
+/*!
+ Slot to be called when thumbnail bitmap generation or loading is complete.
+ */
+void HgWidgetTestAlbumArtManager::thumbnailReady( const QImage& image, void *data, int id, int error )
+{
+ // Find the index
+ if ( mTnmReqMap.contains(id) ) {
+ // Remove the request whether it completed successfully or with error.
+ QString albumArtUri = mTnmReqMap[id];
+ mTnmReqMap.remove( id );
+ mRequestCount--;
+
+ if ( mCachingInProgress ) {
+ if ( error == 0 ) {
+// QPixmap art(pixmap);
+// applyMask(art);
+// QIcon qicon(art);
+ mImageCache.insert(albumArtUri, image);
+ }
+ else {
+ }
+ if ( mTnmReqMap.empty() ) {
+ mCachingInProgress = false;
+ emit albumCacheReady();
+ return;
+ }
+ }
+ else {
+ if ( error == 0 ) {
+ int *clientData = (int *)data;
+ int index = *clientData;
+ delete clientData;
+ QSize size = image.size();
+ QImage newImage;
+ newImage = image.copy();
+ mImageCache.insert(albumArtUri, newImage);
+ emit albumArtReady(index);
+ QTimer::singleShot(0, this, SLOT(executeNext()));
+ }
+ else {
+ }
+ }
+ }
+}
+
+
+/*!
+ Applies mask on the thumbnail.
+ */
+void HgWidgetTestAlbumArtManager::applyMask( QPixmap& pixmap )
+{
+ pixmap.setMask(mMask);
+}
+
+void HgWidgetTestAlbumArtManager::executeNext()
+{
+ // Check to see if any request is pending in the queue
+ while ( !mRequestQueue.isEmpty()
+ && (mRequestCount < KMaxThumbnailReq) ) {
+ QPair<QString, int> req = mRequestQueue.dequeue();
+ QString albumArtUri = req.first;
+ int index = req.second;
+
+ // Using negative index as priority will ensure that thumbnail requests
+ // are processed in the order they were requested.
+ int *clientData = new int(index);
+ int reqId = mThumbnailManager->getThumbnail( albumArtUri, clientData, -1 );
+ if ( reqId != -1 ) {
+ mTnmReqMap.insert( reqId, albumArtUri );
+ mRequestCount++;
+ }
+ else {
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgettestdatamodel.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,418 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QBrush>
+#include <QColor>
+#include <QtCore>
+
+#include <hbicon.h>
+#include <hbnamespace.h>
+#include <hgwidgets/hgwidgets.h>
+
+#include "hgwidgettestdatamodel.h"
+#include "hgwidgettestalbumartmanager.h"
+#include "trace.h"
+
+typedef QPair<int, int> Range;
+typedef QList<Range > RangeList;
+
+/*!
+ \class HgWidgetTestDataModel
+ \brief Music Player collection data model.
+
+ Collection data model implements the interface specified by HbAbstractDataModel,
+ which defines the standard interface that item models must use to be able to
+ interoperate with other components in the model/view architecture.
+
+ Every item of data that can be accessed via a model has an associated model
+ index.
+
+ Each item has a number of data elements associated with it and they can be
+ retrieved by specifying a role (see Qt::ItemDataRole) to the model's data
+ returned by itemData() function.
+
+ \sa HbAbstractDataModel
+*/
+
+/*!
+ Constructs the collection data model.
+ */
+HgWidgetTestDataModel::HgWidgetTestDataModel(QObject *parent)
+ : QAbstractListModel(parent),
+ mCachingInProgress(false),
+ mImageType(TypeQImage),
+ mDefaultIcon((":/images/default.svg")),
+ mUseLowResImages(false)
+{
+ FUNC_LOG;
+
+ mAlbumArtManager = new HgWidgetTestAlbumArtManager;
+ connect( mAlbumArtManager, SIGNAL(albumArtReady(int)), this, SLOT(updateAlbumArt(int)) );
+ connect( mAlbumArtManager, SIGNAL(albumCacheReady()), this, SLOT(albumCacheReady()) );
+ init();
+}
+
+/*!
+ Destructs the collection data model.
+ */
+HgWidgetTestDataModel::~HgWidgetTestDataModel()
+{
+ FUNC_LOG;
+
+ disconnect( mAlbumArtManager, SIGNAL(albumArtReady(int)), this, SLOT(updateAlbumArt(int)) );
+ disconnect( mAlbumArtManager, SIGNAL(albumCacheReady()), this, SLOT(albumCacheReady()) );
+ delete mAlbumArtManager;
+}
+
+void HgWidgetTestDataModel::setThumbnailSize(ThumbnailManager::ThumbnailSize size)
+{
+ mAlbumArtManager->setThumbnailSize(size);
+}
+
+void HgWidgetTestDataModel::init()
+{
+ FUNC_LOG;
+
+ // Read all .jpg image paths from the c:/data/images folder
+ QDir dir;
+ dir.setFilter(QDir::Files | QDir:: Dirs);
+#ifdef __WINS__
+ dir.setPath(QString("c:/data/images"));
+#else
+ dir.setPath(QString("f:/data/images"));
+#endif
+
+ QFileInfoList list = dir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i){
+ QFileInfo fileInfo = list.at(i);
+ if (fileInfo.isFile()){
+ QString s = fileInfo.filePath();
+ if (s.indexOf(QString(".jpg"),0,Qt::CaseInsensitive)>0){
+ mFiles.append(s);
+ mVisibility.append(true);
+ }
+ }
+ }
+
+ QPixmap pixmap(":/images/default.svg");
+ if (!pixmap.isNull()){
+ mQIcon = QIcon(pixmap);
+ if (!mQIcon.isNull()){
+ mHbIcon = HbIcon(mQIcon);
+ }
+ }
+}
+
+/*!
+ Returns the number of rows under the given \a parent.
+
+ View will request for the row count immediately after a model is set.
+ To prevent it from reading data while caching the album art for the first
+ screen, return row count as zero.
+
+ \reimp
+ */
+int HgWidgetTestDataModel::rowCount( const QModelIndex &parent ) const
+{
+ Q_UNUSED(parent);
+ return mFiles.count();
+}
+
+/*!
+ Returns the data stored for the item referred to by the \a index.
+
+ \reimp
+ */
+QVariant HgWidgetTestDataModel::data(const QModelIndex &index, int role) const
+{
+ QVariant returnValue = QVariant();
+ if ( !index.isValid() ) {
+ return returnValue;
+ }
+
+ int row = index.row();
+
+ if( row >= mFiles.count() ){
+ return returnValue;
+ }
+
+ switch ( role )
+ {
+ case HgWidget::HgVisibilityRole:
+ {
+ returnValue = mVisibility[index.row()];
+ } break;
+ case Qt::DisplayRole:
+ {
+ QStringList texts;
+ QString text( "Primary " );
+ text.append(QString::number(row));
+ texts << text;
+ text = "Secondary ";
+ text.append(QString::number(row));
+ texts << text;
+ returnValue = texts;
+ break;
+ }
+ case Qt::DecorationRole:
+ {
+ // INFO("Requesting model item" << row << ", " << mFiles.at(row));
+ if (mFiles.at(row).isEmpty()) {
+ returnValue = mDefaultIcon;
+ }
+ else {
+ QImage icon = mAlbumArtManager->albumArt(mFiles.at(row), row);
+ if ( !icon.isNull() )
+ {
+ if (mUseLowResImages) {
+ QSize size = icon.size();
+ icon = icon.scaled(QSize(size.width()/4, size.height()/4));
+ }
+
+ switch(mImageType)
+ {
+ case TypeHbIcon:
+ {
+ returnValue = mHbIcon;
+ break;
+ }
+ case TypeQImage:
+ {
+ returnValue = icon;
+ break;
+ }
+ case TypeQIcon:
+ {
+ returnValue = mQIcon;
+ break;
+ }
+ default:
+ break;
+ }
+
+ }
+ else
+ {
+ returnValue = mDefaultIcon;
+ }
+ }
+ break;
+ }
+ case Hb::IndexFeedbackRole:
+ {
+ returnValue = QString::number(row);
+ break;
+ }
+ case Qt::BackgroundRole:
+ {
+ if ( (index.row() % 2) == 0 ) {
+ QColor color(211,211,211,127);
+ QBrush brush(color);
+ returnValue = brush;
+ }
+ else {
+ QColor color(255,250,250,127);
+ QBrush brush(color);
+ returnValue = brush;
+ }
+ break;
+ }
+
+ case (Qt::UserRole+2):
+ {
+ QImage icon = mAlbumArtManager->albumArt(mFiles.at(row), row);
+ if (!icon.isNull())
+ {
+ returnValue = icon;
+ }
+ } break;
+ }
+
+ return returnValue;
+}
+
+/*!
+ Must be called when data has changed and model needs to be refreshed
+ to reflect the new data.
+ */
+void HgWidgetTestDataModel::refreshModel()
+{
+ // Cancel all outstanding album art request first, then reset the model.
+ mAlbumArtManager->cancel();
+
+ // Before providing the new data to the view (list, grid, etc.), we want
+ // to make sure that we have enough album arts for the first screen.
+/* mFiles.count() = mCollectionData->count();
+ if ( mFiles.count() > 0 ) {
+ int initCount = ( mFiles.count() > KInitCacheSize ) ? KInitCacheSize : mFiles.count();
+ QStringList albumArtList;
+ QString albumArtUri;
+ for ( int i = 0; i < initCount; i++ ) {
+ albumArtUri = mCollectionData->itemData(i, MpMpxCollectionData::AlbumArtUri);
+ if ( !albumArtUri.isEmpty() ) {
+ albumArtList << albumArtUri;
+ }
+ }
+ mCachingInProgress = mAlbumArtManager->cacheAlbumArt(albumArtList);
+ if ( !mCachingInProgress ) {
+ reset();
+ }
+ }
+ else {
+ reset();
+ }
+ */
+}
+
+/*!
+ Remove items from model (do not actually delete them).
+ */
+void HgWidgetTestDataModel::remove(const QItemSelection &selection)
+{
+ FUNC_LOG;
+
+ QModelIndexList modelIndexes = selection.indexes();
+ int removeCount = modelIndexes.count();
+ int originalItemCount = mFiles.count();
+ if (originalItemCount-removeCount > 0) {
+ RangeList removeRanges;
+ qSort(modelIndexes);
+ while (!modelIndexes.isEmpty()) {
+ QModelIndexList::iterator i = modelIndexes.begin();
+ QModelIndexList::iterator start = i;
+ int lastRow = i->row();
+ while (++i != modelIndexes.end() && i->row() == lastRow+1) {
+ lastRow++;
+ }
+ removeRanges.append(Range(start->row(), lastRow));
+ modelIndexes.erase(start, i);
+ }
+
+ // Work backwards to keep the indexes consistent
+ for (int i = removeRanges.count()-1; i >= 0; i--) {
+ Range range = removeRanges.at(i);
+ beginRemoveRows(QModelIndex(), range.first, range.second);
+ for (int j = range.second; j >= range.first; j--) {
+ INFO("Removing model item" << j);
+ mFiles.removeAt(j);
+ }
+ endRemoveRows();
+ }
+ }
+ else if (originalItemCount-removeCount == 0) {
+ beginRemoveRows(QModelIndex(), 0, originalItemCount-1);
+ mFiles.clear();
+ endRemoveRows();
+ }
+}
+
+/*!
+ Move items to the target index in the model. The selection should be contiguous.
+ */
+void HgWidgetTestDataModel::move(const QItemSelection &selection, const QModelIndex &target)
+{
+ FUNC_LOG;
+
+ QModelIndexList modelIndexes = selection.indexes();
+
+ if (modelIndexes.count() > 0 && target.isValid()) {
+ int first = modelIndexes.front().row();
+ int last = modelIndexes.back().row();
+ int targetRow = target.row();
+ INFO("Move indexes" << first << "-" << last << "to" << targetRow);
+ if (targetRow < first) {
+ beginMoveRows(QModelIndex(), first, last, QModelIndex(), targetRow);
+ for (int i = 0; i <= last-first; i++) {
+ mFiles.move(first+i, targetRow+i);
+ }
+ endMoveRows();
+ }
+ else if (targetRow > last) {
+ beginMoveRows(QModelIndex(), first, last, QModelIndex(), targetRow);
+ for (int i = 0; i <= last-first; i++) {
+ mFiles.move(last-i, targetRow);
+ }
+ endMoveRows();
+ }
+ }
+}
+
+/*!
+ Add count dummy items at the target index in the model.
+ */
+void HgWidgetTestDataModel::add(const QModelIndex &target, int count)
+{
+ FUNC_LOG;
+
+ if (target.isValid()) {
+ beginInsertRows(QModelIndex(), target.row(), target.row()+count-1);
+ for (int i = 0; i < count; i++) {
+ mFiles.insert(target.row(), QString());
+ mVisibility.insert(target.row(), true);
+ }
+ endInsertRows();
+ }
+}
+
+/*!
+ Slot to be called when album art for the \a index needs to be updated.
+ */
+void HgWidgetTestDataModel::updateAlbumArt( int index )
+{
+ if ( index >= 0 && index < mFiles.count() ) {
+ QModelIndex modelIndex = QAbstractItemModel::createIndex(index, 0);
+ emit dataChanged(modelIndex, modelIndex);
+ }
+}
+
+/*!
+ Slot to be called when album art cache is ready.
+ */
+void HgWidgetTestDataModel::albumCacheReady()
+{
+ if ( mCachingInProgress ) {
+ mCachingInProgress = false;
+ reset();
+ }
+}
+
+void HgWidgetTestDataModel::setImageDataType(ImageType type)
+{
+ mImageType = type;
+}
+
+bool HgWidgetTestDataModel::setData(const QModelIndex& index, const QVariant& value, int role)
+{
+ if (role == HgWidget::HgVisibilityRole)
+ {
+ mVisibility[index.row()] = value.toBool();
+ emit dataChanged(index, index);
+ return true;
+ }
+ return false;
+}
+
+void HgWidgetTestDataModel::enableLowResImages(bool enabled) {
+
+ mUseLowResImages = enabled;
+}
+
+bool HgWidgetTestDataModel::lowResImagesEnabled() const {
+
+ return mUseLowResImages;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgettestview.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,702 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <hbaction.h>
+#include <hbdialog.h>
+#include <hbinstance.h>
+#include <hblabel.h>
+#include <hblistwidget.h>
+#include <hbmenu.h>
+#include <hbscrollbar>
+#include <QActionGroup>
+#include <QGraphicsLinearLayout>
+#include "hgwidgettestview.h"
+#include "hgtestview.h"
+#include "hgselectiondialog.h"
+#include "hgwidgettestdatamodel.h"
+#include "hgflipwidget.h"
+#include "trace.h"
+#include <hgwidgets/hggrid.h>
+#include <hgwidgets/hgmediawall.h>
+
+HgWidgetTestView::HgWidgetTestView(QGraphicsItem *parent) :
+ HbView(parent),
+ mWidget(NULL),
+ mModel(NULL),
+ mListWidget(NULL),
+ mToggleOrientation(false),
+ mTBone(false),
+ mFlipWidget(NULL),
+ mFrontItem(NULL)
+{
+ mModel = new HgWidgetTestDataModel(this);
+ mModel->setImageDataType(HgWidgetTestDataModel::TypeQImage);
+ mSelectionModel = new QItemSelectionModel(mModel, this);
+
+ createMenu();
+
+ mLayout = new QGraphicsLinearLayout(Qt::Vertical);
+ mLayout->setContentsMargins(0,0,0,0);
+ initWidget( HgWidgetGrid );
+ setLayout( mLayout );
+}
+
+HgWidgetTestView::~HgWidgetTestView()
+{
+}
+
+void HgWidgetTestView::createMenu()
+{
+ FUNC_LOG;
+
+ HbMenu* modeMenu = new HbMenu("Change widget type");
+ menu()->addMenu(modeMenu);
+
+ HbMenu* scrollBarMenu = new HbMenu("ScrollBar settings");
+ menu()->addMenu( scrollBarMenu );
+
+ HbMenu* imageTypeMenu = new HbMenu("Datamodel image type");
+ menu()->addMenu( imageTypeMenu );
+
+ HbAction* gridAction = modeMenu->addAction( "Use grid" );
+ HbAction* coverFlowAction = modeMenu->addAction( "Use coverFlow" );
+ HbAction* TBone = modeMenu->addAction( "Use TBone" );
+ connect( modeMenu, SIGNAL(triggered(HbAction*)), this, SLOT(switchWidget(HbAction*)) );
+
+ QActionGroup* ac1 = new QActionGroup( this );
+ gridAction->setCheckable( true );
+ coverFlowAction->setCheckable( true );
+ TBone->setCheckable(true);
+ gridAction->setChecked( true );
+ ac1->addAction( gridAction );
+ ac1->addAction( coverFlowAction );
+ ac1->addAction( TBone );
+
+ HbAction* scrollBarAutoHideAction = scrollBarMenu->addAction( "Autohide ScrollBar" );
+ HbAction* scrollBarAlwaysOnAction = scrollBarMenu->addAction( "ScrollBar always on" );
+ HbAction* scrollBarAlwaysOffAction = scrollBarMenu->addAction( "ScrollBar always off" );
+ scrollBarMenu->addSeparator();
+ HbAction* interactiveScrollBarAction = scrollBarMenu->addAction( "Interactive scrollbar" );
+ HbAction* uninteractiveScrollBarAction = scrollBarMenu->addAction( "Uninteractive scrollbar" );
+ connect( scrollBarAutoHideAction, SIGNAL(triggered()), this, SLOT(autoHideScrollBar()) );
+ connect( scrollBarAlwaysOnAction, SIGNAL(triggered()), this, SLOT(scrollBarAlwaysOn()) );
+ connect( scrollBarAlwaysOffAction, SIGNAL(triggered()), this, SLOT(scrollBarAlwaysOff()) );
+ connect( interactiveScrollBarAction, SIGNAL(triggered()), this, SLOT(interactiveScrollBar()) );
+ connect( uninteractiveScrollBarAction, SIGNAL(triggered()), this, SLOT(unInteractiveScrollBar()) );
+
+ QActionGroup* ac2 = new QActionGroup( this );
+ scrollBarAutoHideAction->setCheckable( true );
+ scrollBarAlwaysOnAction->setCheckable( true );
+ scrollBarAlwaysOffAction->setCheckable(true);
+ scrollBarAutoHideAction->setChecked( true );
+ ac2->addAction( scrollBarAutoHideAction );
+ ac2->addAction( scrollBarAlwaysOnAction );
+ ac2->addAction( scrollBarAlwaysOffAction );
+
+ QActionGroup* ac3 = new QActionGroup( this );
+ interactiveScrollBarAction->setCheckable( true );
+ uninteractiveScrollBarAction->setCheckable( true );
+ uninteractiveScrollBarAction->setChecked( true );
+ ac3->addAction( interactiveScrollBarAction );
+ ac3->addAction( uninteractiveScrollBarAction );
+
+ HbAction* qimageAction = imageTypeMenu->addAction( "feed QImages" );
+ HbAction* hbiconAction = imageTypeMenu->addAction( "feed HbIcons" );
+ HbAction* qiconAction = imageTypeMenu->addAction( "feed QIcons" );
+ connect( qimageAction, SIGNAL(triggered()), this, SLOT(feedqimages()) );
+ connect( hbiconAction, SIGNAL(triggered()), this, SLOT(feedhbicons()) );
+ connect( qiconAction, SIGNAL(triggered()), this, SLOT(feedqicons()) );
+
+ QActionGroup* ac4 = new QActionGroup( this );
+ qimageAction->setCheckable( true );
+ hbiconAction->setCheckable( true );
+ qiconAction->setCheckable( true );
+ qimageAction->setChecked( true );
+ ac4->addAction( qimageAction );
+ ac4->addAction( hbiconAction );
+ ac4->addAction( qiconAction );
+
+ menu()->addAction("Toggle scrolldirection", this, SLOT(toggleScrollDirection()));
+ menu()->addAction("Simulate orientation switch", this, SLOT(orientationChanged()));
+
+ mUseLowResAction = menu()->addAction( "Use low res images for coverflow" );
+ mUseLowResAction->setCheckable(true);
+ mUseLowResAction->setChecked(false);
+ mUseLowResAction->setEnabled(false);
+ connect( mUseLowResAction, SIGNAL(triggered()), this, SLOT(toggleLowResForCoverflow()) );
+
+ HbMenu *modelChangeSubMenu = menu()->addMenu("Change model");
+ modelChangeSubMenu->addAction("Remove items", this, SLOT(openDeleteItemsDialog()));
+ modelChangeSubMenu->addAction("Move items", this, SLOT(openMoveItemsDialog()));
+ modelChangeSubMenu->addAction("Add items", this, SLOT(openAddItemsDialog()));
+
+ HbMenu *labelChangeSubMenu = menu()->addMenu("Change labels");
+ HbMenu *titleSubMenu = labelChangeSubMenu->addMenu("Title");
+ HbAction *aboveAction1 = titleSubMenu->addAction("Above", this, SLOT(setTitleAboveImage()));
+ HbAction *belowAction1 = titleSubMenu->addAction("Below", this, SLOT(setTitleBelowImage()));
+ HbAction *hiddenAction1 = titleSubMenu->addAction("Hide", this, SLOT(setTitleHidden()));
+ QActionGroup* ac5 = new QActionGroup(this);
+ aboveAction1->setCheckable(true);
+ belowAction1->setCheckable(true);
+ hiddenAction1->setCheckable(true);
+ hiddenAction1->setChecked(true);
+ ac5->addAction(aboveAction1);
+ ac5->addAction(belowAction1);
+ ac5->addAction(hiddenAction1);
+
+ HbMenu *descriptionSubMenu = labelChangeSubMenu->addMenu("Description");
+ HbAction *aboveAction2 = descriptionSubMenu->addAction("Above", this, SLOT(setDescriptionAboveImage()));
+ HbAction *belowAction2 = descriptionSubMenu->addAction("Below", this, SLOT(setDescriptionBelowImage()));
+ HbAction *hiddenAction2 = descriptionSubMenu->addAction("Hide", this, SLOT(setDescriptionHidden()));
+ QActionGroup* ac6 = new QActionGroup(this);
+ aboveAction2->setCheckable(true);
+ belowAction2->setCheckable(true);
+ hiddenAction2->setCheckable(true);
+ hiddenAction2->setChecked(true);
+ ac6->addAction(aboveAction2);
+ ac6->addAction(belowAction2);
+ ac6->addAction(hiddenAction2);
+}
+
+void HgWidgetTestView::switchWidget(HbAction* action)
+{
+ FUNC_LOG;
+
+ mTBone = false;
+ if( action->text() == "Use grid"){
+ initWidget( HgWidgetGrid );
+ }
+ else if( action->text() == "Use coverFlow"){
+ initWidget( HgWidgetCoverflow );
+ }
+ else if( action->text() == "Use TBone" ){
+ mTBone = true;
+ initWidget( HgWidgetCoverflow );
+ }
+}
+
+void HgWidgetTestView::toggleScrollDirection()
+{
+ FUNC_LOG;
+
+ mToggleOrientation = !mToggleOrientation;
+ initWidget( mWidgetType );
+}
+
+void HgWidgetTestView::initWidget( WidgetType type )
+{
+ FUNC_LOG;
+
+ mWidgetType = type;
+
+ // TODO, disconnecting signals required?
+
+ if( mWidget )
+ mLayout->removeItem(mWidget);
+ if( mListWidget )
+ mLayout->removeItem(mListWidget);
+
+ delete mWidget;
+ mWidget = NULL;
+
+ delete mListWidget;
+ mListWidget = NULL;
+
+ mWidget = createWidget(type);
+ mLayout->addItem(mWidget);
+
+ switch (type)
+ {
+ case HgWidgetGrid:
+ {
+ mUseLowResAction->setEnabled(false);
+ mModel->enableLowResImages(false);
+ // TODO, init grid different model,
+ mModel->setThumbnailSize(ThumbnailManager::ThumbnailMedium);
+ break;
+ }
+ case HgWidgetCoverflow:
+ {
+ mUseLowResAction->setEnabled(true);
+ mModel->enableLowResImages(mUseLowResAction->isChecked());
+ mModel->setThumbnailSize(ThumbnailManager::ThumbnailLarge);
+ if (mTBone) {
+ mListWidget = new HbListWidget;
+ mLayout->addItem(mListWidget);
+ mListWidget->addItem( "List item 1");
+ mListWidget->addItem( "List item 2");
+ mListWidget->addItem( "List item 3");
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ HANDLE_ERROR_NULL(mWidget);
+ if (mWidget)
+ {
+ mWidget->setModel( mModel );
+ connect(mWidget, SIGNAL(activated(QModelIndex)), SLOT(openDialog(QModelIndex)));
+ connect(mWidget, SIGNAL(longPressed(QModelIndex, QPointF)), SLOT(openView(QModelIndex)));
+ QList<HbMainWindow *> mainWindows = hbInstance->allMainWindows();
+ if (mainWindows.count() > 0)
+ {
+ HbMainWindow *primaryWindow = mainWindows[0];
+ connect(primaryWindow, SIGNAL(orientationChanged(Qt::Orientation)), mWidget, SLOT(orientationChanged(Qt::Orientation)));
+ }
+
+ connect(mWidget, SIGNAL(scrollingStarted()), SLOT(onScrollingStarted()));
+ connect(mWidget, SIGNAL(scrollingEnded()), SLOT(onScrollingEnded()));
+ }
+}
+
+void HgWidgetTestView::openDialog(const QModelIndex& index)
+{
+ FUNC_LOG;
+
+ QVariant image = mModel->data(index, Qt::DecorationRole);
+ QVariant texts = mModel->data(index, Qt::DisplayRole);
+
+ if (mWidgetType == HgWidgetCoverflow)
+ {
+ if (image.canConvert<QPixmap>() && texts.canConvert<QStringList>())
+ {
+ QStringList strList = texts.toStringList();
+ if (strList.count() > 1)
+ {
+ if (mFrontItem)
+ mFrontItem->setVisible(false);
+
+ if (mFlipWidget)
+ delete mFlipWidget;
+
+ QPolygonF poly;
+ if (!mWidget->getItemOutline(index, poly))
+ return;
+
+ QRectF itemRect = poly.boundingRect();
+
+ mFlipWidget =
+ new HgFlipWidget(
+ strList.at(0),
+ strList.at(1),
+ image.value<QPixmap>(),
+ this);
+
+ mFlipWidget->setPos(QPointF(
+ itemRect.center().x() - itemRect.width() / 2,
+ itemRect.center().y() - itemRect.height() / 2
+ ));
+
+ mFlipWidget->resize(itemRect.width(), itemRect.height());
+ mFlipWidget->show();
+
+ QObject::connect(mFlipWidget, SIGNAL(closed()), this, SLOT(flipClosed()));
+ mModel->setData(index, false, Qt::UserRole+1);
+ mFlippedIndex = index;
+ }
+ }
+
+ return;
+ }
+
+ HbDialog dlg;
+ dlg.setTimeout(HbPopup::NoTimeout);
+ dlg.setDismissPolicy(HbPopup::TapInside);
+ dlg.setPrimaryAction(new HbAction("Close"));
+ if (texts.canConvert<QStringList>())
+ {
+ QStringList strList = texts.toStringList();
+ if (strList.count() > 0)
+ {
+ dlg.setHeadingWidget(new HbLabel(strList.at(0)));
+ }
+ }
+ if (image.canConvert<QImage>())
+ {
+ HbLabel *content = new HbLabel;
+ QImage realImage(image.value<QImage>());
+ QPixmap pixmap = QPixmap::fromImage( realImage );
+ content->setIcon(HbIcon(pixmap));
+ dlg.setContentWidget(content);
+ }
+ dlg.exec();
+}
+
+void HgWidgetTestView::openView(const QModelIndex& index)
+{
+ FUNC_LOG;
+
+ QVariant image = mModel->data(index, Qt::DecorationRole);
+ QVariant texts = mModel->data(index, Qt::DisplayRole);
+
+ if (image.canConvert<QImage>() && texts.canConvert<QStringList>())
+ {
+ QStringList strList = texts.toStringList();
+ if (strList.count() > 1)
+ {
+ HgTestView* view =
+ new HgTestView(
+ strList.at(0),
+ strList.at(1),
+ QPixmap::fromImage(image.value<QImage>()));
+ QList<HbMainWindow *> mainWindows = hbInstance->allMainWindows();
+ if (mainWindows.count() > 0)
+ {
+ HbMainWindow *primaryWindow = mainWindows[0];
+ primaryWindow->addView(view);
+ primaryWindow->setViewSwitchingEnabled(false);
+ primaryWindow->setCurrentView(view);
+ }
+ }
+ }
+}
+
+void HgWidgetTestView::openDeleteItemsDialog()
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(mWidget);
+
+ HgWidget *widget = copyWidget();
+ HANDLE_ERROR_NULL(widget);
+
+ HgSelectionDialog *dlg =
+ new HgSelectionDialog("Remove items", "Remove", widget); // Takes ownership of widget
+ HANDLE_ERROR_NULL(dlg);
+
+ mWidget->hide();
+ widget->setSelectionMode(HgWidget::MultiSelection);
+ bool removeItems = (dlg->exec() == dlg->primaryAction());
+ QItemSelection selection = mSelectionModel->selection();
+ widget->setSelectionMode(HgWidget::NoSelection); // Clears the selection
+ delete dlg;
+
+ if (removeItems) {
+ mModel->remove(selection);
+ }
+
+ mWidget->show();
+}
+
+void HgWidgetTestView::openMoveItemsDialog()
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(mWidget);
+
+ HgWidget *widget = copyWidget();
+ HANDLE_ERROR_NULL(widget);
+ HgSelectionDialog *dlg =
+ new HgSelectionDialog("Select items to move", "Move to...", widget); // Takes ownership of widget
+ HANDLE_ERROR_NULL(dlg);
+ HANDLE_ERROR_NULL(dlg);
+
+ mWidget->hide();
+ widget->setSelectionMode(HgWidget::ContiguousSelection);
+ bool moveItems = (dlg->exec() == dlg->primaryAction());
+ QItemSelection selection = mSelectionModel->selection();
+ widget->setSelectionMode(HgWidget::NoSelection); // Clears the selection
+ delete dlg;
+ dlg = 0;
+ widget = 0;
+
+ if (moveItems) {
+ widget = copyWidget();
+ HANDLE_ERROR_NULL(widget);
+ widget->setPreferredSize(size().width(), 320);
+ dlg = new HgSelectionDialog("Select target location", "Move", widget); // Takes ownership of widget
+ HANDLE_ERROR_NULL(dlg);
+ widget->setSelectionMode(HgWidget::SingleSelection);
+ moveItems = (dlg->exec() == dlg->primaryAction());
+ QItemSelection target = mSelectionModel->selection();
+ widget->setSelectionMode(HgWidget::NoSelection); // Clears the selection
+ delete dlg;
+
+ if (moveItems) {
+ mModel->move(selection, target.indexes().at(0));
+ }
+ }
+ mWidget->show();
+}
+
+void HgWidgetTestView::openAddItemsDialog()
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(mWidget);
+
+ HgWidget *widget = copyWidget();
+ HANDLE_ERROR_NULL(widget);
+ HgSelectionDialog *dlg =
+ new HgSelectionDialog("Select position to add items to", "Add", widget); // Takes ownership of widget
+ HANDLE_ERROR_NULL(dlg);
+
+ mWidget->hide();
+ widget->setSelectionMode(HgWidget::SingleSelection);
+ bool addItems = (dlg->exec() == dlg->primaryAction());
+ QItemSelection target = mSelectionModel->selection();
+ widget->setSelectionMode(HgWidget::NoSelection); // Clears the selection
+ delete dlg;
+
+ if (addItems) {
+ mModel->add(target.indexes().at(0), 5);
+ }
+
+ mWidget->show();
+}
+
+void HgWidgetTestView::autoHideScrollBar()
+{
+ setScrollBarPolicy(HgWidget::ScrollBarAutoHide);
+}
+
+void HgWidgetTestView::scrollBarAlwaysOn()
+{
+ setScrollBarPolicy(HgWidget::ScrollBarAlwaysOn);
+}
+
+void HgWidgetTestView::scrollBarAlwaysOff()
+{
+ setScrollBarPolicy(HgWidget::ScrollBarAlwaysOff);
+}
+
+void HgWidgetTestView::setScrollBarPolicy( HgWidget::ScrollBarPolicy policy )
+{
+ mWidget->setScrollBarPolicy( policy );
+}
+
+void HgWidgetTestView::setScrollBarInteractive( bool value )
+{
+ if( value )
+ setScrollBarPolicy(HgWidget::ScrollBarAlwaysOn);
+
+ mWidget->scrollBar()->setInteractive(value);
+
+ if (mWidgetType == HgWidgetCoverflow) {
+ mWidget->setIndexFeedbackPolicy(HgWidget::IndexFeedbackSingleCharacter);
+ }
+
+}
+
+void HgWidgetTestView::interactiveScrollBar()
+{
+ setScrollBarInteractive(true);
+}
+
+void HgWidgetTestView::unInteractiveScrollBar()
+{
+ setScrollBarInteractive(false);
+}
+
+HgWidget *HgWidgetTestView::createWidget(WidgetType type) const
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(mModel);
+ HANDLE_ERROR_NULL(mSelectionModel);
+
+ Qt::Orientation scrollDirection = !mToggleOrientation ? Qt::Vertical : Qt::Horizontal ;
+
+ HgWidget* widget = 0;
+
+ switch (type) {
+ case HgWidgetGrid:
+ widget = new HgGrid(scrollDirection);
+ break;
+ case HgWidgetCoverflow:
+ widget = new HgMediawall();
+ break;
+ default:
+ break;
+ }
+
+ HANDLE_ERROR_NULL(widget);
+
+ widget->setModel(mModel);
+ widget->setSelectionModel(mSelectionModel);
+ widget->setLongPressEnabled(true);
+ widget->scrollTo(widget->currentIndex());
+
+ return widget;
+}
+
+HgWidget *HgWidgetTestView::copyWidget() const
+{
+ FUNC_LOG;
+ HANDLE_ERROR_NULL(mWidget);
+
+ HgWidget* widget = createWidget(mWidgetType);
+ widget->setPreferredSize(mWidget->size());
+
+ HgMediawall *original = qobject_cast<HgMediawall *>(mWidget);
+ HgMediawall *copy = qobject_cast<HgMediawall *>(widget);
+ if (original && copy) {
+ copy->setTitlePosition(original->titlePosition());
+ copy->setDescriptionPosition(original->descriptionPosition());
+ copy->setTitleFontSpec(original->titleFontSpec());
+ copy->setDescriptionFontSpec(original->descriptionFontSpec());
+ }
+
+ return widget;
+}
+
+void HgWidgetTestView::feedqimages()
+{
+ mModel->setImageDataType(HgWidgetTestDataModel::TypeQImage);
+}
+
+void HgWidgetTestView::feedqicons()
+{
+ mModel->setImageDataType(HgWidgetTestDataModel::TypeQIcon);
+}
+
+void HgWidgetTestView::feedhbicons()
+{
+ mModel->setImageDataType(HgWidgetTestDataModel::TypeHbIcon);
+}
+
+void HgWidgetTestView::flipClosed()
+{
+ delete mFlipWidget;
+ mFlipWidget = 0;
+ mModel->setData(mFlippedIndex, true, Qt::UserRole+1);
+
+ if (mFrontItem) {
+ mFrontItem->setVisible(true);
+ }
+
+}
+void HgWidgetTestView::orientationChanged()
+{
+ mWidget->orientationChanged(Qt::Horizontal);
+}
+
+void HgWidgetTestView::onScrollingStarted()
+{
+ FUNC_LOG;
+
+ // scrolling started, need to hide
+ // label displaying full resolution image
+ if (mFrontItem)
+ mFrontItem->setVisible(false);
+
+}
+
+void HgWidgetTestView::onScrollingEnded()
+{
+ FUNC_LOG;
+
+ if (mModel->lowResImagesEnabled()) {
+
+ if (!mWidget)
+ return;
+
+ // get index to current item
+ QModelIndex index = mWidget->currentIndex();
+ if (!index.isValid())
+ return;
+
+ // get outlines of the item so we know where to render
+ QPolygonF poly;
+ if (!mWidget->getItemOutline(index, poly))
+ return;
+
+ // fetch highresolution image from the model
+ QVariant imgVariant = mModel->data(index, Qt::UserRole+2);
+ if (imgVariant.isNull())
+ return;
+
+ QRectF itemRect = poly.boundingRect();
+
+ // show it using HbLabel
+ QPixmap pixmap = imgVariant.value<QPixmap>().scaled(itemRect.width(), itemRect.height());
+
+ if (!mFrontItem) {
+ mFrontItem = new HbLabel(this);
+ }
+
+
+ mFrontItem->setVisible(false);
+ mFrontItem->setIcon(HbIcon(pixmap));
+ mFrontItem->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
+ mFrontItem->setPos(itemRect.center() - QPointF(itemRect.width()/2, itemRect.height()/2));
+ mFrontItem->resize(itemRect.width(), itemRect.height());
+ mFrontItem->setVisible(true);
+
+ }
+
+}
+
+void HgWidgetTestView::toggleLowResForCoverflow()
+{
+ if (mWidgetType == HgWidgetCoverflow) {
+ mModel->enableLowResImages(mUseLowResAction->isChecked());
+ initWidget(mWidgetType);
+ }
+}
+
+void HgWidgetTestView::setTitleAboveImage()
+{
+ FUNC_LOG;
+ HgMediawall *mediawall = qobject_cast<HgMediawall *>(mWidget);
+ if (mediawall) {
+ mediawall->setTitlePosition(HgMediawall::PositionAboveImage);
+ }
+}
+
+void HgWidgetTestView::setTitleBelowImage()
+{
+ FUNC_LOG;
+ HgMediawall *mediawall = qobject_cast<HgMediawall *>(mWidget);
+ if (mediawall) {
+ mediawall->setTitlePosition(HgMediawall::PositionBelowImage);
+ }
+}
+
+void HgWidgetTestView::setTitleHidden()
+{
+ FUNC_LOG;
+ HgMediawall *mediawall = qobject_cast<HgMediawall *>(mWidget);
+ if (mediawall) {
+ mediawall->setTitlePosition(HgMediawall::PositionNone);
+ }
+}
+
+void HgWidgetTestView::setDescriptionAboveImage()
+{
+ FUNC_LOG;
+ HgMediawall *mediawall = qobject_cast<HgMediawall *>(mWidget);
+ if (mediawall) {
+ mediawall->setDescriptionPosition(HgMediawall::PositionAboveImage);
+ }
+}
+
+void HgWidgetTestView::setDescriptionBelowImage()
+{
+ FUNC_LOG;
+ HgMediawall *mediawall = qobject_cast<HgMediawall *>(mWidget);
+ if (mediawall) {
+ mediawall->setDescriptionPosition(HgMediawall::PositionBelowImage);
+ }
+}
+
+void HgWidgetTestView::setDescriptionHidden()
+{
+ FUNC_LOG;
+ HgMediawall *mediawall = qobject_cast<HgMediawall *>(mWidget);
+ if (mediawall) {
+ mediawall->setDescriptionPosition(HgMediawall::PositionNone);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/main.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <hbapplication.h>
+#include <hbmainwindow.h>
+#include "hgwidgettestview.h"
+
+int main(int argc, char **argv)
+{
+ HbApplication app(argc, argv);
+ app.setApplicationName("HgWidgetTest");
+
+ HbMainWindow mainWindow;
+ // mainWindow.setOptimizationFlags( QGraphicsView::DontSavePainterState ); If this is used, menu is invisible
+ mainWindow.viewport()->grabGesture(Qt::PanGesture);
+ mainWindow.viewport()->grabGesture(Qt::TapGesture);
+ mainWindow.viewport()->grabGesture(Qt::TapAndHoldGesture);
+
+ HgWidgetTestView *view = new HgWidgetTestView;
+ mainWindow.addView(view);
+
+ mainWindow.show();
+ return app.exec();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/unit/hbautotest.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,832 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Container for pan (drag) gesture -related data and logic.
+*
+*/
+
+#include "hbautotest.h"
+#include <hbmainwindow.h>
+#include <hbwidget.h>
+
+
+const qreal STEP = 10; //How many pixels to drag before sending an event
+
+//Init static members
+bool HbAutoTest::pointerPressed = false;
+QPointF HbAutoTest::pressPoint = QPointF();
+
+void HbAutoTest::mouseMove (HbAutoTestMainWindow *window, HbWidget *widget, QPointF pos, int delay)
+{
+ if (delay!=-1) {
+ QTest::qWait(delay);
+ }
+ QPointF targetPoint=QPointF();
+ if (pos==QPointF()) {
+ targetPoint = middlePointOfWidget(widget);
+ } else {
+ targetPoint = widget->mapToScene(pos);
+ }
+ if (pointerPressed) {
+ //Now we should drag an item
+ drag(window, targetPoint);
+ HbAutoTestMouseEvent me (
+ QEvent::MouseMove,
+ targetPoint.toPoint(),
+ window->viewport()->mapToGlobal(targetPoint.toPoint()),
+ Qt::NoButton,
+ Qt::NoButton,
+ Qt::NoModifier);
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ qApp->notify((window->viewport()), &me);
+ QCoreApplication::sendPostedEvents();
+ QTest::qWait(1);
+ } else {
+ HbAutoTestMouseEvent me (
+ QEvent::MouseMove,
+ targetPoint.toPoint(),
+ window->viewport()->mapToGlobal(targetPoint.toPoint()),
+ Qt::NoButton,
+ Qt::NoButton,
+ Qt::NoModifier);
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ qApp->notify((window->viewport()), &me);
+ QCoreApplication::sendPostedEvents();
+ QTest::qWait(1);
+
+ }
+ QTest::qWait(1);
+ QTest::qWait(1);
+}
+
+void HbAutoTest::mousePress (HbAutoTestMainWindow *window, HbWidget *widget, QPointF pos, int delay)
+{
+ if (delay!=-1) {
+ QTest::qWait(delay);
+ }
+ pointerPressed=true;
+ QPointF targetPoint=QPointF();
+ if (pos==QPointF()) {
+ targetPoint = middlePointOfWidget(widget);
+ } else {
+ targetPoint = widget->mapToScene(pos);
+ }
+ QCursor::setPos(window->mapToGlobal(targetPoint.toPoint()));
+
+ pressPoint=targetPoint;
+
+ HbAutoTestMouseEvent me (
+ QEvent::MouseButtonPress,
+ targetPoint.toPoint(),
+ window->viewport()->mapToGlobal(targetPoint.toPoint()),
+ Qt::LeftButton,
+ Qt::LeftButton,
+ Qt::NoModifier);
+
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ qApp->notify((window->viewport()), &me);
+ QCoreApplication::sendPostedEvents();
+ QCoreApplication::sendPostedEvents();
+ QTest::qWait(1);
+}
+
+void HbAutoTest::mouseRelease (HbAutoTestMainWindow *window, HbWidget *widget, QPointF pos, int delay)
+{
+ if (delay!=-1) {
+ QTest::qWait(delay);
+ }
+ pointerPressed=false;
+ QPointF targetPoint=QPointF();
+ if (pos==QPointF()) {
+ targetPoint = middlePointOfWidget(widget);
+ } else {
+ targetPoint = widget->mapToScene(pos);
+ }
+ QCursor::setPos(window->mapToGlobal(targetPoint.toPoint()));
+ pressPoint=QPointF();
+ HbAutoTestMouseEvent me (
+ QEvent::MouseButtonRelease,
+ targetPoint.toPoint(),
+ window->viewport()->mapToGlobal(targetPoint.toPoint()),
+ Qt::LeftButton,
+ Qt::LeftButton,
+ Qt::NoModifier);
+
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ qApp->notify((window->viewport()), &me);
+ QCoreApplication::sendPostedEvents();
+
+ QTest::qWait(1);
+ QTest::qWait(1);
+}
+
+void HbAutoTest::mouseClick (HbAutoTestMainWindow *window, const HbWidget *widget, QPointF pos, int delay)
+{
+ if (delay!=-1) {
+ QTest::qWait(delay);
+ }
+ QPointF targetPoint=QPointF();
+ if (pos==QPointF()) {
+ targetPoint = middlePointOfWidget(widget);
+ } else {
+ targetPoint = widget->mapToScene(pos);
+ }
+
+ QCursor::setPos(window->mapToGlobal(targetPoint.toPoint()));
+
+ HbAutoTestMouseEvent me (
+ QEvent::MouseButtonPress,
+ targetPoint.toPoint(),
+ window->viewport()->mapToGlobal(targetPoint.toPoint()),
+ Qt::LeftButton,
+ Qt::LeftButton,
+ Qt::NoModifier);
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ qApp->notify((window->viewport()), &me);
+ QCoreApplication::sendPostedEvents();
+ QTest::qWait(1);
+
+ if (delay!=-1) {
+ QTest::qWait(delay);
+ }
+ HbAutoTestMouseEvent me2 (
+ QEvent::MouseButtonRelease,
+ targetPoint.toPoint(),
+ window->viewport()->mapToGlobal(targetPoint.toPoint()),
+ Qt::LeftButton,
+ Qt::LeftButton,
+ Qt::NoModifier);
+
+ QSpontaneKeyEvent::setSpontaneous(&me2);
+ qApp->notify((window->viewport()), &me2);
+ QCoreApplication::sendPostedEvents();
+
+ QTest::qWait(1);
+ QTest::qWait(1);
+}
+
+QPointF HbAutoTest::middlePointOfWidget( const HbWidget* widget)
+{
+ QRectF widgetRect = widget->rect();
+ QRectF widgetSceneRect = widget->mapRectToScene(widgetRect);
+ qreal middleX = ((widgetSceneRect.right() - widgetSceneRect.left())/2)+widgetSceneRect.left();
+ qreal middleY = ((widgetSceneRect.bottom() - widgetSceneRect.top())/2)+widgetSceneRect.top();
+ return QPointF(middleX,middleY);
+}
+
+
+
+void HbAutoTest::drag(HbAutoTestMainWindow *window, QPointF targetPoint)
+{
+ qreal tempX = targetPoint.x() - pressPoint.x();
+ qreal tempY = targetPoint.y() - pressPoint.y();
+ qreal totalTrip = sqrt ((tempX * tempX) + (tempY * tempY));
+
+ int numberOfSteps = qRound(totalTrip / STEP);
+ HbAutoTestMouseEvent me (
+ QEvent::MouseMove,
+ targetPoint.toPoint(),
+ window->viewport()->mapToGlobal(targetPoint.toPoint()),
+ Qt::NoButton ,
+ Qt::LeftButton,
+ Qt::NoModifier);
+
+ QPointF nextPanPoint=pressPoint;
+ for (int i=1; i<numberOfSteps; i++) { //On purpose not =<
+
+ nextPanPoint.setY (pressPoint.y()+((i / (qreal)numberOfSteps) * tempY));
+ nextPanPoint.setX (pressPoint.x()+((i / (qreal)numberOfSteps) * tempX));
+
+ QCursor::setPos(window->mapToGlobal(nextPanPoint.toPoint()));
+
+ me = HbAutoTestMouseEvent (QEvent::MouseMove,
+ nextPanPoint.toPoint(),
+ window->viewport()->mapToGlobal(nextPanPoint.toPoint()),
+ Qt::NoButton,
+ Qt::LeftButton,
+ Qt::NoModifier);
+
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ qApp->notify((window->viewport()), &me);
+ QCoreApplication::sendPostedEvents();
+ }
+
+ QCursor::setPos(window->mapToGlobal(targetPoint.toPoint()));
+
+ //One more (or the only one) step to the target
+ me = HbAutoTestMouseEvent (QEvent::MouseMove,
+ targetPoint.toPoint(),
+ window->viewport()->mapToGlobal(targetPoint.toPoint()),
+ Qt::NoButton,
+ Qt::LeftButton,
+ Qt::NoModifier);
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ qApp->notify((window->viewport()), &me);
+ QCoreApplication::sendPostedEvents();
+}
+
+
+void HbAutoTest::simulateEvent(QWidget *widget, bool press, int code,
+ Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay)
+ {
+ //Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ /*extern int Q_TESTLIB_EXPORT defaultKeyDelay();
+
+ if (delay == -1 || delay < defaultKeyDelay())
+ delay = defaultKeyDelay();
+ if(delay > 0)
+ QTest::qWait(delay);*/
+ Q_UNUSED(delay);
+ QTest::qWait(10); //TODO: Remove this and reveal above out-commented code
+
+ HbAutoTestKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat);
+ QSpontaneKeyEvent::setSpontaneous(&a);
+ if (!qApp->notify(widget, &a))
+ QTest::qWarn("Keyboard event not accepted by receiving widget");
+ }
+
+void HbAutoTest::sendKeyEvent(QTest::KeyAction action, QWidget *widget, Qt::Key code,
+ QString text, Qt::KeyboardModifiers modifier, int delay)
+ {
+ QTEST_ASSERT(qApp);
+
+ if (!widget)
+ widget = QWidget::keyboardGrabber();
+ if (!widget) {
+ if (QWidget *apw = QApplication::activePopupWidget())
+ widget = apw->focusWidget() ? apw->focusWidget() : apw;
+ else
+ widget = QApplication::focusWidget();
+ }
+ if (!widget)
+ widget = QApplication::activeWindow();
+
+ QTEST_ASSERT(widget);
+
+ if (action == QTest::Click) {
+ QPointer<QWidget> ptr(widget);
+ sendKeyEvent(QTest::Press, widget, code, text, modifier, delay);
+ if (!ptr) {
+ // if we send key-events to embedded widgets, they might be destroyed
+ // when the user presses Return
+ return;
+ }
+ sendKeyEvent(QTest::Release, widget, code, text, modifier, delay);
+ return;
+ }
+
+ bool repeat = false;
+
+ if (action == QTest::Press) {
+ if (modifier & Qt::ShiftModifier)
+ simulateEvent(widget, true, Qt::Key_Shift, 0, QString(), false, delay);
+
+ if (modifier & Qt::ControlModifier)
+ simulateEvent(widget, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay);
+
+ if (modifier & Qt::AltModifier)
+ simulateEvent(widget, true, Qt::Key_Alt,
+ modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
+ if (modifier & Qt::MetaModifier)
+ simulateEvent(widget, true, Qt::Key_Meta, modifier & (Qt::ShiftModifier
+ | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
+ simulateEvent(widget, true, code, modifier, text, repeat, delay);
+ } else if (action == QTest::Release) {
+ simulateEvent(widget, false, code, modifier, text, repeat, delay);
+
+ if (modifier & Qt::MetaModifier)
+ simulateEvent(widget, false, Qt::Key_Meta, modifier, QString(), false, delay);
+ if (modifier & Qt::AltModifier)
+ simulateEvent(widget, false, Qt::Key_Alt, modifier &
+ (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
+
+ if (modifier & Qt::ControlModifier)
+ simulateEvent(widget, false, Qt::Key_Control,
+ modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
+
+ if (modifier & Qt::ShiftModifier)
+ simulateEvent(widget, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false, delay);
+ }
+ }
+
+void HbAutoTest::sendKeyEvent(QTest::KeyAction action, QWidget *widget, Qt::Key code,
+ char ascii, Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ QString text;
+ if (ascii)
+ text = QString(QChar::fromLatin1(ascii));
+ sendKeyEvent(action, widget, code, text, modifier, delay);
+ }
+
+void HbAutoTest::keyEvent(QTest::KeyAction action, QWidget *widget, char ascii,
+ Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ sendKeyEvent(action, widget, asciiToKey(ascii), ascii, modifier, delay);
+ }
+
+void HbAutoTest::keyEvent(QTest::KeyAction action, QWidget *widget, Qt::Key key,
+ Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ sendKeyEvent(action, widget, key, keyToAscii(key), modifier, delay);
+ }
+
+void HbAutoTest::keyClicks(QWidget *widget, const QString &sequence,
+ Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ for (int i=0; i < sequence.length(); i++)
+ keyEvent(QTest::Click, widget, sequence.at(i).toLatin1(), modifier, delay);
+ }
+
+void HbAutoTest::keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ keyEvent(QTest::Press, widget, key, modifier, delay);
+ }
+
+void HbAutoTest::keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ keyEvent(QTest::Release, widget, key, modifier, delay);
+ }
+
+void HbAutoTest::keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ keyEvent(QTest::Click, widget, key, modifier, delay);
+ }
+
+void HbAutoTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ keyEvent(QTest::Press, widget, key, modifier, delay);
+ }
+
+void HbAutoTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ keyEvent(QTest::Release, widget, key, modifier, delay); }
+
+void HbAutoTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier, int delay)
+ {
+ Q_ASSERT_X(dynamic_cast<HbAutoTestMainWindow *>(( widget) ) != 0, "HbAutoTest", "Always use with HbAutoTestMainWindow");
+ keyEvent(QTest::Click, widget, key, modifier, delay);
+ }
+
+Qt::Key HbAutoTest::asciiToKey(char ascii)
+{
+ switch ((unsigned char)ascii) {
+ case 0x08: return Qt::Key_Backspace;
+ case 0x09: return Qt::Key_Tab;
+ case 0x0b: return Qt::Key_Backtab;
+ case 0x0d: return Qt::Key_Return;
+ case 0x1b: return Qt::Key_Escape;
+ case 0x20: return Qt::Key_Space;
+ case 0x21: return Qt::Key_Exclam;
+ case 0x22: return Qt::Key_QuoteDbl;
+ case 0x23: return Qt::Key_NumberSign;
+ case 0x24: return Qt::Key_Dollar;
+ case 0x25: return Qt::Key_Percent;
+ case 0x26: return Qt::Key_Ampersand;
+ case 0x27: return Qt::Key_Apostrophe;
+ case 0x28: return Qt::Key_ParenLeft;
+ case 0x29: return Qt::Key_ParenRight;
+ case 0x2a: return Qt::Key_Asterisk;
+ case 0x2b: return Qt::Key_Plus;
+ case 0x2c: return Qt::Key_Comma;
+ case 0x2d: return Qt::Key_Minus;
+ case 0x2e: return Qt::Key_Period;
+ case 0x2f: return Qt::Key_Slash;
+ case 0x30: return Qt::Key_0;
+ case 0x31: return Qt::Key_1;
+ case 0x32: return Qt::Key_2;
+ case 0x33: return Qt::Key_3;
+ case 0x34: return Qt::Key_4;
+ case 0x35: return Qt::Key_5;
+ case 0x36: return Qt::Key_6;
+ case 0x37: return Qt::Key_7;
+ case 0x38: return Qt::Key_8;
+ case 0x39: return Qt::Key_9;
+ case 0x3a: return Qt::Key_Colon;
+ case 0x3b: return Qt::Key_Semicolon;
+ case 0x3c: return Qt::Key_Less;
+ case 0x3d: return Qt::Key_Equal;
+ case 0x3e: return Qt::Key_Greater;
+ case 0x3f: return Qt::Key_Question;
+ case 0x40: return Qt::Key_At;
+ case 0x41: return Qt::Key_A;
+ case 0x42: return Qt::Key_B;
+ case 0x43: return Qt::Key_C;
+ case 0x44: return Qt::Key_D;
+ case 0x45: return Qt::Key_E;
+ case 0x46: return Qt::Key_F;
+ case 0x47: return Qt::Key_G;
+ case 0x48: return Qt::Key_H;
+ case 0x49: return Qt::Key_I;
+ case 0x4a: return Qt::Key_J;
+ case 0x4b: return Qt::Key_K;
+ case 0x4c: return Qt::Key_L;
+ case 0x4d: return Qt::Key_M;
+ case 0x4e: return Qt::Key_N;
+ case 0x4f: return Qt::Key_O;
+ case 0x50: return Qt::Key_P;
+ case 0x51: return Qt::Key_Q;
+ case 0x52: return Qt::Key_R;
+ case 0x53: return Qt::Key_S;
+ case 0x54: return Qt::Key_T;
+ case 0x55: return Qt::Key_U;
+ case 0x56: return Qt::Key_V;
+ case 0x57: return Qt::Key_W;
+ case 0x58: return Qt::Key_X;
+ case 0x59: return Qt::Key_Y;
+ case 0x5a: return Qt::Key_Z;
+ case 0x5b: return Qt::Key_BracketLeft;
+ case 0x5c: return Qt::Key_Backslash;
+ case 0x5d: return Qt::Key_BracketRight;
+ case 0x5e: return Qt::Key_AsciiCircum;
+ case 0x5f: return Qt::Key_Underscore;
+ case 0x60: return Qt::Key_QuoteLeft;
+ case 0x61: return Qt::Key_A;
+ case 0x62: return Qt::Key_B;
+ case 0x63: return Qt::Key_C;
+ case 0x64: return Qt::Key_D;
+ case 0x65: return Qt::Key_E;
+ case 0x66: return Qt::Key_F;
+ case 0x67: return Qt::Key_G;
+ case 0x68: return Qt::Key_H;
+ case 0x69: return Qt::Key_I;
+ case 0x6a: return Qt::Key_J;
+ case 0x6b: return Qt::Key_K;
+ case 0x6c: return Qt::Key_L;
+ case 0x6d: return Qt::Key_M;
+ case 0x6e: return Qt::Key_N;
+ case 0x6f: return Qt::Key_O;
+ case 0x70: return Qt::Key_P;
+ case 0x71: return Qt::Key_Q;
+ case 0x72: return Qt::Key_R;
+ case 0x73: return Qt::Key_S;
+ case 0x74: return Qt::Key_T;
+ case 0x75: return Qt::Key_U;
+ case 0x76: return Qt::Key_V;
+ case 0x77: return Qt::Key_W;
+ case 0x78: return Qt::Key_X;
+ case 0x79: return Qt::Key_Y;
+ case 0x7a: return Qt::Key_Z;
+ case 0x7b: return Qt::Key_BraceLeft;
+ case 0x7c: return Qt::Key_Bar;
+ case 0x7d: return Qt::Key_BraceRight;
+ case 0x7e: return Qt::Key_AsciiTilde;
+
+ // Latin 1 codes adapted from X: keysymdef.h,v 1.21 94/08/28 16:17:06
+ case 0xa0: return Qt::Key_nobreakspace;
+ case 0xa1: return Qt::Key_exclamdown;
+ case 0xa2: return Qt::Key_cent;
+ case 0xa3: return Qt::Key_sterling;
+ case 0xa4: return Qt::Key_currency;
+ case 0xa5: return Qt::Key_yen;
+ case 0xa6: return Qt::Key_brokenbar;
+ case 0xa7: return Qt::Key_section;
+ case 0xa8: return Qt::Key_diaeresis;
+ case 0xa9: return Qt::Key_copyright;
+ case 0xaa: return Qt::Key_ordfeminine;
+ case 0xab: return Qt::Key_guillemotleft;
+ case 0xac: return Qt::Key_notsign;
+ case 0xad: return Qt::Key_hyphen;
+ case 0xae: return Qt::Key_registered;
+ case 0xaf: return Qt::Key_macron;
+ case 0xb0: return Qt::Key_degree;
+ case 0xb1: return Qt::Key_plusminus;
+ case 0xb2: return Qt::Key_twosuperior;
+ case 0xb3: return Qt::Key_threesuperior;
+ case 0xb4: return Qt::Key_acute;
+ case 0xb5: return Qt::Key_mu;
+ case 0xb6: return Qt::Key_paragraph;
+ case 0xb7: return Qt::Key_periodcentered;
+ case 0xb8: return Qt::Key_cedilla;
+ case 0xb9: return Qt::Key_onesuperior;
+ case 0xba: return Qt::Key_masculine;
+ case 0xbb: return Qt::Key_guillemotright;
+ case 0xbc: return Qt::Key_onequarter;
+ case 0xbd: return Qt::Key_onehalf;
+ case 0xbe: return Qt::Key_threequarters;
+ case 0xbf: return Qt::Key_questiondown;
+ case 0xc0: return Qt::Key_Agrave;
+ case 0xc1: return Qt::Key_Aacute;
+ case 0xc2: return Qt::Key_Acircumflex;
+ case 0xc3: return Qt::Key_Atilde;
+ case 0xc4: return Qt::Key_Adiaeresis;
+ case 0xc5: return Qt::Key_Aring;
+ case 0xc6: return Qt::Key_AE;
+ case 0xc7: return Qt::Key_Ccedilla;
+ case 0xc8: return Qt::Key_Egrave;
+ case 0xc9: return Qt::Key_Eacute;
+ case 0xca: return Qt::Key_Ecircumflex;
+ case 0xcb: return Qt::Key_Ediaeresis;
+ case 0xcc: return Qt::Key_Igrave;
+ case 0xcd: return Qt::Key_Iacute;
+ case 0xce: return Qt::Key_Icircumflex;
+ case 0xcf: return Qt::Key_Idiaeresis;
+ case 0xd0: return Qt::Key_ETH;
+ case 0xd1: return Qt::Key_Ntilde;
+ case 0xd2: return Qt::Key_Ograve;
+ case 0xd3: return Qt::Key_Oacute;
+ case 0xd4: return Qt::Key_Ocircumflex;
+ case 0xd5: return Qt::Key_Otilde;
+ case 0xd6: return Qt::Key_Odiaeresis;
+ case 0xd7: return Qt::Key_multiply;
+ case 0xd8: return Qt::Key_Ooblique;
+ case 0xd9: return Qt::Key_Ugrave;
+ case 0xda: return Qt::Key_Uacute;
+ case 0xdb: return Qt::Key_Ucircumflex;
+ case 0xdc: return Qt::Key_Udiaeresis;
+ case 0xdd: return Qt::Key_Yacute;
+ case 0xde: return Qt::Key_THORN;
+ case 0xdf: return Qt::Key_ssharp;
+ case 0xe5: return Qt::Key_Aring;
+ case 0xe6: return Qt::Key_AE;
+ case 0xf7: return Qt::Key_division;
+ case 0xf8: return Qt::Key_Ooblique;
+ case 0xff: return Qt::Key_ydiaeresis;
+ default: QTEST_ASSERT(false); return Qt::Key(0);
+ }
+}
+
+char HbAutoTest::keyToAscii(Qt::Key key)
+{
+ switch (key) {
+ case Qt::Key_Backspace: return 0x8; //BS
+ case Qt::Key_Tab: return 0x09; // HT
+ case Qt::Key_Backtab: return 0x0b; // VT
+ case Qt::Key_Enter:
+ case Qt::Key_Return: return 0x0d; // CR
+ case Qt::Key_Escape: return 0x1b; // ESC
+ case Qt::Key_Space: return 0x20; // 7 bit printable ASCII
+ case Qt::Key_Exclam: return 0x21;
+ case Qt::Key_QuoteDbl: return 0x22;
+ case Qt::Key_NumberSign: return 0x23;
+ case Qt::Key_Dollar: return 0x24;
+ case Qt::Key_Percent: return 0x25;
+ case Qt::Key_Ampersand: return 0x26;
+ case Qt::Key_Apostrophe: return 0x27;
+ case Qt::Key_ParenLeft: return 0x28;
+ case Qt::Key_ParenRight: return 0x29;
+ case Qt::Key_Asterisk: return 0x2a;
+ case Qt::Key_Plus: return 0x2b;
+ case Qt::Key_Comma: return 0x2c;
+ case Qt::Key_Minus: return 0x2d;
+ case Qt::Key_Period: return 0x2e;
+ case Qt::Key_Slash: return 0x2f;
+ case Qt::Key_0: return 0x30;
+ case Qt::Key_1: return 0x31;
+ case Qt::Key_2: return 0x32;
+ case Qt::Key_3: return 0x33;
+ case Qt::Key_4: return 0x34;
+ case Qt::Key_5: return 0x35;
+ case Qt::Key_6: return 0x36;
+ case Qt::Key_7: return 0x37;
+ case Qt::Key_8: return 0x38;
+ case Qt::Key_9: return 0x39;
+ case Qt::Key_Colon: return 0x3a;
+ case Qt::Key_Semicolon: return 0x3b;
+ case Qt::Key_Less: return 0x3c;
+ case Qt::Key_Equal: return 0x3d;
+ case Qt::Key_Greater: return 0x3e;
+ case Qt::Key_Question: return 0x3f;
+ case Qt::Key_At: return 0x40;
+ case Qt::Key_A: return 0x61; // 0x41 == 'A', 0x61 == 'a'
+ case Qt::Key_B: return 0x62;
+ case Qt::Key_C: return 0x63;
+ case Qt::Key_D: return 0x64;
+ case Qt::Key_E: return 0x65;
+ case Qt::Key_F: return 0x66;
+ case Qt::Key_G: return 0x67;
+ case Qt::Key_H: return 0x68;
+ case Qt::Key_I: return 0x69;
+ case Qt::Key_J: return 0x6a;
+ case Qt::Key_K: return 0x6b;
+ case Qt::Key_L: return 0x6c;
+ case Qt::Key_M: return 0x6d;
+ case Qt::Key_N: return 0x6e;
+ case Qt::Key_O: return 0x6f;
+ case Qt::Key_P: return 0x70;
+ case Qt::Key_Q: return 0x71;
+ case Qt::Key_R: return 0x72;
+ case Qt::Key_S: return 0x73;
+ case Qt::Key_T: return 0x74;
+ case Qt::Key_U: return 0x75;
+ case Qt::Key_V: return 0x76;
+ case Qt::Key_W: return 0x77;
+ case Qt::Key_X: return 0x78;
+ case Qt::Key_Y: return 0x79;
+ case Qt::Key_Z: return 0x7a;
+ case Qt::Key_BracketLeft: return 0x5b;
+ case Qt::Key_Backslash: return 0x5c;
+ case Qt::Key_BracketRight: return 0x5d;
+ case Qt::Key_AsciiCircum: return 0x5e;
+ case Qt::Key_Underscore: return 0x5f;
+ case Qt::Key_QuoteLeft: return 0x60;
+
+ case Qt::Key_BraceLeft: return 0x7b;
+ case Qt::Key_Bar: return 0x7c;
+ case Qt::Key_BraceRight: return 0x7d;
+ case Qt::Key_AsciiTilde: return 0x7e;
+
+ case Qt::Key_Delete: return 0;
+ case Qt::Key_Insert: return 0; // = 0x1006,
+ case Qt::Key_Pause: return 0; // = 0x1008,
+ case Qt::Key_Print: return 0; // = 0x1009,
+ case Qt::Key_SysReq: return 0; // = 0x100a,
+
+ case Qt::Key_Clear: return 0; // = 0x100b,
+
+ case Qt::Key_Home: return 0; // = 0x1010, // cursor movement
+ case Qt::Key_End: return 0; // = 0x1011,
+ case Qt::Key_Left: return 0; // = 0x1012,
+ case Qt::Key_Up: return 0; // = 0x1013,
+ case Qt::Key_Right: return 0; // = 0x1014,
+ case Qt::Key_Down: return 0; // = 0x1015,
+ case Qt::Key_PageUp: return 0; // = 0x1016,
+ case Qt::Key_PageDown: return 0; // = 0x1017,
+ case Qt::Key_Shift: return 0; // = 0x1020, // modifiers
+ case Qt::Key_Control: return 0; // = 0x1021,
+ case Qt::Key_Meta: return 0; // = 0x1022,
+ case Qt::Key_Alt: return 0; // = 0x1023,
+ case Qt::Key_CapsLock: return 0; // = 0x1024,
+ case Qt::Key_NumLock: return 0; // = 0x1025,
+ case Qt::Key_ScrollLock: return 0; // = 0x1026,
+ case Qt::Key_F1: return 0; // = 0x1030, // function keys
+ case Qt::Key_F2: return 0; // = 0x1031,
+ case Qt::Key_F3: return 0; // = 0x1032,
+ case Qt::Key_F4: return 0; // = 0x1033,
+ case Qt::Key_F5: return 0; // = 0x1034,
+ case Qt::Key_F6: return 0; // = 0x1035,
+ case Qt::Key_F7: return 0; // = 0x1036,
+ case Qt::Key_F8: return 0; // = 0x1037,
+ case Qt::Key_F9: return 0; // = 0x1038,
+ case Qt::Key_F10: return 0; // = 0x1039,
+ case Qt::Key_F11: return 0; // = 0x103a,
+ case Qt::Key_F12: return 0; // = 0x103b,
+ case Qt::Key_F13: return 0; // = 0x103c,
+ case Qt::Key_F14: return 0; // = 0x103d,
+ case Qt::Key_F15: return 0; // = 0x103e,
+ case Qt::Key_F16: return 0; // = 0x103f,
+ case Qt::Key_F17: return 0; // = 0x1040,
+ case Qt::Key_F18: return 0; // = 0x1041,
+ case Qt::Key_F19: return 0; // = 0x1042,
+ case Qt::Key_F20: return 0; // = 0x1043,
+ case Qt::Key_F21: return 0; // = 0x1044,
+ case Qt::Key_F22: return 0; // = 0x1045,
+ case Qt::Key_F23: return 0; // = 0x1046,
+ case Qt::Key_F24: return 0; // = 0x1047,
+ case Qt::Key_F25: return 0; // = 0x1048, // F25 .. F35 only on X11
+ case Qt::Key_F26: return 0; // = 0x1049,
+ case Qt::Key_F27: return 0; // = 0x104a,
+ case Qt::Key_F28: return 0; // = 0x104b,
+ case Qt::Key_F29: return 0; // = 0x104c,
+ case Qt::Key_F30: return 0; // = 0x104d,
+ case Qt::Key_F31: return 0; // = 0x104e,
+ case Qt::Key_F32: return 0; // = 0x104f,
+ case Qt::Key_F33: return 0; // = 0x1050,
+ case Qt::Key_F34: return 0; // = 0x1051,
+ case Qt::Key_F35: return 0; // = 0x1052,
+ case Qt::Key_Super_L: return 0; // = 0x1053, // extra keys
+ case Qt::Key_Super_R: return 0; // = 0x1054,
+ case Qt::Key_Menu: return 0; // = 0x1055,
+ case Qt::Key_Hyper_L: return 0; // = 0x1056,
+ case Qt::Key_Hyper_R: return 0; // = 0x1057,
+ case Qt::Key_Help: return 0; // = 0x1058,
+ case Qt::Key_Direction_L: return 0; // = 0x1059,
+ case Qt::Key_Direction_R: return 0; // = 0x1060,
+
+ // Latin 1 codes adapted from X: keysymdef.h,v 1.21 94/08/28 16:17:06
+ case Qt::Key_nobreakspace: return char(0xa0);
+ case Qt::Key_exclamdown: return char(0xa1);
+ case Qt::Key_cent: return char(0xa2);
+ case Qt::Key_sterling: return char(0xa3);
+ case Qt::Key_currency: return char(0xa4);
+ case Qt::Key_yen: return char(0xa5);
+ case Qt::Key_brokenbar: return char(0xa6);
+ case Qt::Key_section: return char(0xa7);
+ case Qt::Key_diaeresis: return char(0xa8);
+ case Qt::Key_copyright: return char(0xa9);
+ case Qt::Key_ordfeminine: return char(0xaa);
+ case Qt::Key_guillemotleft: return char(0xab); // left angle quotation mar
+ case Qt::Key_notsign: return char(0xac);
+ case Qt::Key_hyphen: return char(0xad);
+ case Qt::Key_registered: return char(0xae);
+ case Qt::Key_macron: return char(0xaf);
+ case Qt::Key_degree: return char(0xb0);
+ case Qt::Key_plusminus: return char(0xb1);
+ case Qt::Key_twosuperior: return char(0xb2);
+ case Qt::Key_threesuperior: return char(0xb3);
+ case Qt::Key_acute: return char(0xb4);
+ case Qt::Key_mu: return char(0xb5);
+ case Qt::Key_paragraph: return char(0xb6);
+ case Qt::Key_periodcentered: return char(0xb7);
+ case Qt::Key_cedilla: return char(0xb8);
+ case Qt::Key_onesuperior: return char(0xb9);
+ case Qt::Key_masculine: return char(0xba);
+ case Qt::Key_guillemotright: return char(0xbb); // right angle quotation mar
+ case Qt::Key_onequarter: return char(0xbc);
+ case Qt::Key_onehalf: return char(0xbd);
+ case Qt::Key_threequarters: return char(0xbe);
+ case Qt::Key_questiondown: return char(0xbf);
+ case Qt::Key_Agrave: return char(0xc0);
+ case Qt::Key_Aacute: return char(0xc1);
+ case Qt::Key_Acircumflex: return char(0xc2);
+ case Qt::Key_Atilde: return char(0xc3);
+ case Qt::Key_Adiaeresis: return char(0xc4);
+ case Qt::Key_Aring: return char(0xe5);
+ case Qt::Key_AE: return char(0xe6);
+ case Qt::Key_Ccedilla: return char(0xc7);
+ case Qt::Key_Egrave: return char(0xc8);
+ case Qt::Key_Eacute: return char(0xc9);
+ case Qt::Key_Ecircumflex: return char(0xca);
+ case Qt::Key_Ediaeresis: return char(0xcb);
+ case Qt::Key_Igrave: return char(0xcc);
+ case Qt::Key_Iacute: return char(0xcd);
+ case Qt::Key_Icircumflex: return char(0xce);
+ case Qt::Key_Idiaeresis: return char(0xcf);
+ case Qt::Key_ETH: return char(0xd0);
+ case Qt::Key_Ntilde: return char(0xd1);
+ case Qt::Key_Ograve: return char(0xd2);
+ case Qt::Key_Oacute: return char(0xd3);
+ case Qt::Key_Ocircumflex: return char(0xd4);
+ case Qt::Key_Otilde: return char(0xd5);
+ case Qt::Key_Odiaeresis: return char(0xd6);
+ case Qt::Key_multiply: return char(0xd7);
+ case Qt::Key_Ooblique: return char(0xf8);
+ case Qt::Key_Ugrave: return char(0xd9);
+ case Qt::Key_Uacute: return char(0xda);
+ case Qt::Key_Ucircumflex: return char(0xdb);
+ case Qt::Key_Udiaeresis: return char(0xdc);
+ case Qt::Key_Yacute: return char(0xdd);
+ case Qt::Key_THORN: return char(0xde);
+ case Qt::Key_ssharp: return char(0xdf);
+ case Qt::Key_division: return char(0xf7);
+ case Qt::Key_ydiaeresis: return char(0xff);
+
+ // multimedia/internet keys - ignored by default - see QKeyEvent c'tor
+
+ case Qt::Key_Back : return 0; // = 0x1061,
+ case Qt::Key_Forward : return 0; // = 0x1062,
+ case Qt::Key_Stop : return 0; // = 0x1063,
+ case Qt::Key_Refresh : return 0; // = 0x1064,
+
+ case Qt::Key_VolumeDown: return 0; // = 0x1070,
+ case Qt::Key_VolumeMute : return 0; // = 0x1071,
+ case Qt::Key_VolumeUp: return 0; // = 0x1072,
+ case Qt::Key_BassBoost: return 0; // = 0x1073,
+ case Qt::Key_BassUp: return 0; // = 0x1074,
+ case Qt::Key_BassDown: return 0; // = 0x1075,
+ case Qt::Key_TrebleUp: return 0; // = 0x1076,
+ case Qt::Key_TrebleDown: return 0; // = 0x1077,
+
+ case Qt::Key_MediaPlay : return 0; // = 0x1080,
+ case Qt::Key_MediaStop : return 0; // = 0x1081,
+ case Qt::Key_MediaPrevious : return 0; // = 0x1082,
+ case Qt::Key_MediaNext : return 0; // = 0x1083,
+ case Qt::Key_MediaRecord: return 0; // = 0x1084,
+
+ case Qt::Key_HomePage : return 0; // = 0x1090,
+ case Qt::Key_Favorites : return 0; // = 0x1091,
+ case Qt::Key_Search : return 0; // = 0x1092,
+ case Qt::Key_Standby: return 0; // = 0x1093,
+ case Qt::Key_OpenUrl: return 0; // = 0x1094,
+
+ case Qt::Key_LaunchMail : return 0; // = 0x10a0,
+ case Qt::Key_LaunchMedia: return 0; // = 0x10a1,
+ case Qt::Key_Launch0 : return 0; // = 0x10a2,
+ case Qt::Key_Launch1 : return 0; // = 0x10a3,
+ case Qt::Key_Launch2 : return 0; // = 0x10a4,
+ case Qt::Key_Launch3 : return 0; // = 0x10a5,
+ case Qt::Key_Launch4 : return 0; // = 0x10a6,
+ case Qt::Key_Launch5 : return 0; // = 0x10a7,
+ case Qt::Key_Launch6 : return 0; // = 0x10a8,
+ case Qt::Key_Launch7 : return 0; // = 0x10a9,
+ case Qt::Key_Launch8 : return 0; // = 0x10aa,
+ case Qt::Key_Launch9 : return 0; // = 0x10ab,
+ case Qt::Key_LaunchA : return 0; // = 0x10ac,
+ case Qt::Key_LaunchB : return 0; // = 0x10ad,
+ case Qt::Key_LaunchC : return 0; // = 0x10ae,
+ case Qt::Key_LaunchD : return 0; // = 0x10af,
+ case Qt::Key_LaunchE : return 0; // = 0x10b0,
+ case Qt::Key_LaunchF : return 0; // = 0x10b1,
+
+ default: QTEST_ASSERT(false); return 0;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/unit/hbautotest.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,276 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Container for pan (drag) gesture -related data and logic.
+*
+*/
+
+#ifndef HBAUTOTEST_H
+#define HBAUTOTEST_H
+
+#include <hbnamespace.h>
+#include <hbmainwindow.h>
+#include <QtTest/QtTest>
+
+class HbMainWindow;
+class HbWidget;
+class HbAutoTestMainWindow;
+class HbAutoTest;
+class HbAutoTestMouseEvent;
+/*
+INSTRUCTIONS:
+The class HbAutoTest is meant to be used with Orbit applications auto testing instead of GUI testing APIs of QTestLib.
+
+The functions of this class is to used similarily to the related QTestLib functions.
+
+Use HbAutoTestMainWindow (defined below) instead of HbMainWindow to enble filtering.
+Filterin filters out UI events that are not sent by function defined in HbAutoTest class.
+
+*/
+
+class HbAutoTestMouseEvent : public QMouseEvent
+{
+public:
+ HbAutoTestMouseEvent(Type type, const QPoint & pos, const QPoint & globalPos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers )
+ : QMouseEvent(type,pos,globalPos,button,buttons,modifiers){}
+};
+
+class HbAutoTestKeyEvent : public QKeyEvent
+{
+public:
+ HbAutoTestKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, const QString& text = QString(),
+ bool autorep = false, ushort count = 1 )
+ : QKeyEvent(type, key, modifiers, text, autorep, count){}
+};
+
+class HbAutoTest
+{
+public:
+
+ static void mouseMove (HbAutoTestMainWindow *window, HbWidget *widget, QPointF pos = QPointF(), int delay = -1 );
+ static void mousePress (HbAutoTestMainWindow *window, HbWidget *widget, QPointF pos = QPointF(), int delay = -1);
+ static void mouseRelease (HbAutoTestMainWindow *window, HbWidget *widget, QPointF pos = QPointF(), int delay = -1);
+ static void mouseClick (HbAutoTestMainWindow *window, const HbWidget *widget, QPointF pos = QPointF(), int delay = -1);
+
+private:
+ static void drag(HbAutoTestMainWindow *window, QPointF targetPoint);
+ static QPointF middlePointOfWidget( const HbWidget* widget);
+
+ static bool pointerPressed;
+ static QPointF pressPoint;
+
+//Key event Part: copy-pasted from QTestLib and modified to support HbAutoTestKeyEvent to enable filtering.
+//see HbAutoTestMainWindow below.
+public:
+
+ static Qt::Key asciiToKey(char ascii);
+ static char keyToAscii(Qt::Key key);
+
+ static void simulateEvent(QWidget *widget, bool press, int code,
+ Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1);
+
+ static void sendKeyEvent(QTest::KeyAction action, QWidget *widget, Qt::Key code,
+ QString text, Qt::KeyboardModifiers modifier, int delay=-1);
+
+ static void sendKeyEvent(QTest::KeyAction action, QWidget *widget, Qt::Key code,
+ char ascii, Qt::KeyboardModifiers modifier, int delay=-1);
+
+ static void keyEvent(QTest::KeyAction action, QWidget *widget, char ascii,
+ Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+
+ static void keyEvent(QTest::KeyAction action, QWidget *widget, Qt::Key key,
+ Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+
+ static void keyClicks(QWidget *widget, const QString &sequence,
+ Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+
+ static void keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+
+ static void keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+
+ static void keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+
+ static void keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+
+ static void keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+
+ static void keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1);
+};
+
+class HbTestEvent
+{
+public:
+ virtual void simulate(QWidget *w) = 0;
+ virtual HbTestEvent *clone() const = 0;
+
+ virtual ~HbTestEvent() {}
+};
+
+class HbTestKeyEvent: public HbTestEvent
+{
+public:
+ inline HbTestKeyEvent(QTest::KeyAction action, Qt::Key key, Qt::KeyboardModifiers modifiers, int delay)
+ : _action(action), _delay(delay), _modifiers(modifiers), _ascii(0), _key(key) {}
+ inline HbTestKeyEvent(QTest::KeyAction action, char ascii, Qt::KeyboardModifiers modifiers, int delay)
+ : _action(action), _delay(delay), _modifiers(modifiers),
+ _ascii(ascii), _key(Qt::Key_unknown) {}
+ inline HbTestEvent *clone() const { return new HbTestKeyEvent(*this); }
+
+ inline void simulate(QWidget *w)
+ {
+ if (_ascii == 0)
+ HbAutoTest::keyEvent(_action, w, _key, _modifiers, _delay);
+ else
+ HbAutoTest::keyEvent(_action, w, _ascii, _modifiers, _delay);
+ }
+
+protected:
+ QTest::KeyAction _action;
+ int _delay;
+ Qt::KeyboardModifiers _modifiers;
+ char _ascii;
+ Qt::Key _key;
+};
+
+class HbTestKeyClicksEvent: public HbTestEvent
+{
+public:
+ inline HbTestKeyClicksEvent(const QString &keys, Qt::KeyboardModifiers modifiers, int delay)
+ : _keys(keys), _modifiers(modifiers), _delay(delay) {}
+ inline HbTestEvent *clone() const { return new HbTestKeyClicksEvent(*this); }
+
+ inline void simulate(QWidget *w)
+ {
+ HbAutoTest::keyClicks(w, _keys, _modifiers, _delay);
+ }
+
+private:
+ QString _keys;
+ Qt::KeyboardModifiers _modifiers;
+ int _delay;
+};
+
+class HbTestDelayEvent: public HbTestEvent
+{
+public:
+ inline HbTestDelayEvent(int msecs): _delay(msecs) {}
+ inline HbTestEvent *clone() const { return new HbTestDelayEvent(*this); }
+
+ inline void simulate(QWidget * /*w*/) { QTest::qWait(_delay); }
+
+private:
+ int _delay;
+};
+
+class HbTestEventList: public QList<HbTestEvent *>
+{
+public:
+ inline HbTestEventList() {}
+ inline HbTestEventList(const HbTestEventList &other): QList<HbTestEvent *>()
+ { for (int i = 0; i < other.count(); ++i) append(other.at(i)->clone()); }
+ inline ~HbTestEventList()
+ { clear(); }
+ inline void clear()
+ { qDeleteAll(*this); QList<HbTestEvent *>::clear(); }
+
+ inline void addKeyClick(Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { addKeyEvent(QTest::Click, qtKey, modifiers, msecs); }
+ inline void addKeyPress(Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { addKeyEvent(QTest::Press, qtKey, modifiers, msecs); }
+ inline void addKeyRelease(Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { addKeyEvent(QTest::Release, qtKey, modifiers, msecs); }
+ inline void addKeyEvent(QTest::KeyAction action, Qt::Key qtKey,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { append(new HbTestKeyEvent(action, qtKey, modifiers, msecs)); }
+
+ inline void addKeyClick(char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { addKeyEvent(QTest::Click, ascii, modifiers, msecs); }
+ inline void addKeyPress(char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { addKeyEvent(QTest::Press, ascii, modifiers, msecs); }
+ inline void addKeyRelease(char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { addKeyEvent(QTest::Release, ascii, modifiers, msecs); }
+ inline void addKeyClicks(const QString &keys, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { append(new HbTestKeyClicksEvent(keys, modifiers, msecs)); }
+ inline void addKeyEvent(QTest::KeyAction action, char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ { append(new HbTestKeyEvent(action, ascii, modifiers, msecs)); }
+
+ inline void addDelay(int msecs)
+ { append(new HbTestDelayEvent(msecs)); }
+
+ inline void simulate(QWidget *w)
+ {
+ for (int i = 0; i < count(); ++i)
+ at(i)->simulate(w);
+ }
+};
+
+class HbAutoTestMainWindow : public HbMainWindow
+{
+public:
+ HbAutoTestMainWindow() : HbMainWindow() {}
+
+ void mousePressEvent(QMouseEvent *event)
+ {
+ if ( dynamic_cast<HbAutoTestMouseEvent *>(event) ) {
+ HbMainWindow::mousePressEvent(event);
+ } else {
+ ;//Do nothing
+ }
+ }
+
+ void mouseMoveEvent(QMouseEvent *event)
+ {
+ if ( dynamic_cast<HbAutoTestMouseEvent *>(event) ) {
+ HbMainWindow::mouseMoveEvent(event);
+ } else {
+ ;//Do nothing
+ }
+ }
+
+ void mouseReleaseEvent(QMouseEvent *event)
+ {
+ if ( dynamic_cast<HbAutoTestMouseEvent *>(event) ) {
+ HbMainWindow::mouseReleaseEvent(event);
+ } else {
+ ;//Do nothing
+ }
+ }
+
+ void keyPressEvent(QKeyEvent *event)
+ {
+ if ( dynamic_cast<HbAutoTestKeyEvent *>(event) ) {
+ HbMainWindow::keyPressEvent(event);
+ } else {
+ ;//Do nothing
+ }
+ }
+ void keyReleaseEvent(QKeyEvent *event)
+ {
+ if ( dynamic_cast<HbAutoTestKeyEvent *>(event) ) {
+ HbMainWindow::keyReleaseEvent(event);
+ } else {
+ ;//Do nothing
+ }
+ }
+
+ void mouseDoubleClickEvent(QMouseEvent *event)
+ {
+ Q_UNUSED(event);
+ //Just ignore, not supported in Orbit
+ }
+};
+
+
+Q_DECLARE_METATYPE(HbTestEventList)
+#endif //HBAUTOTEST_H
+
Binary file ganeswidgets/tsrc/unit/startupHG.jpg has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/unit/unittest_ganeswidgets.cpp Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,1848 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Container for pan (drag) gesture -related data and logic.
+*
+*/
+
+#include <QtTest/QtTest>
+#include <QMetaType>
+#include <QModelIndex>
+#include "hbautotest.h"
+#include <hbapplication.h>
+#include <hbmainwindow.h>
+#include <hbscrollbar>
+#include <hgwidgets/hgwidgets.h>
+#include <hgwidgets/hggrid.h>
+#include <hgwidgets/hgmediawall.h>
+
+Q_DECLARE_METATYPE(QItemSelection)
+Q_DECLARE_METATYPE(QModelIndex)
+
+static const QPointF grid_portrait_pos0(70, 30);
+static const QPointF grid_portrait_pos1(180, 30);
+static const QPointF grid_portrait_pos2(280, 30);
+static const QPointF grid_portrait_pos3(70, 120);
+static const QPointF grid_portrait_pos4(180, 120);
+static const QPointF grid_portrait_pos5(280, 120);
+static const QPointF grid_portrait_pos6(70, 200);
+static const QPointF grid_portrait_pos7(180, 200);
+static const QPointF grid_portrait_pos8(280, 200);
+
+class TestGanesWidgets : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ TestGanesWidgets();
+ virtual ~TestGanesWidgets();
+
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void test_panGridLandscape();
+ void test_panGridPortrait();
+ void test_panCoverFlowLandscape();
+ void test_panCoverFlowPortrait();
+ void test_scrollbarGridLandscape();
+ void test_scrollbarGridPortrait();
+ void test_scrollbarCoverFlowLandscape();
+ void test_scrollbarCoverFlowPortrait();
+ void test_addRemoveItemsGrid();
+ void test_addRemoveItemsCoverflow();
+ void test_updateData();
+ void test_tap();
+ void test_currentItemCoverflow();
+ void test_currentItemGrid();
+ void test_selectionMode();
+ void test_selectionModel();
+ void test_scrollTo();
+ void test_addItemsCoverFlow();
+ void test_removeItemsCoverFlow();
+ void test_moveItemsCoverFlow();
+
+private:
+
+ void pan( Qt::Orientation, TBool begin );
+
+private:
+
+ HbMainWindow* mWindow;
+ HgWidget* mWidget;
+
+};
+
+class TestModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+
+ explicit TestModel(QList<QModelIndex> *requestedIndexes = 0);
+ virtual ~TestModel();
+
+ int rowCount(const QModelIndex &parent=QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
+
+ void generateItems(int count);
+ void appendItem();
+ void insertItems(int index, int count=1);
+ void removeItems(int index, int count=1);
+ void moveItems(int from, int to, int count=1);
+ void changeItem(int index);
+ void reset();
+
+ QImage mImage;
+ QStringList mItems;
+ bool mValidData;
+
+ QList<QModelIndex> *mRequestedIndexes;
+};
+
+TestModel::TestModel(QList<QModelIndex> *requestedIndexes) :
+ mValidData(true),
+ mRequestedIndexes(requestedIndexes)
+{
+ mImage = QImage(":icons/startupHG.jpg");
+}
+
+TestModel::~TestModel()
+{
+
+}
+
+void TestModel::generateItems(int count)
+{
+ for (int i=0; i<count; i++) {
+ mItems.append(QString("Item %0").arg(i));
+ }
+}
+
+void TestModel::appendItem()
+{
+ insertItems(mItems.count(),1);
+}
+
+void TestModel::insertItems(int index, int count)
+{
+ beginInsertRows(QModelIndex(), index, index+count-1); // Inclusive
+ int end = index+count;
+ for ( ;index<end; index++) {
+ mItems.insert(index, QString("Item %0").arg(mItems.count()));
+ }
+ endInsertRows();
+}
+
+void TestModel::removeItems(int index, int count)
+{
+ if (index >= 0 && index < mItems.count()) {
+ beginRemoveRows(QModelIndex(), index, index+count-1); // Inclusive
+ int end = index+count;
+ for (; index<end; index++) {
+ mItems.removeAt(index);
+ }
+ endRemoveRows();
+ }
+}
+
+void TestModel::moveItems(int from, int to, int count)
+{
+ if (beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to)) { // Inclusive
+ // No need to actually move rows here
+ endMoveRows();
+ }
+ else {
+ qDebug() << "Cannot move" << from << "-" << from+count-1 << "to" << to;
+ }
+}
+
+void TestModel::reset()
+{
+ beginResetModel();
+ mItems.clear();
+ endResetModel();
+}
+
+
+void TestModel::changeItem(int index)
+{
+ if ( index >= 0 && index < mItems.count() ) {
+ QModelIndex modelIndex = QAbstractItemModel::createIndex(index, 0);
+ emit dataChanged(modelIndex, modelIndex);
+ }
+}
+
+int TestModel::rowCount(const QModelIndex &parent) const
+{
+ return mItems.count();
+}
+
+QVariant TestModel::data(const QModelIndex &index, int role) const
+{
+ QVariant returnValue;
+
+ if( !mValidData)
+ return returnValue;
+
+ int row = index.row();
+
+ switch ( role )
+ {
+ case Qt::DisplayRole:
+ {
+ QStringList texts;
+ QString text("Primary %0");
+ text.arg(row);
+ texts << text;
+ text = "Secondary %0";
+ text.arg(row);
+ texts << text;
+ returnValue = texts;
+ break;
+ }
+ case Qt::DecorationRole:
+ {
+ returnValue = mImage;
+ if (mRequestedIndexes && !mRequestedIndexes->contains(index)) {
+ mRequestedIndexes->append(index);
+ qSort(*mRequestedIndexes);
+ }
+ break;
+ }
+ default:
+ break;
+
+ }
+
+ return returnValue;
+}
+
+
+TestGanesWidgets::TestGanesWidgets()
+{
+}
+
+TestGanesWidgets::~TestGanesWidgets()
+{
+
+}
+
+void TestGanesWidgets::initTestCase()
+{
+
+}
+
+void TestGanesWidgets::cleanupTestCase()
+{
+
+}
+
+void TestGanesWidgets::init()
+{
+
+}
+
+void TestGanesWidgets::cleanup()
+{
+
+}
+
+void TestGanesWidgets::pan( Qt::Orientation orientation, TBool begin )
+{
+ QPointF start(100,100);
+ QPointF move;
+ QPointF end;
+ if (orientation==Qt::Horizontal){
+ move = QPointF(100,0);
+ }
+ else {
+ move = QPointF(0,100);
+ }
+
+ if( begin )
+ end = start - move;
+ else
+ end = start + move;
+
+ HbAutoTest::mousePress( (HbAutoTestMainWindow*)mWindow, mWidget, start, -1 );
+ HbAutoTest::mouseMove( (HbAutoTestMainWindow*)mWindow, mWidget, end, -1 );
+ HbAutoTest::mouseRelease( (HbAutoTestMainWindow*)mWindow, mWidget, end, 100 );
+}
+
+void TestGanesWidgets::test_panGridLandscape()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgGrid(Qt::Horizontal);
+ TestModel model;
+ model.generateItems(30);
+ mWindow->addView( mWidget );
+ QVERIFY( mWidget->model() == 0 );
+ mWidget->setModel( &model );
+ QVERIFY( &model == mWidget->model() );
+
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Horizontal, true );
+
+ model.reset();
+ model.generateItems(5);
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Horizontal, false );
+
+ model.reset();
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Horizontal, true );
+
+ QTest::qWait(4000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_panGridPortrait()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgGrid(Qt::Vertical );
+ TestModel model;
+ model.generateItems(30);
+ mWindow->addView( mWidget );
+ QVERIFY( mWidget->model() == 0 );
+ mWidget->setModel( &model );
+ QVERIFY( &model == mWidget->model() );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Vertical, true );
+
+ model.reset();
+ model.generateItems(5);
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Vertical, false );
+
+ model.reset();
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Vertical, true );
+
+ QTest::qWait(4000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_panCoverFlowLandscape()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(30);
+ mWindow->addView( mWidget );
+ QVERIFY( mWidget->model() == 0 );
+ mWidget->setModel( &model );
+ QVERIFY( &model == mWidget->model() );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Horizontal, true );
+
+ model.reset();
+ model.generateItems(5);
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Horizontal, false );
+
+ model.reset();
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Horizontal, true );
+
+ QTest::qWait(4000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_panCoverFlowPortrait()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(30);
+ mWindow->addView( mWidget );
+ QVERIFY( mWidget->model() == 0 );
+ mWidget->setModel( &model );
+ QVERIFY( &model == mWidget->model() );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Vertical, true );
+
+ model.reset();
+ model.generateItems(5);
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Vertical, false );
+
+ model.reset();
+
+ QTest::qWait( 2000 );
+
+ pan( Qt::Vertical, true );
+
+ QTest::qWait(4000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_scrollbarGridLandscape()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(200);
+ mWindow->addView( mWidget );
+ mWidget->setModel( &model );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAutoHide);
+
+ mWidget->setScrollBarPolicy(HgWidget::ScrollBarAlwaysOn);
+ mWidget->scrollBar()->setInteractive(true);
+ QRectF rect = mWidget->scrollBar()->rect();
+
+ QTest::qWait(1000);
+
+ QPointF move( 20,0 );
+
+ HbAutoTest::mousePress( (HbAutoTestMainWindow*)mWindow, mWidget->scrollBar(), rect.topLeft()+move, -1 );
+ HbAutoTest::mouseMove( (HbAutoTestMainWindow*)mWindow, mWidget->scrollBar(), rect.topRight()-move, 50 );
+ HbAutoTest::mouseRelease( (HbAutoTestMainWindow*)mWindow, mWidget->scrollBar(), rect.topRight()-move, 100 );
+
+ QTest::qWait(3000);
+
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOn );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAlwaysOn);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOff );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAlwaysOff);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAutoHide );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAutoHide);
+
+ QVERIFY(mWidget->scrollBar() != 0);
+ HbScrollBar* scrollBar = new HbScrollBar();
+ mWidget->setScrollBar(scrollBar);
+ QVERIFY(mWidget->scrollBar()==scrollBar);
+ mWidget->setScrollBar(0);
+ QVERIFY(mWidget->scrollBar()!= 0);
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+
+}
+
+void TestGanesWidgets::test_scrollbarGridPortrait()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(200);
+ mWindow->addView( mWidget );
+ mWidget->setModel( &model );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAutoHide);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOn );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAlwaysOn);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOff );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAlwaysOff);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAutoHide );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAutoHide);
+
+ QVERIFY(mWidget->scrollBar() != 0);
+ HbScrollBar* scrollBar = new HbScrollBar();
+ mWidget->setScrollBar(scrollBar);
+ QVERIFY(mWidget->scrollBar()==scrollBar);
+ mWidget->setScrollBar(0);
+ QVERIFY(mWidget->scrollBar()!= 0);
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+
+}
+
+void TestGanesWidgets::test_scrollbarCoverFlowLandscape()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(200);
+ mWindow->addView( mWidget );
+ mWidget->setModel( &model );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAutoHide);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOn );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAlwaysOn);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOff );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAlwaysOff);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAutoHide );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAutoHide);
+
+ QVERIFY(mWidget->scrollBar() != 0);
+ HbScrollBar* scrollBar = new HbScrollBar();
+ mWidget->setScrollBar(scrollBar);
+ QVERIFY(mWidget->scrollBar()==scrollBar);
+ mWidget->setScrollBar(0);
+ QVERIFY(mWidget->scrollBar()!= 0);
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+
+}
+
+void TestGanesWidgets::test_scrollbarCoverFlowPortrait()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(200);
+ mWindow->addView( mWidget );
+ mWidget->setModel( &model );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAutoHide);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOn );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAlwaysOn);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOff );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAlwaysOff);
+ mWidget->setScrollBarPolicy( HgWidget::ScrollBarAutoHide );
+ QVERIFY(mWidget->scrollBarPolicy() == HgWidget::ScrollBarAutoHide);
+
+ QVERIFY(mWidget->scrollBar() != 0);
+ HbScrollBar* scrollBar = new HbScrollBar();
+ mWidget->setScrollBar(scrollBar);
+ QVERIFY(mWidget->scrollBar()==scrollBar);
+ mWidget->setScrollBar(0);
+ QVERIFY(mWidget->scrollBar()!= 0);
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+
+}
+
+void TestGanesWidgets::test_addRemoveItemsGrid()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(2);
+ mWindow->addView( mWidget );
+ mWidget->setModel( &model );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ model.appendItem();
+ model.appendItem();
+ model.removeItems(0);
+ model.removeItems(3);
+ model.removeItems(0);
+ model.removeItems(0);
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_addRemoveItemsCoverflow()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(2);
+ mWindow->addView( mWidget );
+ mWidget->setModel( &model );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ model.appendItem();
+ model.appendItem();
+ model.removeItems(0);
+ model.removeItems(3);
+ model.removeItems(0);
+ model.removeItems(0);
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_tap()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgMediawall();
+ TestModel model;
+ model.generateItems(50);
+ mWindow->addView( mWidget );
+ mWidget->setModel( &model );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ QSignalSpy stateSpy( mWidget, SIGNAL( activated(QModelIndex) ) );
+ QSignalSpy stateSpy2( mWidget, SIGNAL( longPressed(QModelIndex) ) );
+
+ QPointF pos(100,100);
+ HbAutoTest::mouseClick( (HbAutoTestMainWindow*)mWindow, mWidget, pos, 100 );
+
+ QTest::qWait(1000);
+
+ // Generating gestures doesn't work so enable this condition later.
+// QCOMPARE(stateSpy.count(),1);
+
+ QVERIFY(!mWidget->longPressEnabled());
+ mWidget->setLongPressEnabled(true);
+ QVERIFY(mWidget->longPressEnabled());
+
+ HbAutoTest::mousePress( (HbAutoTestMainWindow*)mWindow, mWidget, pos, -1 );
+ HbAutoTest::mouseRelease( (HbAutoTestMainWindow*)mWindow, mWidget, pos, 2000 );
+
+ // Generating gestures doesn't work so enable this condition later.
+// QCOMPARE( stateSpy2.count(),1 );
+
+ mWidget->setLongPressEnabled(false);
+ QVERIFY(!mWidget->longPressEnabled());
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_updateData()
+{
+ mWindow = new HbMainWindow;
+ mWidget = new HgGrid( Qt::Vertical );
+ TestModel model;
+ model.generateItems(50);
+ mWindow->addView( mWidget );
+ model.mValidData = false;
+ mWidget->setModel( &model );
+ mWindow->show();
+
+ QTest::qWait( 2000 );
+
+ model.mValidData = true;
+ for(int i=0;i<50;i++){
+ model.changeItem(i);
+ }
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_currentItemCoverflow()
+{
+ const QPointF pos1(160, 300);
+ const QPointF pos2(300, 300);
+ const QPointF pos3(20, 300);
+
+ mWindow = new HbMainWindow;
+ mWindow->viewport()->grabGesture(Qt::PanGesture);
+ mWindow->viewport()->grabGesture(Qt::TapGesture); // Add TapAndHoldGesture once it's working
+ mWidget = new HgMediawall();
+
+ TestModel model;
+ model.generateItems(50);
+ mWindow->addView(mWidget);
+ mWidget->setModel(&model);
+ mWindow->show();
+
+ QVERIFY(mWidget->selectionModel());
+ qRegisterMetaType<QModelIndex>("QModelIndex");
+ QSignalSpy currentItemSpy(mWidget->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)));
+
+ QTest::qWait(2000);
+
+ QVERIFY(mWidget->currentIndex() == model.index(0, 0));
+
+ mWidget->setCurrentIndex(model.index(7, 0));
+ QVERIFY(mWidget->currentIndex() == model.index(7, 0));
+
+ mWidget->setCurrentIndex(QModelIndex());
+ QVERIFY(!mWidget->currentIndex().isValid());
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, pos1, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(0, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(0, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, pos2, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(1, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(1, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, pos2, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(2, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(2, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, pos2, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(3, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(3, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, pos3, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(2, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(2, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, pos3, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(1, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(1, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, pos3, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(0, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(0, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, pos3, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(0, 0));
+ QVERIFY(currentItemSpy.count() == 0);
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_currentItemGrid()
+{
+ mWindow = new HbMainWindow;
+ mWindow->viewport()->grabGesture(Qt::PanGesture);
+ mWindow->viewport()->grabGesture(Qt::TapGesture); // Add TapAndHoldGesture once it's working
+ mWidget = new HgGrid( Qt::Vertical);
+
+ TestModel model;
+ model.generateItems(50);
+ mWindow->addView(mWidget);
+ mWidget->setModel(&model);
+ mWindow->show();
+
+ QVERIFY(mWidget->selectionModel());
+ qRegisterMetaType<QModelIndex>("QModelIndex");
+ QSignalSpy currentItemSpy(mWidget->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)));
+
+ QTest::qWait(2000);
+
+ QVERIFY(mWidget->currentIndex() == model.index(0, 0));
+
+ mWidget->setCurrentIndex(model.index(7, 0));
+ QVERIFY(mWidget->currentIndex() == model.index(7, 0));
+
+ mWidget->setCurrentIndex(QModelIndex());
+ QVERIFY(!mWidget->currentIndex().isValid());
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos1, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(1, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(1, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos4, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(4, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(4, 0));
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos4, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(4, 0));
+ QVERIFY(currentItemSpy.count() == 0);
+
+ currentItemSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos8, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->currentIndex() == model.index(8, 0));
+ QVERIFY(currentItemSpy.count() == 1);
+ QVERIFY(currentItemSpy.at(0).count() > 0);
+ QVERIFY(qvariant_cast<QModelIndex>(currentItemSpy.at(0).at(0)) == model.index(8, 0));
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_selectionMode()
+{
+ mWindow = new HbMainWindow;
+ mWindow->viewport()->grabGesture(Qt::PanGesture);
+ mWindow->viewport()->grabGesture(Qt::TapGesture); // Add TapAndHoldGesture once it's working
+ mWidget = new HgGrid( Qt::Vertical);
+
+ mWindow->addView(mWidget);
+ mWindow->show();
+
+ QTest::qWait(2000);
+
+ // Widget does not have selection model yet
+ QVERIFY(mWidget->selectionModel() == 0);
+
+ // Selection methods should have no effect unless there is a model
+ mWidget->setSelectionMode(HgWidget::MultiSelection);
+ QVERIFY(mWidget->selectionMode() == HgWidget::MultiSelection);
+ QVERIFY(mWidget->selectionModel() == 0);
+ mWidget->selectAll();
+ QVERIFY(mWidget->selectionModel() == 0);
+
+ TestModel model;
+ model.generateItems(9);
+ mWidget->setModel(&model);
+ QVERIFY(mWidget->selectionModel() != 0);
+
+ qRegisterMetaType<QItemSelection>("QItemSelection");
+ QSignalSpy selectionSpy(mWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)));
+
+ QTest::qWait(2000);
+
+ mWidget->setSelectionMode(HgWidget::NoSelection);
+ QVERIFY(mWidget->selectionMode() == HgWidget::NoSelection);
+ // Default selection mode: no selection
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos0, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 0);
+ QVERIFY(selectionSpy.count() == 0);
+
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos1, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 0);
+ QVERIFY(selectionSpy.count() == 0);
+
+ mWidget->selectAll();
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 0);
+ QVERIFY(selectionSpy.count() == 0);
+
+ // Single selection mode: at most 1 item selected at a time
+ mWidget->setSelectionMode(HgWidget::SingleSelection);
+ QVERIFY(mWidget->selectionMode() == HgWidget::SingleSelection);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 0);
+
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos1, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 1);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(1, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ QItemSelection selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(1, 0)));
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos3, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 1);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(3, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 1);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0)); // new selected
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(3, 0)));
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(1)); // deselected
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(1, 0)));
+
+ selectionSpy.clear();
+ mWidget->clearSelection();
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 0);
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 0);
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos8, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 1);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(8, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(8, 0)));
+
+ selectionSpy.clear();
+ // Changing selection mode with default parameter should clear the selection
+ mWidget->setSelectionMode(HgWidget::ContiguousSelection);
+ QVERIFY(mWidget->selectionMode() == HgWidget::ContiguousSelection);
+
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 0);
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 0);
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos2, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 1);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(2, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(2, 0)));
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos3, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 2);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(3, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(3, 0)));
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos5, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 4);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(4, 0)));
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(5, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 2);
+ QVERIFY(selection.contains(model.index(4, 0)));
+ QVERIFY(selection.contains(model.index(5, 0)));
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos0, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 6);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(0, 0)));
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(1, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 2);
+ QVERIFY(selection.contains(model.index(0, 0)));
+ QVERIFY(selection.contains(model.index(1, 0)));
+
+ // In contiguous selection mode, clicking a selected item does nothing
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos5, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 6);
+ QVERIFY(selectionSpy.count() == 0);
+
+ selectionSpy.clear();
+ mWidget->selectAll();
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 9);
+ QVERIFY(selectionSpy.count() == 1);
+
+ selectionSpy.clear();
+ // Changing selection mode with resetSelection = false should NOT clear the selection
+ mWidget->setSelectionMode(HgWidget::MultiSelection, false);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 9);
+ QVERIFY(selectionSpy.count() == 0);
+
+ selectionSpy.clear();
+ // In multiselection mode, clicking a selected item deselects it
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos5, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 8);
+ QVERIFY(!(mWidget->selectionModel()->isSelected(model.index(5, 0))));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 1);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0)); // new selected
+ QVERIFY(selection.indexes().count() == 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(1)); // deselected
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(5, 0)));
+
+ selectionSpy.clear();
+ mWidget->clearSelection();
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 0);
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 1);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0)); // new selected
+ QVERIFY(selection.indexes().count() == 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(1)); // deselected
+ QVERIFY(selection.indexes().count() == 8);
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos3, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 1);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(3, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 1);
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos5, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 2);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(5, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(5, 0)));
+
+ selectionSpy.clear();
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos8, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 3);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(8, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0));
+ QVERIFY(selection.indexes().count() == 1);
+ QVERIFY(selection.contains(model.index(8, 0)));
+
+ selectionSpy.clear();
+ // Setting the same mode does nothing
+ mWidget->setSelectionMode(HgWidget::MultiSelection);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 3);
+ QVERIFY(selectionSpy.count() == 0);
+
+ selectionSpy.clear();
+ // Keep the selection, even if it is not suitable for the new selection mode
+ mWidget->setSelectionMode(HgWidget::SingleSelection, false);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 3);
+ QVERIFY(selectionSpy.count() == 0);
+
+ selectionSpy.clear();
+ // First click resets the selection to a valid setup
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos5, 100);
+ QTest::qWait(1000);
+ QVERIFY(mWidget->selectionModel()->selectedIndexes().count() == 1);
+ QVERIFY(mWidget->selectionModel()->isSelected(model.index(5, 0)));
+ QVERIFY(selectionSpy.count() == 1);
+ QVERIFY(selectionSpy.at(0).count() > 1);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(0)); // new selected
+ QVERIFY(selection.indexes().count() == 0);
+ selection = qvariant_cast<QItemSelection>(selectionSpy.at(0).at(1)); // deselected
+ QVERIFY(selection.indexes().count() == 2);
+ QVERIFY(selection.contains(model.index(3, 0)));
+ QVERIFY(selection.contains(model.index(8, 0)));
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_selectionModel()
+{
+ mWindow = new HbMainWindow;
+ mWindow->viewport()->grabGesture(Qt::PanGesture);
+ mWindow->viewport()->grabGesture(Qt::TapGesture); // Add TapAndHoldGesture once it's working
+ mWidget = new HgGrid( Qt::Vertical);
+ TestModel model;
+ model.generateItems(9);
+ mWidget->setModel(&model);
+ mWindow->addView(mWidget);
+ mWindow->show();
+ QTest::qWait(2000);
+
+ QVERIFY(mWidget->selectionModel() != 0);
+
+ QItemSelectionModel *defaultSelectionModel = mWidget->selectionModel();
+ QSignalSpy defaultSelectionSpy(defaultSelectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)));
+
+ QItemSelectionModel *testSelectionModel1 = new QItemSelectionModel(&model);
+ QSignalSpy testSelectionSpy1(testSelectionModel1, SIGNAL(selectionChanged(QItemSelection, QItemSelection)));
+
+ QItemSelectionModel *testSelectionModel2 = new QItemSelectionModel(&model);
+ QSignalSpy testSelectionSpy2(testSelectionModel2, SIGNAL(selectionChanged(QItemSelection, QItemSelection)));
+
+ mWidget->setSelectionMode(HgWidget::MultiSelection);
+
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos2, 100);
+ QTest::qWait(1000);
+ QVERIFY(defaultSelectionModel->selectedIndexes().count() == 1);
+ QVERIFY(defaultSelectionSpy.count() == 1);
+ QVERIFY(testSelectionModel1->selectedIndexes().count() == 0);
+ QVERIFY(testSelectionSpy1.count() == 0);
+ QVERIFY(testSelectionModel2->selectedIndexes().count() == 0);
+ QVERIFY(testSelectionSpy2.count() == 0);
+
+ defaultSelectionSpy.clear();
+ testSelectionSpy1.clear();
+ testSelectionSpy2.clear();
+
+ mWidget->setSelectionModel(testSelectionModel1);
+ HbAutoTest::mouseClick((HbAutoTestMainWindow*)mWindow, mWidget, grid_portrait_pos5, 100);
+ QTest::qWait(1000);
+ // Default selection model is not valid any more
+ QVERIFY(defaultSelectionSpy.count() == 0);
+ QVERIFY(testSelectionModel1->selectedIndexes().count() == 1);
+ QVERIFY(testSelectionSpy1.count() == 1);
+ QVERIFY(testSelectionModel2->selectedIndexes().count() == 0);
+ QVERIFY(testSelectionSpy2.count() == 0);
+
+ defaultSelectionSpy.clear();
+ testSelectionSpy1.clear();
+ testSelectionSpy2.clear();
+
+ mWidget->setSelectionModel(testSelectionModel2);
+ mWidget->selectAll();
+ QVERIFY(testSelectionModel1->selectedIndexes().count() == 1);
+ QVERIFY(testSelectionSpy1.count() == 0);
+ QVERIFY(testSelectionModel2->selectedIndexes().count() == 9);
+ QVERIFY(testSelectionSpy2.count() == 1);
+
+ defaultSelectionSpy.clear();
+ testSelectionSpy1.clear();
+ testSelectionSpy2.clear();
+
+ // Setting the same selection model again does nothing
+ mWidget->setSelectionModel(testSelectionModel2);
+ QVERIFY(testSelectionModel1->selectedIndexes().count() == 1);
+ QVERIFY(testSelectionSpy1.count() == 0);
+ QVERIFY(testSelectionModel2->selectedIndexes().count() == 9);
+ QVERIFY(testSelectionSpy2.count() == 0);
+
+ defaultSelectionSpy.clear();
+ testSelectionSpy1.clear();
+ testSelectionSpy2.clear();
+
+ mWidget->setSelectionModel(testSelectionModel1);
+ mWidget->clearSelection();
+ QVERIFY(testSelectionModel1->selectedIndexes().count() == 0);
+ QVERIFY(testSelectionSpy1.count() == 1);
+ QVERIFY(testSelectionModel2->selectedIndexes().count() == 9);
+ QVERIFY(testSelectionSpy2.count() == 0);
+
+ QTest::qWait(2000);
+
+ delete testSelectionModel1;
+ delete testSelectionModel2;
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_scrollTo()
+{
+ qRegisterMetaType<QModelIndex>("QModelIndex");
+ qRegisterMetaType<QModelIndex>("QItemSelection");
+ // TODO: How to verify that items are freed?
+
+ mWindow = new HbMainWindow;
+ mWindow->viewport()->grabGesture(Qt::PanGesture);
+ mWindow->viewport()->grabGesture(Qt::TapGesture); // Add TapAndHoldGesture once it's working
+ mWidget = new HgGrid( Qt::Vertical);
+ QList<QModelIndex> requestedIndexes;
+ TestModel model(&requestedIndexes);
+ model.generateItems(1024);
+ mWidget->setModel(&model);
+ mWindow->addView(mWidget);
+ mWindow->show();
+ QTest::qWait(2000);
+
+ QVERIFY(requestedIndexes.count() == 120); // Scroll buffer size in grid mode is assumed to be 120
+ QVERIFY(requestedIndexes.front() == model.index(0, 0));
+ QVERIFY(requestedIndexes.back() == model.index(119, 0));
+ requestedIndexes.clear();
+
+ QSignalSpy activatedSpy(mWidget, SIGNAL(activated(QModelIndex)));
+ QSignalSpy currentSpy(mWidget->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)));
+ QSignalSpy selectionSpy(mWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)));
+
+ mWidget->scrollTo(model.index(100, 0));
+ QTest::qWait(1000);
+ QVERIFY(activatedSpy.count() == 0); // scrollto doesn't activate item
+ QVERIFY(currentSpy.count() == 0); // scrollto doesn't change the current
+ QVERIFY(selectionSpy.count() == 0); // scrollto doesn't change the selection
+ QVERIFY(requestedIndexes.count() == 40); // The whole scroll buffer should be updated
+ QVERIFY(requestedIndexes.front() == model.index(120, 0));
+ QVERIFY(requestedIndexes.back() == model.index(159, 0));
+ requestedIndexes.clear();
+
+ mWidget->scrollTo(model.index(1023, 0));
+ QTest::qWait(1000);
+ QVERIFY(activatedSpy.count() == 0); // scrollto doesn't activate item
+ QVERIFY(currentSpy.count() == 0); // scrollto doesn't change the current
+ QVERIFY(selectionSpy.count() == 0); // scrollto doesn't change the selection
+ QVERIFY(requestedIndexes.count() == 120); // The whole scroll buffer should be updated
+ QVERIFY(requestedIndexes.front() == model.index(904, 0));
+ QVERIFY(requestedIndexes.back() == model.index(1023, 0));
+ requestedIndexes.clear();
+
+ mWidget->scrollTo(QModelIndex());
+ QTest::qWait(1000);
+ QVERIFY(activatedSpy.count() == 0); // scrollto doesn't activate item
+ QVERIFY(currentSpy.count() == 0); // scrollto doesn't change the current
+ QVERIFY(selectionSpy.count() == 0); // scrollto doesn't change the selection
+ QVERIFY(requestedIndexes.count() == 0); // Items are not re-fetched from model
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_addItemsCoverFlow()
+{
+ // TODO: How to verify that items are freed?
+
+ mWindow = new HbMainWindow;
+ mWindow->viewport()->grabGesture(Qt::PanGesture);
+ mWindow->viewport()->grabGesture(Qt::TapGesture); // Add TapAndHoldGesture once it's working
+ mWidget = new HgMediawall();
+
+ QList<QModelIndex> requestedIndexes;
+ TestModel model(&requestedIndexes);
+ model.generateItems(120);
+ mWidget->setModel(&model);
+ mWindow->addView(mWidget);
+ mWindow->show();
+
+ QTest::qWait(2000);
+
+ QVERIFY(requestedIndexes.count() == 40); // Scroll buffer size in coverflow mode is assumed to be 40
+ QVERIFY(requestedIndexes.front() == model.index(0, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+
+ // Move buffer to the end of items
+ mWidget->scrollTo(model.index(119, 0));
+ QTest::qWait(1000);
+ requestedIndexes.clear();
+
+ // Add one item to beginning of buffer
+ model.insertItems(80, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New item falls outside of buffer as buffer is moved up
+ requestedIndexes.clear();
+ // Last item is now 120
+
+ // Add many items to beginning of buffer
+ model.insertItems(81, 4);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items falls outside of buffer as buffer is moved up
+ requestedIndexes.clear();
+ // Last item is now 124
+
+ // Add one item to the end
+ model.insertItems(124, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // The new item is requested
+ QVERIFY(requestedIndexes.front() == model.index(124, 0));
+ requestedIndexes.clear();
+ // Last item is now 125
+
+ // Add many items to the end
+ model.insertItems(125, 4);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 4); // The new items are requested
+ QVERIFY(requestedIndexes.front() == model.index(125, 0));
+ QVERIFY(requestedIndexes.back() == model.index(128, 0));
+ requestedIndexes.clear();
+ // Last item is now 129
+
+ // Add one item to middle of buffer
+ model.insertItems(110, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // The new item is requested
+ QVERIFY(requestedIndexes.front() == model.index(110, 0));
+ requestedIndexes.clear();
+ // Last item is now 130
+
+ // Add many items to middle of buffer
+ model.insertItems(110, 4);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 4); // The new items are requested
+ QVERIFY(requestedIndexes.front() == model.index(110, 0));
+ QVERIFY(requestedIndexes.back() == model.index(113, 0));
+ requestedIndexes.clear();
+ // Last item is now 134
+
+ // Add items to the buffer limit (beginning of buffer)
+ model.insertItems(90, 20);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New item falls outside of buffer as buffer is moved up
+ // Last item is now 154
+
+ // Add items to outside of buffer (before buffer)
+ model.insertItems(0, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // The new items are not requested
+ requestedIndexes.clear();
+
+ // Move buffer to the beginning of items
+ mWidget->scrollTo(model.index(0, 0));
+ QTest::qWait(1000);
+ requestedIndexes.clear();
+
+ // Add one item to beginning
+ model.insertItems(0, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // The new item is requested
+ QVERIFY(requestedIndexes.front() == model.index(0, 0));
+ requestedIndexes.clear();
+
+ // Add many items to beginning
+ model.insertItems(0, 5);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // The new items are requested
+ QVERIFY(requestedIndexes.front() == model.index(0, 0));
+ QVERIFY(requestedIndexes.back() == model.index(4, 0));
+ requestedIndexes.clear();
+
+ // Add one item to middle of buffer
+ model.insertItems(20, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // The new item is requested
+ QVERIFY(requestedIndexes.front() == model.index(20, 0));
+ requestedIndexes.clear();
+
+ // Add many items to middle of buffer
+ model.insertItems(20, 5);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // The new items are requested
+ QVERIFY(requestedIndexes.front() == model.index(20, 0));
+ QVERIFY(requestedIndexes.back() == model.index(24, 0));
+ requestedIndexes.clear();
+
+ // Add one item to end of buffer
+ model.insertItems(39, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // The new item is requested
+ QVERIFY(requestedIndexes.front() == model.index(39, 0));
+ requestedIndexes.clear();
+
+ // Add many items to end of buffer
+ model.insertItems(30, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 10); // The new items are requested
+ QVERIFY(requestedIndexes.front() == model.index(30, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+
+ // Add items to outside of buffer (after buffer)
+ model.insertItems(40, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // The new items are not requested
+ requestedIndexes.clear();
+
+ // Add items to the buffer limit (end of buffer)
+ model.insertItems(35, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // The new items inside buffer are requested
+ QVERIFY(requestedIndexes.front() == model.index(35, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+
+ // Move buffer to the middle of items
+ mWidget->scrollTo(model.index(60, 0));
+ QTest::qWait(1000);
+ requestedIndexes.clear();
+
+ // Add items to the buffer limit (beginning of buffer)
+ model.insertItems(35, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // The new items inside buffer are requested
+ QVERIFY(requestedIndexes.front() == model.index(40, 0));
+ QVERIFY(requestedIndexes.back() == model.index(44, 0));
+
+ // Add items over the whole buffer
+ model.insertItems(35, 50);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 40); // The new items inside buffer are requested
+ QVERIFY(requestedIndexes.front() == model.index(40, 0));
+ QVERIFY(requestedIndexes.back() == model.index(79, 0));
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_removeItemsCoverFlow()
+{
+ // TODO: How to verify that items are freed?
+
+ mWindow = new HbMainWindow;
+ mWindow->viewport()->grabGesture(Qt::PanGesture);
+ mWindow->viewport()->grabGesture(Qt::TapGesture); // Add TapAndHoldGesture once it's working
+ mWidget = new HgMediawall();
+
+ QList<QModelIndex> requestedIndexes;
+ TestModel model(&requestedIndexes);
+ model.generateItems(240);
+ mWidget->setModel(&model);
+ mWindow->addView(mWidget);
+ mWindow->show();
+
+ QTest::qWait(2000);
+
+ QVERIFY(requestedIndexes.count() == 40); // Scroll buffer size in coverflow mode is assumed to be 40
+ QVERIFY(requestedIndexes.front() == model.index(0, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+
+ // Move buffer to the end of items
+ mWidget->scrollTo(model.index(239, 0));
+ QTest::qWait(1000);
+ requestedIndexes.clear();
+
+ // Remove one item from the beginning of buffer
+ model.removeItems(200, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // New item is fetched to replace the removed one
+ QVERIFY(requestedIndexes.front() == model.index(199, 0));
+ requestedIndexes.clear();
+ // Last item is now 238
+
+ // Remove many items from beginning of buffer
+ model.removeItems(199, 4);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 4); // New items are fetched to replace the removed ones
+ QVERIFY(requestedIndexes.front() == model.index(195, 0));
+ QVERIFY(requestedIndexes.back() == model.index(198, 0));
+ requestedIndexes.clear();
+ // Last item is now 234
+
+ // Remove one item from the end
+ model.removeItems(234, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // New item is fetched to replace the removed one
+ QVERIFY(requestedIndexes.front() == model.index(194, 0));
+ requestedIndexes.clear();
+ // Last item is now 233
+
+ // Remove many items from the end
+ model.removeItems(230, 4);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 4); // New items are fetched to replace the removed ones
+ QVERIFY(requestedIndexes.front() == model.index(190, 0));
+ QVERIFY(requestedIndexes.back() == model.index(193, 0));
+ requestedIndexes.clear();
+ // Last item is now 229
+
+ // Remove one item from the middle of buffer
+ model.removeItems(210, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // New item is fetched to replace the removed one
+ QVERIFY(requestedIndexes.front() == model.index(189, 0));
+ requestedIndexes.clear();
+ // Last item is now 228
+
+ // Remove many items from the middle of buffer
+ model.removeItems(210, 4);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 4); // New items are fetched to replace the removed ones
+ QVERIFY(requestedIndexes.front() == model.index(185, 0));
+ QVERIFY(requestedIndexes.back() == model.index(188, 0));
+ requestedIndexes.clear();
+ // Last item is now 224
+
+ // Remove items from the buffer limit (beginning of buffer)
+ model.removeItems(180, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // New items are fetched to replace the removed ones
+ QVERIFY(requestedIndexes.front() == model.index(175, 0));
+ QVERIFY(requestedIndexes.back() == model.index(179, 0));
+ requestedIndexes.clear();
+ // Last item is now 214
+
+ // Remove items from outside of buffer (before buffer)
+ model.removeItems(0, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // Buffer is not moved
+ requestedIndexes.clear();
+ // Last item is now 204
+
+ // Move buffer to the beginning of items
+ mWidget->scrollTo(model.index(0, 0));
+ QTest::qWait(1000);
+ requestedIndexes.clear();
+
+ // Remove one item from beginning
+ model.removeItems(0, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // New item is fetched to replace the removed one
+ QVERIFY(requestedIndexes.front() == model.index(39, 0));
+ requestedIndexes.clear();
+ // Last item is now 203
+
+ // Remove many items from beginning
+ model.removeItems(0, 5);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // New items are fetched to replace the removed ones
+ QVERIFY(requestedIndexes.front() == model.index(35, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+ // Last item is now 198
+
+ // Remove one item from the middle of buffer
+ model.removeItems(20, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // New item is fetched to replace the removed one
+ QVERIFY(requestedIndexes.front() == model.index(39, 0));
+ requestedIndexes.clear();
+ // Last item is now 197
+
+ // Remove many items from the middle of buffer
+ model.removeItems(20, 5);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // New items are fetched to replace the removed ones
+ QVERIFY(requestedIndexes.front() == model.index(35, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+ // Last item is now 192
+
+ // Remove one item from the end of buffer
+ model.removeItems(39, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // New item is fetched to replace the removed one
+ QVERIFY(requestedIndexes.front() == model.index(39, 0));
+ requestedIndexes.clear();
+ // Last item is now 191
+
+ // Remove many items from the end of buffer
+ model.removeItems(30, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 10); // New items are fetched to replace the removed ones
+ QVERIFY(requestedIndexes.front() == model.index(30, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+ // Last item is now 181
+
+ // Remove items from outside of buffer (after buffer)
+ model.removeItems(50, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // Buffer is not updated
+ requestedIndexes.clear();
+ // Last item is now 171
+
+ // Remove items from the buffer limit (end of buffer)
+ model.insertItems(35, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // The new items inside buffer are requested
+ QVERIFY(requestedIndexes.front() == model.index(35, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ // Last item is now 161
+
+ // Move buffer to the middle of items
+ mWidget->scrollTo(model.index(80, 0));
+ QTest::qWait(1000);
+ requestedIndexes.clear();
+
+ // Remove items from the buffer limit (beginning of buffer)
+ model.removeItems(59, 2);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 1); // New item is fetched to replace the one removed from the buffer
+ QVERIFY(requestedIndexes.front() == model.index(99, 0));
+ // Last item is now 159
+
+ // Remove items over the whole buffer
+ model.removeItems(55, 50);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 40); // Whole buffer is updated
+ QVERIFY(requestedIndexes.front() == model.index(60, 0));
+ QVERIFY(requestedIndexes.back() == model.index(99, 0));
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+void TestGanesWidgets::test_moveItemsCoverFlow()
+{
+ // TODO: How to verify that items are freed?
+
+ mWindow = new HbMainWindow;
+ mWindow->viewport()->grabGesture(Qt::PanGesture);
+ mWindow->viewport()->grabGesture(Qt::TapGesture); // Add TapAndHoldGesture once it's working
+ mWidget = new HgMediawall();
+
+ QList<QModelIndex> requestedIndexes;
+ TestModel model(&requestedIndexes);
+ model.generateItems(120);
+ mWidget->setModel(&model);
+ mWindow->addView(mWidget);
+ mWindow->show();
+
+ QTest::qWait(2000);
+
+ QVERIFY(requestedIndexes.count() == 40); // Scroll buffer size in coverflow mode is assumed to be 40
+ QVERIFY(requestedIndexes.front() == model.index(0, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+
+ // Move one item forward
+ model.moveItems(0, 20, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ model.moveItems(0, 2, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ model.moveItems(0, 39, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // Move many items forward
+ model.moveItems(0, 20, 5);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // Move one item backward
+ model.moveItems(39, 20, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ model.moveItems(39, 38, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ model.moveItems(39, 0, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // Move many items backward
+ model.moveItems(30, 20, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // This should do nothing
+ model.moveItems(20, 20, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // Move items from the border of the buffer forward
+ model.moveItems(35, 50, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // New items are fetched to replace the moved ones
+ QVERIFY(requestedIndexes.front() == model.index(35, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+
+ // Move items from the border of the buffer backward
+ model.moveItems(35, 20, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // Items that were originally outside of buffer are fetched
+ QVERIFY(requestedIndexes.front() == model.index(25, 0));
+ QVERIFY(requestedIndexes.back() == model.index(29, 0));
+ requestedIndexes.clear();
+
+ // Move items from the buffer outside it
+ model.moveItems(20, 90, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 10); // New items are fetched to replace the moved ones
+ QVERIFY(requestedIndexes.front() == model.index(30, 0));
+ QVERIFY(requestedIndexes.back() == model.index(39, 0));
+ requestedIndexes.clear();
+
+ // Move items from outside the buffer inside it
+ model.moveItems(90, 20, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 10); // Moved items are fetched
+ QVERIFY(requestedIndexes.front() == model.index(20, 0));
+ QVERIFY(requestedIndexes.back() == model.index(29, 0));
+ requestedIndexes.clear();
+
+ // Move buffer to the end of items
+ mWidget->scrollTo(model.index(119, 0));
+ QTest::qWait(1000);
+ requestedIndexes.clear();
+
+ // Move one item forward
+ model.moveItems(80, 100, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ model.moveItems(80, 82, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ model.moveItems(80, 119, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // Move many items forward
+ model.moveItems(80, 100, 5);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // Move one item backward
+ model.moveItems(119, 100, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ model.moveItems(119, 118, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ model.moveItems(119, 80, 1);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // Move many items backward
+ model.moveItems(110, 95, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 0); // New items are not fetched as the changes happened inside the buffer
+
+ // Move items from the border of the buffer backward
+ model.moveItems(75, 60, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // New items are fetched to replace the moved ones
+ QVERIFY(requestedIndexes.front() == model.index(80, 0));
+ QVERIFY(requestedIndexes.back() == model.index(84, 0));
+ requestedIndexes.clear();
+
+ // Move items from the border of the buffer forward
+ model.moveItems(75, 100, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 5); // Items that were originally outside of buffer are fetched
+ QVERIFY(requestedIndexes.front() == model.index(100, 0));
+ QVERIFY(requestedIndexes.back() == model.index(104, 0));
+ requestedIndexes.clear();
+
+ // Move items from the buffer outside it
+ model.moveItems(100, 10, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 10); // New items are fetched to replace the moved ones
+ QVERIFY(requestedIndexes.front() == model.index(80, 0));
+ QVERIFY(requestedIndexes.back() == model.index(89, 0));
+ requestedIndexes.clear();
+
+ // Move items from outside the buffer inside it
+ model.moveItems(10, 100, 10);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 10); // Moved items are fetched
+ QVERIFY(requestedIndexes.front() == model.index(100, 0));
+ QVERIFY(requestedIndexes.back() == model.index(109, 0));
+ requestedIndexes.clear();
+
+ // Move buffer to the middle of items
+ mWidget->scrollTo(model.index(60, 0));
+ QTest::qWait(1000);
+ requestedIndexes.clear();
+
+ // Move items over the whole buffer forward
+ model.moveItems(35, 110, 50);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 40); // Whole buffer is updated
+ QVERIFY(requestedIndexes.front() == model.index(40, 0));
+ QVERIFY(requestedIndexes.back() == model.index(79, 0));
+
+ // Move items over the whole buffer backward
+ model.moveItems(35, 10, 50);
+ QTest::qWait(1000);
+ QVERIFY(requestedIndexes.count() == 40); // Whole buffer is updated
+ QVERIFY(requestedIndexes.front() == model.index(40, 0));
+ QVERIFY(requestedIndexes.back() == model.index(79, 0));
+
+ QTest::qWait(2000);
+
+ delete mWindow;
+ mWindow = 0;
+}
+
+#ifdef _UNITTEST_GANESWIDGETS_LOG_TO_C_
+ int main (int argc, char* argv[])
+ {
+ HbApplication app(argc, argv);
+ TestGanesWidgets tc;
+// int c = 3;
+// char* v[] = {argv[0], "-o", "c:/test.txt"};
+ return QTest::qExec(&tc, argc, argv);
+// return QTest::qExec(&tc, c, v);
+ }
+#else
+ QTEST_MAIN(TestGanesWidgets)
+#endif
+
+#include "unittest_ganeswidgets.moc"
+
+// EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/unit/unittest_ganeswidgets.pro Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,31 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+# Contributors:
+# Description:
+
+TEMPLATE = app
+CONFIG += qtestlib \
+ hb
+TARGET = unittest_ganeswidgets
+DEFINES += _UNITTEST_GANESWIDGETS_LOG_TO_C_
+TARGET.CAPABILITY = All \
+ -TCB
+INCLUDEPATH += . \
+ inc \
+ $$APP_LAYER_SYSTEMINCLUDE \
+ $$MW_LAYER_SYSTEMINCLUDE \
+ /sf/mw/hb/src/hbcore/gui
+LIBS += -lestor.dll \
+ -lganeswidgets.dll
+
+# Input
+SOURCES += hbautotest.cpp \
+ unittest_ganeswidgets.cpp
+RESOURCES = unittest_ganeswidgets.qrc
+HEADERS =
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/tsrc/unit/unittest_ganeswidgets.qrc Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/icons">
+ <file>startupHG.jpg</file>
+ </qresource>
+</RCC>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgwidgets.pro Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+TEMPLATE = subdirs
+
+# Platforms
+SYMBIAN_PLATFORMS = WINSCW ARMV5
+
+CONFIG += ordered
+
+SUBDIRS += hgwidgets_plat/hgwidgets_plat.pro
+SUBDIRS += ganeswidgets/ganeswidgets.pro
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgwidgets_plat/ganeswidgets_api/ganeswidgets_api.pri Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+PUBLIC_HEADERS += ganeswidgets_api/inc/hgwidgets.h \
+ ganeswidgets_api/inc/hggrid.h \
+ ganeswidgets_api/inc/hgmediawall.h
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgwidgets_plat/ganeswidgets_api/inc/hggrid.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGGRID_H
+#define HGGRID_H
+
+#include <hgwidgets/hgwidgets.h>
+
+class HgGridPrivate;
+
+class HG_WIDGETS_EXPORT HgGrid : public HgWidget
+{
+ Q_OBJECT
+public:
+
+ HgGrid(Qt::Orientation scrollDirection, QGraphicsItem *parent = 0 );
+ virtual ~HgGrid();
+
+private:
+ Q_DECLARE_PRIVATE_D(d_ptr, HgGrid)
+ Q_DISABLE_COPY(HgGrid)
+};
+
+#endif //HGGRID_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgwidgets_plat/ganeswidgets_api/inc/hgmediawall.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGMEDIAWALL_H
+#define HGMEDIAWALL_H
+
+#include <hgwidgets/hgwidgets.h>
+
+class HgMediawallPrivate;
+
+class HG_WIDGETS_EXPORT HgMediawall : public HgWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(LabelPosition titlePosition READ titlePosition WRITE setTitlePosition)
+ Q_PROPERTY(LabelPosition descriptionPosition READ descriptionPosition WRITE setDescriptionPosition)
+ Q_PROPERTY(HbFontSpec titleFontSpec READ titleFontSpec WRITE setTitleFontSpec)
+ Q_PROPERTY(HbFontSpec descriptionFontSpec READ descriptionFontSpec WRITE setDescriptionFontSpec)
+ Q_ENUMS(LabelPosition)
+
+public:
+
+ HgMediawall(QGraphicsItem *parent = 0 );
+ virtual ~HgMediawall();
+
+ enum LabelPosition {
+ PositionNone = 0,
+ PositionAboveImage,
+ PositionBelowImage
+ };
+
+ void setTitlePosition(LabelPosition position);
+ LabelPosition titlePosition() const;
+ void setDescriptionPosition(LabelPosition position);
+ LabelPosition descriptionPosition() const;
+ void setTitleFontSpec(const HbFontSpec &fontSpec);
+ HbFontSpec titleFontSpec() const;
+ void setDescriptionFontSpec(const HbFontSpec &fontSpec);
+ HbFontSpec descriptionFontSpec() const;
+
+private:
+ Q_DECLARE_PRIVATE_D(d_ptr, HgMediawall)
+ Q_DISABLE_COPY(HgMediawall)
+};
+
+#endif //HGMEDIAWALL_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgwidgets_plat/ganeswidgets_api/inc/hgwidgets.h Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,148 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef HGWIDGET_H
+#define HGWIDGET_H
+
+#include <QItemSelectionModel>
+#include <hbglobal.h>
+#include <hbnamespace.h>
+#include <hbwidget.h>
+
+#ifdef BUILD_HG_WIDGETS
+# define HG_WIDGETS_EXPORT Q_DECL_EXPORT
+# define HG_WIDGETS_PRIVATE_EXPORT Q_DECL_EXPORT
+#else
+# define HG_WIDGETS_EXPORT Q_DECL_IMPORT
+# define HG_WIDGETS_PRIVATE_EXPORT Q_DECL_IMPORT
+#endif // BUILD_HG_WIDGETS
+
+class HgWidgetPrivate;
+class HbScrollBar;
+
+class HG_WIDGETS_EXPORT HgWidget : public HbWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(bool longPressEnabled READ longPressEnabled WRITE setLongPressEnabled )
+ Q_PROPERTY(ScrollBarPolicy scrollBarPolicy READ scrollBarPolicy WRITE setScrollBarPolicy)
+ Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(IndexFeedbackPolicy IndexFeedbackPolicy READ indexFeedbackPolicy WRITE setIndexFeedbackPolicy)
+ Q_ENUMS(ScrollBarPolicy)
+ Q_ENUMS(HgWidgetType)
+ Q_ENUMS(SelectionMode)
+ Q_ENUMS(IndexFeedbackPolicy)
+public:
+
+ enum HgDataRole
+ {
+ HgVisibilityRole = Qt::UserRole + 1
+ };
+
+ enum IndexFeedbackPolicy {
+ IndexFeedbackNone = 0,
+ IndexFeedbackSingleCharacter,
+ IndexFeedbackThreeCharacter,
+ IndexFeedbackString
+ };
+
+ virtual ~HgWidget ();
+
+ enum ScrollBarPolicy {
+ ScrollBarAsNeeded = Qt::ScrollBarAsNeeded,
+ ScrollBarAlwaysOff = Qt::ScrollBarAlwaysOff,
+ ScrollBarAlwaysOn = Qt::ScrollBarAlwaysOn,
+ ScrollBarAutoHide
+ };
+
+ virtual void setModel(QAbstractItemModel *model);
+ QAbstractItemModel *model() const;
+
+ void setSelectionModel(QItemSelectionModel *selectionModel);
+ QItemSelectionModel *selectionModel() const;
+
+ enum SelectionMode {
+ NoSelection = 0,
+ SingleSelection,
+ MultiSelection,
+ ContiguousSelection
+ };
+
+ SelectionMode selectionMode() const;
+ void setSelectionMode(SelectionMode mode, bool resetSelection = true);
+ void selectAll();
+ void clearSelection();
+
+ QModelIndex currentIndex() const;
+ void setCurrentIndex(const QModelIndex &index,
+ QItemSelectionModel::SelectionFlags selectionFlag=QItemSelectionModel::NoUpdate);
+
+ void scrollTo(const QModelIndex &index);
+
+ bool longPressEnabled() const;
+ void setLongPressEnabled(bool value);
+
+ ScrollBarPolicy scrollBarPolicy() const;
+ void setScrollBarPolicy(ScrollBarPolicy policy);
+ HbScrollBar *scrollBar() const;
+ void setScrollBar(HbScrollBar *scrollBar);
+
+ bool getItemOutline(const QModelIndex& index, QPolygonF& points);
+ Qt::Orientation scrollDirection() const;
+
+ QList<QModelIndex> getVisibleItemIndices() const;
+
+ void setIndexFeedbackPolicy( IndexFeedbackPolicy policy);
+ IndexFeedbackPolicy indexFeedbackPolicy() const;
+
+signals:
+ void activated(const QModelIndex &index);
+ void longPressed(const QModelIndex &index, const QPointF &coords);
+ void scrollingStarted();
+ void scrollingEnded();
+public slots:
+
+ void aboutToChangeOrientation();
+ void orientationChanged(Qt::Orientation orientation);
+
+protected slots:
+
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+
+protected:
+
+ bool eventFilter(QObject *obj,QEvent *event);
+
+ bool event(QEvent *event);
+
+ HgWidget(HbWidgetPrivate* widgetPrivate, QGraphicsItem *parent = 0);
+
+private:
+ Q_DECLARE_PRIVATE_D(d_ptr, HgWidget)
+ Q_DISABLE_COPY(HgWidget)
+ Q_PRIVATE_SLOT(d_func(), void _q_scrollPositionChanged(qreal index, bool scrollBarAnimation))
+ Q_PRIVATE_SLOT(d_func(), void _q_releaseItems(int releaseStart, int releaseEnd))
+ Q_PRIVATE_SLOT(d_func(), void _q_requestItems(int requestStart, int requestEnd))
+ Q_PRIVATE_SLOT(d_func(), void _q_hideScrollBars() )
+ Q_PRIVATE_SLOT(d_func(), void _q_thumbPositionChanged(qreal value, Qt::Orientation orientation))
+ Q_PRIVATE_SLOT(d_func(), void _q_insertRows(const QModelIndex &parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_removeRows(const QModelIndex &parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_moveRows(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow))
+ Q_PRIVATE_SLOT(d_func(), void _q_groovePressed(qreal, Qt::Orientation))
+};
+
+#endif //HGWIDGET_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgwidgets_plat/hgwidgets_plat.pro Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+TEMPLATE = subdirs
+
+SYMBIAN_PLATFORMS = WINSCW ARMV5
+
+CONFIG += ordered
+
+include(ganeswidgets_api/ganeswidgets_api.pri)
+
+symbian {
+ headers.sources = $$PUBLIC_HEADERS
+ BLD_INF_RULES.prj_exports += "$${LITERAL_HASH}include <platform_paths.hrh>"
+ for(header, headers.sources) {
+ FILENAME = $$basename(header)
+ BLD_INF_RULES.prj_exports += "$$header MW_LAYER_PUBLIC_EXPORT_PATH(hgwidgets/$$FILENAME)"
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/layers.sysdef.xml Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!DOCTYPE SystemDefinition SYSTEM "sysdef_1_5_1.dtd" [<!ENTITY layer_real_source_path "sf/mw/hgwidgets" >]>
+
+<SystemDefinition name="hgwidgets" schema="1.5.1">
+ <systemModel>
+
+ <layer name="app_layer">
+ <module name="hgwidgets">
+ <unit unitID="imm.hgwidgets" name="hgwidgets" bldFile="&layer_real_source_path;" proFile="hgwidgets.pro" qmakeArgs="" mrp=""/>
+ </module>
+ </layer>
+
+ <layer name="api_test_layer">
+ <module name="hgwidgets_api_tests">
+ </module>
+ </layer>
+
+ <layer name="unit_test_layer">
+ <module name="hgwidgets_unit_tests">
+ </module>
+ </layer>
+
+ </systemModel>
+</SystemDefinition>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdef_1_5_1.dtd Mon Apr 19 14:40:06 2010 +0300
@@ -0,0 +1,88 @@
+ <!ELEMENT SystemDefinition (systemModel?, build?)>
+ <!ATTLIST SystemDefinition
+ name CDATA #REQUIRED
+ schema CDATA #REQUIRED>
+ <!ELEMENT systemModel (layer+)>
+ <!ELEMENT layer (logicalset* | module*)*>
+ <!ATTLIST layer
+ name CDATA #REQUIRED
+ levels CDATA #IMPLIED
+ span CDATA #IMPLIED>
+ <!ELEMENT logicalset (logicalsubset* | module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalset name CDATA #REQUIRED>
+ <!ELEMENT logicalsubset (module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalsubset name CDATA #REQUIRED>
+ <!ELEMENT module (component* | unit* | package* | prebuilt*)*>
+ <!ATTLIST module
+ name CDATA #REQUIRED
+ level CDATA #IMPLIED>
+ <!ELEMENT component (unit* | package* | prebuilt*)*>
+ <!ATTLIST component name CDATA #REQUIRED>
+ <!ELEMENT unit EMPTY>
+ <!ATTLIST unit
+ unitID ID #REQUIRED
+ name CDATA #REQUIRED
+ mrp CDATA #REQUIRED
+ filter CDATA #IMPLIED
+ bldFile CDATA #REQUIRED
+ priority CDATA #IMPLIED
+ contract CDATA #IMPLIED
+ proFile CDATA #IMPLIED
+ qmakeArgs CDATA #IMPLIED>
+ <!ELEMENT package EMPTY>
+ <!ATTLIST package
+ name CDATA #REQUIRED
+ mrp CDATA #REQUIRED
+ filter CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT prebuilt EMPTY>
+ <!ATTLIST prebuilt
+ name CDATA #REQUIRED
+ version CDATA #REQUIRED
+ late (Y|N) #IMPLIED
+ filter CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT build (option* | target+ | targetList+ | unitList+ | configuration+)*>
+ <!ELEMENT unitList (unitRef+)>
+ <!ATTLIST unitList
+ name ID #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT unitRef EMPTY>
+ <!ATTLIST unitRef unit IDREF #REQUIRED>
+ <!ELEMENT targetList EMPTY>
+ <!ATTLIST targetList
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ target IDREFS #REQUIRED>
+ <!ELEMENT target EMPTY>
+ <!ATTLIST target
+ name ID #REQUIRED
+ abldTarget CDATA #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT option EMPTY>
+ <!ATTLIST option
+ name ID #REQUIRED
+ abldOption CDATA #REQUIRED
+ description CDATA #REQUIRED
+ enable (Y | N | y | n) #REQUIRED>
+ <!ELEMENT configuration (unitListRef+ | layerRef+ | task+)*>
+ <!ATTLIST configuration
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ filter CDATA #REQUIRED>
+ <!ELEMENT task ( unitListRef* , (buildLayer | specialInstructions))>
+ <!ELEMENT unitListRef EMPTY>
+ <!ATTLIST unitListRef unitList IDREF #REQUIRED>
+ <!ELEMENT layerRef EMPTY>
+ <!ATTLIST layerRef layerName CDATA #REQUIRED>
+ <!ELEMENT buildLayer EMPTY>
+ <!ATTLIST buildLayer
+ command CDATA #REQUIRED
+ targetList IDREFS #IMPLIED
+ unitParallel (Y | N | y | n) #REQUIRED
+ targetParallel (Y | N | y | n) #IMPLIED>
+ <!ELEMENT specialInstructions EMPTY>
+ <!ATTLIST specialInstructions
+ name CDATA #REQUIRED
+ cwd CDATA #REQUIRED
+ command CDATA #REQUIRED>