Merge lp:~aacid/unity/UseC++LVWPH into lp:unity/8.0
- UseC++LVWPH
- Merge into 8.0
Status: | Merged |
---|---|
Approved by: | Gerry Boland |
Approved revision: | no longer in the source branch. |
Merged at revision: | 63 |
Proposed branch: | lp:~aacid/unity/UseC++LVWPH |
Merge into: | lp:unity/8.0 |
Diff against target: |
5381 lines (+4516/-585) 29 files modified
Components/Carousel.qml (+2/-0) Components/ListItems/Base.qml (+20/-22) Components/ListItems/Header.qml (+0/-6) Components/ListItems/ThinDivider.qml (+0/-4) Components/ListViewWithPageHeader.qml (+0/-189) Dash/DashApps.qml (+2/-3) Dash/DashHome.qml (+1/-2) Dash/DashMusic.qml (+1/-2) Dash/DashVideos.qml (+2/-3) Dash/GenericScopeView.qml (+1/-1) Dash/ScopeListView.qml (+23/-0) debian/control (+2/-0) debian/unity8.install (+1/-0) plugins/CMakeLists.txt (+1/-0) plugins/ListViewWithPageHeader/CMakeLists.txt (+44/-0) plugins/ListViewWithPageHeader/listviewwithpageheader.cpp (+1059/-0) plugins/ListViewWithPageHeader/listviewwithpageheader.h (+180/-0) plugins/ListViewWithPageHeader/plugin.cpp (+29/-0) plugins/ListViewWithPageHeader/plugin.h (+33/-0) plugins/ListViewWithPageHeader/qmldir (+2/-0) run_on_device (+1/-1) tests/plugins/CMakeLists.txt (+1/-0) tests/plugins/ListViewWithPageHeader/CMakeLists.txt (+31/-0) tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp (+1311/-0) tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp (+1567/-0) tests/plugins/ListViewWithPageHeader/test.qml (+96/-0) tests/plugins/ListViewWithPageHeader/test_section.qml (+106/-0) tests/qmltests/CMakeLists.txt (+0/-1) tests/qmltests/Components/tst_ListViewWithPageHeader.qml (+0/-351) |
To merge this branch: | bzr merge lp:~aacid/unity/UseC++LVWPH |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Gerry Boland (community) | Approve | ||
Review via email: mp+168073@code.launchpad.net |
Commit message
ListViewWithPag
Description of the change
Albert Astals Cid (aacid) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:32
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:34
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:35
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:37
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:38
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:40
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:40
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:41
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:42
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:43
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:44
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:45
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:45
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
None: http://
SUCCESS: http://
deb: http://
None: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:47
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:48
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:49
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:49
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:50
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:52
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:53
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:55
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:56
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:58
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:60
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:61
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:62
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:63
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:64
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:66
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:67
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:68
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:70
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:71
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:72
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:72
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:73
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:74
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:75
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:75
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:76
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:76
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:77
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : | # |
Hmm Jenkins hang, rebuild triggered.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:77
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:77
http://
Executed test runs:
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:77
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : | # |
> Compared values are not the same Actual (lvwph-
Hm?
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:77
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:78
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
http://
Bug:
1. open this demo with qmlscene
2. Resize the window to make it bigger
Problem: ListView does not redraw upon being resized, only redraws after a viewPortMove. Would be an issue when including orientation support into Dash, as LV would then be resized.
Gerry Boland (gerboland) wrote : | # |
http://
Crash Bug:
1. open this demo with qmlscene
2. scroll the list to the bottom
2. Resize the window to make it bigger
Crash!
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:80
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:82
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:83
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
I'm ever so slightly taking the mickey with this test case, but it does cause a crash.
http://
Open this in qmlscene, and scroll up & down a bit. Can you repro?
Gerry Boland (gerboland) wrote : | # |
Subtle visual bug in shell, see this screengrab:
http://
On left is this branch, on right is trunk.
Notice that on trunk, the carousel image is visible through the white pixels of the divider line at the bottom of the section delegate. This is deliberate as is wanted by design.
Gerry Boland (gerboland) wrote : | # |
http://
Here I'm testing heightToClip. Unless I'm using it wrong, it appears to be only correct for the first delegate in each section. You see this by scrolling up slowly.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:84
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
> I'm ever so slightly taking the mickey with this test case, but it does cause
> a crash.
> http://
> Open this in qmlscene, and scroll up & down a bit. Can you repro?
Fixed in http://
Albert Astals Cid (aacid) wrote : | # |
> http://
> Here I'm testing heightToClip. Unless I'm using it wrong, it appears to be
> only correct for the first delegate in each section. You see this by scrolling
> up slowly.
Fixed in http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:85
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:86
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
> Subtle visual bug in shell, see this screengrab:
> http://
>
> On left is this branch, on right is trunk.
> Notice that on trunk, the carousel image is visible through the white pixels
> of the divider line at the bottom of the section delegate. This is deliberate
> as is wanted by design.
Fixed in http://
Gerry Boland (gerboland) wrote : | # |
http://
Load up that qml file, grab the list and drag cursor down so page header expands (i.e. list overshoots). Now release the mouse button/finger. PageHeader stays expanded for some time before eventually reseting
Gerry Boland (gerboland) wrote : | # |
> http://
> Load up that qml file, grab the list and drag cursor down so page header
> expands (i.e. list overshoots). Now release the mouse button/finger.
> PageHeader stays expanded for some time before eventually reseting
After discussion, this would be non-trivial to fix. As it is a non-crashing bug, and visually not too bad, I say this bug can be ignored for this MR.
Gerry Boland (gerboland) wrote : | # |
+ clip: true // Don't leak horizontally to other dashes
This needed only now? Could we not enable clipping only while switching lens - would help prevent unnecessary clips.
+# FIXME There's no cmake var for this :-/
+ /usr/include/
Could you get the version string (5.0.2) out of cmake somehow, to construct this path? For when we adopt 5.0.3 say.
Albert Astals Cid (aacid) wrote : | # |
> + clip: true // Don't leak horizontally to other dashes
> This needed only now? Could we not enable clipping only while switching lens -
> would help prevent unnecessary clips.
No, that's needed all the time (uncomment it and see what happens). Previously we did not need it because the whole LVPWH was clipping.
> +# FIXME There's no cmake var for this :-/
> + /usr/include/
> Could you get the version string (5.0.2) out of cmake somehow, to construct
> this path? For when we adopt 5.0.3 say.
Should be doable, let me have a look
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:87
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:88
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:89
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
Visual bug on phone (not blocker):
1. Open Browser application
2. Go to Dash lens
3. Tap Search button in panel
4. Enter "t" - grid behind shows all results of search, "Running apps" disappeared
5. Tap backspace to clear search
See how first the "Running apps" section and preview appears underneath the grid, and then the grid is pushed down.
Since running apps will be going away, this is probably not important.
Gerry Boland (gerboland) wrote : | # |
+ // This could be optimized by trying to reuse the interesection
+ // of items that may end up intersecting between the existing
+ // m_visibleItems and the items we are creating in the next loop
Mark as TODO?
+ const qreal buffer = height() / 2;
Maybe make the buffer easier to configure. A "const qreal bufferRatio = 0.5" somewhere.
Gerry Boland (gerboland) wrote : | # |
+ setMaximumFlick
+ setFlickDeceler
Why? Flickable defaults not ok? 10 and 2 come from where?
Q_FOREACH & foreach - you mix the two, please choose one
=== modified file 'run_on_device'
Why the adding --delete?
Albert Astals Cid (aacid) wrote : | # |
> + // This could be optimized by trying to reuse the interesection
> + // of items that may end up intersecting between the existing
> + // m_visibleItems and the items we are creating in the next loop
> Mark as TODO?
http://
> + const qreal buffer = height() / 2;
> Maybe make the buffer easier to configure. A "const qreal bufferRatio = 0.5"
> somewhere.
http://
Albert Astals Cid (aacid) wrote : | # |
> + setMaximumFlick
> + setFlickDeceler
> Why? Flickable defaults not ok? 10 and 2 come from where?
They come from the old code
maximumFlickVel
flickDeceleration: height * 2
> Q_FOREACH & foreach - you mix the two, please choose one
http://
> === modified file 'run_on_device'
> Why the adding --delete?
Because otherwise the ListViewWithPag
Gerry Boland (gerboland) wrote : | # |
> > + clip: true // Don't leak horizontally to other dashes
> > This needed only now? Could we not enable clipping only while switching lens
> -
> > would help prevent unnecessary clips.
>
> No, that's needed all the time (uncomment it and see what happens). Previously
> we did not need it because the whole LVPWH was clipping.
Yep, you've not enough information to clip more intelligently. Best solution IMO would be to clip only when not current lens, or when lensView is moving. Since Carousel is a tiny bit slow on phone, it could help a bit. For laterz.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:92
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
Another bug (Albert found):
1. Go to music lens
2. scroll down to bottom
3. Switch to home lens
4. Switch back to music lens
Header of Music lens goes a bit crazy. Some more lens switching completely breaks LVWPH
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:94
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:95
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
One final thing I've noticed: on the phone, on apps lens, try to flick down fast to bring list to the bottom. Often for me, with fast flicks, the list stops moving suddenly for no reason I can see - usually at the same place.
Unsure what's going on there tbh. Can you repro?
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:95
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
> One final thing I've noticed: on the phone, on apps lens, try to flick down
> fast to bring list to the bottom. Often for me, with fast flicks, the list
> stops moving suddenly for no reason I can see - usually at the same place.
>
> Unsure what's going on there tbh. Can you repro?
Yes, I have been able to reproduce that, my analisis shows that it is because of this:
* We are scrollling
* We create the last item of the list, it reports a very small size
* We continue scrolling down and eventually we start going into overshoot mode, the list decides to go back to the stable position
* At this moment the last item grows, but the list is already going back to the previous stable position
There's not much more we can do from the list, I'm going to try to see if we can make items give more accurate heights from the beginning.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:96
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:96
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:96
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
Everything working perfectly, nice work Albert!
Gerry Boland (gerboland) wrote : | # |
Just waiting for CI to approve, then will top-level-approce
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:99
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'Components/Carousel.qml' |
2 | --- Components/Carousel.qml 2013-06-06 07:57:05 +0000 |
3 | +++ Components/Carousel.qml 2013-07-01 11:23:32 +0000 |
4 | @@ -24,6 +24,8 @@ |
5 | Item { |
6 | id: carousel |
7 | |
8 | + clip: true // Don't leak horizontally to other dashes |
9 | + |
10 | /// The component to be used as delegate. This component has to be derived from BaseCarouselDelegate |
11 | property Component itemComponent |
12 | /// Model for the Carousel, which has to be a model usable by a ListView |
13 | |
14 | === modified file 'Components/ListItems/Base.qml' |
15 | --- Components/ListItems/Base.qml 2013-06-05 22:03:08 +0000 |
16 | +++ Components/ListItems/Base.qml 2013-07-01 11:23:32 +0000 |
17 | @@ -54,35 +54,33 @@ |
18 | */ |
19 | function __showDivider() { |
20 | // if we're not in ListView, always show a thin dividing line at the bottom |
21 | - if (ListView.view !== null) { |
22 | - |
23 | + var model = null; |
24 | + if (typeof ListViewWithPageHeader !== 'undefined') { |
25 | + if (typeof ListViewWithPageHeader.model !== 'undefined') { |
26 | + model = ListViewWithPageHeader.model; |
27 | + } |
28 | + } else if (ListView.view !== null) { |
29 | + model = ListView.view.model; |
30 | + } |
31 | // if we're last item in ListView don't show divider |
32 | - if (index === ListView.view.model.count - 1) return false; |
33 | - } |
34 | + if (model && index === model.count - 1) return false; |
35 | + |
36 | return true; |
37 | } |
38 | |
39 | - property bool __clippingRequired: ListView.view !== null |
40 | - && ListView.view.section.labelPositioning & ViewSection.CurrentLabelAtStart |
41 | - |
42 | - property real __yPositionRelativeToListView: ListView.view ? y - ListView.view.contentY : y |
43 | + /* Relevant really only for ListViewWithPageHeader case: specify how many pixels we can overlap with the section header */ |
44 | + readonly property int allowedOverlap: units.dp(1) |
45 | |
46 | property real __heightToClip: { |
47 | // Check this is in position where clipping is needed |
48 | - if (__clippingRequired && __yPositionRelativeToListView <= __sectionDelegateHeight |
49 | - && __yPositionRelativeToListView > -height) { |
50 | - return Math.min(__sectionDelegateHeight - __yPositionRelativeToListView, height); |
51 | - } else { |
52 | - return 0; |
53 | - } |
54 | - } |
55 | - |
56 | - property int __sectionDelegateHeight: { |
57 | - if (__clippingRequired && ListView.view.hasOwnProperty("__sectionDelegateHeight")) { |
58 | - return ListView.view.__sectionDelegateHeight; |
59 | - } else { |
60 | - return 0; |
61 | - } |
62 | + if (typeof ListViewWithPageHeader !== 'undefined') { |
63 | + if (typeof heightToClip !== 'undefined') { |
64 | + if (heightToClip >= allowedOverlap) { |
65 | + return heightToClip - allowedOverlap; |
66 | + } |
67 | + } |
68 | + } |
69 | + return 0; |
70 | } |
71 | |
72 | /*! |
73 | |
74 | === modified file 'Components/ListItems/Header.qml' |
75 | --- Components/ListItems/Header.qml 2013-06-05 22:03:08 +0000 |
76 | +++ Components/ListItems/Header.qml 2013-07-01 11:23:32 +0000 |
77 | @@ -25,12 +25,6 @@ |
78 | */ |
79 | property alias text: label.text |
80 | |
81 | - /* When this header is used in a ListViewWithPageHeader with CurrentLabelAtStart mode, to stop |
82 | - the list's delegates contents being visible through this header, they clip themselves |
83 | - depending on their position. However to allow delegates underlap the bottom X pixels of this |
84 | - header (so delegate appears through ThinDivider say) we set an offset property here. */ |
85 | - readonly property int bottomBorderAllowedOverlap: bottomBorder.allowedBottomOverlap |
86 | - |
87 | height: units.gu(4.5) |
88 | |
89 | Item { |
90 | |
91 | === modified file 'Components/ListItems/ThinDivider.qml' |
92 | --- Components/ListItems/ThinDivider.qml 2013-06-05 22:03:08 +0000 |
93 | +++ Components/ListItems/ThinDivider.qml 2013-07-01 11:23:32 +0000 |
94 | @@ -23,9 +23,5 @@ |
95 | } |
96 | height: (visible) ? units.dp(2) : 0 |
97 | |
98 | - /* Relevant really only for ListViewWithPageHeader with Base delegates: should this image |
99 | - be overlapping content, specify how many pixels from the bottom should be transparent */ |
100 | - readonly property int allowedBottomOverlap: units.dp(1) |
101 | - |
102 | source: "graphics/ListItemDividerHorizontal.png" |
103 | } |
104 | |
105 | === removed file 'Components/ListViewWithPageHeader.qml' |
106 | --- Components/ListViewWithPageHeader.qml 2013-06-05 22:03:08 +0000 |
107 | +++ Components/ListViewWithPageHeader.qml 1970-01-01 00:00:00 +0000 |
108 | @@ -1,189 +0,0 @@ |
109 | -/* |
110 | - * Copyright (C) 2013 Canonical, Ltd. |
111 | - * |
112 | - * This program is free software; you can redistribute it and/or modify |
113 | - * it under the terms of the GNU General Public License as published by |
114 | - * the Free Software Foundation; version 3. |
115 | - * |
116 | - * This program is distributed in the hope that it will be useful, |
117 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
118 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
119 | - * GNU General Public License for more details. |
120 | - * |
121 | - * You should have received a copy of the GNU General Public License |
122 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
123 | - */ |
124 | - |
125 | -import QtQuick 2.0 |
126 | -import "Math.js" as MathLocal |
127 | - |
128 | -Item { |
129 | - id: root |
130 | - property Item pageHeader: null |
131 | - property Component sectionDelegate: null |
132 | - property string sectionProperty: "" |
133 | - property alias model: listView.model |
134 | - property alias delegate: listView.delegate |
135 | - property ListView view: listView |
136 | - property alias moving: flicker.moving |
137 | - property alias atYEnd: flicker.atYEnd |
138 | - property bool clipListView: true |
139 | - |
140 | - readonly property real __headerHeight: (pageHeader) ? pageHeader.implicitHeight : 0 |
141 | - property real __headerVisibleHeight: __headerHeight |
142 | - readonly property real __overshootHeight: (flicker.contentY < 0) ? -flicker.contentY : 0 |
143 | - |
144 | - |
145 | - // TODO move to AnimationController |
146 | - ParallelAnimation { |
147 | - id: headerAnimation |
148 | - property real targetContentY |
149 | - NumberAnimation { |
150 | - target: root |
151 | - property: "__headerVisibleHeight" |
152 | - to: root.__headerHeight |
153 | - duration: 200 |
154 | - easing.type: Easing.OutQuad |
155 | - } |
156 | - NumberAnimation { |
157 | - target: listView |
158 | - property: "contentY" |
159 | - to: headerAnimation.targetContentY |
160 | - duration: 200 |
161 | - easing.type: Easing.OutQuad |
162 | - } |
163 | - } |
164 | - |
165 | - function positionAtBeginning() { |
166 | - __headerVisibleHeight = __headerHeight |
167 | - flicker.contentY = 0 |
168 | - } |
169 | - |
170 | - function showHeader() { |
171 | - headerAnimation.targetContentY = listView.contentY + (__headerHeight - __headerVisibleHeight) |
172 | - headerAnimation.start() |
173 | - } |
174 | - |
175 | - function flick(xVelocity, yVelocity) { |
176 | - flicker.flick(xVelocity, yVelocity); |
177 | - } |
178 | - |
179 | - onPageHeaderChanged: { |
180 | - pageHeader.parent = pageHeaderContainer; |
181 | - pageHeader.anchors.fill = pageHeaderContainer; |
182 | - } |
183 | - |
184 | - Item { |
185 | - id: pageHeaderClipper |
186 | - parent: flicker // parent to Flickable so mouse click events passed through to the header component |
187 | - anchors { |
188 | - top: parent.top |
189 | - left: parent.left |
190 | - right: parent.right |
191 | - } |
192 | - height: __headerVisibleHeight + __overshootHeight |
193 | - |
194 | - Item { |
195 | - id: pageHeaderContainer |
196 | - anchors { |
197 | - left: parent.left |
198 | - right: parent.right |
199 | - bottom: parent.bottom |
200 | - } |
201 | - height: __headerHeight + __overshootHeight |
202 | - } |
203 | - } |
204 | - |
205 | - ListView { |
206 | - id: listView |
207 | - parent: flicker // parent to Flickable so mouse click events passed through to List delegates |
208 | - anchors { |
209 | - left: parent.left |
210 | - right: parent.right |
211 | - top: parent.top |
212 | - topMargin: __headerVisibleHeight |
213 | - } |
214 | - height: root.height |
215 | - |
216 | - // FIXME scrolling workaround, see below |
217 | - cacheBuffer: height*10 |
218 | - |
219 | - section.property: sectionProperty |
220 | - section.criteria: ViewSection.FullString |
221 | - section.labelPositioning: ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart |
222 | - section.delegate: sectionDelegate |
223 | - |
224 | - interactive: false |
225 | - clip: root.clipListView |
226 | - |
227 | - property int __sectionDelegateHeight: __getHeight(section.delegate) |
228 | - function __getHeight(component) { |
229 | - // want height (minus allowed overlap) of the section delegate as is needed for clipping |
230 | - if (component === null) return 0; |
231 | - var object = component.createObject(); //FIXME: throws 'section' not defined error |
232 | - var value = object.height - object.bottomBorderAllowedOverlap; |
233 | - object.destroy(); |
234 | - return value; |
235 | - } |
236 | - |
237 | - property real previousOriginY: 0 |
238 | - onOriginYChanged: { |
239 | - var deltaOriginY = originY - previousOriginY; |
240 | - previousOriginY = originY; |
241 | - /* When originY changes, it causes the top of the flicker and the top of the list to fall |
242 | - out of sync - and thus the contentY positioning will be broken. To correct for this we |
243 | - manually change the flickable's contentY here */ |
244 | - flicker.contentY -= deltaOriginY; |
245 | - } |
246 | - |
247 | - /* For case when list content greater than container height and list scrolled down so header |
248 | - hidden. If content shrinks to be smaller than the container height, we want the header to |
249 | - re-appear */ |
250 | - property real __previousContentHeight: 0 |
251 | - onContentHeightChanged: { |
252 | - var deltaContentHeight = contentHeight - __previousContentHeight; |
253 | - __previousContentHeight = contentHeight; |
254 | - if (contentHeight < height && deltaContentHeight < 0 && __headerVisibleHeight < height - contentHeight) { |
255 | - __headerVisibleHeight = Math.min(height - contentHeight, __headerHeight); |
256 | - } |
257 | - } |
258 | - } |
259 | - |
260 | - Flickable { |
261 | - id: flicker |
262 | - anchors.fill: parent |
263 | - contentHeight: listView.contentHeight + __headerHeight |
264 | - maximumFlickVelocity: height * 10 |
265 | - flickDeceleration: height * 2 |
266 | - onContentYChanged: { |
267 | - var deltaContentY = contentY - __previousContentY; |
268 | - __previousContentY = contentY; |
269 | - |
270 | - // first decide if movement will prompt the page header to change height |
271 | - if ((deltaContentY < 0 && __headerVisibleHeight >= 0) || |
272 | - (deltaContentY > 0 && __headerVisibleHeight <= __headerHeight)) { |
273 | - |
274 | - // calculate header height - but prevent bounce from changing it |
275 | - if (contentY > 0 && contentY < contentHeight - height) { |
276 | - __headerVisibleHeight = MathLocal.clamp(__headerVisibleHeight - deltaContentY, 0, __headerHeight); |
277 | - } |
278 | - } |
279 | - |
280 | - // now we move list position, taking into account page header height |
281 | - |
282 | - // BUG: With section headers enabled, the values of originY and contentY appear not |
283 | - // correct at the exact point originY changes. originY changes when the ListView |
284 | - // deletes/creates hidden delegates which are above the visible delegates. |
285 | - // As a result of this bug, you experience jittering scrolling when rapidly moving |
286 | - // around in large lists. See https://bugreports.qt-project.org/browse/QTBUG-27997 |
287 | - // A workaround is to use a large enough cacheBuffer to prevent deletions/creations |
288 | - // so effectively originY is always zero. |
289 | - var newContentY = flicker.contentY + listView.originY - __headerHeight + __headerVisibleHeight |
290 | - if (newContentY < listView.contentHeight) { |
291 | - listView.contentY = newContentY; |
292 | - } |
293 | - } |
294 | - |
295 | - property real __previousContentY: 0 |
296 | - } |
297 | -} |
298 | |
299 | === modified file 'Dash/DashApps.qml' |
300 | --- Dash/DashApps.qml 2013-06-12 12:52:35 +0000 |
301 | +++ Dash/DashApps.qml 2013-07-01 11:23:32 +0000 |
302 | @@ -99,7 +99,7 @@ |
303 | When using Loader to load external QML file in the list deelgate, the ListView has |
304 | a bug where it can position the delegate content to overlap the section header |
305 | of the ListView - a workaround is to use sourceComponent of Loader instead */ |
306 | - Component { id: runningApplicationsGrid; RunningApplicationsGrid {} } |
307 | + Component { id: runningApplicationsGrid; RunningApplicationsGrid { clip: true } } |
308 | Component { |
309 | id: applicationsFilterGrid; |
310 | ApplicationsFilterGrid { |
311 | @@ -112,7 +112,7 @@ |
312 | "ApplicationsFilterGrid": applicationsFilterGrid, |
313 | } |
314 | |
315 | - ListViewWithPageHeader { |
316 | + ScopeListView { |
317 | id: categoryView |
318 | anchors.fill: parent |
319 | model: SortFilterProxyModel { |
320 | @@ -150,7 +150,6 @@ |
321 | item.model = categoryModels[modelName] |
322 | } |
323 | } |
324 | - asynchronous: true |
325 | } |
326 | |
327 | ListView.onRemove: SequentialAnimation { |
328 | |
329 | === modified file 'Dash/DashHome.qml' |
330 | --- Dash/DashHome.qml 2013-06-14 13:54:08 +0000 |
331 | +++ Dash/DashHome.qml 2013-07-01 11:23:32 +0000 |
332 | @@ -130,7 +130,7 @@ |
333 | "VideosGrid": videosGrid, |
334 | } |
335 | |
336 | - ListViewWithPageHeader { |
337 | + ScopeListView { |
338 | id: listView |
339 | anchors.fill: parent |
340 | model: categoryListModel |
341 | @@ -161,7 +161,6 @@ |
342 | item.clicked.connect(playVideo); |
343 | } |
344 | } |
345 | - asynchronous: true |
346 | } |
347 | } |
348 | |
349 | |
350 | === modified file 'Dash/DashMusic.qml' |
351 | --- Dash/DashMusic.qml 2013-06-14 20:57:40 +0000 |
352 | +++ Dash/DashMusic.qml 2013-07-01 11:23:32 +0000 |
353 | @@ -64,7 +64,7 @@ |
354 | } |
355 | } |
356 | |
357 | - ListViewWithPageHeader { |
358 | + ScopeListView { |
359 | id: categoryView |
360 | anchors.fill: parent |
361 | model: scopeView.categories |
362 | @@ -84,7 +84,6 @@ |
363 | onLoaded: { |
364 | item.model = results |
365 | } |
366 | - asynchronous: true |
367 | } |
368 | } |
369 | |
370 | |
371 | === modified file 'Dash/DashVideos.qml' |
372 | --- Dash/DashVideos.qml 2013-06-14 20:57:40 +0000 |
373 | +++ Dash/DashVideos.qml 2013-07-01 11:23:32 +0000 |
374 | @@ -97,11 +97,11 @@ |
375 | } |
376 | } |
377 | |
378 | - ListViewWithPageHeader { |
379 | + ScopeListView { |
380 | id: categoryView |
381 | anchors.fill: parent |
382 | model: scopeView.categories |
383 | - clipListView: !previewLoader.onScreen |
384 | + forceNoClip: previewLoader.onScreen |
385 | |
386 | onAtYEndChanged: if (atYEnd) endReached() |
387 | onMovingChanged: if (moving && atYEnd) endReached() |
388 | @@ -119,7 +119,6 @@ |
389 | onLoaded: { |
390 | item.model = results |
391 | } |
392 | - asynchronous: true |
393 | |
394 | Connections { |
395 | target: loader.item |
396 | |
397 | === modified file 'Dash/GenericScopeView.qml' |
398 | --- Dash/GenericScopeView.qml 2013-06-12 12:52:35 +0000 |
399 | +++ Dash/GenericScopeView.qml 2013-07-01 11:23:32 +0000 |
400 | @@ -43,7 +43,7 @@ |
401 | } |
402 | } |
403 | |
404 | - ListViewWithPageHeader { |
405 | + ScopeListView { |
406 | id: categoryView |
407 | anchors.fill: parent |
408 | model: scopeView.categories |
409 | |
410 | === added file 'Dash/ScopeListView.qml' |
411 | --- Dash/ScopeListView.qml 1970-01-01 00:00:00 +0000 |
412 | +++ Dash/ScopeListView.qml 2013-07-01 11:23:32 +0000 |
413 | @@ -0,0 +1,23 @@ |
414 | +/* |
415 | + * Copyright (C) 2013 Canonical, Ltd. |
416 | + * |
417 | + * This program is free software; you can redistribute it and/or modify |
418 | + * it under the terms of the GNU General Public License as published by |
419 | + * the Free Software Foundation; version 3. |
420 | + * |
421 | + * This program is distributed in the hope that it will be useful, |
422 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
423 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
424 | + * GNU General Public License for more details. |
425 | + * |
426 | + * You should have received a copy of the GNU General Public License |
427 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
428 | + */ |
429 | + |
430 | +import QtQuick 2.0 |
431 | +import ListViewWithPageHeader 0.1 |
432 | + |
433 | +ListViewWithPageHeader { |
434 | + maximumFlickVelocity: height * 10 |
435 | + flickDeceleration: height * 2 |
436 | +} |
437 | |
438 | === modified file 'debian/control' |
439 | --- debian/control 2013-06-20 00:01:16 +0000 |
440 | +++ debian/control 2013-07-01 11:23:32 +0000 |
441 | @@ -11,6 +11,7 @@ |
442 | libgles2-mesa-dev[armhf], |
443 | libhud-client2-dev, |
444 | libpulse-dev, |
445 | + libqt5v8-5-private-dev, |
446 | libunity-core-6.0-dev (<< 7.80), |
447 | libxcb1-dev, |
448 | pkg-config, |
449 | @@ -20,6 +21,7 @@ |
450 | qtbase5-private-dev, |
451 | qtdeclarative5-dev, |
452 | qtdeclarative5-dev-tools, |
453 | + qtdeclarative5-private-dev, |
454 | qtdeclarative5-qtquick2-plugin, |
455 | qtdeclarative5-test-plugin, |
456 | qtdeclarative5-ubuntu-ui-toolkit-plugin, |
457 | |
458 | === modified file 'debian/unity8.install' |
459 | --- debian/unity8.install 2013-06-05 22:03:08 +0000 |
460 | +++ debian/unity8.install 2013-07-01 11:23:32 +0000 |
461 | @@ -15,6 +15,7 @@ |
462 | /usr/share/unity8/graphics/* |
463 | /usr/share/unity8/plugins/HudClient/* |
464 | /usr/share/unity8/plugins/LightDM/* |
465 | +/usr/share/unity8/plugins/ListViewWithPageHeader/* |
466 | /usr/share/unity8/plugins/Ubuntu/* |
467 | /usr/share/unity8/plugins/Unity/* |
468 | /usr/share/unity8/plugins/Utils/* |
469 | |
470 | === modified file 'plugins/CMakeLists.txt' |
471 | --- plugins/CMakeLists.txt 2013-06-05 22:03:08 +0000 |
472 | +++ plugins/CMakeLists.txt 2013-07-01 11:23:32 +0000 |
473 | @@ -3,3 +3,4 @@ |
474 | add_subdirectory(Unity) |
475 | add_subdirectory(HudClient) |
476 | add_subdirectory(LightDM) |
477 | +add_subdirectory(ListViewWithPageHeader) |
478 | |
479 | === added directory 'plugins/ListViewWithPageHeader' |
480 | === added file 'plugins/ListViewWithPageHeader/CMakeLists.txt' |
481 | --- plugins/ListViewWithPageHeader/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
482 | +++ plugins/ListViewWithPageHeader/CMakeLists.txt 2013-07-01 11:23:32 +0000 |
483 | @@ -0,0 +1,44 @@ |
484 | +# There's no cmake var for v8 include path :-/ |
485 | +# so create one |
486 | +LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0) |
487 | +SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8) |
488 | + |
489 | +include_directories( |
490 | + ${CMAKE_CURRENT_SOURCE_DIR} |
491 | + ${CMAKE_CURRENT_BINARY_DIR} |
492 | + ${Qt5Qml_PRIVATE_INCLUDE_DIRS} |
493 | + ${Qt5Quick_INCLUDE_DIRS} |
494 | + ${Qt5Quick_PRIVATE_INCLUDE_DIRS} |
495 | + ${Qt5V8_PRIVATE_INCLUDE_DIR} |
496 | +) |
497 | + |
498 | +remove_definitions(-DQT_NO_KEYWORDS) |
499 | + |
500 | +set(QMLPLUGIN_SRC |
501 | + plugin.cpp |
502 | + listviewwithpageheader.cpp |
503 | + ) |
504 | + |
505 | +add_library(ListViewWithPageHeader-qml MODULE |
506 | + ${QMLPLUGIN_SRC} |
507 | + ) |
508 | + |
509 | +target_link_libraries(ListViewWithPageHeader-qml |
510 | + ${Qt5Gui_LIBRARIES} |
511 | + ${Qt5Quick_LIBRARIES} |
512 | + ) |
513 | + |
514 | +qt5_use_modules(ListViewWithPageHeader-qml Qml Quick) |
515 | + |
516 | +# copy qmldir file into build directory for shadow builds |
517 | +file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" |
518 | + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} |
519 | + ) |
520 | + |
521 | +install(TARGETS ListViewWithPageHeader-qml |
522 | + DESTINATION ${SHELL_APP_DIR}/plugins/ListViewWithPageHeader |
523 | + ) |
524 | + |
525 | +install(FILES qmldir |
526 | + DESTINATION ${SHELL_APP_DIR}/plugins/ListViewWithPageHeader |
527 | + ) |
528 | |
529 | === added file 'plugins/ListViewWithPageHeader/listviewwithpageheader.cpp' |
530 | --- plugins/ListViewWithPageHeader/listviewwithpageheader.cpp 1970-01-01 00:00:00 +0000 |
531 | +++ plugins/ListViewWithPageHeader/listviewwithpageheader.cpp 2013-07-01 11:23:32 +0000 |
532 | @@ -0,0 +1,1059 @@ |
533 | +/* |
534 | + * Copyright (C) 2013 Canonical, Ltd. |
535 | + * |
536 | + * This program is free software; you can redistribute it and/or modify |
537 | + * it under the terms of the GNU General Public License as published by |
538 | + * the Free Software Foundation; version 3. |
539 | + * |
540 | + * This program is distributed in the hope that it will be useful, |
541 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
542 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
543 | + * GNU General Public License for more details. |
544 | + * |
545 | + * You should have received a copy of the GNU General Public License |
546 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
547 | + */ |
548 | + |
549 | +/* |
550 | + * Some documentation on how this thing works: |
551 | + * |
552 | + * A flickable has two very important concepts that define the top and |
553 | + * height of the flickable area. |
554 | + * The top is returned in minYExtent() |
555 | + * The height is set using setContentHeight() |
556 | + * By changing those two values we can make the list grow up or down |
557 | + * as needed. e.g. if we are in the middle of the list |
558 | + * and something that is above the viewport grows, since we do not |
559 | + * want to change the viewport because of that we just adjust the |
560 | + * minYExtent so that the list grows up. |
561 | + * |
562 | + * The implementation on the list relies on the delegateModel doing |
563 | + * most of the instantiation work. You call createItem() when you |
564 | + * need to create an item asking for it async or not. If returns null |
565 | + * it means the item will be created async and the model will call the |
566 | + * itemCreated slot with the item. |
567 | + * |
568 | + * updatePolish is the central point of dispatch for the work of the |
569 | + * class. It is called by the scene graph just before drawing the class. |
570 | + * In it we: |
571 | + * * Make sure all items are positioned correctly |
572 | + * * Add/Remove items if needed |
573 | + * * Update the content height if it was dirty |
574 | + * |
575 | + * m_visibleItems contains all the items we have created at the moment. |
576 | + * Actually not all of them are visible since it includes the ones |
577 | + * in the cache area we create asynchronously to help performance. |
578 | + * The first item in m_visibleItems has the m_firstVisibleIndex in |
579 | + * the model. If you actually want to know what is the first |
580 | + * item in the viewport you have to find the first non culled element |
581 | + * in m_visibleItems |
582 | + * |
583 | + * All the items (except the header) are childs of m_clipItem which |
584 | + * is a child of the contentItem() of the flickable (The contentItem() |
585 | + * is what actually 'moves' in a a flickable). This way |
586 | + * we can implement the clipping needed so we can have the header |
587 | + * shown in the middle of the list over the items without the items |
588 | + * leaking under the header in case it is transparent. |
589 | + * |
590 | + * The first item of m_visibleItems is the one that defines the |
591 | + * positions of all the rest of items (see updatePolish()) and |
592 | + * this is why sometimes we move it even if it's not the item |
593 | + * that has triggered the function (i.e. in itemGeometryChanged()) |
594 | + * |
595 | + * m_visibleItems is a list of ListItem. Each ListItem |
596 | + * will contain a item and potentially a sectionItem. The sectionItem |
597 | + * is only there when the list is using sectionDelegate+sectionProperty |
598 | + * and this is the first item of the section. Each ListItem is vertically |
599 | + * layouted with the sectionItem first and then the item. |
600 | + * |
601 | + * For sectioning we also have a section item alone (m_topSectionItem) |
602 | + * that is used for the cases we need to show the sticky section item at |
603 | + * the top of the view. |
604 | + * |
605 | + * Each delegate item has a context property called heightToClip that is |
606 | + * used to communicate to the delegate implementation in case it has to |
607 | + * clip itself because of overlapping with the top sticky section item. |
608 | + * This is an implementation decision since it has been agreed it |
609 | + * is easier to implement the clipping in QML with this info than to |
610 | + * do it at the C++ level. |
611 | + * |
612 | + * Note that minYExtent and height are not always totally accurate, since |
613 | + * we don't have the items created we can't guess their heights |
614 | + * so we can only guarantee the values are correct when the first/last |
615 | + * items of the list are visible, otherwise we just live with good enough |
616 | + * values that make the list scrollable |
617 | + * |
618 | + * There are a few things that are not really implemented or tested properly |
619 | + * which we don't use at the moment like changing the model, changing |
620 | + * the section delegate, having a section delegate that changes its size, etc. |
621 | + * The known missing features are marked with TODOs along the code. |
622 | + */ |
623 | + |
624 | +#include "listviewwithpageheader.h" |
625 | + |
626 | +#include <QDebug> |
627 | +#include <qqmlinfo.h> |
628 | +#include <qqmlengine.h> |
629 | +#include <private/qquickvisualdatamodel_p.h> |
630 | +#include <private/qqmlglobal_p.h> |
631 | +#include <private/qquickitem_p.h> |
632 | +#include <private/qquickanimation_p.h> |
633 | +// #include <private/qquickrectangle_p.h> |
634 | + |
635 | +static const qreal bufferRatio = 0.5; |
636 | + |
637 | +qreal ListViewWithPageHeader::ListItem::height() const |
638 | +{ |
639 | + return m_item->height() + (m_sectionItem ? m_sectionItem->height() : 0); |
640 | +} |
641 | + |
642 | +qreal ListViewWithPageHeader::ListItem::y() const |
643 | +{ |
644 | + return m_item->y() - (m_sectionItem ? m_sectionItem->height() : 0); |
645 | +} |
646 | + |
647 | +void ListViewWithPageHeader::ListItem::setY(qreal newY) |
648 | +{ |
649 | + if (m_sectionItem) { |
650 | + m_sectionItem->setY(newY); |
651 | + m_item->setY(newY + m_sectionItem->height()); |
652 | + } else { |
653 | + m_item->setY(newY); |
654 | + } |
655 | +} |
656 | + |
657 | +bool ListViewWithPageHeader::ListItem::culled() const |
658 | +{ |
659 | + return QQuickItemPrivate::get(m_item)->culled; |
660 | +} |
661 | + |
662 | +void ListViewWithPageHeader::ListItem::setCulled(bool culled) |
663 | +{ |
664 | + QQuickItemPrivate::get(m_item)->setCulled(culled); |
665 | + if (m_sectionItem) |
666 | + QQuickItemPrivate::get(m_sectionItem)->setCulled(culled); |
667 | +} |
668 | + |
669 | +ListViewWithPageHeader::ListViewWithPageHeader() |
670 | + : m_delegateModel(nullptr) |
671 | + , m_asyncRequestedIndex(-1) |
672 | + , m_delegateValidated(false) |
673 | + , m_firstVisibleIndex(-1) |
674 | + , m_minYExtent(0) |
675 | + , m_contentHeightDirty(false) |
676 | + , m_headerItem(nullptr) |
677 | + , m_previousContentY(0) |
678 | + , m_headerItemShownHeight(0) |
679 | + , m_sectionDelegate(nullptr) |
680 | + , m_topSectionItem(nullptr) |
681 | + , m_forceNoClip(false) |
682 | + , m_inLayout(false) |
683 | +{ |
684 | + m_clipItem = new QQuickItem(contentItem()); |
685 | +// m_clipItem = new QQuickRectangle(contentItem()); |
686 | +// ((QQuickRectangle*)m_clipItem)->setColor(Qt::gray); |
687 | + |
688 | + m_headerShowAnimation = new QQuickNumberAnimation(this); |
689 | + m_headerShowAnimation->setEasing(QEasingCurve::OutQuad); |
690 | + m_headerShowAnimation->setProperty("contentY"); |
691 | + m_headerShowAnimation->setDuration(200); |
692 | + m_headerShowAnimation->setTargetObject(this); |
693 | + |
694 | + connect(this, SIGNAL(contentWidthChanged()), this, SLOT(onContentWidthChanged())); |
695 | + connect(this, SIGNAL(contentHeightChanged()), this, SLOT(onContentHeightChanged())); |
696 | + connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged())); |
697 | + connect(m_headerShowAnimation, SIGNAL(stopped()), this, SLOT(onShowHeaderAnimationFinished())); |
698 | +} |
699 | + |
700 | +ListViewWithPageHeader::~ListViewWithPageHeader() |
701 | +{ |
702 | +} |
703 | + |
704 | +QAbstractItemModel *ListViewWithPageHeader::model() const |
705 | +{ |
706 | + return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() : nullptr; |
707 | +} |
708 | + |
709 | +void ListViewWithPageHeader::setModel(QAbstractItemModel *model) |
710 | +{ |
711 | + if (model != this->model()) { |
712 | + if (!m_delegateModel) { |
713 | + createDelegateModel(); |
714 | + } else { |
715 | + disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool))); |
716 | + } |
717 | + m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model)); |
718 | + connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool))); |
719 | + Q_EMIT modelChanged(); |
720 | + // TODO? |
721 | +// Q_EMIT contentHeightChanged(); |
722 | +// Q_EMIT contentYChanged(); |
723 | + } |
724 | +} |
725 | + |
726 | +QQmlComponent *ListViewWithPageHeader::delegate() const |
727 | +{ |
728 | + return m_delegateModel ? m_delegateModel->delegate() : nullptr; |
729 | +} |
730 | + |
731 | +void ListViewWithPageHeader::setDelegate(QQmlComponent *delegate) |
732 | +{ |
733 | + if (delegate != this->delegate()) { |
734 | + if (!m_delegateModel) { |
735 | + createDelegateModel(); |
736 | + } |
737 | + |
738 | + // Cleanup the existing items |
739 | + Q_FOREACH(ListItem *item, m_visibleItems) |
740 | + releaseItem(item); |
741 | + m_visibleItems.clear(); |
742 | + m_firstVisibleIndex = -1; |
743 | + adjustMinYExtent(); |
744 | + setContentY(0); |
745 | + m_clipItem->setY(0); |
746 | + if (m_topSectionItem) { |
747 | + QQuickItemPrivate::get(m_topSectionItem)->setCulled(true); |
748 | + } |
749 | + |
750 | + m_delegateModel->setDelegate(delegate); |
751 | + |
752 | + Q_EMIT delegateChanged(); |
753 | + m_delegateValidated = false; |
754 | + m_contentHeightDirty = true; |
755 | + polish(); |
756 | + } |
757 | +} |
758 | + |
759 | +QQuickItem *ListViewWithPageHeader::header() const |
760 | +{ |
761 | + return m_headerItem; |
762 | +} |
763 | + |
764 | +void ListViewWithPageHeader::setHeader(QQuickItem *headerItem) |
765 | +{ |
766 | + if (m_headerItem != headerItem) { |
767 | + qreal oldHeaderHeight = 0; |
768 | + qreal oldHeaderY = 0; |
769 | + if (m_headerItem) { |
770 | + oldHeaderHeight = m_headerItem->height(); |
771 | + oldHeaderY = m_headerItem->y(); |
772 | + m_headerItem->setParentItem(nullptr); |
773 | + } |
774 | + m_headerItem = headerItem; |
775 | + if (m_headerItem) { |
776 | + m_headerItem->setParentItem(contentItem()); |
777 | + m_headerItem->setZ(1); |
778 | + } |
779 | + qreal newHeaderHeight = m_headerItem ? m_headerItem->height() : 0; |
780 | + if (!m_visibleItems.isEmpty() && newHeaderHeight != oldHeaderHeight) { |
781 | + headerHeightChanged(newHeaderHeight, oldHeaderHeight, oldHeaderY); |
782 | + polish(); |
783 | + m_contentHeightDirty = true; |
784 | + } |
785 | + Q_EMIT headerChanged(); |
786 | + } |
787 | +} |
788 | + |
789 | +QQmlComponent *ListViewWithPageHeader::sectionDelegate() const |
790 | +{ |
791 | + return m_sectionDelegate; |
792 | +} |
793 | + |
794 | +void ListViewWithPageHeader::setSectionDelegate(QQmlComponent *delegate) |
795 | +{ |
796 | + if (delegate != m_sectionDelegate) { |
797 | + // TODO clean existing sections |
798 | + |
799 | + m_sectionDelegate = delegate; |
800 | + |
801 | + m_topSectionItem = getSectionItem(QString()); |
802 | + m_topSectionItem->setZ(3); |
803 | + QQuickItemPrivate::get(m_topSectionItem)->setCulled(true); |
804 | + |
805 | + // TODO create sections for existing items |
806 | + |
807 | + Q_EMIT sectionDelegateChanged(); |
808 | + } |
809 | +} |
810 | + |
811 | +QString ListViewWithPageHeader::sectionProperty() const |
812 | +{ |
813 | + return m_sectionProperty; |
814 | +} |
815 | + |
816 | +void ListViewWithPageHeader::setSectionProperty(const QString &property) |
817 | +{ |
818 | + if (property != m_sectionProperty) { |
819 | + m_sectionProperty = property; |
820 | + |
821 | + updateWatchedRoles(); |
822 | + |
823 | + // TODO recreate sections |
824 | + |
825 | + Q_EMIT sectionPropertyChanged(); |
826 | + } |
827 | +} |
828 | + |
829 | +bool ListViewWithPageHeader::forceNoClip() const |
830 | +{ |
831 | + return m_forceNoClip; |
832 | +} |
833 | + |
834 | +void ListViewWithPageHeader::setForceNoClip(bool noClip) |
835 | +{ |
836 | + if (noClip != m_forceNoClip) { |
837 | + m_forceNoClip = noClip; |
838 | + updateClipItem(); |
839 | + Q_EMIT forceNoClipChanged(); |
840 | + } |
841 | +} |
842 | + |
843 | +void ListViewWithPageHeader::positionAtBeginning() |
844 | +{ |
845 | + qreal headerHeight = (m_headerItem ? m_headerItem->height() : 0); |
846 | + if (m_firstVisibleIndex != 0) { |
847 | + // TODO This could be optimized by trying to reuse the interesection |
848 | + // of items that may end up intersecting between the existing |
849 | + // m_visibleItems and the items we are creating in the next loop |
850 | + Q_FOREACH(ListItem *item, m_visibleItems) |
851 | + releaseItem(item); |
852 | + m_visibleItems.clear(); |
853 | + m_firstVisibleIndex = -1; |
854 | + |
855 | + // Create the item 0, it will be already correctly positioned at createItem() |
856 | + m_clipItem->setY(0); |
857 | + ListItem *item = createItem(0, false); |
858 | + // Create the subsequent items |
859 | + int modelIndex = 1; |
860 | + qreal pos = item->y() + item->height(); |
861 | + const qreal buffer = height() * bufferRatio; |
862 | + const qreal bufferTo = height() + buffer; |
863 | + while (modelIndex < m_delegateModel->count() && pos <= bufferTo) { |
864 | + if (!(item = createItem(modelIndex, false))) |
865 | + break; |
866 | + pos += item->height(); |
867 | + ++modelIndex; |
868 | + } |
869 | + |
870 | + m_previousContentY = m_visibleItems.first()->y() - headerHeight; |
871 | + } |
872 | + setContentY(m_visibleItems.first()->y() + m_clipItem->y() - headerHeight); |
873 | +} |
874 | + |
875 | +void ListViewWithPageHeader::showHeader() |
876 | +{ |
877 | + auto to = qMax(-minYExtent(), contentY() - m_headerItem->height() + m_headerItemShownHeight); |
878 | + if (to != contentY()) { |
879 | + m_headerShowAnimation->setTo(to); |
880 | + m_headerShowAnimation->start(); |
881 | + } |
882 | +} |
883 | + |
884 | +qreal ListViewWithPageHeader::minYExtent() const |
885 | +{ |
886 | +// qDebug() << "ListViewWithPageHeader::minYExtent" << m_minYExtent; |
887 | + return m_minYExtent; |
888 | +} |
889 | + |
890 | +void ListViewWithPageHeader::componentComplete() |
891 | +{ |
892 | + if (m_delegateModel) |
893 | + m_delegateModel->componentComplete(); |
894 | + |
895 | + QQuickFlickable::componentComplete(); |
896 | + |
897 | + polish(); |
898 | +} |
899 | + |
900 | +void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient) |
901 | +{ |
902 | + QQuickFlickable::viewportMoved(orient); |
903 | +// qDebug() << "ListViewWithPageHeader::viewportMoved" << contentY(); |
904 | + qreal diff = m_previousContentY - contentY(); |
905 | + if (m_headerItem) { |
906 | + auto oldHeaderItemShownHeight = m_headerItemShownHeight; |
907 | + if (contentY() < -m_minYExtent) { |
908 | + // Stick the header item to the top when dragging down |
909 | + m_headerItem->setY(contentY()); |
910 | + m_headerItem->setHeight(m_headerItem->implicitHeight() + (-m_minYExtent - contentY())); |
911 | + } else { |
912 | + m_headerItem->setHeight(m_headerItem->implicitHeight()); |
913 | + // We are going down (but it's not because of the rebound at the end) |
914 | + // (but the header was not shown by it's own position) |
915 | + // or the header is partially shown |
916 | + const bool scrolledUp = m_previousContentY > contentY(); |
917 | + const bool notRebounding = contentY() + height() < contentHeight(); |
918 | + const bool notShownByItsOwn = contentY() + diff > m_headerItem->y() + m_headerItem->height(); |
919 | + |
920 | + if (!scrolledUp && contentY() == -m_minYExtent) { |
921 | + m_headerItemShownHeight = 0; |
922 | + m_headerItem->setY(contentY()); |
923 | + } else if ((scrolledUp && notRebounding && notShownByItsOwn) || (m_headerItemShownHeight > 0)) { |
924 | + m_headerItemShownHeight += diff; |
925 | + if (contentY() == -m_minYExtent) { |
926 | + m_headerItemShownHeight = 0; |
927 | + } else { |
928 | + m_headerItemShownHeight = qBound(static_cast<qreal>(0.), m_headerItemShownHeight, m_headerItem->height()); |
929 | + } |
930 | + if (m_headerItemShownHeight > 0) { |
931 | + m_headerItem->setY(contentY() - m_headerItem->height() + m_headerItemShownHeight); |
932 | + } else { |
933 | + m_headerItem->setY(-m_minYExtent); |
934 | + } |
935 | + } |
936 | + } |
937 | + // We will be changing the clip item, need to accomadate for it |
938 | + // otherwise we move the firstItem down/up twice (unless the |
939 | + // show header animation is running, where we want to keep the viewport stable) |
940 | + if (!m_headerShowAnimation->isRunning()) { |
941 | + diff += oldHeaderItemShownHeight - m_headerItemShownHeight; |
942 | + } else { |
943 | + diff = -diff; |
944 | + } |
945 | + } |
946 | + if (!m_visibleItems.isEmpty()) { |
947 | + updateClipItem(); |
948 | + ListItem *firstItem = m_visibleItems.first(); |
949 | + firstItem->setY(firstItem->y() + diff); |
950 | + if (m_headerShowAnimation->isRunning()) { |
951 | + adjustMinYExtent(); |
952 | + } |
953 | + } |
954 | + |
955 | + m_previousContentY = contentY(); |
956 | + layout(); |
957 | + polish(); |
958 | +} |
959 | + |
960 | +void ListViewWithPageHeader::createDelegateModel() |
961 | +{ |
962 | + m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this); |
963 | + connect(m_delegateModel, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(itemCreated(int,QQuickItem*))); |
964 | + if (isComponentComplete()) |
965 | + m_delegateModel->componentComplete(); |
966 | + updateWatchedRoles(); |
967 | +} |
968 | + |
969 | +void ListViewWithPageHeader::refill() |
970 | +{ |
971 | + if (m_inLayout) { |
972 | + return; |
973 | + } |
974 | + if (!isComponentComplete()) { |
975 | + return; |
976 | + } |
977 | + |
978 | + const qreal buffer = height() * bufferRatio; |
979 | + const qreal from = contentY(); |
980 | + const qreal to = from + height(); |
981 | + const qreal bufferFrom = from - buffer; |
982 | + const qreal bufferTo = to + buffer; |
983 | + |
984 | + bool added = addVisibleItems(from, to, false); |
985 | + bool removed = removeNonVisibleItems(bufferFrom, bufferTo); |
986 | + added |= addVisibleItems(bufferFrom, bufferTo, true); |
987 | + |
988 | + if (added || removed) { |
989 | + m_contentHeightDirty = true; |
990 | + } |
991 | +} |
992 | + |
993 | +bool ListViewWithPageHeader::addVisibleItems(qreal fillFrom, qreal fillTo, bool asynchronous) |
994 | +{ |
995 | + if (!delegate()) |
996 | + return false; |
997 | + |
998 | + if (m_delegateModel->count() == 0) |
999 | + return false; |
1000 | + |
1001 | + ListItem *item; |
1002 | +// qDebug() << "ListViewWithPageHeader::addVisibleItems" << fillFrom << fillTo << asynchronous; |
1003 | + |
1004 | + int modelIndex = 0; |
1005 | + qreal pos = 0; |
1006 | + if (!m_visibleItems.isEmpty()) { |
1007 | + modelIndex = m_firstVisibleIndex + m_visibleItems.count(); |
1008 | + item = m_visibleItems.last(); |
1009 | + pos = item->y() + item->height() + m_clipItem->y(); |
1010 | + } |
1011 | + bool changed = false; |
1012 | +// qDebug() << (modelIndex < m_delegateModel->count()) << pos << fillTo; |
1013 | + while (modelIndex < m_delegateModel->count() && pos <= fillTo) { |
1014 | +// qDebug() << "refill: append item" << modelIndex << "pos" << pos << "asynchronous" << asynchronous; |
1015 | + if (!(item = createItem(modelIndex, asynchronous))) |
1016 | + break; |
1017 | + pos += item->height(); |
1018 | + ++modelIndex; |
1019 | + changed = true; |
1020 | + } |
1021 | + |
1022 | + modelIndex = 0; |
1023 | + pos = 0; |
1024 | + if (!m_visibleItems.isEmpty()) { |
1025 | + modelIndex = m_firstVisibleIndex - 1; |
1026 | + item = m_visibleItems.first(); |
1027 | + pos = item->y() + m_clipItem->y(); |
1028 | + } |
1029 | + while (modelIndex >= 0 && pos > fillFrom) { |
1030 | +// qDebug() << "refill: prepend item" << modelIndex << "pos" << pos << "fillFrom" << fillFrom << "asynchronous" << asynchronous; |
1031 | + if (!(item = createItem(modelIndex, asynchronous))) |
1032 | + break; |
1033 | + pos -= item->height(); |
1034 | + --modelIndex; |
1035 | + changed = true; |
1036 | + } |
1037 | + |
1038 | + return changed; |
1039 | +} |
1040 | + |
1041 | +void ListViewWithPageHeader::reallyReleaseItem(ListItem *listItem) |
1042 | +{ |
1043 | + QQuickItem *item = listItem->m_item; |
1044 | + QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item); |
1045 | + if (flags & QQuickVisualModel::Destroyed) { |
1046 | + item->setParentItem(nullptr); |
1047 | + } |
1048 | + delete listItem->m_sectionItem; |
1049 | + delete listItem; |
1050 | +} |
1051 | + |
1052 | +void ListViewWithPageHeader::releaseItem(ListItem *listItem) |
1053 | +{ |
1054 | + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(listItem->m_item); |
1055 | + itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry); |
1056 | + m_itemsToRelease << listItem; |
1057 | +} |
1058 | + |
1059 | +void ListViewWithPageHeader::updateWatchedRoles() |
1060 | +{ |
1061 | + if (m_delegateModel) { |
1062 | + QList<QByteArray> roles; |
1063 | + if (!m_sectionProperty.isEmpty()) |
1064 | + roles << m_sectionProperty.toUtf8(); |
1065 | + m_delegateModel->setWatchedRoles(roles); |
1066 | + } |
1067 | +} |
1068 | + |
1069 | +QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, bool alreadyInserted) |
1070 | +{ |
1071 | + if (!m_sectionDelegate) |
1072 | + return nullptr; |
1073 | + |
1074 | + const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty); |
1075 | + if (modelIndex > 0) { |
1076 | + const QString prevSection = m_delegateModel->stringValue(modelIndex - 1, m_sectionProperty); |
1077 | + if (section == prevSection) |
1078 | + return nullptr; |
1079 | + } |
1080 | + if (modelIndex + 1 < model()->rowCount() && !alreadyInserted) { |
1081 | + // Already inserted items can't steal next section header |
1082 | + const QString nextSection = m_delegateModel->stringValue(modelIndex + 1, m_sectionProperty); |
1083 | + if (section == nextSection) { |
1084 | + // Steal the section header |
1085 | + ListItem *nextItem = itemAtIndex(modelIndex); // Not +1 since not yet inserted into m_visibleItems |
1086 | + if (nextItem) { |
1087 | + QQuickItem *sectionItem = nextItem->m_sectionItem; |
1088 | + nextItem->m_sectionItem = nullptr; |
1089 | + return sectionItem; |
1090 | + } |
1091 | + } |
1092 | + } |
1093 | + |
1094 | + return getSectionItem(section); |
1095 | +} |
1096 | + |
1097 | +QQuickItem *ListViewWithPageHeader::getSectionItem(const QString §ionText) |
1098 | +{ |
1099 | + QQuickItem *sectionItem = nullptr; |
1100 | + |
1101 | + QQmlContext *creationContext = m_sectionDelegate->creationContext(); |
1102 | + QQmlContext *context = new QQmlContext(creationContext ? creationContext : qmlContext(this)); |
1103 | + context->setContextProperty(QLatin1String("section"), sectionText); |
1104 | + QObject *nobj = m_sectionDelegate->beginCreate(context); |
1105 | + if (nobj) { |
1106 | + QQml_setParent_noEvent(context, nobj); |
1107 | + sectionItem = qobject_cast<QQuickItem *>(nobj); |
1108 | + if (!sectionItem) { |
1109 | + delete nobj; |
1110 | + } else { |
1111 | + sectionItem->setZ(2); |
1112 | + QQml_setParent_noEvent(sectionItem, m_clipItem); |
1113 | + sectionItem->setParentItem(m_clipItem); |
1114 | + } |
1115 | + } else { |
1116 | + delete context; |
1117 | + } |
1118 | + m_sectionDelegate->completeCreate(); |
1119 | + |
1120 | + // TODO attach to sectionItem so we can accomodate to it changing its height |
1121 | + |
1122 | + return sectionItem; |
1123 | +} |
1124 | + |
1125 | +bool ListViewWithPageHeader::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) |
1126 | +{ |
1127 | +// qDebug() << "ListViewWithPageHeader::removeNonVisibleItems" << bufferFrom << bufferTo; |
1128 | + // Do not remove items if we are overshooting up or down, since we'll come back |
1129 | + // to the "stable" position and delete/create items without any reason |
1130 | + if (contentY() < -m_minYExtent) { |
1131 | + return false; |
1132 | + } else if (contentY() + height() > contentHeight()) { |
1133 | + return false; |
1134 | + } |
1135 | + bool changed = false; |
1136 | + |
1137 | + bool foundVisible = false; |
1138 | + int i = 0; |
1139 | + int removedItems = 0; |
1140 | + const auto oldFirstVisibleIndex = m_firstVisibleIndex; |
1141 | + while (i < m_visibleItems.count()) { |
1142 | + ListItem *item = m_visibleItems[i]; |
1143 | + const qreal pos = item->y() + m_clipItem->y(); |
1144 | +// qDebug() << i << pos << (pos + item->height()) << bufferFrom << bufferTo; |
1145 | + if (pos + item->height() < bufferFrom || pos > bufferTo) { |
1146 | +// qDebug() << "Releasing" << i << (pos + item->height() < bufferFrom) << pos + item->height() << bufferFrom << (pos > bufferTo) << pos << bufferTo; |
1147 | + releaseItem(item); |
1148 | + m_visibleItems.removeAt(i); |
1149 | + changed = true; |
1150 | + ++removedItems; |
1151 | + } else { |
1152 | + if (!foundVisible) { |
1153 | + foundVisible = true; |
1154 | + const int itemIndex = m_firstVisibleIndex + removedItems + i; |
1155 | + m_firstVisibleIndex = itemIndex; |
1156 | + } |
1157 | + ++i; |
1158 | + } |
1159 | + } |
1160 | + if (m_firstVisibleIndex != oldFirstVisibleIndex) { |
1161 | + adjustMinYExtent(); |
1162 | + } |
1163 | + |
1164 | + return changed; |
1165 | +} |
1166 | + |
1167 | +ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIndex, bool asynchronous) |
1168 | +{ |
1169 | +// qDebug() << "CREATE ITEM" << modelIndex; |
1170 | + if (asynchronous && m_asyncRequestedIndex != -1) |
1171 | + return nullptr; |
1172 | + |
1173 | + m_asyncRequestedIndex = -1; |
1174 | + QQuickItem *item = m_delegateModel->item(modelIndex, asynchronous); |
1175 | + if (!item) { |
1176 | + m_asyncRequestedIndex = modelIndex; |
1177 | + return 0; |
1178 | + } else { |
1179 | +// qDebug() << "ListViewWithPageHeader::createItem::We have the item" << modelIndex << item; |
1180 | + ListItem *listItem = new ListItem; |
1181 | + listItem->m_item = item; |
1182 | + listItem->m_sectionItem = getSectionItem(modelIndex, false /*Not yet inserted into m_visibleItems*/); |
1183 | + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry); |
1184 | + ListItem *prevItem = itemAtIndex(modelIndex - 1); |
1185 | + bool lostItem = false; // Is an item that we requested async but because of model changes |
1186 | + // it is no longer attached to any of the existing items (has no prev nor next item) |
1187 | + // nor is the first item |
1188 | + if (prevItem) { |
1189 | + listItem->setY(prevItem->y() + prevItem->height()); |
1190 | + } else { |
1191 | + ListItem *currItem = itemAtIndex(modelIndex); |
1192 | + if (currItem) { |
1193 | + // There's something already in m_visibleItems at out index, meaning this is an insert, so attach to its top |
1194 | + listItem->setY(currItem->y() - listItem->height()); |
1195 | + } else { |
1196 | + ListItem *nextItem = itemAtIndex(modelIndex + 1); |
1197 | + if (nextItem) { |
1198 | + listItem->setY(nextItem->y() - listItem->height()); |
1199 | + } else if (modelIndex == 0 && m_headerItem) { |
1200 | + listItem->setY(m_headerItem->height()); |
1201 | + } else if (!m_visibleItems.isEmpty()) { |
1202 | + lostItem = true; |
1203 | + } |
1204 | + } |
1205 | + } |
1206 | + if (lostItem) { |
1207 | + releaseItem(listItem); |
1208 | + listItem = nullptr; |
1209 | + } else { |
1210 | + listItem->setCulled(listItem->y() + listItem->height() + m_clipItem->y() < contentY() || listItem->y() + m_clipItem->y() >= contentY() + height()); |
1211 | + if (m_visibleItems.isEmpty()) { |
1212 | + m_visibleItems << listItem; |
1213 | + } else { |
1214 | + m_visibleItems.insert(modelIndex - m_firstVisibleIndex, listItem); |
1215 | + } |
1216 | + if (m_firstVisibleIndex < 0 || modelIndex < m_firstVisibleIndex) { |
1217 | + m_firstVisibleIndex = modelIndex; |
1218 | + polish(); |
1219 | + } |
1220 | + adjustMinYExtent(); |
1221 | + m_contentHeightDirty = true; |
1222 | + } |
1223 | + return listItem; |
1224 | + } |
1225 | +} |
1226 | + |
1227 | +void ListViewWithPageHeader::itemCreated(int modelIndex, QQuickItem *item) |
1228 | +{ |
1229 | +// qDebug() << "ListViewWithPageHeader::itemCreated" << modelIndex << item; |
1230 | + |
1231 | + item->setParentItem(m_clipItem); |
1232 | + QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext(); |
1233 | + context->setContextProperty(QLatin1String("ListViewWithPageHeader"), this); |
1234 | + context->setContextProperty(QLatin1String("heightToClip"), QVariant::fromValue<int>(0)); |
1235 | + if (modelIndex == m_asyncRequestedIndex) { |
1236 | + createItem(modelIndex, false); |
1237 | + refill(); |
1238 | + } |
1239 | +} |
1240 | + |
1241 | +void ListViewWithPageHeader::updateClipItem() |
1242 | +{ |
1243 | + m_clipItem->setHeight(height() - m_headerItemShownHeight); |
1244 | + m_clipItem->setY(contentY() + m_headerItemShownHeight); |
1245 | + m_clipItem->setClip(!m_forceNoClip && m_headerItemShownHeight > 0); |
1246 | +} |
1247 | + |
1248 | +void ListViewWithPageHeader::onContentHeightChanged() |
1249 | +{ |
1250 | + updateClipItem(); |
1251 | +} |
1252 | + |
1253 | +void ListViewWithPageHeader::onContentWidthChanged() |
1254 | +{ |
1255 | + m_clipItem->setWidth(contentItem()->width()); |
1256 | +} |
1257 | + |
1258 | +void ListViewWithPageHeader::onHeightChanged() |
1259 | +{ |
1260 | + polish(); |
1261 | +} |
1262 | + |
1263 | +void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bool /*reset*/) |
1264 | +{ |
1265 | + // TODO Do something with reset |
1266 | +// qDebug() << "ListViewWithPageHeader::onModelUpdated" << changeSet << reset; |
1267 | + const auto oldFirstVisibleIndex = m_firstVisibleIndex; |
1268 | + |
1269 | + Q_FOREACH(const QQuickChangeSet::Remove &remove, changeSet.removes()) { |
1270 | +// qDebug() << "ListViewWithPageHeader::onModelUpdated Remove" << remove.index << remove.count; |
1271 | + if (remove.index + remove.count > m_firstVisibleIndex && remove.index < m_firstVisibleIndex + m_visibleItems.count()) { |
1272 | + const qreal oldFirstValidIndexPos = m_visibleItems.first()->y(); |
1273 | + // If all the items we are removing are either not created or culled |
1274 | + // we have to grow down to avoid viewport changing |
1275 | + bool growDown = true; |
1276 | + for (int i = 0; growDown && i < remove.count; ++i) { |
1277 | + const int modelIndex = remove.index + i; |
1278 | + ListItem *item = itemAtIndex(modelIndex); |
1279 | + if (item && !item->culled()) { |
1280 | + growDown = false; |
1281 | + } |
1282 | + } |
1283 | + for (int i = remove.count - 1; i >= 0; --i) { |
1284 | + const int visibleIndex = remove.index + i - m_firstVisibleIndex; |
1285 | + if (visibleIndex >= 0 && visibleIndex < m_visibleItems.count()) { |
1286 | + ListItem *item = m_visibleItems[visibleIndex]; |
1287 | + // Pass the section item down if needed |
1288 | + if (item->m_sectionItem && visibleIndex + 1 < m_visibleItems.count()) { |
1289 | + ListItem *nextItem = m_visibleItems[visibleIndex + 1]; |
1290 | + if (!nextItem->m_sectionItem) { |
1291 | + nextItem->m_sectionItem = item->m_sectionItem; |
1292 | + item->m_sectionItem = nullptr; |
1293 | + } |
1294 | + } |
1295 | + releaseItem(item); |
1296 | + m_visibleItems.removeAt(visibleIndex); |
1297 | + } |
1298 | + } |
1299 | + if (growDown) { |
1300 | + adjustMinYExtent(); |
1301 | + } else if (remove.index <= m_firstVisibleIndex && !m_visibleItems.isEmpty()) { |
1302 | + // We removed the first item that is the one that positions the rest |
1303 | + // position the new first item correctly |
1304 | + m_visibleItems.first()->setY(oldFirstValidIndexPos); |
1305 | + } |
1306 | + } else if (remove.index + remove.count <= m_firstVisibleIndex) { |
1307 | + m_firstVisibleIndex -= remove.count; |
1308 | + } |
1309 | + for (int i = remove.count - 1; i >= 0; --i) { |
1310 | + const int modelIndex = remove.index + i; |
1311 | + if (modelIndex == m_asyncRequestedIndex) { |
1312 | + m_asyncRequestedIndex = -1; |
1313 | + } else if (modelIndex < m_asyncRequestedIndex) { |
1314 | + m_asyncRequestedIndex--; |
1315 | + } |
1316 | + } |
1317 | + } |
1318 | + |
1319 | + Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) { |
1320 | +// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count; |
1321 | + const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count(); |
1322 | + const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && m_visibleItems.first()->y() + m_clipItem->y() > contentY(); |
1323 | + if (insertingInValidIndexes || firstItemWithViewOnTop) |
1324 | + { |
1325 | + // If the items we are adding won't be really visible |
1326 | + // we grow up instead of down to not change the viewport |
1327 | + bool growUp = false; |
1328 | + if (!firstItemWithViewOnTop) { |
1329 | + for (int i = 0; i < m_visibleItems.count(); ++i) { |
1330 | + if (!m_visibleItems[i]->culled()) { |
1331 | + if (insert.index <= m_firstVisibleIndex + i) { |
1332 | + growUp = true; |
1333 | + } |
1334 | + break; |
1335 | + } |
1336 | + } |
1337 | + } |
1338 | + |
1339 | + const qreal oldFirstValidIndexPos = m_visibleItems.first()->y(); |
1340 | + for (int i = insert.count - 1; i >= 0; --i) { |
1341 | + const int modelIndex = insert.index + i; |
1342 | + ListItem *item = createItem(modelIndex, false); |
1343 | + if (growUp) { |
1344 | + ListItem *firstItem = m_visibleItems.first(); |
1345 | + firstItem->setY(firstItem->y() - item->height()); |
1346 | + adjustMinYExtent(); |
1347 | + } |
1348 | + // Adding an item may break a "same section" chain, so check |
1349 | + // if we need adding a new section item |
1350 | + if (m_sectionDelegate) { |
1351 | + ListItem *nextItem = itemAtIndex(modelIndex + 1); |
1352 | + if (nextItem && !nextItem->m_sectionItem) { |
1353 | + nextItem->m_sectionItem = getSectionItem(modelIndex + 1, true /* alredy inserted into m_visibleItems*/); |
1354 | + if (growUp && nextItem->m_sectionItem) { |
1355 | + ListItem *firstItem = m_visibleItems.first(); |
1356 | + firstItem->setY(firstItem->y() - nextItem->m_sectionItem->height()); |
1357 | + adjustMinYExtent(); |
1358 | + } |
1359 | + } |
1360 | + } |
1361 | + } |
1362 | + if (firstItemWithViewOnTop) { |
1363 | + ListItem *firstItem = m_visibleItems.first(); |
1364 | + firstItem->setY(oldFirstValidIndexPos); |
1365 | + } |
1366 | + } else if (insert.index <= m_firstVisibleIndex) { |
1367 | + m_firstVisibleIndex += insert.count; |
1368 | + } |
1369 | + |
1370 | + for (int i = insert.count - 1; i >= 0; --i) { |
1371 | + const int modelIndex = insert.index + i; |
1372 | + if (modelIndex <= m_asyncRequestedIndex) { |
1373 | + m_asyncRequestedIndex++; |
1374 | + } |
1375 | + } |
1376 | + } |
1377 | + |
1378 | + if (m_firstVisibleIndex != oldFirstVisibleIndex) { |
1379 | + adjustMinYExtent(); |
1380 | + } |
1381 | + |
1382 | + layout(); |
1383 | + polish(); |
1384 | + m_contentHeightDirty = true; |
1385 | +} |
1386 | + |
1387 | +void ListViewWithPageHeader::onShowHeaderAnimationFinished() |
1388 | +{ |
1389 | + m_contentHeightDirty = true; |
1390 | + polish(); |
1391 | +} |
1392 | + |
1393 | +void ListViewWithPageHeader::itemGeometryChanged(QQuickItem * /*item*/, const QRectF &newGeometry, const QRectF &oldGeometry) |
1394 | +{ |
1395 | + const qreal heightDiff = newGeometry.height() - oldGeometry.height(); |
1396 | + if (heightDiff != 0) { |
1397 | + if (oldGeometry.y() + oldGeometry.height() + m_clipItem->y() < contentY() && !m_visibleItems.isEmpty()) { |
1398 | + ListItem *firstItem = m_visibleItems.first(); |
1399 | + firstItem->setY(firstItem->y() - heightDiff); |
1400 | + adjustMinYExtent(); |
1401 | + layout(); |
1402 | + } |
1403 | + refill(); |
1404 | + adjustMinYExtent(); |
1405 | + polish(); |
1406 | + m_contentHeightDirty = true; |
1407 | + } |
1408 | +} |
1409 | + |
1410 | +void ListViewWithPageHeader::headerHeightChanged(qreal newHeaderHeight, qreal oldHeaderHeight, qreal oldHeaderY) |
1411 | +{ |
1412 | + const qreal heightDiff = newHeaderHeight - oldHeaderHeight; |
1413 | + if (m_headerItemShownHeight > 0) { |
1414 | + // If the header is shown because of the clip |
1415 | + // Change its size |
1416 | + m_headerItemShownHeight += heightDiff; |
1417 | + m_headerItemShownHeight = qBound(static_cast<qreal>(0.), m_headerItemShownHeight, newHeaderHeight); |
1418 | + updateClipItem(); |
1419 | + adjustMinYExtent(); |
1420 | + } else { |
1421 | + if (oldHeaderY + oldHeaderHeight > contentY()) { |
1422 | + // If the header is shown because its position |
1423 | + // Change its size |
1424 | + ListItem *firstItem = m_visibleItems.first(); |
1425 | + firstItem->setY(firstItem->y() + heightDiff); |
1426 | + layout(); |
1427 | + } else { |
1428 | + // If the header is not on screen, just change the start of the list |
1429 | + // so the viewport is not changed |
1430 | + adjustMinYExtent(); |
1431 | + } |
1432 | + } |
1433 | +} |
1434 | + |
1435 | + |
1436 | +void ListViewWithPageHeader::adjustMinYExtent() |
1437 | +{ |
1438 | + if (m_visibleItems.isEmpty()) { |
1439 | + m_minYExtent = 0; |
1440 | + } else { |
1441 | + qreal nonCreatedHeight = 0; |
1442 | + if (m_firstVisibleIndex != 0) { |
1443 | + // Calculate the average height of items to estimate the position of the list start |
1444 | + const int visibleItems = m_visibleItems.count(); |
1445 | + qreal visibleItemsHeight = 0; |
1446 | + Q_FOREACH(ListItem *item, m_visibleItems) { |
1447 | + visibleItemsHeight += item->height(); |
1448 | + } |
1449 | + nonCreatedHeight = m_firstVisibleIndex * visibleItemsHeight / visibleItems; |
1450 | +// qDebug() << m_firstVisibleIndex << visibleItemsHeight << visibleItems << nonCreatedHeight; |
1451 | + } |
1452 | + m_minYExtent = nonCreatedHeight - m_visibleItems.first()->y() - m_clipItem->y() + (m_headerItem ? m_headerItem->implicitHeight() : 0); |
1453 | + } |
1454 | +} |
1455 | + |
1456 | +ListViewWithPageHeader::ListItem *ListViewWithPageHeader::itemAtIndex(int modelIndex) const |
1457 | +{ |
1458 | + const int visibleIndexedModelIndex = modelIndex - m_firstVisibleIndex; |
1459 | + if (visibleIndexedModelIndex >= 0 && visibleIndexedModelIndex < m_visibleItems.count()) |
1460 | + return m_visibleItems[visibleIndexedModelIndex]; |
1461 | + |
1462 | + return nullptr; |
1463 | +} |
1464 | + |
1465 | +void ListViewWithPageHeader::layout() |
1466 | +{ |
1467 | + if (m_inLayout) |
1468 | + return; |
1469 | + |
1470 | + m_inLayout = true; |
1471 | + if (!m_visibleItems.isEmpty()) { |
1472 | + const qreal visibleFrom = contentY() - m_clipItem->y() + m_headerItemShownHeight; |
1473 | + const qreal visibleTo = contentY() + height() - m_clipItem->y(); |
1474 | + |
1475 | + qreal pos = m_visibleItems.first()->y(); |
1476 | + |
1477 | +// qDebug() << "ListViewWithPageHeader::layout Updating positions and heights. contentY" << contentY() << "minYExtent" << minYExtent(); |
1478 | + int firstReallyVisibleItem = -1; |
1479 | + int modelIndex = m_firstVisibleIndex; |
1480 | + Q_FOREACH(ListItem *item, m_visibleItems) { |
1481 | + const bool cull = pos + item->height() < visibleFrom || pos >= visibleTo; |
1482 | + item->setCulled(cull); |
1483 | + item->setY(pos); |
1484 | + if (!cull && firstReallyVisibleItem == -1) { |
1485 | + firstReallyVisibleItem = modelIndex; |
1486 | + if (m_topSectionItem) { |
1487 | + // Update the top sticky section header |
1488 | + const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty); |
1489 | + QQmlContext *context = QQmlEngine::contextForObject(m_topSectionItem)->parentContext(); |
1490 | + context->setContextProperty(QLatin1String("section"), section); |
1491 | + |
1492 | + // Positing the top section sticky item is a two step process |
1493 | + // First we set it either we cull it (because it doesn't need to be sticked to the top) |
1494 | + // or stick it to the top |
1495 | + // Then after the loop we'll make sure that if there's another section just below it |
1496 | + // pushed the sticky section up to make it disappear |
1497 | + const qreal topSectionStickPos = m_headerItemShownHeight + contentY() - m_clipItem->y(); |
1498 | + if (topSectionStickPos <= pos) { |
1499 | + QQuickItemPrivate::get(m_topSectionItem)->setCulled(true); |
1500 | + if (item->m_sectionItem) { |
1501 | + // This seems it should happen since why would we cull the top section |
1502 | + // if the first visible item has no section header? This only happens briefly |
1503 | + // when increasing the height of a list that is at the bottom, the m_topSectionItem |
1504 | + // gets shown shortly in the next polish call |
1505 | + QQuickItemPrivate::get(item->m_sectionItem)->setCulled(false); |
1506 | + } |
1507 | + } else { |
1508 | + QQuickItemPrivate::get(m_topSectionItem)->setCulled(false); |
1509 | + m_topSectionItem->setY(topSectionStickPos); |
1510 | + if (item->m_sectionItem) { |
1511 | + QQuickItemPrivate::get(item->m_sectionItem)->setCulled(true); |
1512 | + } |
1513 | + } |
1514 | + } |
1515 | + } |
1516 | + QQmlContext *context = QQmlEngine::contextForObject(item->m_item)->parentContext(); |
1517 | + const qreal clipFrom = visibleFrom + (!item->m_sectionItem && m_topSectionItem && !QQuickItemPrivate::get(m_topSectionItem)->culled ? m_topSectionItem->height() : 0); |
1518 | + if (!cull && pos < clipFrom) { |
1519 | + context->setContextProperty(QLatin1String("heightToClip"), clipFrom - pos); |
1520 | + } else { |
1521 | + context->setContextProperty(QLatin1String("heightToClip"), QVariant::fromValue<int>(0)); |
1522 | + } |
1523 | +// qDebug() << "ListViewWithPageHeader::layout" << item->m_item; |
1524 | + pos += item->height(); |
1525 | + ++modelIndex; |
1526 | + } |
1527 | + |
1528 | + // Second step of section sticky item positioning |
1529 | + // Look at the next section header, check if it's pushing up the sticky one |
1530 | + if (m_topSectionItem) { |
1531 | + if (firstReallyVisibleItem >= 0) { |
1532 | + for (int i = firstReallyVisibleItem - m_firstVisibleIndex + 1; i < m_visibleItems.count(); ++i) { |
1533 | + ListItem *item = m_visibleItems[i]; |
1534 | + if (item->m_sectionItem) { |
1535 | + if (m_topSectionItem->y() + m_topSectionItem->height() > item->y()) { |
1536 | + m_topSectionItem->setY(item->y() - m_topSectionItem->height()); |
1537 | + } |
1538 | + break; |
1539 | + } |
1540 | + } |
1541 | + } |
1542 | + } |
1543 | + } |
1544 | + m_inLayout = false; |
1545 | +} |
1546 | + |
1547 | +void ListViewWithPageHeader::updatePolish() |
1548 | +{ |
1549 | + Q_FOREACH(ListItem *item, m_itemsToRelease) |
1550 | + reallyReleaseItem(item); |
1551 | + m_itemsToRelease.clear(); |
1552 | + |
1553 | + if (!model()) |
1554 | + return; |
1555 | + |
1556 | + layout(); |
1557 | + |
1558 | + refill(); |
1559 | + |
1560 | + if (m_contentHeightDirty) { |
1561 | + qreal contentHeight; |
1562 | + if (m_visibleItems.isEmpty()) { |
1563 | + contentHeight = m_headerItem ? m_headerItem->height() : 0; |
1564 | + } else { |
1565 | + const int modelCount = model()->rowCount(); |
1566 | + const int visibleItems = m_visibleItems.count(); |
1567 | + const int lastValidIndex = m_firstVisibleIndex + visibleItems - 1; |
1568 | + qreal nonCreatedHeight = 0; |
1569 | + if (lastValidIndex != modelCount - 1) { |
1570 | + const int visibleItems = m_visibleItems.count(); |
1571 | + qreal visibleItemsHeight = 0; |
1572 | + Q_FOREACH(ListItem *item, m_visibleItems) { |
1573 | + visibleItemsHeight += item->height(); |
1574 | + } |
1575 | + const int unknownSizes = modelCount - (m_firstVisibleIndex + visibleItems); |
1576 | + nonCreatedHeight = unknownSizes * visibleItemsHeight / visibleItems; |
1577 | + } |
1578 | + ListItem *item = m_visibleItems.last(); |
1579 | + contentHeight = nonCreatedHeight + item->y() + item->height() + m_clipItem->y(); |
1580 | + if (m_firstVisibleIndex != 0) { |
1581 | + // Make sure that if we are shrinking we tell the view we still fit |
1582 | + m_minYExtent = qMax(m_minYExtent, -(contentHeight - height())); |
1583 | + } |
1584 | + } |
1585 | + |
1586 | + m_contentHeightDirty = false; |
1587 | + setContentHeight(contentHeight); |
1588 | + } |
1589 | +} |
1590 | + |
1591 | +#include "moc_listviewwithpageheader.cpp" |
1592 | |
1593 | === added file 'plugins/ListViewWithPageHeader/listviewwithpageheader.h' |
1594 | --- plugins/ListViewWithPageHeader/listviewwithpageheader.h 1970-01-01 00:00:00 +0000 |
1595 | +++ plugins/ListViewWithPageHeader/listviewwithpageheader.h 2013-07-01 11:23:32 +0000 |
1596 | @@ -0,0 +1,180 @@ |
1597 | +/* |
1598 | + * Copyright (C) 2013 Canonical, Ltd. |
1599 | + * |
1600 | + * This program is free software; you can redistribute it and/or modify |
1601 | + * it under the terms of the GNU General Public License as published by |
1602 | + * the Free Software Foundation; version 3. |
1603 | + * |
1604 | + * This program is distributed in the hope that it will be useful, |
1605 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1606 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1607 | + * GNU General Public License for more details. |
1608 | + * |
1609 | + * You should have received a copy of the GNU General Public License |
1610 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1611 | + */ |
1612 | + |
1613 | +#ifndef LISTVIEWWITHPAGEHEADER_H |
1614 | +#define LISTVIEWWITHPAGEHEADER_H |
1615 | + |
1616 | +#include <private/qquickitemchangelistener_p.h> |
1617 | +#include <private/qquickflickable_p.h> |
1618 | + |
1619 | +class QAbstractItemModel; |
1620 | +class QQuickChangeSet; |
1621 | +class QQuickNumberAnimation; |
1622 | +class QQuickVisualDataModel; |
1623 | + |
1624 | + |
1625 | +/** |
1626 | + Note for users of this class |
1627 | + |
1628 | + ListViewWithPageHeader already loads delegates async when appropiate so if |
1629 | + your delegate uses a Loader you should not enable the asynchronous feature since |
1630 | + that will need to introduce sizing problems |
1631 | + |
1632 | + With the double async it may happen what while we are scrolling down |
1633 | + we reach to a point where given the size of the just created delegate with loader not yet loaded (which will be very close to 0) |
1634 | + we are already "at the end" of the list, but then a few milliseconds later the loader finishes loading and we could |
1635 | + have kept scrolling. This is specially visible at the end of the list where you realize |
1636 | + that scrolling ended a bit before the end of the list but the speed of the flicking was good |
1637 | + to reach the end |
1638 | + |
1639 | + By not having the second async we get a better sizing when the delegate is created and things work better |
1640 | +*/ |
1641 | + |
1642 | +class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeListener |
1643 | +{ |
1644 | + Q_OBJECT |
1645 | + Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged) |
1646 | + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) |
1647 | + Q_PROPERTY(QQuickItem *pageHeader READ header WRITE setHeader NOTIFY headerChanged) |
1648 | + Q_PROPERTY(QQmlComponent *sectionDelegate READ sectionDelegate WRITE setSectionDelegate NOTIFY sectionDelegateChanged) |
1649 | + Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged) |
1650 | + Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged) |
1651 | + |
1652 | + friend class ListViewWithPageHeaderTest; |
1653 | + friend class ListViewWithPageHeaderTestSection; |
1654 | + |
1655 | +public: |
1656 | + ListViewWithPageHeader(); |
1657 | + ~ListViewWithPageHeader(); |
1658 | + |
1659 | + QAbstractItemModel *model() const; |
1660 | + void setModel(QAbstractItemModel *model); |
1661 | + |
1662 | + QQmlComponent *delegate() const; |
1663 | + void setDelegate(QQmlComponent *delegate); |
1664 | + |
1665 | + QQuickItem *header() const; |
1666 | + void setHeader(QQuickItem *header); |
1667 | + |
1668 | + QQmlComponent *sectionDelegate() const; |
1669 | + void setSectionDelegate(QQmlComponent *delegate); |
1670 | + |
1671 | + QString sectionProperty() const; |
1672 | + void setSectionProperty(const QString &property); |
1673 | + |
1674 | + bool forceNoClip() const; |
1675 | + void setForceNoClip(bool noClip); |
1676 | + |
1677 | + Q_INVOKABLE void positionAtBeginning(); |
1678 | + Q_INVOKABLE void showHeader(); |
1679 | + |
1680 | +Q_SIGNALS: |
1681 | + void modelChanged(); |
1682 | + void delegateChanged(); |
1683 | + void headerChanged(); |
1684 | + void sectionDelegateChanged(); |
1685 | + void sectionPropertyChanged(); |
1686 | + void forceNoClipChanged(); |
1687 | + |
1688 | +protected: |
1689 | + void componentComplete(); |
1690 | + void viewportMoved(Qt::Orientations orient); |
1691 | + qreal minYExtent() const; |
1692 | + void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry); |
1693 | + void updatePolish(); |
1694 | + |
1695 | +private Q_SLOTS: |
1696 | + void itemCreated(int modelIndex, QQuickItem *item); |
1697 | + void onContentHeightChanged(); |
1698 | + void onContentWidthChanged(); |
1699 | + void onHeightChanged(); |
1700 | + void onModelUpdated(const QQuickChangeSet &changeSet, bool reset); |
1701 | + void onShowHeaderAnimationFinished(); |
1702 | + |
1703 | +private: |
1704 | + class ListItem |
1705 | + { |
1706 | + public: |
1707 | + qreal height() const; |
1708 | + |
1709 | + qreal y() const; |
1710 | + void setY(qreal newY); |
1711 | + |
1712 | + bool culled() const; |
1713 | + void setCulled(bool culled); |
1714 | + |
1715 | + QQuickItem *m_item; |
1716 | + QQuickItem *m_sectionItem; |
1717 | + }; |
1718 | + |
1719 | + void createDelegateModel(); |
1720 | + |
1721 | + void layout(); |
1722 | + void refill(); |
1723 | + bool addVisibleItems(qreal fillFrom, qreal fillTo, bool asynchronous); |
1724 | + bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo); |
1725 | + ListItem *createItem(int modelIndex, bool asynchronous); |
1726 | + |
1727 | + void adjustMinYExtent(); |
1728 | + void updateClipItem(); |
1729 | + void headerHeightChanged(qreal newHeaderHeight, qreal oldHeaderHeight, qreal oldHeaderY); |
1730 | + ListItem *itemAtIndex(int modelIndex) const; // Returns the item at modelIndex if has been created |
1731 | + void releaseItem(ListItem *item); |
1732 | + void reallyReleaseItem(ListItem *item); |
1733 | + void updateWatchedRoles(); |
1734 | + QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted); |
1735 | + QQuickItem *getSectionItem(const QString §ionText); |
1736 | + |
1737 | + QQuickVisualDataModel *m_delegateModel; |
1738 | + |
1739 | + // Index we are waiting because we requested it asynchronously |
1740 | + int m_asyncRequestedIndex; |
1741 | + |
1742 | + // Used to only give a warning once if the delegate does not return objects |
1743 | + bool m_delegateValidated; |
1744 | + |
1745 | + // Visible indexes, [0] is m_firstValidIndex, [0+1] is m_firstValidIndex +1, ... |
1746 | + QList<ListItem *> m_visibleItems; |
1747 | + int m_firstVisibleIndex; |
1748 | + |
1749 | + qreal m_minYExtent; |
1750 | + |
1751 | + QQuickItem *m_clipItem; |
1752 | + |
1753 | + // If any of the heights has changed |
1754 | + // or new items have been added/removed |
1755 | + bool m_contentHeightDirty; |
1756 | + |
1757 | + QQuickItem *m_headerItem; |
1758 | + qreal m_previousContentY; |
1759 | + qreal m_headerItemShownHeight; // The height of header shown when the header is shown outside its topmost position |
1760 | + // i.e. it's being shown after dragging down in the middle of the list |
1761 | + QQuickNumberAnimation *m_headerShowAnimation; |
1762 | + |
1763 | + QQmlComponent *m_sectionDelegate; |
1764 | + QString m_sectionProperty; |
1765 | + QQuickItem *m_topSectionItem; |
1766 | + |
1767 | + bool m_forceNoClip; |
1768 | + bool m_inLayout; |
1769 | + |
1770 | + // Qt 5.0 doesn't like releasing the items just after itemCreated |
1771 | + // so we delay the releasing until the next updatePolish |
1772 | + QList<ListItem *> m_itemsToRelease; |
1773 | +}; |
1774 | + |
1775 | + |
1776 | +#endif |
1777 | |
1778 | === added file 'plugins/ListViewWithPageHeader/plugin.cpp' |
1779 | --- plugins/ListViewWithPageHeader/plugin.cpp 1970-01-01 00:00:00 +0000 |
1780 | +++ plugins/ListViewWithPageHeader/plugin.cpp 2013-07-01 11:23:32 +0000 |
1781 | @@ -0,0 +1,29 @@ |
1782 | +/* |
1783 | + * Copyright (C) 2013 Canonical, Ltd. |
1784 | + * |
1785 | + * This program is free software; you can redistribute it and/or modify |
1786 | + * it under the terms of the GNU General Public License as published by |
1787 | + * the Free Software Foundation; version 3. |
1788 | + * |
1789 | + * This program is distributed in the hope that it will be useful, |
1790 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1791 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1792 | + * GNU General Public License for more details. |
1793 | + * |
1794 | + * You should have received a copy of the GNU General Public License |
1795 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1796 | + * |
1797 | + */ |
1798 | + |
1799 | +#include "plugin.h" |
1800 | + |
1801 | +#include "listviewwithpageheader.h" |
1802 | + |
1803 | +#include <QAbstractItemModel> |
1804 | + |
1805 | +void ListViewWithPageHeaderPlugin::registerTypes(const char *uri) |
1806 | +{ |
1807 | + Q_ASSERT(uri == QLatin1String("ListViewWithPageHeader")); |
1808 | + qmlRegisterType<QAbstractItemModel>(); |
1809 | + qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader"); |
1810 | +} |
1811 | |
1812 | === added file 'plugins/ListViewWithPageHeader/plugin.h' |
1813 | --- plugins/ListViewWithPageHeader/plugin.h 1970-01-01 00:00:00 +0000 |
1814 | +++ plugins/ListViewWithPageHeader/plugin.h 2013-07-01 11:23:32 +0000 |
1815 | @@ -0,0 +1,33 @@ |
1816 | +/* |
1817 | + * Copyright (C) 2012 Canonical, Ltd. |
1818 | + * |
1819 | + * This program is free software; you can redistribute it and/or modify |
1820 | + * it under the terms of the GNU General Public License as published by |
1821 | + * the Free Software Foundation; version 3. |
1822 | + * |
1823 | + * This program is distributed in the hope that it will be useful, |
1824 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1825 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1826 | + * GNU General Public License for more details. |
1827 | + * |
1828 | + * You should have received a copy of the GNU General Public License |
1829 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1830 | + * |
1831 | + */ |
1832 | + |
1833 | +#ifndef LISTVIEWWITHPAGEHEADER_PLUGIN_H |
1834 | +#define LISTVIEWWITHPAGEHEADER_PLUGIN_H |
1835 | + |
1836 | +#include <QtQml/QQmlEngine> |
1837 | +#include <QtQml/QQmlExtensionPlugin> |
1838 | + |
1839 | +class ListViewWithPageHeaderPlugin : public QQmlExtensionPlugin |
1840 | +{ |
1841 | + Q_OBJECT |
1842 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
1843 | + |
1844 | +public: |
1845 | + void registerTypes(const char *uri); |
1846 | +}; |
1847 | + |
1848 | +#endif |
1849 | |
1850 | === added file 'plugins/ListViewWithPageHeader/qmldir' |
1851 | --- plugins/ListViewWithPageHeader/qmldir 1970-01-01 00:00:00 +0000 |
1852 | +++ plugins/ListViewWithPageHeader/qmldir 2013-07-01 11:23:32 +0000 |
1853 | @@ -0,0 +1,2 @@ |
1854 | +module ListViewWithPageHeader |
1855 | +plugin ListViewWithPageHeader-qml |
1856 | |
1857 | === modified file 'run_on_device' |
1858 | --- run_on_device 2013-06-24 11:08:38 +0000 |
1859 | +++ run_on_device 2013-07-01 11:23:32 +0000 |
1860 | @@ -75,7 +75,7 @@ |
1861 | sync_code() { |
1862 | [ -e .bzr ] && bzr export --uncommitted --format=dir /tmp/$CODE_DIR |
1863 | [ -e .git ] && git checkout-index -a -f --prefix=/tmp/$CODE_DIR/ |
1864 | - rsync -crlOzv -e "ssh -p $TARGET_SSH_PORT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" /tmp/$CODE_DIR/ $USER@$TARGET_IP:$CODE_DIR/ |
1865 | + rsync -crlOzv --delete --exclude builddir -e "ssh -p $TARGET_SSH_PORT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" /tmp/$CODE_DIR/ $USER@$TARGET_IP:$CODE_DIR/ |
1866 | rm -rf /tmp/$CODE_DIR |
1867 | } |
1868 | |
1869 | |
1870 | === modified file 'tests/plugins/CMakeLists.txt' |
1871 | --- tests/plugins/CMakeLists.txt 2013-06-05 22:03:08 +0000 |
1872 | +++ tests/plugins/CMakeLists.txt 2013-07-01 11:23:32 +0000 |
1873 | @@ -1,2 +1,3 @@ |
1874 | add_subdirectory(Utils) |
1875 | add_subdirectory(Ubuntu) |
1876 | +add_subdirectory(ListViewWithPageHeader) |
1877 | |
1878 | === added directory 'tests/plugins/ListViewWithPageHeader' |
1879 | === added file 'tests/plugins/ListViewWithPageHeader/CMakeLists.txt' |
1880 | --- tests/plugins/ListViewWithPageHeader/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1881 | +++ tests/plugins/ListViewWithPageHeader/CMakeLists.txt 2013-07-01 11:23:32 +0000 |
1882 | @@ -0,0 +1,31 @@ |
1883 | +# There's no cmake var for v8 include path :-/ |
1884 | +# so create one |
1885 | +LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0) |
1886 | +SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8) |
1887 | + |
1888 | +include_directories( |
1889 | + ${Qt5Qml_PRIVATE_INCLUDE_DIRS} |
1890 | + ${Qt5Quick_INCLUDE_DIRS} |
1891 | + ${Qt5Quick_PRIVATE_INCLUDE_DIRS} |
1892 | + ${Qt5V8_PRIVATE_INCLUDE_DIR} |
1893 | + ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/ListViewWithPageHeader |
1894 | + ${CMAKE_CURRENT_BINARY_DIR} |
1895 | + ) |
1896 | + |
1897 | +remove_definitions(-DQT_NO_KEYWORDS) |
1898 | + |
1899 | +add_definitions(-DLISTVIEWWITHPAGEHEADER_FOLDER="${CMAKE_CURRENT_SOURCE_DIR}") |
1900 | +add_definitions(-DBUILT_PLUGINS_DIR="${CMAKE_BINARY_DIR}/plugins") |
1901 | + |
1902 | +add_executable(listviewwithpageheadertestExec listviewwithpageheadertest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/ListViewWithPageHeader/listviewwithpageheader.cpp) |
1903 | +qt5_use_modules(listviewwithpageheadertestExec Test Core Qml) |
1904 | +target_link_libraries(listviewwithpageheadertestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES}) |
1905 | +add_custom_target(testlistviewwithpageheader ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheader.xml,xunitxml -o -,txt) |
1906 | + |
1907 | +add_executable(listviewwithpageheadertestsectionExec listviewwithpageheadertestsection.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/ListViewWithPageHeader/listviewwithpageheader.cpp) |
1908 | +qt5_use_modules(listviewwithpageheadertestsectionExec Test Core Qml) |
1909 | +target_link_libraries(listviewwithpageheadertestsectionExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES}) |
1910 | +add_custom_target(testlistviewwithpageheadersection ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersection.xml,xunitxml -o -,txt) |
1911 | + |
1912 | +add_dependencies(qmluitests testlistviewwithpageheader) |
1913 | +add_dependencies(qmluitests testlistviewwithpageheadersection) |
1914 | |
1915 | === added file 'tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp' |
1916 | --- tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp 1970-01-01 00:00:00 +0000 |
1917 | +++ tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp 2013-07-01 11:23:32 +0000 |
1918 | @@ -0,0 +1,1311 @@ |
1919 | +/* |
1920 | + * Copyright (C) 2013 Canonical, Ltd. |
1921 | + * |
1922 | + * This program is free software; you can redistribute it and/or modify |
1923 | + * it under the terms of the GNU General Public License as published by |
1924 | + * the Free Software Foundation; version 3. |
1925 | + * |
1926 | + * This program is distributed in the hope that it will be useful, |
1927 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1928 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1929 | + * GNU General Public License for more details. |
1930 | + * |
1931 | + * You should have received a copy of the GNU General Public License |
1932 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1933 | + */ |
1934 | + |
1935 | +#include "listviewwithpageheader.h" |
1936 | + |
1937 | +#include <QAbstractItemModel> |
1938 | +#include <QQmlEngine> |
1939 | +#include <QQuickView> |
1940 | +#include <QtTestGui> |
1941 | +#include <private/qquicklistmodel_p.h> |
1942 | +#include <private/qquickanimation_p.h> |
1943 | +#include <private/qquickitem_p.h> |
1944 | + |
1945 | +class ListViewWithPageHeaderTest : public QObject |
1946 | +{ |
1947 | + Q_OBJECT |
1948 | + |
1949 | +private: |
1950 | + void verifyItem(int visibleIndex, qreal pos, qreal height, bool culled) |
1951 | + { |
1952 | + ListViewWithPageHeader::ListItem *item = lvwph->m_visibleItems[visibleIndex]; |
1953 | + QTRY_COMPARE(item->y(), pos); |
1954 | + QTRY_COMPARE(item->height(), height); |
1955 | + QCOMPARE(QQuickItemPrivate::get(item->m_item)->culled, culled); |
1956 | + } |
1957 | + |
1958 | + void changeContentY(qreal change) |
1959 | + { |
1960 | + const qreal dest = lvwph->contentY() + change; |
1961 | + if (dest > lvwph->contentY()) { |
1962 | + const qreal jump = 25; |
1963 | + while (lvwph->contentY() + jump < dest) { |
1964 | + lvwph->setContentY(lvwph->contentY() + jump); |
1965 | + QTest::qWait(1); |
1966 | + } |
1967 | + } else { |
1968 | + const qreal jump = -25; |
1969 | + while (lvwph->contentY() + jump > dest) { |
1970 | + lvwph->setContentY(lvwph->contentY() + jump); |
1971 | + QTest::qWait(1); |
1972 | + } |
1973 | + } |
1974 | + lvwph->setContentY(dest); |
1975 | + QTest::qWait(1); |
1976 | + } |
1977 | + |
1978 | + void scrollToTop() |
1979 | + { |
1980 | + const qreal jump = -25; |
1981 | + while (!lvwph->isAtYBeginning()) { |
1982 | + if (lvwph->contentY() + jump > -lvwph->minYExtent()) { |
1983 | + lvwph->setContentY(lvwph->contentY() + jump); |
1984 | + } else { |
1985 | + lvwph->setContentY(lvwph->contentY() - 1); |
1986 | + } |
1987 | + QTest::qWait(1); |
1988 | + } |
1989 | + } |
1990 | + |
1991 | + void scrollToBottom() |
1992 | + { |
1993 | + const qreal jump = 25; |
1994 | + while (!lvwph->isAtYEnd()) { |
1995 | + if (lvwph->contentY() + lvwph->height() + jump < lvwph->contentHeight()) { |
1996 | + lvwph->setContentY(lvwph->contentY() + jump); |
1997 | + } else { |
1998 | + lvwph->setContentY(lvwph->contentY() + 1); |
1999 | + } |
2000 | + QTest::qWait(1); |
2001 | + } |
2002 | + } |
2003 | + |
2004 | + void verifyInitialTopPosition() |
2005 | + { |
2006 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2007 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2008 | + verifyItem(0, 50., 150., false); |
2009 | + verifyItem(1, 200., 200., false); |
2010 | + verifyItem(2, 400., 350., false); |
2011 | + verifyItem(3, 750., 350., true); |
2012 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2013 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2014 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2015 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2016 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2017 | + QCOMPARE(lvwph->contentY(), 0.); |
2018 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2019 | + } |
2020 | + |
2021 | +private Q_SLOTS: |
2022 | + |
2023 | + void initTestCase() |
2024 | + { |
2025 | + } |
2026 | + |
2027 | + void init() |
2028 | + { |
2029 | + view = new QQuickView(); |
2030 | + view->engine()->addImportPath(BUILT_PLUGINS_DIR); |
2031 | + view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test.qml")); |
2032 | + lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>()); |
2033 | + model = view->rootObject()->findChild<QQuickListModel*>(); |
2034 | + otherDelegate = view->rootObject()->findChild<QQmlComponent*>(); |
2035 | + QVERIFY(lvwph); |
2036 | + QVERIFY(model); |
2037 | + QVERIFY(otherDelegate); |
2038 | + view->show(); |
2039 | + QTest::qWaitForWindowExposed(view); |
2040 | + |
2041 | + verifyInitialTopPosition(); |
2042 | + } |
2043 | + |
2044 | + void cleanup() |
2045 | + { |
2046 | + delete view; |
2047 | + } |
2048 | + |
2049 | + void testCreationDeletion() |
2050 | + { |
2051 | + // Nothing, init/cleanup already tests this |
2052 | + } |
2053 | + |
2054 | + void testDrag1PixelUp() |
2055 | + { |
2056 | + lvwph->setContentY(lvwph->contentY() + 1); |
2057 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2058 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2059 | + verifyItem(0, 49., 150., false); |
2060 | + verifyItem(1, 199., 200., false); |
2061 | + verifyItem(2, 399., 350., false); |
2062 | + verifyItem(3, 749., 350., true); |
2063 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2064 | + QCOMPARE(lvwph->m_clipItem->y(), 1.); |
2065 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2066 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2067 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2068 | + QCOMPARE(lvwph->contentY(), 1.); |
2069 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2070 | + } |
2071 | + |
2072 | + void testHeaderDetachDragDown() |
2073 | + { |
2074 | + QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0)); |
2075 | + QTest::qWait(100); |
2076 | + QTest::mouseMove(view, QPoint(0, 5)); |
2077 | + QTest::qWait(100); |
2078 | + QTest::mouseMove(view, QPoint(0, 10)); |
2079 | + QTest::qWait(100); |
2080 | + QTest::mouseMove(view, QPoint(0, 15)); |
2081 | + QTest::qWait(100); |
2082 | + QTest::mouseMove(view, QPoint(0, 20)); |
2083 | + QTest::qWait(100); |
2084 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2085 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2086 | + verifyItem(0, 55., 150., false); |
2087 | + verifyItem(1, 205., 200., false); |
2088 | + verifyItem(2, 405., 350., false); |
2089 | + verifyItem(3, 755., 350., true); |
2090 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2091 | + QCOMPARE(lvwph->m_clipItem->y(), -5.); |
2092 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2093 | + QCOMPARE(lvwph->m_headerItem->y(), -5.); |
2094 | + QCOMPARE(lvwph->m_headerItem->height(), 55.); |
2095 | + QCOMPARE(lvwph->contentY(), -5.); |
2096 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2097 | + |
2098 | + QTest::mouseRelease(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 15)); |
2099 | + |
2100 | + verifyInitialTopPosition(); |
2101 | + } |
2102 | + |
2103 | + void testDrag375PixelUp() |
2104 | + { |
2105 | + changeContentY(375); |
2106 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2107 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2108 | + verifyItem(0, -325., 150., true); |
2109 | + verifyItem(1, -175, 200., false); |
2110 | + verifyItem(2, 25, 350., false); |
2111 | + verifyItem(3, 375, 350., false); |
2112 | + verifyItem(4, 725, 350., true); |
2113 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2114 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
2115 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2116 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2117 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2118 | + QCOMPARE(lvwph->contentY(), 375.); |
2119 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2120 | + } |
2121 | + |
2122 | + void testDrag520PixelUp() |
2123 | + { |
2124 | + changeContentY(520); |
2125 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2126 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
2127 | + verifyItem(0, -320., 200., true); |
2128 | + verifyItem(1, -120, 350., false); |
2129 | + verifyItem(2, 230, 350., false); |
2130 | + verifyItem(3, 580, 350., true); |
2131 | + // Just here as first check against m_minYExtent when m_firstVisibleIndex is not 0 |
2132 | + // We as humans know that m_minYExtent will be 0 but since the first delegate is not there anymore |
2133 | + // we have to estimate its size, the average item height is 312.5 which is 162.5 more than the |
2134 | + // "real" size of 150 and that's why the m_minYExtent has that "peculiar" value |
2135 | + // It's fine since what it means is that we could scroll more up than the original position |
2136 | + // but we will recalculate m_minYExtent when the item 0 is created and set it correctly |
2137 | + QCOMPARE(lvwph->m_minYExtent, 162.5); |
2138 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
2139 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2140 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2141 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2142 | + QCOMPARE(lvwph->contentY(), 520.); |
2143 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2144 | + } |
2145 | + |
2146 | + void testDragHeaderUpThenShow() |
2147 | + { |
2148 | + changeContentY(120); |
2149 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2150 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2151 | + verifyItem(0, -70., 150., false); |
2152 | + verifyItem(1, 80., 200., false); |
2153 | + verifyItem(2, 280., 350., false); |
2154 | + verifyItem(3, 630., 350., true); |
2155 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2156 | + QCOMPARE(lvwph->m_clipItem->y(), 120.); |
2157 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2158 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2159 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2160 | + QCOMPARE(lvwph->contentY(), 120.); |
2161 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2162 | + |
2163 | + changeContentY(-30); |
2164 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2165 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2166 | + verifyItem(0, -70., 150., false); |
2167 | + verifyItem(1, 80., 200., false); |
2168 | + verifyItem(2, 280., 350., false); |
2169 | + verifyItem(3, 630., 350., true); |
2170 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2171 | + QCOMPARE(lvwph->m_clipItem->y(), 120.); |
2172 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
2173 | + QTRY_COMPARE(lvwph->m_headerItem->y(), 70.); |
2174 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2175 | + QCOMPARE(lvwph->contentY(), 90.); |
2176 | + QCOMPARE(lvwph->m_headerItemShownHeight, 30.); |
2177 | + } |
2178 | + |
2179 | + void testDragHeaderUpThenShowWithoutHidingTotally() |
2180 | + { |
2181 | + changeContentY(10); |
2182 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2183 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2184 | + verifyItem(0, 40., 150., false); |
2185 | + verifyItem(1, 190., 200., false); |
2186 | + verifyItem(2, 390., 350., false); |
2187 | + verifyItem(3, 740., 350., true); |
2188 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2189 | + QCOMPARE(lvwph->m_clipItem->y(), 10.); |
2190 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2191 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2192 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2193 | + QCOMPARE(lvwph->contentY(), 10.); |
2194 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2195 | + |
2196 | + changeContentY(-1); |
2197 | + |
2198 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2199 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2200 | + verifyItem(0, 41., 150., false); |
2201 | + verifyItem(1, 191., 200., false); |
2202 | + verifyItem(2, 391., 350., false); |
2203 | + verifyItem(3, 741., 350., true); |
2204 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2205 | + QCOMPARE(lvwph->m_clipItem->y(), 9.); |
2206 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2207 | + QTRY_COMPARE(lvwph->m_headerItem->y(), 0.); |
2208 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2209 | + QCOMPARE(lvwph->contentY(), 9.); |
2210 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2211 | + } |
2212 | + |
2213 | + void testPositionAtBeginningIndex0Visible() |
2214 | + { |
2215 | + changeContentY(375); |
2216 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2217 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2218 | + verifyItem(0, -325., 150., true); |
2219 | + verifyItem(1, -175, 200., false); |
2220 | + verifyItem(2, 25, 350., false); |
2221 | + verifyItem(3, 375, 350., false); |
2222 | + verifyItem(4, 725, 350., true); |
2223 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2224 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
2225 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2226 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2227 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2228 | + QCOMPARE(lvwph->contentY(), 375.); |
2229 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2230 | + |
2231 | + lvwph->positionAtBeginning(); |
2232 | + |
2233 | + verifyInitialTopPosition(); |
2234 | + } |
2235 | + |
2236 | + void testPositionAtBeginningIndex0NotVisible() |
2237 | + { |
2238 | + changeContentY(520); |
2239 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2240 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
2241 | + verifyItem(0, -320., 200., true); |
2242 | + verifyItem(1, -120, 350., false); |
2243 | + verifyItem(2, 230, 350., false); |
2244 | + verifyItem(3, 580, 350., true); |
2245 | + QCOMPARE(lvwph->m_minYExtent, 162.5); |
2246 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
2247 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2248 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2249 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2250 | + QCOMPARE(lvwph->contentY(), 520.); |
2251 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2252 | + |
2253 | + lvwph->positionAtBeginning(); |
2254 | + |
2255 | + verifyInitialTopPosition(); |
2256 | + } |
2257 | + |
2258 | + void testIndex0GrowOnScreen() |
2259 | + { |
2260 | + model->setProperty(0, "size", 400); |
2261 | + |
2262 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2263 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2264 | + verifyItem(0, 50., 400., false); |
2265 | + verifyItem(1, 450., 200., false); |
2266 | + verifyItem(2, 650., 350., true); |
2267 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2268 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2269 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2270 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2271 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2272 | + QCOMPARE(lvwph->contentY(), 0.); |
2273 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2274 | + } |
2275 | + |
2276 | + void testIndex0GrowOffScreen() |
2277 | + { |
2278 | + changeContentY(375); |
2279 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2280 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2281 | + verifyItem(0, -325., 150., true); |
2282 | + verifyItem(1, -175, 200., false); |
2283 | + verifyItem(2, 25, 350., false); |
2284 | + verifyItem(3, 375, 350., false); |
2285 | + verifyItem(4, 725, 350., true); |
2286 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2287 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
2288 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2289 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2290 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2291 | + QCOMPARE(lvwph->contentY(), 375.); |
2292 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2293 | + |
2294 | + model->setProperty(0, "size", 400); |
2295 | + |
2296 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2297 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2298 | + verifyItem(0, -575., 400., true); |
2299 | + verifyItem(1, -175, 200., false); |
2300 | + verifyItem(2, 25, 350., false); |
2301 | + verifyItem(3, 375, 350., false); |
2302 | + verifyItem(4, 725, 350., true); |
2303 | + QCOMPARE(lvwph->m_minYExtent, 250.); |
2304 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
2305 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2306 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2307 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2308 | + QCOMPARE(lvwph->contentY(), 375.); |
2309 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2310 | + |
2311 | + scrollToTop(); |
2312 | + |
2313 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2314 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2315 | + verifyItem(0, 50., 400., false); |
2316 | + verifyItem(1, 450, 200., false); |
2317 | + verifyItem(2, 650, 350., true); |
2318 | + QCOMPARE(lvwph->m_minYExtent, 250.); |
2319 | + QCOMPARE(lvwph->m_clipItem->y(), -250.); |
2320 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2321 | + QCOMPARE(lvwph->m_headerItem->y(), -250.); |
2322 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2323 | + QCOMPARE(lvwph->contentY(), -250.); |
2324 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2325 | + |
2326 | + changeContentY(30); |
2327 | + |
2328 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2329 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2330 | + verifyItem(0, 20., 400., false); |
2331 | + verifyItem(1, 420, 200., false); |
2332 | + verifyItem(2, 620, 350., true); |
2333 | + QCOMPARE(lvwph->m_minYExtent, 250.); |
2334 | + QCOMPARE(lvwph->m_clipItem->y(), -220.); |
2335 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2336 | + QCOMPARE(lvwph->m_headerItem->y(), -250.); |
2337 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2338 | + QCOMPARE(lvwph->contentY(), -220.); |
2339 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2340 | + } |
2341 | + |
2342 | + void testIndex0GrowNotCreated() |
2343 | + { |
2344 | + changeContentY(520); |
2345 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2346 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
2347 | + verifyItem(0, -320., 200., true); |
2348 | + verifyItem(1, -120, 350., false); |
2349 | + verifyItem(2, 230, 350., false); |
2350 | + verifyItem(3, 580, 350., true); |
2351 | + QCOMPARE(lvwph->m_minYExtent, 162.5); |
2352 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
2353 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2354 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2355 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2356 | + QCOMPARE(lvwph->contentY(), 520.); |
2357 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2358 | + |
2359 | + model->setProperty(0, "size", 400); |
2360 | + |
2361 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2362 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
2363 | + verifyItem(0, -320., 200., true); |
2364 | + verifyItem(1, -120, 350., false); |
2365 | + verifyItem(2, 230, 350., false); |
2366 | + verifyItem(3, 580, 350., true); |
2367 | + QCOMPARE(lvwph->m_minYExtent, 162.5); |
2368 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
2369 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2370 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2371 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2372 | + QCOMPARE(lvwph->contentY(), 520.); |
2373 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2374 | + |
2375 | + scrollToTop(); |
2376 | + |
2377 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2378 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2379 | + verifyItem(0, 50., 400., false); |
2380 | + verifyItem(1, 450, 200., false); |
2381 | + verifyItem(2, 650, 350., true); |
2382 | + QCOMPARE(lvwph->m_minYExtent, 250.); |
2383 | + QCOMPARE(lvwph->m_clipItem->y(), -250.); |
2384 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2385 | + QCOMPARE(lvwph->m_headerItem->y(), -250.); |
2386 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2387 | + QCOMPARE(lvwph->contentY(), -250.); |
2388 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2389 | + } |
2390 | + |
2391 | + void testShowHideShowHeaderAtBottom() |
2392 | + { |
2393 | + scrollToBottom(); |
2394 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2395 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2396 | + verifyItem(0, -508., 350., true); |
2397 | + verifyItem(1, -158, 350., false); |
2398 | + verifyItem(2, 192, 350., false); |
2399 | + QCOMPARE(lvwph->m_minYExtent, 350.); |
2400 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2401 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2402 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2403 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2404 | + QCOMPARE(lvwph->contentY(), 1258.); |
2405 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2406 | + |
2407 | + changeContentY(-30); |
2408 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2409 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2410 | + verifyItem(0, -508., 350., true); |
2411 | + verifyItem(1, -158, 350., false); |
2412 | + verifyItem(2, 192, 350., false); |
2413 | + QCOMPARE(lvwph->m_minYExtent, 350.); |
2414 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2415 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
2416 | + QCOMPARE(lvwph->m_headerItem->y(), 1208.); |
2417 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2418 | + QCOMPARE(lvwph->contentY(), 1228.); |
2419 | + QCOMPARE(lvwph->m_headerItemShownHeight, 30.); |
2420 | + |
2421 | + changeContentY(30); |
2422 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2423 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2424 | + verifyItem(0, -508., 350., true); |
2425 | + verifyItem(1, -158, 350., false); |
2426 | + verifyItem(2, 192, 350., false); |
2427 | + QCOMPARE(lvwph->m_minYExtent, 350.); |
2428 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2429 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2430 | + QCOMPARE(lvwph->m_headerItem->y(), -350.); |
2431 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2432 | + QCOMPARE(lvwph->contentY(), 1258.); |
2433 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2434 | + |
2435 | + changeContentY(-30); |
2436 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2437 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2438 | + verifyItem(0, -508., 350., true); |
2439 | + verifyItem(1, -158, 350., false); |
2440 | + verifyItem(2, 192, 350., false); |
2441 | + QCOMPARE(lvwph->m_minYExtent, 350.); |
2442 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2443 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
2444 | + QCOMPARE(lvwph->m_headerItem->y(), 1208.); |
2445 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2446 | + QCOMPARE(lvwph->contentY(), 1228.); |
2447 | + QCOMPARE(lvwph->m_headerItemShownHeight, 30.); |
2448 | + } |
2449 | + |
2450 | + void testChangeDelegateAtBottom() |
2451 | + { |
2452 | + scrollToBottom(); |
2453 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2454 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2455 | + verifyItem(0, -508., 350., true); |
2456 | + verifyItem(1, -158, 350., false); |
2457 | + verifyItem(2, 192, 350., false); |
2458 | + QCOMPARE(lvwph->m_minYExtent, 350.); |
2459 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2460 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2461 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2462 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2463 | + QCOMPARE(lvwph->contentY(), 1258.); |
2464 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2465 | + |
2466 | + lvwph->setDelegate(otherDelegate); |
2467 | + |
2468 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 6); |
2469 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2470 | + verifyItem(0, 50., 35., false); |
2471 | + verifyItem(1, 85, 35., false); |
2472 | + verifyItem(2, 120, 35., false); |
2473 | + verifyItem(3, 155, 35., false); |
2474 | + verifyItem(4, 190, 35., false); |
2475 | + verifyItem(5, 225, 35., false); |
2476 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2477 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2478 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2479 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2480 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2481 | + QCOMPARE(lvwph->contentY(), 0.); |
2482 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2483 | + } |
2484 | + |
2485 | + void testSetEmptyHeaderAtTop() |
2486 | + { |
2487 | + lvwph->setHeader(nullptr); |
2488 | + |
2489 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2490 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2491 | + verifyItem(0, 0., 150., false); |
2492 | + verifyItem(1, 150., 200., false); |
2493 | + verifyItem(2, 350., 350., false); |
2494 | + verifyItem(3, 700., 350., true); |
2495 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2496 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2497 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2498 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
2499 | + QCOMPARE(lvwph->contentY(), 0.); |
2500 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2501 | + } |
2502 | + |
2503 | + void testSetEmptyHeaderAtBottom() |
2504 | + { |
2505 | + scrollToBottom(); |
2506 | + lvwph->setHeader(nullptr); |
2507 | + |
2508 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2509 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2510 | + verifyItem(0, -508., 350., true); |
2511 | + verifyItem(1, -158, 350., false); |
2512 | + verifyItem(2, 192, 350., false); |
2513 | + QCOMPARE(lvwph->m_minYExtent, 300.); |
2514 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2515 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2516 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
2517 | + QCOMPARE(lvwph->contentY(), 1258.); |
2518 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2519 | + |
2520 | + scrollToTop(); |
2521 | + |
2522 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2523 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2524 | + verifyItem(0, 0., 150., false); |
2525 | + verifyItem(1, 150., 200., false); |
2526 | + verifyItem(2, 350., 350., false); |
2527 | + verifyItem(3, 700., 350., true); |
2528 | + QCOMPARE(lvwph->m_minYExtent, -50.); |
2529 | + QCOMPARE(lvwph->m_clipItem->y(), 50.); |
2530 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2531 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
2532 | + QCOMPARE(lvwph->contentY(), 50.); |
2533 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2534 | + } |
2535 | + |
2536 | + void testSetEmptyHeaderWhenPartlyShownClipped() |
2537 | + { |
2538 | + scrollToBottom(); |
2539 | + changeContentY(-30); |
2540 | + lvwph->setHeader(nullptr); |
2541 | + |
2542 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2543 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2544 | + verifyItem(0, -508., 350., true); |
2545 | + verifyItem(1, -158, 350., false); |
2546 | + verifyItem(2, 192, 350., false); |
2547 | + QCOMPARE(lvwph->m_minYExtent, 330.); |
2548 | + QCOMPARE(lvwph->m_clipItem->y(), 1228.); |
2549 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2550 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
2551 | + QCOMPARE(lvwph->contentY(), 1228.); |
2552 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2553 | + QTRY_VERIFY(lvwph->isAtYEnd()); |
2554 | + |
2555 | + scrollToTop(); |
2556 | + |
2557 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2558 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2559 | + verifyItem(0, 0., 150., false); |
2560 | + verifyItem(1, 150., 200., false); |
2561 | + verifyItem(2, 350., 350., false); |
2562 | + verifyItem(3, 700., 350., true); |
2563 | + QCOMPARE(lvwph->m_minYExtent, -20.); |
2564 | + QCOMPARE(lvwph->m_clipItem->y(), 20.); |
2565 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2566 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
2567 | + QCOMPARE(lvwph->contentY(), 20.); |
2568 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2569 | + } |
2570 | + |
2571 | + void testSetEmptyHeaderWhenPartlyShownNotClipped() |
2572 | + { |
2573 | + changeContentY(30); |
2574 | + lvwph->setHeader(nullptr); |
2575 | + |
2576 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2577 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2578 | + verifyItem(0, -30., 150., false); |
2579 | + verifyItem(1, 120., 200., false); |
2580 | + verifyItem(2, 320., 350., false); |
2581 | + verifyItem(3, 670., 350., true); |
2582 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2583 | + QCOMPARE(lvwph->m_clipItem->y(), 30.); |
2584 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2585 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
2586 | + QCOMPARE(lvwph->contentY(), 30.); |
2587 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2588 | + } |
2589 | + |
2590 | + void testSetNullDelegate() |
2591 | + { |
2592 | + lvwph->setDelegate(nullptr); |
2593 | + |
2594 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 0); |
2595 | + QCOMPARE(lvwph->m_firstVisibleIndex, -1); |
2596 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2597 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2598 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2599 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2600 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2601 | + QCOMPARE(lvwph->contentY(), 0.); |
2602 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2603 | + QTRY_COMPARE(lvwph->contentHeight(), 50.); |
2604 | + QVERIFY(lvwph->isAtYBeginning()); |
2605 | + QVERIFY(lvwph->isAtYEnd()); |
2606 | + } |
2607 | + |
2608 | + void testInsertItems() |
2609 | + { |
2610 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100)); |
2611 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125)); |
2612 | + |
2613 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2614 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2615 | + verifyItem(0, 50., 150., false); |
2616 | + verifyItem(1, 200., 125., false); |
2617 | + verifyItem(2, 325., 100., false); |
2618 | + verifyItem(3, 425., 200., false); |
2619 | + verifyItem(4, 625., 350., true); |
2620 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2621 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2622 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2623 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2624 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2625 | + QCOMPARE(lvwph->contentY(), 0.); |
2626 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2627 | + } |
2628 | + |
2629 | + void testInsertItemsOnNotShownPosition() |
2630 | + { |
2631 | + changeContentY(700); |
2632 | + |
2633 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2634 | + QTRY_COMPARE(lvwph->m_firstVisibleIndex, 2); |
2635 | + verifyItem(0, -300., 350., false); |
2636 | + verifyItem(1, 50, 350., false); |
2637 | + verifyItem(2, 400, 350., false); |
2638 | + verifyItem(3, 750, 350., true); |
2639 | + QCOMPARE(lvwph->m_minYExtent, 350.); |
2640 | + QCOMPARE(lvwph->m_clipItem->y(), 700.); |
2641 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2642 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2643 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2644 | + QCOMPARE(lvwph->contentY(), 700.); |
2645 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2646 | + |
2647 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100)); |
2648 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125)); |
2649 | + |
2650 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2651 | + QCOMPARE(lvwph->m_firstVisibleIndex, 4); |
2652 | + verifyItem(0, -300., 350., false); |
2653 | + verifyItem(1, 50, 350., false); |
2654 | + verifyItem(2, 400, 350., false); |
2655 | + verifyItem(3, 750, 350., true); |
2656 | + QCOMPARE(lvwph->m_minYExtent, 1050.); |
2657 | + QCOMPARE(lvwph->m_clipItem->y(), 700.); |
2658 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2659 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2660 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2661 | + QCOMPARE(lvwph->contentY(), 700.); |
2662 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2663 | + |
2664 | + scrollToTop(); |
2665 | + |
2666 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2667 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2668 | + verifyItem(0, 50., 150., false); |
2669 | + verifyItem(1, 200., 125., false); |
2670 | + verifyItem(2, 325., 100., false); |
2671 | + verifyItem(3, 425., 200., false); |
2672 | + verifyItem(4, 625., 350., true); |
2673 | + QCOMPARE(lvwph->m_minYExtent, 225.); |
2674 | + QCOMPARE(lvwph->m_clipItem->y(), -225.); |
2675 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2676 | + QCOMPARE(lvwph->m_headerItem->y(), -225.); |
2677 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2678 | + QCOMPARE(lvwph->contentY(), -225.); |
2679 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2680 | + } |
2681 | + |
2682 | + void testInsertItemsAtEndOfViewport() |
2683 | + { |
2684 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 100)); |
2685 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 125)); |
2686 | + |
2687 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2688 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2689 | + verifyItem(0, 50., 150., false); |
2690 | + verifyItem(1, 200., 200., false); |
2691 | + verifyItem(2, 400., 350., false); |
2692 | + verifyItem(3, 750., 125., true); |
2693 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2694 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2695 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2696 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2697 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2698 | + QCOMPARE(lvwph->contentY(), 0.); |
2699 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2700 | + } |
2701 | + |
2702 | + void testInsertItemsBeforeValidIndex() |
2703 | + { |
2704 | + changeContentY(520); |
2705 | + |
2706 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2707 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
2708 | + verifyItem(0, -320., 200., true); |
2709 | + verifyItem(1, -120, 350., false); |
2710 | + verifyItem(2, 230, 350., false); |
2711 | + verifyItem(3, 580, 350., true); |
2712 | + QCOMPARE(lvwph->m_minYExtent, 162.5); |
2713 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
2714 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2715 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2716 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2717 | + QCOMPARE(lvwph->contentY(), 520.); |
2718 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2719 | + |
2720 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100)); |
2721 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125)); |
2722 | + |
2723 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2724 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2725 | + verifyItem(0, -320., 200., true); |
2726 | + verifyItem(1, -120, 350., false); |
2727 | + verifyItem(2, 230, 350., false); |
2728 | + verifyItem(3, 580, 350., true); |
2729 | + QCOMPARE(lvwph->m_minYExtent, 787.5); |
2730 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
2731 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2732 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2733 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2734 | + QCOMPARE(lvwph->contentY(), 520.); |
2735 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2736 | + } |
2737 | + |
2738 | + void testInsertItemsBeforeViewport() |
2739 | + { |
2740 | + changeContentY(375); |
2741 | + |
2742 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2743 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2744 | + verifyItem(0, -325., 150., true); |
2745 | + verifyItem(1, -175, 200., false); |
2746 | + verifyItem(2, 25, 350., false); |
2747 | + verifyItem(3, 375, 350., false); |
2748 | + verifyItem(4, 725, 350., true); |
2749 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2750 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
2751 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2752 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2753 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2754 | + QCOMPARE(lvwph->contentY(), 375.); |
2755 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2756 | + |
2757 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100)); |
2758 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125)); |
2759 | + |
2760 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2761 | + QCOMPARE(lvwph->m_firstVisibleIndex, 2); |
2762 | + verifyItem(0, -275., 100., true); |
2763 | + verifyItem(1, -175, 200., false); |
2764 | + verifyItem(2, 25, 350., false); |
2765 | + verifyItem(3, 375, 350., false); |
2766 | + verifyItem(4, 725, 350., true); |
2767 | + QCOMPARE(lvwph->m_minYExtent, 490.); |
2768 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
2769 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2770 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2771 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2772 | + QCOMPARE(lvwph->contentY(), 375.); |
2773 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2774 | + |
2775 | + scrollToTop(); |
2776 | + |
2777 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2778 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2779 | + verifyItem(0, 50., 150., false); |
2780 | + verifyItem(1, 200., 125., false); |
2781 | + verifyItem(2, 325., 100., false); |
2782 | + verifyItem(3, 425., 200., false); |
2783 | + verifyItem(4, 625., 350., true); |
2784 | + QCOMPARE(lvwph->m_minYExtent, 225.); |
2785 | + QCOMPARE(lvwph->m_clipItem->y(), -225.); |
2786 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2787 | + QCOMPARE(lvwph->m_headerItem->y(), -225.); |
2788 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2789 | + QCOMPARE(lvwph->contentY(), -225.); |
2790 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2791 | + } |
2792 | + |
2793 | + void testInsertItemsAtBottom() |
2794 | + { |
2795 | + scrollToBottom(); |
2796 | + |
2797 | + QVERIFY(lvwph->isAtYEnd()); |
2798 | + |
2799 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 100)); |
2800 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 125)); |
2801 | + |
2802 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
2803 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
2804 | + verifyItem(0, -508., 350., true); |
2805 | + verifyItem(1, -158, 350., false); |
2806 | + verifyItem(2, 192, 350., false); |
2807 | + verifyItem(3, 542, 125., true); |
2808 | + verifyItem(4, 667, 100., true); |
2809 | + QCOMPARE(lvwph->m_minYExtent, 65.); |
2810 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2811 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2812 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2813 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2814 | + QCOMPARE(lvwph->contentY(), 1258.); |
2815 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2816 | + QVERIFY(!lvwph->isAtYEnd()); |
2817 | + |
2818 | + scrollToBottom(); |
2819 | + |
2820 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2821 | + QCOMPARE(lvwph->m_firstVisibleIndex, 4); |
2822 | + verifyItem(0, -383., 350., true); |
2823 | + verifyItem(1, -33, 350., false); |
2824 | + verifyItem(2, 317, 125., false); |
2825 | + verifyItem(3, 442, 100., false); |
2826 | + QCOMPARE(lvwph->m_minYExtent, -125.); |
2827 | + QCOMPARE(lvwph->m_clipItem->y(), 1483.); |
2828 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2829 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2830 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2831 | + QCOMPARE(lvwph->contentY(), 1483.); |
2832 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2833 | + QVERIFY(lvwph->isAtYEnd()); |
2834 | + } |
2835 | + |
2836 | + void testInsertItemAtTop() |
2837 | + { |
2838 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2839 | + |
2840 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2841 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2842 | + verifyItem(0, 50., 75., false); |
2843 | + verifyItem(1, 125., 150., false); |
2844 | + verifyItem(2, 275., 200., false); |
2845 | + verifyItem(3, 475., 350., false); |
2846 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2847 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2848 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2849 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2850 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2851 | + QCOMPARE(lvwph->contentY(), 0.); |
2852 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2853 | + QVERIFY(lvwph->isAtYBeginning()); |
2854 | + } |
2855 | + |
2856 | + void testInsertItem10SmallItemsAtTopWhenAtBottom() |
2857 | + { |
2858 | + scrollToBottom(); |
2859 | + |
2860 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2861 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2862 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2863 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2864 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2865 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2866 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2867 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2868 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2869 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75)); |
2870 | + |
2871 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2872 | + QCOMPARE(lvwph->m_firstVisibleIndex, 13); |
2873 | + verifyItem(0, -508., 350., true); |
2874 | + verifyItem(1, -158, 350., false); |
2875 | + verifyItem(2, 192, 350., false); |
2876 | + QCOMPARE(lvwph->m_minYExtent, 3850.); |
2877 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2878 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2879 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2880 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2881 | + QCOMPARE(lvwph->contentY(), 1258.); |
2882 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2883 | + |
2884 | + changeContentY(-1700); |
2885 | + |
2886 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 12); |
2887 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2888 | + verifyItem(0, -308., 75., true); |
2889 | + verifyItem(1, -233., 75., true); |
2890 | + verifyItem(2, -158., 75., true); |
2891 | + verifyItem(3, -83., 75., true); |
2892 | + verifyItem(4, -8., 75., false); |
2893 | + verifyItem(5, 67., 75., false); |
2894 | + verifyItem(6, 142., 75., false); |
2895 | + verifyItem(7, 217., 75., false); |
2896 | + verifyItem(8, 292., 75., false); |
2897 | + verifyItem(9, 367., 75., false); |
2898 | + verifyItem(10, 442., 150., false); |
2899 | + verifyItem(11, 592., 200., true); |
2900 | + QCOMPARE(lvwph->m_minYExtent, 750.); |
2901 | + QCOMPARE(lvwph->m_clipItem->y(), -392.); |
2902 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
2903 | + QCOMPARE(lvwph->m_headerItem->y(), -442.); |
2904 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2905 | + QCOMPARE(lvwph->contentY(), -442.); |
2906 | + QCOMPARE(lvwph->m_headerItemShownHeight, 50.); |
2907 | + } |
2908 | + |
2909 | + void testRemoveItemsAtTop() |
2910 | + { |
2911 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2)); |
2912 | + |
2913 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2914 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2915 | + verifyItem(0, 50., 350., false); |
2916 | + verifyItem(1, 400., 350., false); |
2917 | + verifyItem(2, 750., 350., true); |
2918 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
2919 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
2920 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2921 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2922 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2923 | + QCOMPARE(lvwph->contentY(), 0.); |
2924 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2925 | + QVERIFY(lvwph->isAtYBeginning()); |
2926 | + } |
2927 | + |
2928 | + void testRemoveNonCreatedItemsAtTopWhenAtBottom() |
2929 | + { |
2930 | + scrollToBottom(); |
2931 | + |
2932 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2)); |
2933 | + |
2934 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2935 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
2936 | + verifyItem(0, -508., 350., true); |
2937 | + verifyItem(1, -158, 350., false); |
2938 | + verifyItem(2, 192, 350., false); |
2939 | + QCOMPARE(lvwph->m_minYExtent, -350.); |
2940 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
2941 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2942 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2943 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2944 | + QCOMPARE(lvwph->contentY(), 1258.); |
2945 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2946 | + } |
2947 | + |
2948 | + void testRemoveLastItemsAtBottom() |
2949 | + { |
2950 | + scrollToBottom(); |
2951 | + |
2952 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 4), Q_ARG(QVariant, 2)); |
2953 | + |
2954 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
2955 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
2956 | + verifyItem(0, -358., 200., true); |
2957 | + verifyItem(1, -158, 350., false); |
2958 | + verifyItem(2, 192, 350., false); |
2959 | + QCOMPARE(lvwph->m_minYExtent, 150.); |
2960 | + QCOMPARE(lvwph->m_clipItem->y(), 558.); |
2961 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2962 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2963 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2964 | + QCOMPARE(lvwph->contentY(), 558.); |
2965 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2966 | + } |
2967 | + |
2968 | + void testRemoveItemOutOfViewport() |
2969 | + { |
2970 | + changeContentY(520); |
2971 | + |
2972 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2973 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
2974 | + verifyItem(0, -320., 200., true); |
2975 | + verifyItem(1, -120, 350., false); |
2976 | + verifyItem(2, 230, 350., false); |
2977 | + verifyItem(3, 580, 350., true); |
2978 | + QCOMPARE(lvwph->m_minYExtent, 162.5); |
2979 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
2980 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2981 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2982 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
2983 | + QCOMPARE(lvwph->contentY(), 520.); |
2984 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
2985 | + |
2986 | + |
2987 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 1)); |
2988 | + |
2989 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
2990 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
2991 | + verifyItem(0, -270., 150., true); |
2992 | + verifyItem(1, -120., 350., false); |
2993 | + verifyItem(2, 230, 350., false); |
2994 | + verifyItem(3, 580, 350., true); |
2995 | + QCOMPARE(lvwph->m_minYExtent, -200.); |
2996 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
2997 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
2998 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
2999 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3000 | + QCOMPARE(lvwph->contentY(), 520.); |
3001 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3002 | + } |
3003 | + |
3004 | + void testMoveFirstItems() |
3005 | + { |
3006 | + QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 1), Q_ARG(QVariant, 1)); |
3007 | + |
3008 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3009 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3010 | + verifyItem(0, 50., 200., false); |
3011 | + verifyItem(1, 250., 150., false); |
3012 | + verifyItem(2, 400., 350., false); |
3013 | + verifyItem(3, 750., 350., true); |
3014 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3015 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3016 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3017 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3018 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3019 | + QCOMPARE(lvwph->contentY(), 0.); |
3020 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3021 | + |
3022 | + } |
3023 | + |
3024 | + void testMoveFirstOutOfVisibleItems() |
3025 | + { |
3026 | + QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 4), Q_ARG(QVariant, 1)); |
3027 | + |
3028 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3029 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3030 | + verifyItem(0, 50., 200., false); |
3031 | + verifyItem(1, 250., 350., false); |
3032 | + verifyItem(2, 600., 350., true); |
3033 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3034 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3035 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3036 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3037 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3038 | + QCOMPARE(lvwph->contentY(), 0.); |
3039 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3040 | + |
3041 | + } |
3042 | + |
3043 | + void testMoveFirstToLastAtBottom() |
3044 | + { |
3045 | + scrollToBottom(); |
3046 | + |
3047 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3048 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
3049 | + verifyItem(0, -508., 350., true); |
3050 | + verifyItem(1, -158, 350., false); |
3051 | + verifyItem(2, 192, 350., false); |
3052 | + QCOMPARE(lvwph->m_minYExtent, 350.); |
3053 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
3054 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3055 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3056 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3057 | + QCOMPARE(lvwph->contentY(), 1258.); |
3058 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3059 | + |
3060 | + QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 5), Q_ARG(QVariant, 1)); |
3061 | + |
3062 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3063 | + QCOMPARE(lvwph->m_firstVisibleIndex, 2); |
3064 | + verifyItem(0, -508., 350., true); |
3065 | + verifyItem(1, -158, 350., false); |
3066 | + verifyItem(2, 192, 350., false); |
3067 | + verifyItem(3, 542, 150., true); |
3068 | + QCOMPARE(lvwph->m_minYExtent, -100.); |
3069 | + QCOMPARE(lvwph->m_clipItem->y(), 1258.); |
3070 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3071 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3072 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3073 | + QCOMPARE(lvwph->contentY(), 1258.); |
3074 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3075 | + QVERIFY(!lvwph->isAtYEnd()); |
3076 | + } |
3077 | + |
3078 | + void testChangeSizeVisibleItemNotOnViewport() |
3079 | + { |
3080 | + changeContentY(440); |
3081 | + |
3082 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
3083 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3084 | + verifyItem(0, -390., 150., true); |
3085 | + verifyItem(1, -240., 200., true); |
3086 | + verifyItem(2, -40, 350., false); |
3087 | + verifyItem(3, 310, 350., false); |
3088 | + verifyItem(4, 660, 350., true); |
3089 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3090 | + QCOMPARE(lvwph->m_clipItem->y(), 440.); |
3091 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3092 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3093 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3094 | + QCOMPARE(lvwph->contentY(), 440.); |
3095 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3096 | + |
3097 | + model->setProperty(1, "size", 100); |
3098 | + |
3099 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
3100 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3101 | + verifyItem(0, -290., 150., true); |
3102 | + verifyItem(1, -140., 100., true); |
3103 | + verifyItem(2, -40, 350., false); |
3104 | + verifyItem(3, 310, 350., false); |
3105 | + verifyItem(4, 660, 350., true); |
3106 | + QCOMPARE(lvwph->m_minYExtent, -100.); |
3107 | + QCOMPARE(lvwph->m_clipItem->y(), 440.); |
3108 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3109 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3110 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3111 | + QCOMPARE(lvwph->contentY(), 440.); |
3112 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3113 | + } |
3114 | + |
3115 | + void testShowHeaderCloseToTheTop() |
3116 | + { |
3117 | + changeContentY(375); |
3118 | + |
3119 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
3120 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3121 | + verifyItem(0, -325., 150., true); |
3122 | + verifyItem(1, -175, 200., false); |
3123 | + verifyItem(2, 25, 350., false); |
3124 | + verifyItem(3, 375, 350., false); |
3125 | + verifyItem(4, 725, 350., true); |
3126 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3127 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
3128 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3129 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3130 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3131 | + QCOMPARE(lvwph->contentY(), 375.); |
3132 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.);; |
3133 | + |
3134 | + lvwph->showHeader(); |
3135 | + |
3136 | + QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning()); |
3137 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
3138 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3139 | + verifyItem(0, -375., 150., true); |
3140 | + verifyItem(1, -225, 200., true); |
3141 | + verifyItem(2, -25, 350., false); |
3142 | + verifyItem(3, 325, 350., false); |
3143 | + verifyItem(4, 675, 350., true); |
3144 | + QCOMPARE(lvwph->m_minYExtent, 50.); |
3145 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
3146 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
3147 | + QCOMPARE(lvwph->m_headerItem->y(), 325.); |
3148 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3149 | + QCOMPARE(lvwph->contentY(), 325.); |
3150 | + QCOMPARE(lvwph->m_headerItemShownHeight, 50.);; |
3151 | + |
3152 | + scrollToTop(); |
3153 | + |
3154 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3155 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3156 | + verifyItem(0, 50., 150., false); |
3157 | + verifyItem(1, 200., 200., false); |
3158 | + verifyItem(2, 400., 350., false); |
3159 | + verifyItem(3, 750., 350., true); |
3160 | + QCOMPARE(lvwph->m_minYExtent, 50.); |
3161 | + QCOMPARE(lvwph->m_clipItem->y(), -50.); |
3162 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3163 | + QCOMPARE(lvwph->m_headerItem->y(), -50.); |
3164 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3165 | + QCOMPARE(lvwph->contentY(), -50.); |
3166 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3167 | + } |
3168 | + |
3169 | + void testShowHeaderAtBottom() |
3170 | + { |
3171 | + scrollToBottom(); |
3172 | + |
3173 | + lvwph->showHeader(); |
3174 | + |
3175 | + QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning()); |
3176 | + QTRY_VERIFY (lvwph->isAtYEnd()); |
3177 | + } |
3178 | + |
3179 | + void growWindow() |
3180 | + { |
3181 | + view->rootObject()->setHeight(850); |
3182 | + |
3183 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
3184 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3185 | + verifyItem(0, 50., 150., false); |
3186 | + verifyItem(1, 200., 200., false); |
3187 | + verifyItem(2, 400., 350., false); |
3188 | + verifyItem(3, 750., 350., false); |
3189 | + verifyItem(4, 1100., 350., true); |
3190 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3191 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3192 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3193 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3194 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3195 | + QCOMPARE(lvwph->contentY(), 0.); |
3196 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3197 | + } |
3198 | + |
3199 | + void growWindowAtBottom() |
3200 | + { |
3201 | + scrollToBottom(); |
3202 | + |
3203 | + view->rootObject()->setHeight(850); |
3204 | + |
3205 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3206 | + QCOMPARE(lvwph->m_firstVisibleIndex, 2); |
3207 | + verifyItem(0, -550., 350., true); |
3208 | + verifyItem(1, -200., 350., false); |
3209 | + verifyItem(2, 150, 350., false); |
3210 | + verifyItem(3, 500, 350., false); |
3211 | + QCOMPARE(lvwph->m_minYExtent, 350.); |
3212 | + QCOMPARE(lvwph->m_clipItem->y(), 950.); |
3213 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3214 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3215 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3216 | + QCOMPARE(lvwph->contentY(), 950.); |
3217 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3218 | + } |
3219 | + |
3220 | +private: |
3221 | + QQuickView *view; |
3222 | + ListViewWithPageHeader *lvwph; |
3223 | + QQuickListModel *model; |
3224 | + QQmlComponent *otherDelegate; |
3225 | +}; |
3226 | + |
3227 | +QTEST_MAIN(ListViewWithPageHeaderTest) |
3228 | + |
3229 | +#include "listviewwithpageheadertest.moc" |
3230 | |
3231 | === added file 'tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp' |
3232 | --- tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp 1970-01-01 00:00:00 +0000 |
3233 | +++ tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp 2013-07-01 11:23:32 +0000 |
3234 | @@ -0,0 +1,1567 @@ |
3235 | +/* |
3236 | + * Copyright (C) 2013 Canonical, Ltd. |
3237 | + * |
3238 | + * This program is free software; you can redistribute it and/or modify |
3239 | + * it under the terms of the GNU General Public License as published by |
3240 | + * the Free Software Foundation; version 3. |
3241 | + * |
3242 | + * This program is distributed in the hope that it will be useful, |
3243 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3244 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3245 | + * GNU General Public License for more details. |
3246 | + * |
3247 | + * You should have received a copy of the GNU General Public License |
3248 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3249 | + */ |
3250 | + |
3251 | +#include "listviewwithpageheader.h" |
3252 | + |
3253 | +#include <QAbstractItemModel> |
3254 | +#include <QQmlEngine> |
3255 | +#include <QQuickView> |
3256 | +#include <QtTestGui> |
3257 | +#include <private/qquicklistmodel_p.h> |
3258 | +#include <private/qquickanimation_p.h> |
3259 | +#include <private/qquickitem_p.h> |
3260 | + |
3261 | +class ListViewWithPageHeaderTestSection : public QObject |
3262 | +{ |
3263 | + Q_OBJECT |
3264 | + |
3265 | +private: |
3266 | + void verifyItem(int visibleIndex, qreal pos, qreal height, bool culled, const QString §ionHeader, bool sectionHeaderCulled) |
3267 | + { |
3268 | + QTRY_VERIFY(visibleIndex < lvwph->m_visibleItems.count()); |
3269 | + QTRY_COMPARE(lvwph->m_visibleItems[visibleIndex]->y(), pos); |
3270 | + QTRY_COMPARE(lvwph->m_visibleItems[visibleIndex]->height(), height); |
3271 | + QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_item)->culled, culled); |
3272 | + QCOMPARE(section(lvwph->m_visibleItems[visibleIndex]->m_sectionItem), sectionHeader); |
3273 | + if (!sectionHeader.isNull()) { |
3274 | + QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_sectionItem)->culled, sectionHeaderCulled); |
3275 | + } |
3276 | + } |
3277 | + |
3278 | + void changeContentY(qreal change) |
3279 | + { |
3280 | + const qreal dest = lvwph->contentY() + change; |
3281 | + if (dest > lvwph->contentY()) { |
3282 | + const qreal jump = 25; |
3283 | + while (lvwph->contentY() + jump < dest) { |
3284 | + lvwph->setContentY(lvwph->contentY() + jump); |
3285 | + QTest::qWait(1); |
3286 | + } |
3287 | + } else { |
3288 | + const qreal jump = -25; |
3289 | + while (lvwph->contentY() + jump > dest) { |
3290 | + lvwph->setContentY(lvwph->contentY() + jump); |
3291 | + QTest::qWait(1); |
3292 | + } |
3293 | + } |
3294 | + lvwph->setContentY(dest); |
3295 | + QTest::qWait(1); |
3296 | + } |
3297 | + |
3298 | + void scrollToTop() |
3299 | + { |
3300 | + const qreal jump = -25; |
3301 | + while (!lvwph->isAtYBeginning()) { |
3302 | + if (lvwph->contentY() + jump > -lvwph->minYExtent()) { |
3303 | + lvwph->setContentY(lvwph->contentY() + jump); |
3304 | + } else { |
3305 | + lvwph->setContentY(lvwph->contentY() - 1); |
3306 | + } |
3307 | + QTest::qWait(1); |
3308 | + } |
3309 | + } |
3310 | + |
3311 | + void scrollToBottom() |
3312 | + { |
3313 | + const qreal jump = 25; |
3314 | + while (!lvwph->isAtYEnd()) { |
3315 | + if (lvwph->contentY() + lvwph->height() + jump < lvwph->contentHeight()) { |
3316 | + lvwph->setContentY(lvwph->contentY() + jump); |
3317 | + } else { |
3318 | + lvwph->setContentY(lvwph->contentY() + 1); |
3319 | + } |
3320 | + QTest::qWait(1); |
3321 | + } |
3322 | + } |
3323 | + |
3324 | + void verifyInitialTopPosition() |
3325 | + { |
3326 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3327 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3328 | + verifyItem(0, 50., 190., false, "Agressive", false); |
3329 | + verifyItem(1, 240., 240., false, "Regular", false); |
3330 | + verifyItem(2, 480., 390., false, "Mild", false); |
3331 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3332 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3333 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3334 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3335 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3336 | + QCOMPARE(lvwph->contentY(), 0.); |
3337 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3338 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3339 | + } |
3340 | + |
3341 | + QString section(QQuickItem *item) |
3342 | + { |
3343 | + return item ? QQmlEngine::contextForObject(item)->parentContext()->contextProperty(QLatin1String("section")).toString() : QString(); |
3344 | + } |
3345 | + |
3346 | +private Q_SLOTS: |
3347 | + |
3348 | + void initTestCase() |
3349 | + { |
3350 | + } |
3351 | + |
3352 | + void init() |
3353 | + { |
3354 | + view = new QQuickView(); |
3355 | + view->engine()->addImportPath(BUILT_PLUGINS_DIR); |
3356 | + view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test_section.qml")); |
3357 | + lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>()); |
3358 | + model = view->rootObject()->findChild<QQuickListModel*>(); |
3359 | + otherDelegate = view->rootObject()->findChild<QQmlComponent*>(); |
3360 | + QVERIFY(lvwph); |
3361 | + QVERIFY(model); |
3362 | + QVERIFY(otherDelegate); |
3363 | + view->show(); |
3364 | + QTest::qWaitForWindowExposed(view); |
3365 | + |
3366 | + verifyInitialTopPosition(); |
3367 | + } |
3368 | + |
3369 | + void cleanup() |
3370 | + { |
3371 | + delete view; |
3372 | + } |
3373 | + |
3374 | + void testCreationDeletion() |
3375 | + { |
3376 | + // Nothing, init/cleanup already tests this |
3377 | + } |
3378 | + |
3379 | + void testDrag1PixelUp() |
3380 | + { |
3381 | + lvwph->setContentY(lvwph->contentY() + 1); |
3382 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3383 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3384 | + verifyItem(0, 49., 190., false, "Agressive", false); |
3385 | + verifyItem(1, 239., 240., false, "Regular", false); |
3386 | + verifyItem(2, 479., 390., false, "Mild", false); |
3387 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3388 | + QCOMPARE(lvwph->m_clipItem->y(), 1.); |
3389 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3390 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3391 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3392 | + QCOMPARE(lvwph->contentY(), 1.); |
3393 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3394 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3395 | + } |
3396 | + |
3397 | + void testHeaderDetachDragDown() |
3398 | + { |
3399 | + QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0)); |
3400 | + QTest::qWait(100); |
3401 | + QTest::mouseMove(view, QPoint(0, 5)); |
3402 | + QTest::qWait(100); |
3403 | + QTest::mouseMove(view, QPoint(0, 10)); |
3404 | + QTest::qWait(100); |
3405 | + QTest::mouseMove(view, QPoint(0, 15)); |
3406 | + QTest::qWait(100); |
3407 | + QTest::mouseMove(view, QPoint(0, 20)); |
3408 | + QTest::qWait(100); |
3409 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3410 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3411 | + verifyItem(0, 55., 190., false, "Agressive", false); |
3412 | + verifyItem(1, 245., 240., false, "Regular", false); |
3413 | + verifyItem(2, 485., 390., false, "Mild", false); |
3414 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3415 | + QCOMPARE(lvwph->m_clipItem->y(), -5.); |
3416 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3417 | + QCOMPARE(lvwph->m_headerItem->y(), -5.); |
3418 | + QCOMPARE(lvwph->m_headerItem->height(), 55.); |
3419 | + QCOMPARE(lvwph->contentY(), -5.); |
3420 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3421 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3422 | + |
3423 | + QTest::mouseRelease(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 15)); |
3424 | + |
3425 | + verifyInitialTopPosition(); |
3426 | + } |
3427 | + |
3428 | + void testDrag375PixelUp() |
3429 | + { |
3430 | + changeContentY(375); |
3431 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3432 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3433 | + verifyItem(0, -325., 190., true, "Agressive", true); |
3434 | + verifyItem(1, -135, 240., false, "Regular", true); |
3435 | + verifyItem(2, 105, 390., false, "Mild", false); |
3436 | + verifyItem(3, 495, 390., false, "Bold", false); |
3437 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3438 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
3439 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3440 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3441 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3442 | + QCOMPARE(lvwph->contentY(), 375.); |
3443 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3444 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3445 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
3446 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3447 | + } |
3448 | + |
3449 | + void testDrag520PixelUp() |
3450 | + { |
3451 | + changeContentY(520); |
3452 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3453 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
3454 | + verifyItem(0, -280., 240., true, "Regular", true); |
3455 | + verifyItem(1, -40, 390., false, "Mild", true); |
3456 | + verifyItem(2, 350, 390., false, "Bold", false); |
3457 | + verifyItem(3, 740, 350., true, QString(), true); |
3458 | + QCOMPARE(lvwph->m_minYExtent, 152.5); |
3459 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
3460 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3461 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3462 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3463 | + QCOMPARE(lvwph->contentY(), 520.); |
3464 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3465 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3466 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
3467 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3468 | + } |
3469 | + |
3470 | + void testDragHeaderUpThenShow() |
3471 | + { |
3472 | + changeContentY(120); |
3473 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3474 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3475 | + verifyItem(0, -70., 190., false, "Agressive", true); |
3476 | + verifyItem(1, 120., 240., false, "Regular", false); |
3477 | + verifyItem(2, 360., 390., false, "Mild", false); |
3478 | + verifyItem(3, 750., 390., true, "Bold", true); |
3479 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3480 | + QCOMPARE(lvwph->m_clipItem->y(), 120.); |
3481 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3482 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3483 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3484 | + QCOMPARE(lvwph->contentY(), 120.); |
3485 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3486 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3487 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive")); |
3488 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3489 | + |
3490 | + changeContentY(-30); |
3491 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3492 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3493 | + verifyItem(0, -70., 190., false, "Agressive", true); |
3494 | + verifyItem(1, 120., 240., false, "Regular", false); |
3495 | + verifyItem(2, 360., 390., false, "Mild", false); |
3496 | + verifyItem(3, 750., 390., true, "Bold", true); |
3497 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3498 | + QCOMPARE(lvwph->m_clipItem->y(), 120.); |
3499 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
3500 | + QTRY_COMPARE(lvwph->m_headerItem->y(), 70.); |
3501 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3502 | + QCOMPARE(lvwph->contentY(), 90.); |
3503 | + QCOMPARE(lvwph->m_headerItemShownHeight, 30.); |
3504 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3505 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive")); |
3506 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3507 | + } |
3508 | + |
3509 | + void testDragHeaderUpThenShowWithoutHidingTotally() |
3510 | + { |
3511 | + changeContentY(10); |
3512 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3513 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3514 | + verifyItem(0, 40., 190., false, "Agressive", false); |
3515 | + verifyItem(1, 230., 240., false, "Regular", false); |
3516 | + verifyItem(2, 470., 390., false, "Mild", false); |
3517 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3518 | + QCOMPARE(lvwph->m_clipItem->y(), 10.); |
3519 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3520 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3521 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3522 | + QCOMPARE(lvwph->contentY(), 10.); |
3523 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3524 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3525 | + |
3526 | + changeContentY(-1); |
3527 | + |
3528 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3529 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3530 | + verifyItem(0, 41., 190., false, "Agressive", false); |
3531 | + verifyItem(1, 231., 240., false, "Regular", false); |
3532 | + verifyItem(2, 471., 390., false, "Mild", false); |
3533 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3534 | + QCOMPARE(lvwph->m_clipItem->y(), 9.); |
3535 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3536 | + QTRY_COMPARE(lvwph->m_headerItem->y(), 0.); |
3537 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3538 | + QCOMPARE(lvwph->contentY(), 9.); |
3539 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3540 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3541 | + } |
3542 | + |
3543 | + void testPositionAtBeginningIndex0Visible() |
3544 | + { |
3545 | + changeContentY(375); |
3546 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3547 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3548 | + verifyItem(0, -325., 190., true, "Agressive", true); |
3549 | + verifyItem(1, -135, 240., false, "Regular", true); |
3550 | + verifyItem(2, 105, 390., false, "Mild", false); |
3551 | + verifyItem(3, 495, 390., false, "Bold", false); |
3552 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3553 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
3554 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3555 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3556 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3557 | + QCOMPARE(lvwph->contentY(), 375.); |
3558 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3559 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3560 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
3561 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3562 | + |
3563 | + lvwph->positionAtBeginning(); |
3564 | + |
3565 | + verifyInitialTopPosition(); |
3566 | + } |
3567 | + |
3568 | + void testPositionAtBeginningIndex0NotVisible() |
3569 | + { |
3570 | + changeContentY(520); |
3571 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3572 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
3573 | + verifyItem(0, -280., 240., true, "Regular", true); |
3574 | + verifyItem(1, -40, 390., false, "Mild", true); |
3575 | + verifyItem(2, 350, 390., false, "Bold", false); |
3576 | + verifyItem(3, 740, 350., true, QString(), true); |
3577 | + QCOMPARE(lvwph->m_minYExtent, 152.5); |
3578 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
3579 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3580 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3581 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3582 | + QCOMPARE(lvwph->contentY(), 520.); |
3583 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3584 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3585 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
3586 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3587 | + |
3588 | + lvwph->positionAtBeginning(); |
3589 | + |
3590 | + verifyInitialTopPosition(); |
3591 | + } |
3592 | + |
3593 | + void testIndex0GrowOnScreen() |
3594 | + { |
3595 | + model->setProperty(0, "size", 400); |
3596 | + |
3597 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3598 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3599 | + verifyItem(0, 50., 440., false, "Agressive", false); |
3600 | + verifyItem(1, 490., 240., false, "Regular", false); |
3601 | + verifyItem(2, 730., 390., true, "Mild", true); |
3602 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3603 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3604 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3605 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3606 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3607 | + QCOMPARE(lvwph->contentY(), 0.); |
3608 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3609 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3610 | + } |
3611 | + |
3612 | + void testIndex0GrowOffScreen() |
3613 | + { |
3614 | + changeContentY(375); |
3615 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3616 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3617 | + verifyItem(0, -325., 190., true, "Agressive", true); |
3618 | + verifyItem(1, -135, 240., false, "Regular", true); |
3619 | + verifyItem(2, 105, 390., false, "Mild", false); |
3620 | + verifyItem(3, 495, 390., false, "Bold", false); |
3621 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3622 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
3623 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3624 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3625 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3626 | + QCOMPARE(lvwph->contentY(), 375.); |
3627 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3628 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3629 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
3630 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3631 | + |
3632 | + model->setProperty(0, "size", 400); |
3633 | + |
3634 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3635 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3636 | + verifyItem(0, -575., 440., true, "Agressive", true); |
3637 | + verifyItem(1, -135, 240., false, "Regular", true); |
3638 | + verifyItem(2, 105, 390., false, "Mild", false); |
3639 | + verifyItem(3, 495, 390., false, "Bold", false); |
3640 | + QCOMPARE(lvwph->m_minYExtent, 250.); |
3641 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
3642 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3643 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3644 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3645 | + QCOMPARE(lvwph->contentY(), 375.); |
3646 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3647 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3648 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
3649 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3650 | + |
3651 | + scrollToTop(); |
3652 | + |
3653 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3654 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3655 | + verifyItem(0, 50., 440., false, "Agressive", false); |
3656 | + verifyItem(1, 490, 240., false, "Regular", false); |
3657 | + verifyItem(2, 730, 390., true, "Mild", true); |
3658 | + QCOMPARE(lvwph->m_minYExtent, 250.); |
3659 | + QCOMPARE(lvwph->m_clipItem->y(), -250.); |
3660 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3661 | + QCOMPARE(lvwph->m_headerItem->y(), -250.); |
3662 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3663 | + QCOMPARE(lvwph->contentY(), -250.); |
3664 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3665 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3666 | + |
3667 | + changeContentY(30); |
3668 | + |
3669 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3670 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3671 | + verifyItem(0, 20., 440., false, "Agressive", false); |
3672 | + verifyItem(1, 460, 240., false, "Regular", false); |
3673 | + verifyItem(2, 700, 390., true, "Mild", true); |
3674 | + QCOMPARE(lvwph->m_minYExtent, 250.); |
3675 | + QCOMPARE(lvwph->m_clipItem->y(), -220.); |
3676 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3677 | + QCOMPARE(lvwph->m_headerItem->y(), -250.); |
3678 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3679 | + QCOMPARE(lvwph->contentY(), -220.); |
3680 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3681 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3682 | + } |
3683 | + |
3684 | + void testIndex0GrowNotCreated() |
3685 | + { |
3686 | + changeContentY(520); |
3687 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3688 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
3689 | + verifyItem(0, -280., 240., true, "Regular", true); |
3690 | + verifyItem(1, -40, 390., false, "Mild", true); |
3691 | + verifyItem(2, 350, 390., false, "Bold", false); |
3692 | + verifyItem(3, 740, 350., true, QString(), true); |
3693 | + QCOMPARE(lvwph->m_minYExtent, 152.5); |
3694 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
3695 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3696 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3697 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3698 | + QCOMPARE(lvwph->contentY(), 520.); |
3699 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3700 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3701 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
3702 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3703 | + |
3704 | + model->setProperty(0, "size", 400); |
3705 | + |
3706 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
3707 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
3708 | + verifyItem(0, -280., 240., true, "Regular", true); |
3709 | + verifyItem(1, -40, 390., false, "Mild", true); |
3710 | + verifyItem(2, 350, 390., false, "Bold", false); |
3711 | + verifyItem(3, 740, 350., true, QString(), true); |
3712 | + QCOMPARE(lvwph->m_minYExtent, 152.5); |
3713 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
3714 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3715 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3716 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3717 | + QCOMPARE(lvwph->contentY(), 520.); |
3718 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3719 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3720 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
3721 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3722 | + |
3723 | + scrollToTop(); |
3724 | + |
3725 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3726 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3727 | + verifyItem(0, 50., 440., false, "Agressive", false); |
3728 | + verifyItem(1, 490, 240., false, "Regular", false); |
3729 | + verifyItem(2, 730, 390., true, "Mild", true); |
3730 | + QCOMPARE(lvwph->m_minYExtent, 250.); |
3731 | + QCOMPARE(lvwph->m_clipItem->y(), -250.); |
3732 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3733 | + QCOMPARE(lvwph->m_headerItem->y(), -250.); |
3734 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3735 | + QCOMPARE(lvwph->contentY(), -250.); |
3736 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3737 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3738 | + } |
3739 | + |
3740 | + void testShowHideShowHeaderAtBottom() |
3741 | + { |
3742 | + scrollToBottom(); |
3743 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3744 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
3745 | + verifyItem(0, -588., 390., true, "Bold", true); |
3746 | + verifyItem(1, -198, 350., false, QString(), true); |
3747 | + verifyItem(2, 152, 390., false, "Lazy", false); |
3748 | + QCOMPARE(lvwph->m_minYExtent, 310.); |
3749 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
3750 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3751 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3752 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3753 | + QCOMPARE(lvwph->contentY(), 1458.); |
3754 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3755 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3756 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
3757 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3758 | + |
3759 | + changeContentY(-30); |
3760 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3761 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
3762 | + verifyItem(0, -588., 390., true, "Bold", true); |
3763 | + verifyItem(1, -198, 350., false, QString(), true); |
3764 | + verifyItem(2, 152, 390., false, "Lazy", false); |
3765 | + QCOMPARE(lvwph->m_minYExtent, 310.); |
3766 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
3767 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
3768 | + QCOMPARE(lvwph->m_headerItem->y(), 1408.); |
3769 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3770 | + QCOMPARE(lvwph->contentY(), 1428.); |
3771 | + QCOMPARE(lvwph->m_headerItemShownHeight, 30.); |
3772 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3773 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
3774 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3775 | + |
3776 | + changeContentY(30); |
3777 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3778 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
3779 | + verifyItem(0, -588., 390., true, "Bold", true); |
3780 | + verifyItem(1, -198, 350., false, QString(), true); |
3781 | + verifyItem(2, 152, 390., false, "Lazy", false); |
3782 | + QCOMPARE(lvwph->m_minYExtent, 310.); |
3783 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
3784 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3785 | + QCOMPARE(lvwph->m_headerItem->y(), -310.); |
3786 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3787 | + QCOMPARE(lvwph->contentY(), 1458.); |
3788 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3789 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3790 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
3791 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3792 | + |
3793 | + changeContentY(-30); |
3794 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3795 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
3796 | + verifyItem(0, -588., 390., true, "Bold", true); |
3797 | + verifyItem(1, -198, 350., false, QString(), true); |
3798 | + verifyItem(2, 152, 390., false, "Lazy", false); |
3799 | + QCOMPARE(lvwph->m_minYExtent, 310.); |
3800 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
3801 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
3802 | + QCOMPARE(lvwph->m_headerItem->y(), 1408.); |
3803 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3804 | + QCOMPARE(lvwph->contentY(), 1428.); |
3805 | + QCOMPARE(lvwph->m_headerItemShownHeight, 30.); |
3806 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3807 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
3808 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3809 | + } |
3810 | + |
3811 | + void testChangeDelegateAtBottom() |
3812 | + { |
3813 | + scrollToBottom(); |
3814 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3815 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
3816 | + verifyItem(0, -588., 390., true, "Bold", true); |
3817 | + verifyItem(1, -198, 350., false, QString(), true); |
3818 | + verifyItem(2, 152, 390., false, "Lazy", false); |
3819 | + QCOMPARE(lvwph->m_minYExtent, 310.); |
3820 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
3821 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3822 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3823 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3824 | + QCOMPARE(lvwph->contentY(), 1458.); |
3825 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3826 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3827 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
3828 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3829 | + |
3830 | + lvwph->setDelegate(otherDelegate); |
3831 | + |
3832 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 6); |
3833 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3834 | + verifyItem(0, 50., 75., false, "Agressive", false); |
3835 | + verifyItem(1, 125, 75., false, "Regular", false); |
3836 | + verifyItem(2, 200, 75., false, "Mild", false); |
3837 | + verifyItem(3, 275, 75., false, "Bold", false); |
3838 | + verifyItem(4, 350, 35., false, QString(), true); |
3839 | + verifyItem(5, 385, 75., false, "Lazy", false); |
3840 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3841 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3842 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3843 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3844 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3845 | + QCOMPARE(lvwph->contentY(), 0.); |
3846 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3847 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3848 | + } |
3849 | + |
3850 | + void testSetEmptyHeaderAtTop() |
3851 | + { |
3852 | + lvwph->setHeader(nullptr); |
3853 | + |
3854 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3855 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3856 | + verifyItem(0, 0., 190., false, "Agressive", false); |
3857 | + verifyItem(1, 190., 240., false, "Regular", false); |
3858 | + verifyItem(2, 430., 390., false, "Mild", false); |
3859 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3860 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3861 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3862 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
3863 | + QCOMPARE(lvwph->contentY(), 0.); |
3864 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3865 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3866 | + } |
3867 | + |
3868 | + void testSetEmptyHeaderAtBottom() |
3869 | + { |
3870 | + scrollToBottom(); |
3871 | + lvwph->setHeader(nullptr); |
3872 | + |
3873 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3874 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
3875 | + verifyItem(0, -588., 390., true, "Bold", true); |
3876 | + verifyItem(1, -198, 350., false, QString(), true); |
3877 | + verifyItem(2, 152, 390., false, "Lazy", false); |
3878 | + QCOMPARE(lvwph->m_minYExtent, 260.); |
3879 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
3880 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3881 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
3882 | + QCOMPARE(lvwph->contentY(), 1458.); |
3883 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3884 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3885 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
3886 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3887 | + |
3888 | + scrollToTop(); |
3889 | + |
3890 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3891 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3892 | + verifyItem(0, 0., 190., false, "Agressive", false); |
3893 | + verifyItem(1, 190., 240., false, "Regular", false); |
3894 | + verifyItem(2, 430., 390., false, "Mild", false); |
3895 | + QCOMPARE(lvwph->m_minYExtent, -50.); |
3896 | + QCOMPARE(lvwph->m_clipItem->y(), 50.); |
3897 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3898 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
3899 | + QCOMPARE(lvwph->contentY(), 50.); |
3900 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3901 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3902 | + } |
3903 | + |
3904 | + void testSetEmptyHeaderWhenPartlyShownClipped() |
3905 | + { |
3906 | + scrollToBottom(); |
3907 | + changeContentY(-30); |
3908 | + lvwph->setHeader(nullptr); |
3909 | + |
3910 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3911 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
3912 | + verifyItem(0, -588., 390., true, "Bold", true); |
3913 | + verifyItem(1, -198, 350., false, QString(), true); |
3914 | + verifyItem(2, 152, 390., false, "Lazy", false); |
3915 | + QCOMPARE(lvwph->m_minYExtent, 290.); |
3916 | + QCOMPARE(lvwph->m_clipItem->y(), 1428.); |
3917 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3918 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
3919 | + QCOMPARE(lvwph->contentY(), 1428.); |
3920 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3921 | + QTRY_VERIFY(lvwph->isAtYEnd()); |
3922 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3923 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
3924 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3925 | + |
3926 | + scrollToTop(); |
3927 | + |
3928 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3929 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3930 | + verifyItem(0, 0., 190., false, "Agressive", false); |
3931 | + verifyItem(1, 190., 240., false, "Regular", false); |
3932 | + verifyItem(2, 430., 390., false, "Mild", false); |
3933 | + QCOMPARE(lvwph->m_minYExtent, -20.); |
3934 | + QCOMPARE(lvwph->m_clipItem->y(), 20.); |
3935 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3936 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
3937 | + QCOMPARE(lvwph->contentY(), 20.); |
3938 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3939 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3940 | + } |
3941 | + |
3942 | + void testSetEmptyHeaderWhenPartlyShownNotClipped() |
3943 | + { |
3944 | + changeContentY(30); |
3945 | + lvwph->setHeader(nullptr); |
3946 | + |
3947 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
3948 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3949 | + verifyItem(0, -30., 190., false, "Agressive", true); |
3950 | + verifyItem(1, 160., 240., false, "Regular", false); |
3951 | + verifyItem(2, 400., 390., false, "Mild", false); |
3952 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3953 | + QCOMPARE(lvwph->m_clipItem->y(), 30.); |
3954 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3955 | + QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr); |
3956 | + QCOMPARE(lvwph->contentY(), 30.); |
3957 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3958 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3959 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive")); |
3960 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
3961 | + } |
3962 | + |
3963 | + void testSetNullDelegate() |
3964 | + { |
3965 | + lvwph->setDelegate(nullptr); |
3966 | + |
3967 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 0); |
3968 | + QCOMPARE(lvwph->m_firstVisibleIndex, -1); |
3969 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3970 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3971 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3972 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3973 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3974 | + QCOMPARE(lvwph->contentY(), 0.); |
3975 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
3976 | + QTRY_COMPARE(lvwph->contentHeight(), 50.); |
3977 | + QVERIFY(lvwph->isAtYBeginning()); |
3978 | + QVERIFY(lvwph->isAtYEnd()); |
3979 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
3980 | + } |
3981 | + |
3982 | + void testInsertItems() |
3983 | + { |
3984 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive")); |
3985 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular")); |
3986 | + |
3987 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
3988 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
3989 | + verifyItem(0, 50., 190., false, "Agressive", false); |
3990 | + verifyItem(1, 240., 165., false, "Regular", false); |
3991 | + verifyItem(2, 405., 140., false, "Agressive", false); |
3992 | + verifyItem(3, 545., 240., true, "Regular", true); |
3993 | + verifyItem(4, 785., 390., true, "Mild", true); |
3994 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
3995 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
3996 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
3997 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
3998 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
3999 | + QCOMPARE(lvwph->contentY(), 0.); |
4000 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4001 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4002 | + } |
4003 | + |
4004 | + void testInsertItemsStealSectionItem() |
4005 | + { |
4006 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular")); |
4007 | + |
4008 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4009 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4010 | + verifyItem(0, 50., 190., false, "Agressive", false); |
4011 | + verifyItem(1, 240., 165., false, "Regular", false); |
4012 | + verifyItem(2, 405., 200., false, QString(), true); |
4013 | + verifyItem(3, 605., 390., true, "Mild", true); |
4014 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4015 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
4016 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4017 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4018 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4019 | + QCOMPARE(lvwph->contentY(), 0.); |
4020 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4021 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4022 | + } |
4023 | + |
4024 | + |
4025 | + void testInsertItemsOnNotShownPosition() |
4026 | + { |
4027 | + changeContentY(800); |
4028 | + |
4029 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4030 | + QTRY_COMPARE(lvwph->m_firstVisibleIndex, 2); |
4031 | + verifyItem(0, -320., 390., false, "Mild", true); |
4032 | + verifyItem(1, 70, 390., false, "Bold", false); |
4033 | + verifyItem(2, 460, 350., false, QString(), false); |
4034 | + verifyItem(3, 810, 390., true, "Lazy", true); |
4035 | + QCOMPARE(lvwph->m_minYExtent, 330.); |
4036 | + QCOMPARE(lvwph->m_clipItem->y(), 800.); |
4037 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4038 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4039 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4040 | + QCOMPARE(lvwph->contentY(), 800.); |
4041 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4042 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4043 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4044 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4045 | + |
4046 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive")); |
4047 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular")); |
4048 | + |
4049 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4050 | + QCOMPARE(lvwph->m_firstVisibleIndex, 4); |
4051 | + verifyItem(0, -320., 390., false, "Mild", true); |
4052 | + verifyItem(1, 70, 390., false, "Bold", false); |
4053 | + verifyItem(2, 460, 350., false, QString(), false); |
4054 | + verifyItem(3, 810, 390., true, "Lazy", true); |
4055 | + QCOMPARE(lvwph->m_minYExtent, 1090.); |
4056 | + QCOMPARE(lvwph->m_clipItem->y(), 800.); |
4057 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4058 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4059 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4060 | + QCOMPARE(lvwph->contentY(), 800.); |
4061 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4062 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4063 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4064 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4065 | + |
4066 | + scrollToTop(); |
4067 | + |
4068 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
4069 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4070 | + verifyItem(0, 50., 190., false, "Agressive", false); |
4071 | + verifyItem(1, 240., 165., false, "Regular", false); |
4072 | + verifyItem(2, 405., 140., false, "Agressive", false); |
4073 | + verifyItem(3, 545., 240., true, "Regular", true); |
4074 | + verifyItem(4, 785., 390., true, "Mild", true); |
4075 | + QCOMPARE(lvwph->m_minYExtent, 305.); |
4076 | + QCOMPARE(lvwph->m_clipItem->y(), -305.); |
4077 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4078 | + QCOMPARE(lvwph->m_headerItem->y(), -305.); |
4079 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4080 | + QCOMPARE(lvwph->contentY(), -305.); |
4081 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4082 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4083 | + } |
4084 | + |
4085 | + void testInsertItemsAtEndOfViewport() |
4086 | + { |
4087 | + changeContentY(60); |
4088 | + |
4089 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4090 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4091 | + verifyItem(0, -10., 190., false, "Agressive", true); |
4092 | + verifyItem(1, 180., 240., false, "Regular", false); |
4093 | + verifyItem(2, 420., 390., false, "Mild", false); |
4094 | + verifyItem(3, 810., 390., true, "Bold", true); |
4095 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4096 | + QCOMPARE(lvwph->m_clipItem->y(), 60.); |
4097 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4098 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4099 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4100 | + QCOMPARE(lvwph->contentY(), 60.); |
4101 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4102 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4103 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive")); |
4104 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4105 | + |
4106 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive")); |
4107 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular")); |
4108 | + |
4109 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4110 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4111 | + verifyItem(0, -10., 190., false, "Agressive", true); |
4112 | + verifyItem(1, 180., 240., false, "Regular", false); |
4113 | + verifyItem(2, 420., 390., false, "Mild", false); |
4114 | + verifyItem(3, 810., 165., true, "Regular", true); |
4115 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4116 | + QCOMPARE(lvwph->m_clipItem->y(), 60.); |
4117 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4118 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4119 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4120 | + QCOMPARE(lvwph->contentY(), 60.); |
4121 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4122 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4123 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive")); |
4124 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4125 | + } |
4126 | + |
4127 | + void testInsertItemsBeforeValidIndex() |
4128 | + { |
4129 | + changeContentY(520); |
4130 | + |
4131 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4132 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
4133 | + verifyItem(0, -280., 240., true, "Regular", true); |
4134 | + verifyItem(1, -40, 390., false, "Mild", true); |
4135 | + verifyItem(2, 350, 390., false, "Bold", false); |
4136 | + verifyItem(3, 740, 350., true, QString(), true); |
4137 | + QCOMPARE(lvwph->m_minYExtent, 152.5); |
4138 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
4139 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4140 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4141 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4142 | + QCOMPARE(lvwph->contentY(), 520.); |
4143 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4144 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4145 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4146 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4147 | + |
4148 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive")); |
4149 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular")); |
4150 | + |
4151 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4152 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
4153 | + verifyItem(0, -280., 240., true, "Regular", true); |
4154 | + verifyItem(1, -40, 390., false, "Mild", true); |
4155 | + verifyItem(2, 350, 390., false, "Bold", false); |
4156 | + verifyItem(3, 740, 350., true, QString(), true); |
4157 | + QCOMPARE(lvwph->m_minYExtent, 837.5); |
4158 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
4159 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4160 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4161 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4162 | + QCOMPARE(lvwph->contentY(), 520.); |
4163 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4164 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4165 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4166 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4167 | + } |
4168 | + |
4169 | + void testInsertItemsBeforeViewport() |
4170 | + { |
4171 | + changeContentY(375); |
4172 | + |
4173 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4174 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4175 | + verifyItem(0, -325., 190., true, "Agressive", true); |
4176 | + verifyItem(1, -135, 240., false, "Regular", true); |
4177 | + verifyItem(2, 105, 390., false, "Mild", false); |
4178 | + verifyItem(3, 495, 390., false, "Bold", false); |
4179 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4180 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
4181 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4182 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4183 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4184 | + QCOMPARE(lvwph->contentY(), 375.); |
4185 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4186 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4187 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
4188 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4189 | + |
4190 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive")); |
4191 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular")); |
4192 | + |
4193 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4194 | + QCOMPARE(lvwph->m_firstVisibleIndex, 2); |
4195 | + verifyItem(0, -275., 140., true, "Agressive", true); |
4196 | + verifyItem(1, -135., 240., false, "Regular", true); |
4197 | + verifyItem(2, 105, 390., false, "Mild", false); |
4198 | + verifyItem(3, 495, 390., false, "Bold", false); |
4199 | + QCOMPARE(lvwph->m_minYExtent, 530.); |
4200 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
4201 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4202 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4203 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4204 | + QCOMPARE(lvwph->contentY(), 375.); |
4205 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4206 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4207 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
4208 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4209 | + |
4210 | + scrollToTop(); |
4211 | + |
4212 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
4213 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4214 | + verifyItem(0, 50., 190., false, "Agressive", false); |
4215 | + verifyItem(1, 240., 165., false, "Regular", false); |
4216 | + verifyItem(2, 405., 140., false, "Agressive", false); |
4217 | + verifyItem(3, 545., 240., true, "Regular", true); |
4218 | + verifyItem(4, 785., 390., true, "Mild", true); |
4219 | + QCOMPARE(lvwph->m_minYExtent, 305.); |
4220 | + QCOMPARE(lvwph->m_clipItem->y(), -305.); |
4221 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4222 | + QCOMPARE(lvwph->m_headerItem->y(), -305.); |
4223 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4224 | + QCOMPARE(lvwph->contentY(), -305.); |
4225 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4226 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4227 | + } |
4228 | + |
4229 | + void testInsertItemsAtBottom() |
4230 | + { |
4231 | + scrollToBottom(); |
4232 | + |
4233 | + QVERIFY(lvwph->isAtYEnd()); |
4234 | + |
4235 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive")); |
4236 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular")); |
4237 | + |
4238 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
4239 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
4240 | + verifyItem(0, -588., 390., true, "Bold", true); |
4241 | + verifyItem(1, -198, 350., false, QString(), true); |
4242 | + verifyItem(2, 152, 390., false, "Lazy", false); |
4243 | + verifyItem(3, 542, 165., true, "Regular", true); |
4244 | + verifyItem(4, 707, 140., true, "Agressive", true); |
4245 | + QCOMPARE(lvwph->m_minYExtent, 41.); |
4246 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
4247 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4248 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4249 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4250 | + QCOMPARE(lvwph->contentY(), 1458.); |
4251 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4252 | + QVERIFY(!lvwph->isAtYEnd()); |
4253 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4254 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
4255 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4256 | + |
4257 | + scrollToBottom(); |
4258 | + |
4259 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4260 | + QCOMPARE(lvwph->m_firstVisibleIndex, 4); |
4261 | + verifyItem(0, -503., 350., true, QString(), true); |
4262 | + verifyItem(1, -153, 390., false, "Lazy", true); |
4263 | + verifyItem(2, 237, 165., false, "Regular", false); |
4264 | + verifyItem(3, 402, 140., false, "Agressive", false); |
4265 | + QCOMPARE(lvwph->m_minYExtent, -165.); |
4266 | + QCOMPARE(lvwph->m_clipItem->y(), 1763.); |
4267 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4268 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4269 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4270 | + QCOMPARE(lvwph->contentY(), 1763.); |
4271 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4272 | + QVERIFY(lvwph->isAtYEnd()); |
4273 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4274 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Lazy")); |
4275 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4276 | + } |
4277 | + |
4278 | + void testInsertItemAtTop() |
4279 | + { |
4280 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive")); |
4281 | + |
4282 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4283 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4284 | + verifyItem(0, 50., 115., false, "Agressive", false); |
4285 | + verifyItem(1, 165., 150., false, QString(), false); |
4286 | + verifyItem(2, 315., 240., false, "Regular", false); |
4287 | + verifyItem(3, 555., 390., true, "Mild", true); |
4288 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4289 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
4290 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4291 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4292 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4293 | + QCOMPARE(lvwph->contentY(), 0.); |
4294 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4295 | + QVERIFY(lvwph->isAtYBeginning()); |
4296 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4297 | + } |
4298 | + |
4299 | + void testInsertItem10SmallItemsAtTopWhenAtBottom() |
4300 | + { |
4301 | + scrollToBottom(); |
4302 | + |
4303 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive")); |
4304 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive")); |
4305 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive")); |
4306 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Regular")); |
4307 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Regular")); |
4308 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Regular")); |
4309 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive")); |
4310 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive")); |
4311 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Regular")); |
4312 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive")); |
4313 | + |
4314 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
4315 | + QCOMPARE(lvwph->m_firstVisibleIndex, 13); |
4316 | + verifyItem(0, -588., 390., true, "Bold", true); |
4317 | + verifyItem(1, -198, 350., false, QString(), true); |
4318 | + verifyItem(2, 152, 390., false, "Lazy", false); |
4319 | + QCOMPARE(lvwph->m_minYExtent, 12230./3.); |
4320 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
4321 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4322 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4323 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4324 | + QCOMPARE(lvwph->contentY(), 1458.); |
4325 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4326 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4327 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
4328 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4329 | + |
4330 | + changeContentY(-1700); |
4331 | + |
4332 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 10); |
4333 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
4334 | + verifyItem(0, -323., 75., true, QString(), true); |
4335 | + verifyItem(1, -248., 115., true, "Regular", true); |
4336 | + verifyItem(2, -133., 75., true, QString(), true); |
4337 | + verifyItem(3, -58., 75., false, QString(), true); |
4338 | + verifyItem(4, 17., 115., false, "Agressive", false); |
4339 | + verifyItem(5, 132., 75., false, QString(), true); |
4340 | + verifyItem(6, 207., 75., false, QString(), true); |
4341 | + verifyItem(7, 282., 150., false, QString(), true); |
4342 | + verifyItem(8, 432., 240., false, "Regular", false); |
4343 | + QCOMPARE(lvwph->m_minYExtent, 980.5); |
4344 | + QCOMPARE(lvwph->m_clipItem->y(), -192.); |
4345 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
4346 | + QCOMPARE(lvwph->m_headerItem->y(), -242.); |
4347 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4348 | + QCOMPARE(lvwph->contentY(), -242.); |
4349 | + QCOMPARE(lvwph->m_headerItemShownHeight, 50.); |
4350 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4351 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
4352 | + QCOMPARE(lvwph->m_topSectionItem->y(), -23.); |
4353 | + } |
4354 | + |
4355 | + void testRemoveItemsAtTop() |
4356 | + { |
4357 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2)); |
4358 | + |
4359 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 2); |
4360 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4361 | + verifyItem(0, 50., 390., false, "Mild", false); |
4362 | + verifyItem(1, 440., 390., false, "Bold", false); |
4363 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4364 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
4365 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4366 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4367 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4368 | + QCOMPARE(lvwph->contentY(), 0.); |
4369 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4370 | + QVERIFY(lvwph->isAtYBeginning()); |
4371 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4372 | + } |
4373 | + |
4374 | + void testRemoveNonCreatedItemsAtTopWhenAtBottom() |
4375 | + { |
4376 | + scrollToBottom(); |
4377 | + |
4378 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2)); |
4379 | + |
4380 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
4381 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
4382 | + verifyItem(0, -588., 390., true, "Bold", true); |
4383 | + verifyItem(1, -198, 350., false, QString(), true); |
4384 | + verifyItem(2, 152, 390., false, "Lazy", false); |
4385 | + QCOMPARE(lvwph->m_minYExtent, -1330./3.); |
4386 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
4387 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4388 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4389 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4390 | + QCOMPARE(lvwph->contentY(), 1458.); |
4391 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4392 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4393 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
4394 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4395 | + } |
4396 | + |
4397 | + void testRemoveLastItemsAtBottom() |
4398 | + { |
4399 | + scrollToBottom(); |
4400 | + |
4401 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 4), Q_ARG(QVariant, 2)); |
4402 | + |
4403 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
4404 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
4405 | + verifyItem(0, -478., 240., true, "Regular", true); |
4406 | + verifyItem(1, -238, 390., false, "Mild", true); |
4407 | + verifyItem(2, 152, 390., false, "Bold", false); |
4408 | + QCOMPARE(lvwph->m_minYExtent, 150.); |
4409 | + QCOMPARE(lvwph->m_clipItem->y(), 718.); |
4410 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4411 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4412 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4413 | + QCOMPARE(lvwph->contentY(), 718.); |
4414 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4415 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4416 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4417 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4418 | + } |
4419 | + |
4420 | + void testRemoveItemOutOfViewport() |
4421 | + { |
4422 | + changeContentY(520); |
4423 | + |
4424 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4425 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
4426 | + verifyItem(0, -280., 240., true, "Regular", true); |
4427 | + verifyItem(1, -40, 390., false, "Mild", true); |
4428 | + verifyItem(2, 350, 390., false, "Bold", false); |
4429 | + verifyItem(3, 740, 350., true, QString(), true); |
4430 | + QCOMPARE(lvwph->m_minYExtent, 152.5); |
4431 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
4432 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4433 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4434 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4435 | + QCOMPARE(lvwph->contentY(), 520.); |
4436 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4437 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4438 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4439 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4440 | + |
4441 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 1)); |
4442 | + |
4443 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4444 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4445 | + verifyItem(0, -230., 190., true, "Agressive", true); |
4446 | + verifyItem(1, -40, 390., false, "Mild", true); |
4447 | + verifyItem(2, 350, 390., false, "Bold", false); |
4448 | + verifyItem(3, 740, 350., true, QString(), true); |
4449 | + QCOMPARE(lvwph->m_minYExtent, -240.); |
4450 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
4451 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4452 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4453 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4454 | + QCOMPARE(lvwph->contentY(), 520.); |
4455 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4456 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4457 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4458 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4459 | + } |
4460 | + |
4461 | + void testRemoveFirstOfCategory() |
4462 | + { |
4463 | + changeContentY(520); |
4464 | + |
4465 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4466 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
4467 | + verifyItem(0, -280., 240., true, "Regular", true); |
4468 | + verifyItem(1, -40, 390., false, "Mild", true); |
4469 | + verifyItem(2, 350, 390., false, "Bold", false); |
4470 | + verifyItem(3, 740, 350., true, QString(), true); |
4471 | + QCOMPARE(lvwph->m_minYExtent, 152.5); |
4472 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
4473 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4474 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4475 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4476 | + QCOMPARE(lvwph->contentY(), 520.); |
4477 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4478 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4479 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4480 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4481 | + |
4482 | + QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 3), Q_ARG(QVariant, 1)); |
4483 | + |
4484 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4485 | + QCOMPARE(lvwph->m_firstVisibleIndex, 1); |
4486 | + verifyItem(0, -280., 240., true, "Regular", true); |
4487 | + verifyItem(1, -40, 390., false, "Mild", true); |
4488 | + verifyItem(2, 350, 390., false, "Bold", false); |
4489 | + verifyItem(3, 740, 390., true, "Lazy", true); |
4490 | + QCOMPARE(lvwph->m_minYExtent, 162.5); |
4491 | + QCOMPARE(lvwph->m_clipItem->y(), 520.); |
4492 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4493 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4494 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4495 | + QCOMPARE(lvwph->contentY(), 520.); |
4496 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4497 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4498 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4499 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4500 | + } |
4501 | + |
4502 | + void testAddSecondToCulledCategoryOfTwo() |
4503 | + { |
4504 | + // Do some setup |
4505 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 25), Q_ARG(QVariant, "Agressive")); |
4506 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 25), Q_ARG(QVariant, "Agressive")); |
4507 | + |
4508 | + changeContentY(200); |
4509 | + |
4510 | + // Very the items are culled |
4511 | + verifyItem(0, -150., 65., true, "Agressive", true); |
4512 | + verifyItem(1, -85, 25., true, QString(), true); |
4513 | + |
4514 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 25), Q_ARG(QVariant, "Agressive")); |
4515 | + |
4516 | + // Very the new item is there correctly |
4517 | + verifyItem(0, -175., 65., true, "Agressive", true); |
4518 | + verifyItem(1, -110, 25., true, QString(), true); |
4519 | + verifyItem(2, -85, 25., true, QString(), true); |
4520 | + } |
4521 | + |
4522 | + void testMoveFirstItems() |
4523 | + { |
4524 | + QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 1), Q_ARG(QVariant, 1)); |
4525 | + |
4526 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
4527 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4528 | + verifyItem(0, 50., 240., false, "Regular", false); |
4529 | + verifyItem(1, 290., 190., false, "Agressive", false); |
4530 | + verifyItem(2, 480., 390., false, "Mild", false); |
4531 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4532 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
4533 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4534 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4535 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4536 | + QCOMPARE(lvwph->contentY(), 0.); |
4537 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4538 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4539 | + } |
4540 | + |
4541 | + void testMoveFirstOutOfVisibleItems() |
4542 | + { |
4543 | + QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 4), Q_ARG(QVariant, 1)); |
4544 | + |
4545 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
4546 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4547 | + verifyItem(0, 50., 240., false, "Regular", false); |
4548 | + verifyItem(1, 290., 390., false, "Mild", false); |
4549 | + verifyItem(2, 680., 390., true, "Bold", true); |
4550 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4551 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
4552 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4553 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4554 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4555 | + QCOMPARE(lvwph->contentY(), 0.); |
4556 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4557 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4558 | + } |
4559 | + |
4560 | + void testMoveFirstToLastAtBottom() |
4561 | + { |
4562 | + scrollToBottom(); |
4563 | + |
4564 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
4565 | + QCOMPARE(lvwph->m_firstVisibleIndex, 3); |
4566 | + verifyItem(0, -588., 390., true, "Bold", true); |
4567 | + verifyItem(1, -198, 350., false, QString(), true); |
4568 | + verifyItem(2, 152, 390., false, "Lazy", false); |
4569 | + QCOMPARE(lvwph->m_minYExtent, 310.); |
4570 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
4571 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4572 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4573 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4574 | + QCOMPARE(lvwph->contentY(), 1458.); |
4575 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4576 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4577 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
4578 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4579 | + |
4580 | + QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 5), Q_ARG(QVariant, 1)); |
4581 | + |
4582 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4583 | + QCOMPARE(lvwph->m_firstVisibleIndex, 2); |
4584 | + verifyItem(0, -588., 390., true, "Bold", true); |
4585 | + verifyItem(1, -198, 350., false, QString(), true); |
4586 | + verifyItem(2, 152, 390., false, "Lazy", false); |
4587 | + verifyItem(3, 542, 190., true, "Agressive", true); |
4588 | + QCOMPARE(lvwph->m_minYExtent, -160.); |
4589 | + QCOMPARE(lvwph->m_clipItem->y(), 1458.); |
4590 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4591 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4592 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4593 | + QCOMPARE(lvwph->contentY(), 1458.); |
4594 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4595 | + QVERIFY(!lvwph->isAtYEnd()); |
4596 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4597 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold")); |
4598 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4599 | + } |
4600 | + |
4601 | + void testChangeSizeVisibleItemNotOnViewport() |
4602 | + { |
4603 | + changeContentY(490); |
4604 | + |
4605 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
4606 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4607 | + verifyItem(0, -440., 190., true, "Agressive", true); |
4608 | + verifyItem(1, -250., 240., true, "Regular", true); |
4609 | + verifyItem(2, -10, 390., false, "Mild", true); |
4610 | + verifyItem(3, 380, 390., false, "Bold", false); |
4611 | + verifyItem(4, 770, 350., true, QString(), true); |
4612 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4613 | + QCOMPARE(lvwph->m_clipItem->y(), 490.); |
4614 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4615 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4616 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4617 | + QCOMPARE(lvwph->contentY(), 490.); |
4618 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4619 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4620 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4621 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4622 | + |
4623 | + model->setProperty(1, "size", 100); |
4624 | + |
4625 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
4626 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4627 | + verifyItem(0, -340., 190., true, "Agressive", true); |
4628 | + verifyItem(1, -150., 140., true, "Regular", true); |
4629 | + verifyItem(2, -10, 390., false, "Mild", true); |
4630 | + verifyItem(3, 380, 390., false, "Bold", false); |
4631 | + verifyItem(4, 770, 350., true, QString(), true); |
4632 | + QCOMPARE(lvwph->m_minYExtent, -100.); |
4633 | + QCOMPARE(lvwph->m_clipItem->y(), 490.); |
4634 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4635 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4636 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4637 | + QCOMPARE(lvwph->contentY(), 490.); |
4638 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4639 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4640 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild")); |
4641 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4642 | + } |
4643 | + |
4644 | + void testShowHeaderCloseToTheTop() |
4645 | + { |
4646 | + changeContentY(375); |
4647 | + |
4648 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4649 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4650 | + verifyItem(0, -325., 190., true, "Agressive", true); |
4651 | + verifyItem(1, -135, 240., false, "Regular", true); |
4652 | + verifyItem(2, 105, 390., false, "Mild", false); |
4653 | + verifyItem(3, 495, 390., false, "Bold", false); |
4654 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4655 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
4656 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4657 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4658 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4659 | + QCOMPARE(lvwph->contentY(), 375.); |
4660 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.);; |
4661 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4662 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
4663 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4664 | + |
4665 | + lvwph->showHeader(); |
4666 | + |
4667 | + QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning()); |
4668 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 4); |
4669 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4670 | + verifyItem(0, -375., 190., true, "Agressive", true); |
4671 | + verifyItem(1, -185, 240., false, "Regular", true); |
4672 | + verifyItem(2, 55, 390., false, "Mild", false); |
4673 | + verifyItem(3, 445, 390., false, "Bold", false); |
4674 | + QCOMPARE(lvwph->m_minYExtent, 50.); |
4675 | + QCOMPARE(lvwph->m_clipItem->y(), 375.); |
4676 | + QCOMPARE(lvwph->m_clipItem->clip(), true); |
4677 | + QCOMPARE(lvwph->m_headerItem->y(), 325.); |
4678 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4679 | + QCOMPARE(lvwph->contentY(), 325.); |
4680 | + QCOMPARE(lvwph->m_headerItemShownHeight, 50.); |
4681 | + QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4682 | + QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular")); |
4683 | + QCOMPARE(lvwph->m_topSectionItem->y(), 0.); |
4684 | + |
4685 | + scrollToTop(); |
4686 | + |
4687 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 3); |
4688 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4689 | + verifyItem(0, 50., 190., false, "Agressive", false); |
4690 | + verifyItem(1, 240., 240., false, "Regular", false); |
4691 | + verifyItem(2, 480., 390., false, "Mild", false); |
4692 | + QCOMPARE(lvwph->m_minYExtent, 50.); |
4693 | + QCOMPARE(lvwph->m_clipItem->y(), -50.); |
4694 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4695 | + QCOMPARE(lvwph->m_headerItem->y(), -50.); |
4696 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4697 | + QCOMPARE(lvwph->contentY(), -50.); |
4698 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4699 | + QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled); |
4700 | + } |
4701 | + |
4702 | + void testShowHeaderAtBottom() |
4703 | + { |
4704 | + scrollToBottom(); |
4705 | + |
4706 | + lvwph->showHeader(); |
4707 | + |
4708 | + QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning()); |
4709 | + QTRY_VERIFY (lvwph->isAtYEnd()); |
4710 | + } |
4711 | + |
4712 | + void growWindow() |
4713 | + { |
4714 | + view->rootObject()->setHeight(850); |
4715 | + |
4716 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 5); |
4717 | + QCOMPARE(lvwph->m_firstVisibleIndex, 0); |
4718 | + verifyItem(0, 50., 190., false, "Agressive", false); |
4719 | + verifyItem(1, 240., 240., false, "Regular", false); |
4720 | + verifyItem(2, 480., 390., false, "Mild", false); |
4721 | + verifyItem(3, 870., 390., true, "Bold", true); |
4722 | + verifyItem(4, 1260., 350., true, QString(), true); |
4723 | + QCOMPARE(lvwph->m_minYExtent, 0.); |
4724 | + QCOMPARE(lvwph->m_clipItem->y(), 0.); |
4725 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4726 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4727 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4728 | + QCOMPARE(lvwph->contentY(), 0.); |
4729 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4730 | + } |
4731 | + |
4732 | + void growWindowAtBottom() |
4733 | + { |
4734 | + // Need a bunch small items at the bottom to trigger the problem |
4735 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4736 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4737 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4738 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4739 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4740 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4741 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular")); |
4742 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular")); |
4743 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular")); |
4744 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular")); |
4745 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular")); |
4746 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular")); |
4747 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4748 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4749 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4750 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4751 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4752 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4753 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4754 | + QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive")); |
4755 | + |
4756 | + scrollToBottom(); |
4757 | + |
4758 | + view->rootObject()->setHeight(850); |
4759 | + |
4760 | + QTRY_COMPARE(lvwph->m_visibleItems.count(), 21); |
4761 | + QCOMPARE(lvwph->m_firstVisibleIndex, 5); |
4762 | + verifyItem(0, -660., 390., true, "Lazy", true); |
4763 | + verifyItem(1, -270., 90., true, "Agressive", true); |
4764 | + verifyItem(2, -180, 50., true, QString(), true); |
4765 | + verifyItem(3, -130, 50., true, QString(), true); |
4766 | + verifyItem(4, -80, 50., true, QString(), true); |
4767 | + verifyItem(5, -30, 50., false, QString(), true); |
4768 | + verifyItem(6, 20, 50., false, QString(), true); |
4769 | + verifyItem(7, 70, 50., false, QString(), true); |
4770 | + verifyItem(8, 120, 50., false, QString(), true); |
4771 | + verifyItem(9, 170, 90., false, "Regular", false); |
4772 | + verifyItem(10, 260, 50., false, QString(), true); |
4773 | + verifyItem(11, 310, 50., false, QString(), true); |
4774 | + verifyItem(12, 360, 50., false, QString(), true); |
4775 | + verifyItem(13, 410, 50., false, QString(), true); |
4776 | + verifyItem(14, 460, 50., false, QString(), true); |
4777 | + verifyItem(15, 510, 90., false, "Agressive", false); |
4778 | + verifyItem(16, 600, 50., false, QString(), true); |
4779 | + verifyItem(17, 650, 50., false, QString(), true); |
4780 | + verifyItem(18, 700, 50., false, QString(), true); |
4781 | + verifyItem(19, 750, 50., false, QString(), true); |
4782 | + verifyItem(20, 800, 50., false, QString(), true); |
4783 | + QCOMPARE(lvwph->m_minYExtent, 5 * 1510./21. + 660 - 1970 + 50); |
4784 | + QCOMPARE(lvwph->m_clipItem->y(), 1970.); |
4785 | + QCOMPARE(lvwph->m_clipItem->clip(), false); |
4786 | + QCOMPARE(lvwph->m_headerItem->y(), 0.); |
4787 | + QCOMPARE(lvwph->m_headerItem->height(), 50.); |
4788 | + QCOMPARE(lvwph->contentY(), 1970.); |
4789 | + QCOMPARE(lvwph->m_headerItemShownHeight, 0.); |
4790 | + } |
4791 | + |
4792 | +private: |
4793 | + QQuickView *view; |
4794 | + ListViewWithPageHeader *lvwph; |
4795 | + QQuickListModel *model; |
4796 | + QQmlComponent *otherDelegate; |
4797 | +}; |
4798 | + |
4799 | +QTEST_MAIN(ListViewWithPageHeaderTestSection) |
4800 | + |
4801 | +#include "listviewwithpageheadertestsection.moc" |
4802 | |
4803 | === added file 'tests/plugins/ListViewWithPageHeader/test.qml' |
4804 | --- tests/plugins/ListViewWithPageHeader/test.qml 1970-01-01 00:00:00 +0000 |
4805 | +++ tests/plugins/ListViewWithPageHeader/test.qml 2013-07-01 11:23:32 +0000 |
4806 | @@ -0,0 +1,96 @@ |
4807 | +/* |
4808 | + * Copyright (C) 2013 Canonical, Ltd. |
4809 | + * |
4810 | + * This program is free software; you can redistribute it and/or modify |
4811 | + * it under the terms of the GNU General Public License as published by |
4812 | + * the Free Software Foundation; version 3. |
4813 | + * |
4814 | + * This program is distributed in the hope that it will be useful, |
4815 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4816 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4817 | + * GNU General Public License for more details. |
4818 | + * |
4819 | + * You should have received a copy of the GNU General Public License |
4820 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4821 | + */ |
4822 | + |
4823 | +import QtQuick 2.0 |
4824 | +import ListViewWithPageHeader 0.1 |
4825 | + |
4826 | +Rectangle { |
4827 | + width: 300 |
4828 | + height: 542 |
4829 | + color: "lightblue" |
4830 | + |
4831 | + ListModel { |
4832 | + id: model |
4833 | + |
4834 | + function insertItem(index, size) { |
4835 | + insert(index, { size: size }); |
4836 | + } |
4837 | + |
4838 | + function removeItems(index, count) { |
4839 | + remove(index, count); |
4840 | + } |
4841 | + |
4842 | + function moveItems(indexFrom, indexTo, count) { |
4843 | + move(indexFrom, indexTo, count); |
4844 | + } |
4845 | + |
4846 | + ListElement { size: 150 } |
4847 | + ListElement { size: 200 } |
4848 | + ListElement { size: 350 } |
4849 | + ListElement { size: 350 } |
4850 | + ListElement { size: 350 } |
4851 | + ListElement { size: 350 } |
4852 | + } |
4853 | + |
4854 | + Component { |
4855 | + id: otherRect |
4856 | + Rectangle { |
4857 | + height: 35 |
4858 | + width: parent.width |
4859 | + color: index % 2 == 0 ? "yellow" : "purple" |
4860 | + } |
4861 | + } |
4862 | + |
4863 | + ListViewWithPageHeader { |
4864 | + id: listView |
4865 | + width: parent.width |
4866 | + anchors.top: parent.top |
4867 | + anchors.bottom: parent.bottom |
4868 | + model: model |
4869 | + delegate: Rectangle { |
4870 | + property bool timerDone: false |
4871 | + width: parent.width - 20 |
4872 | + x: 10 |
4873 | + color: index % 2 == 0 ? "red" : "blue" |
4874 | + height: timerDone ? size : 350 |
4875 | + Text { |
4876 | + text: index |
4877 | + } |
4878 | + Timer { |
4879 | + id: sizeTimer |
4880 | + interval: 10; |
4881 | + onTriggered: { |
4882 | + timerDone = true |
4883 | + } |
4884 | + } |
4885 | + Component.onCompleted: { |
4886 | + sizeTimer.start() |
4887 | + } |
4888 | + } |
4889 | + |
4890 | + pageHeader: Rectangle { |
4891 | + color: "transparent" |
4892 | + width: parent.width |
4893 | + height: 50 |
4894 | + implicitHeight: 50 |
4895 | + Text { |
4896 | + anchors.fill: parent |
4897 | + text: "APPS" |
4898 | + font.pixelSize: 40 |
4899 | + } |
4900 | + } |
4901 | + } |
4902 | +} |
4903 | |
4904 | === added file 'tests/plugins/ListViewWithPageHeader/test_section.qml' |
4905 | --- tests/plugins/ListViewWithPageHeader/test_section.qml 1970-01-01 00:00:00 +0000 |
4906 | +++ tests/plugins/ListViewWithPageHeader/test_section.qml 2013-07-01 11:23:32 +0000 |
4907 | @@ -0,0 +1,106 @@ |
4908 | +/* |
4909 | + * Copyright (C) 2013 Canonical, Ltd. |
4910 | + * |
4911 | + * This program is free software; you can redistribute it and/or modify |
4912 | + * it under the terms of the GNU General Public License as published by |
4913 | + * the Free Software Foundation; version 3. |
4914 | + * |
4915 | + * This program is distributed in the hope that it will be useful, |
4916 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4917 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4918 | + * GNU General Public License for more details. |
4919 | + * |
4920 | + * You should have received a copy of the GNU General Public License |
4921 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4922 | + */ |
4923 | + |
4924 | +import QtQuick 2.0 |
4925 | +import ListViewWithPageHeader 0.1 |
4926 | + |
4927 | +Rectangle { |
4928 | + width: 300 |
4929 | + height: 542 |
4930 | + color: "lightblue" |
4931 | + |
4932 | + ListModel { |
4933 | + id: model |
4934 | + |
4935 | + function insertItem(index, size, type) { |
4936 | + insert(index, { size: size, type: type }); |
4937 | + } |
4938 | + |
4939 | + function removeItems(index, count) { |
4940 | + remove(index, count); |
4941 | + } |
4942 | + |
4943 | + function moveItems(indexFrom, indexTo, count) { |
4944 | + move(indexFrom, indexTo, count); |
4945 | + } |
4946 | + |
4947 | + ListElement { type: "Agressive"; size: 150 } |
4948 | + ListElement { type: "Regular"; size: 200 } |
4949 | + ListElement { type: "Mild"; size: 350 } |
4950 | + ListElement { type: "Bold"; size: 350 } |
4951 | + ListElement { type: "Bold"; size: 350 } |
4952 | + ListElement { type: "Lazy"; size: 350 } |
4953 | + } |
4954 | + |
4955 | + Component { |
4956 | + id: otherRect |
4957 | + Rectangle { |
4958 | + height: 35 |
4959 | + width: parent.width |
4960 | + color: index % 2 == 0 ? "yellow" : "purple" |
4961 | + } |
4962 | + } |
4963 | + |
4964 | + ListViewWithPageHeader { |
4965 | + id: listView |
4966 | + width: parent.width |
4967 | + anchors.top: parent.top |
4968 | + anchors.bottom: parent.bottom |
4969 | + model: model |
4970 | + delegate: Rectangle { |
4971 | + property bool timerDone: false |
4972 | + width: parent.width - 20 |
4973 | + x: 10 |
4974 | + color: index % 2 == 0 ? "red" : "blue" |
4975 | + height: timerDone ? size : 350 |
4976 | + Text { |
4977 | + text: index |
4978 | + } |
4979 | + Timer { |
4980 | + id: sizeTimer |
4981 | + interval: 10; |
4982 | + onTriggered: { |
4983 | + timerDone = true |
4984 | + } |
4985 | + } |
4986 | + Component.onCompleted: { |
4987 | + sizeTimer.start() |
4988 | + } |
4989 | + } |
4990 | + |
4991 | + pageHeader: Rectangle { |
4992 | + color: "transparent" |
4993 | + width: parent.width |
4994 | + height: 50 |
4995 | + implicitHeight: 50 |
4996 | + Text { |
4997 | + anchors.fill: parent |
4998 | + text: "APPS" |
4999 | + font.pixelSize: 40 |
5000 | + } |
Setting to needs review because i want CI to give it a go, still work in progress (need to add a few more tests)