Merge lp:~nick-dedekind/unity8/expanded-panel-design into lp:unity8
- expanded-panel-design
- Merge into trunk
Status: | Merged | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Michael Terry | ||||||||||||||||
Approved revision: | 1339 | ||||||||||||||||
Merged at revision: | 1376 | ||||||||||||||||
Proposed branch: | lp:~nick-dedekind/unity8/expanded-panel-design | ||||||||||||||||
Merge into: | lp:unity8 | ||||||||||||||||
Prerequisite: | lp:~nick-dedekind/unity8/sharedunitymenumodel | ||||||||||||||||
Diff against target: |
5736 lines (+2171/-2135) 56 files modified
plugins/Unity/Indicators/Indicators.qmltypes (+2/-4) plugins/Unity/Indicators/indicators.h (+0/-2) plugins/Unity/Indicators/indicatorsmodel.cpp (+0/-6) plugins/Unity/Indicators/rootactionstate.cpp (+1/-1) plugins/Unity/Indicators/rootactionstate.h (+4/-4) plugins/Unity/Indicators/sharedunitymenumodel.cpp (+6/-1) plugins/Unity/Indicators/unitymenumodelcache.cpp (+1/-5) plugins/Unity/Indicators/unitymenumodelcache.h (+1/-3) plugins/Unity/Indicators/visibleindicatorsmodel.cpp (+0/-2) qml/Components/DragHandle.qml (+6/-1) qml/Components/EdgeDemo.qml (+13/-10) qml/Components/ListItems/VerticalThinDivider.qml (+0/-26) qml/Components/ScrollCalculator.qml (+81/-0) qml/Panel/Handle.qml (+43/-0) qml/Panel/IndicatorItem.qml (+0/-53) qml/Panel/IndicatorItemRow.qml (+297/-0) qml/Panel/IndicatorPage.qml (+10/-16) qml/Panel/IndicatorRow.qml (+0/-163) qml/Panel/Indicators.qml (+0/-415) qml/Panel/Indicators/DefaultIndicatorWidget.qml (+0/-119) qml/Panel/Indicators/IndicatorBase.qml (+1/-5) qml/Panel/Indicators/IndicatorDelegate.qml (+2/-2) qml/Panel/Indicators/VisibleIndicators.qml (+4/-5) qml/Panel/Indicators/client/IndicatorRepresentation.qml (+22/-11) qml/Panel/Indicators/client/IndicatorsList.qml (+2/-2) qml/Panel/Indicators/client/IndicatorsTree.qml (+4/-26) qml/Panel/IndicatorsBar.qml (+269/-0) qml/Panel/IndicatorsMenu.qml (+318/-0) qml/Panel/MenuContent.qml (+26/-83) qml/Panel/Panel.qml (+0/-191) qml/Panel/PanelVelocityCalculator.qml (+54/-0) qml/Shell.qml (+16/-5) tests/autopilot/unity8/indicators/tests/test_indicators.py (+1/-1) tests/autopilot/unity8/shell/emulators/main_window.py (+6/-6) tests/mocks/Unity/Indicators/Indicators.qmltypes (+2/-4) tests/mocks/Unity/Indicators/IndicatorsModel.qml (+89/-79) tests/mocks/Unity/Indicators/RootActionState.qml (+2/-2) tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp (+0/-2) tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cpp (+10/-8) tests/mocks/Unity/Indicators/fakeunitymenumodelcache.h (+4/-8) tests/qmltests/CMakeLists.txt (+5/-5) tests/qmltests/Greeter/tst_Clock.qml (+1/-3) tests/qmltests/Panel/IndicatorTest.qml (+80/-0) tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml (+0/-52) tests/qmltests/Panel/tst_ActiveCallHint.qml (+0/-1) tests/qmltests/Panel/tst_IndicatorItem.qml (+0/-50) tests/qmltests/Panel/tst_IndicatorItemRow.qml (+290/-0) tests/qmltests/Panel/tst_IndicatorPage.qml (+5/-7) tests/qmltests/Panel/tst_IndicatorRow.qml (+0/-158) tests/qmltests/Panel/tst_Indicators.qml (+0/-231) tests/qmltests/Panel/tst_IndicatorsBar.qml (+224/-0) tests/qmltests/Panel/tst_IndicatorsMenu.qml (+258/-0) tests/qmltests/Panel/tst_MenuContent.qml (+9/-17) tests/qmltests/Panel/tst_Panel.qml (+0/-337) tests/qmltests/Panel/tst_SearchIndicator.qml (+0/-1) tests/qmltests/tst_Shell.qml (+2/-2) |
||||||||||||||||
To merge this branch: | bzr merge lp:~nick-dedekind/unity8/expanded-panel-design | ||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Terry | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Daniel d'Andrada (community) | Abstain | ||
MichaĆ Sawicz | Needs Fixing | ||
Albert Astals Cid (community) | Abstain | ||
Andrea Cimitan (community) | Needs Fixing | ||
Nick Dedekind (community) | Needs Fixing | ||
Omer Akram | functional | Pending | |
Review via email: mp+237031@code.launchpad.net |
Commit message
Implementation of expandable panel design
Description of the change
New Panel design described in:
https:/
* Are there any related MPs required for this MP to build/function as expected? Please list.
No
* Did you perform an exploratory manual test run of your code change and any related functionality?
No
* Did you make sure that your branch does not contain spurious tags?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A
* If you changed the UI, has there been a design review?
No
PS Jenkins bot (ps-jenkins) wrote : | # |
Nick Dedekind (nick-dedekind) wrote : | # |
From Vesa:
The invisible commit line shouldn't be there any more. User should be able to make the selection until finger is released regardless of vertical position. Also means the when closing indicators the selection should change immediately after the drag is started.
Combining icons is fine as it is. You asked about this on irc. We want icons to be combined even though it was not mentioned in the document. And multiple icons representing single menu is ok.
Velocity detection to prevent the item change is too aggressive? Makes the UI quite unresponsive when moving horizontally and making selection. The old indicators implementation suffered from the same issue.
Autoscroll is a bit jarring sometimes. Anyway to fix it?
Wobbly effect of the highlight when item changes. Could we get rid of that? I know my prototype has it and it most probably is due to the different timings of two different behavior that are then combined to create the full effect. But this is actually unwanted behavior. For example the current indicators implementation handles the highlight change smoothly which is what we want here as well.
Aligning items to left after release/commit. If you swipe down from transfers for example, after release it should scroll to align the left most item to left of the screen.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1296
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Andrea Cimitan (cimi) wrote : | # |
Ordering properties and signals for those files:
qml/Components/
qml/Panel/
And coming...
Andrea Cimitan (cimi) wrote : | # |
More
Nick Dedekind (nick-dedekind) wrote : | # |
> More
Addressed all i think. Added a few comments to yours.
Nick Dedekind (nick-dedekind) wrote : | # |
Comments for review
Andrea Cimitan (cimi) wrote : | # |
Thanks for addressing... I still feel like we need more time to understand the logic and see if we can write it more simply, added a few comments, will ask another review! more eyes are better!
Andrea Cimitan (cimi) : | # |
Andrea Cimitan (cimi) : | # |
Andrea Cimitan (cimi) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1303
http://
Executed test runs:
FAILURE: http://
None: http://
SUCCESS: 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:1309
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nick Dedekind (nick-dedekind) wrote : | # |
more comments + fixes.
Albert Astals Cid (aacid) wrote : | # |
Text conflict in qml/Shell.qml
Text conflict in tests/qmltests/
Text conflict in tests/qmltests/
3 conflicts encountered.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1312
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:1313
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
$ bzr tags | grep ?
0.1.16 ?
Nick Dedekind (nick-dedekind) wrote : | # |
> $ bzr tags | grep ?
> 0.1.16 ?
removed
Nick Dedekind (nick-dedekind) wrote : | # |
> Thanks for addressing... I still feel like we need more time to understand the
> logic and see if we can write it more simply, added a few comments, will ask
> another review! more eyes are better!
I've addressed some of the complexity as well as fixed some of the bugs.
- 1316. By Nick Dedekind
-
reverted debug change
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1315
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
All these autopilot errors seem relevant?
https:/
Daniel d'Andrada (dandrader) wrote : | # |
In qml/Panel/
It looks like every time the velocityTimer is triggered, the velocity is being calculated twice (stopLateralChanges being updated twice).
"""
2418 + calc.trackedPos
2419 + root.stopLatera
"""
Line 2418 will trigger calc.onTrackedP
Albert Astals Cid (aacid) wrote : | # |
So i did this:
* Swipe down on the time & date indicator
* Release finger from phone
* Decide i want to see Network
* Tap on the Network icon
* Decide i want to close the indicators
* Put finger horizontally in the middle of the bottom of the phone and swipe up
* The indicator gets changed to battery
I find this behaviour weird, have you asked design?
Nick Dedekind (nick-dedekind) wrote : | # |
> So i did this:
> * Swipe down on the time & date indicator
> * Release finger from phone
> * Decide i want to see Network
> * Tap on the Network icon
> * Decide i want to close the indicators
> * Put finger horizontally in the middle of the bottom of the phone and swipe
> up
> * The indicator gets changed to battery
>
> I find this behaviour weird, have you asked design?
There is no locking threshold anymore, as requested by design. Indicator changes as soon as we swipe from bottom.
See first comment from Vesa's review above.
Nick Dedekind (nick-dedekind) wrote : | # |
> > So i did this:
> > * Swipe down on the time & date indicator
> > * Release finger from phone
> > * Decide i want to see Network
> > * Tap on the Network icon
> > * Decide i want to close the indicators
> > * Put finger horizontally in the middle of the bottom of the phone and
> swipe
> > up
> > * The indicator gets changed to battery
> >
> > I find this behaviour weird, have you asked design?
>
> There is no locking threshold anymore, as requested by design. Indicator
> changes as soon as we swipe from bottom.
> See first comment from Vesa's review above.
And yes. I find it weird as well...
Daniel d'Andrada (dandrader) wrote : | # |
> In qml/Panel/
>
> It looks like every time the velocityTimer is triggered, the velocity is being
> calculated twice (stopLateralChanges being updated twice).
>
> """
> 2418 + calc.trackedPos
> 2419 + root.stopLatera
> velocityThreashold;
> """
>
> Line 2418 will trigger calc.onTrackedP
> line 2419.
So the velocity is actually being calculated on every single value change, but with the timer I think you indended to do it only every 50 milliseconds, right (to avoid unnecessary cpu load)?
Daniel d'Andrada (dandrader) wrote : | # |
"""
property real velocityThreashold: 0.4
"""
Typo: s/Threashold/
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1316
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nick Dedekind (nick-dedekind) wrote : | # |
> In qml/Panel/
>
> It looks like every time the velocityTimer is triggered, the velocity is being
> calculated twice (stopLateralChanges being updated twice).
>
> """
> 2418 + calc.trackedPos
> 2419 + root.stopLatera
> velocityThreashold;
> """
>
> Line 2418 will trigger calc.onTrackedP
> line 2419.
Yes, but it's required since we need to do the calculation even if onTrackedPositi
- 1317. By Nick Dedekind
-
recalc guard
Nick Dedekind (nick-dedekind) wrote : | # |
> """
> property real velocityThreashold: 0.4
> """
>
> Typo: s/Threashold/
Fixed.
- 1318. By Nick Dedekind
-
s/Threashold/
Threshold
Daniel d'Andrada (dandrader) wrote : | # |
> > In qml/Panel/
> >
> > It looks like every time the velocityTimer is triggered, the velocity is
> being
> > calculated twice (stopLateralChanges being updated twice).
> >
> > """
> > 2418 + calc.trackedPos
> > 2419 + root.stopLatera
> > velocityThreashold;
> > """
> >
> > Line 2418 will trigger calc.onTrackedP
> as
> > line 2419.
>
> Yes, but it's required since we need to do the calculation even if
> onTrackedPositi
> a check a guard only to do the recalc in the timer if the trackedPosition
> doesn't change.
Ahhh... now I got it, might make sense then to stick to updating the velocity every 50ms, ie only on the timer, instead of both due to timer timeout and due to tracked value change, to be consistent. Will hopefully simplify the code as well.
Also it seems this timer is always running. You don't seem to ever stop it?
Daniel d'Andrada (dandrader) wrote : | # |
> Ahhh... now I got it, might make sense then to stick to updating the velocity
> every 50ms, ie only on the timer, instead of both due to timer timeout and due
> to tracked value change, to be consistent. Will hopefully simplify the code as
> well.
>
> Also it seems this timer is always running. You don't seem to ever stop it?
Nevermind that. Timer.repeat defaults to false. :)
- 1319. By Nick Dedekind
-
performance tweaks.
Nick Dedekind (nick-dedekind) wrote : | # |
> > > In qml/Panel/
> > >
> > > It looks like every time the velocityTimer is triggered, the velocity is
> > being
> > > calculated twice (stopLateralChanges being updated twice).
> > >
> > > """
> > > 2418 + calc.trackedPos
> > > 2419 + root.stopLatera
> > > velocityThreashold;
> > > """
> > >
> > > Line 2418 will trigger calc.onTrackedP
> > as
> > > line 2419.
> >
> > Yes, but it's required since we need to do the calculation even if
> > onTrackedPositi
> in
> > a check a guard only to do the recalc in the timer if the trackedPosition
> > doesn't change.
>
> Ahhh... now I got it, might make sense then to stick to updating the velocity
> every 50ms, ie only on the timer, instead of both due to timer timeout and due
> to tracked value change, to be consistent. Will hopefully simplify the code as
> well.
Ok, I've moved everything into a update function.
I've also improved performance by only starting the timer if tracked, and only emitting the threshold signal if it was previously in "stopped mode".
>
> Also it seems this timer is always running. You don't seem to ever stop it?
- 1320. By Nick Dedekind
-
even better velocity calc
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1318
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
"""
}
"""
Could be simply:
-------
PanelVelocityCa
Thus:
bar.enableLater
In IndicatorsMenu.qml
"""
"""
There should be no need for this code, and thus, for this velocityThresho
IndicatorItemRow should be smart enough to call that function himself once his enableLateralCh
Daniel d'Andrada (dandrader) wrote : | # |
> """
> onVelocityThres
> bar.updateItemF
> """
>
>
> There should be no need for this code, and thus, for this
> velocityThresho
> IndicatorItemRow should be smart enough to call that function himself once his
> enableLateralCh
Then this function in IndicatorsBar.qml could go away as well:
"""
function updateItemFromL
if (position === -1) return;
var mapped = root.mapToItem(row, position, 0);
}
"""
Daniel d'Andrada (dandrader) wrote : | # |
In Panel.qml:
"""
VerticalThinDivider {
id: indicatorDividor
anchors {
top: indicators.top
bottom: indicators.bottom
right: indicators.left
topMargin: indicatorArea.
}
width: units.dp(2)
source: "graphics/
}
"""
Should we still be using the VerticalThinDivider component for that? By looking at VerticalThinDiv
Could also get rid of the "id:" line as it's currently not used and has a typo anyway.
- 1321. By Nick Dedekind
-
review comments
- 1322. By Nick Dedekind
-
AP emulator update
Nick Dedekind (nick-dedekind) wrote : | # |
> """
> enableLateralCh
> if (!d.activeDragH
> if (!d.activeDragH
>
> return !yVelocityCalcu
> }
> """
>
> Could be simply:
>
> enableLateralCh
> d.activeDragHan
> && !yVelocityCalcu
>
> -------
>
> PanelVelocityCa
> PanelVelocityCa
> IndicatorsMenu do. All PanelVelocityCa
> trackedValue velocity is above or below the given threshold.
>
> Thus:
>
> bar.enableLater
> &&
> !yVelocityCalcu
>
>
> In IndicatorsMenu.qml
>
> """
> onVelocityThres
> bar.updateItemF
> """
>
>
> There should be no need for this code, and thus, for this
> velocityThresho
> IndicatorItemRow should be smart enough to call that function himself once his
> enableLateralCh
Fixed all + other reviews.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1320
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: 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:1322
http://
Executed test runs:
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Timo Jyrinki (timo-jyrinki) wrote : | # |
This should be targeted to the rtm-14.09 branch, or alternatively there should be a duplicate of this branch targeting it, so that it can be included in the silo.
MichaĆ Sawicz (saviq) wrote : | # |
> This should be targeted to the rtm-14.09 branch, or alternatively there should
> be a duplicate of this branch targeting it, so that it can be included in the
> silo.
Yup, already there:
https:/
Albert Astals Cid (aacid) wrote : | # |
Text conflict in qml/Panel/
Contents conflict in qml/Panel/
Text conflict in qml/Panel/
Text conflict in qml/Panel/
Text conflict in tests/qmltests/
5 conflicts encountered.
- 1323. By Nick Dedekind
-
merged with trunk
- 1324. By Nick Dedekind
-
fixed include
Nick Dedekind (nick-dedekind) wrote : | # |
> Text conflict in qml/Panel/
> Contents conflict in qml/Panel/
> Text conflict in qml/Panel/
> Text conflict in qml/Panel/
> Text conflict in tests/qmltests/
> 5 conflicts encountered.
Fixed
- 1325. By Nick Dedekind
-
sync indicator page delegate loader
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1324
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
I don't see the use for that previouslyStopped var in qml/Panel/
Couldn't it just be like this?
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1325
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Andrea Cimitan (cimi) wrote : | # |
> I don't see the use for that previouslyStopped var in
> qml/Panel/
>
> Couldn't it just be like this?
> http://
if velocityAboveTh
Albert Astals Cid (aacid) wrote : | # |
Others seem to be taking good care of this and on my previous quick reads/tests of the code i could not find anything glaringly wrong, so abstaining
- 1326. By Nick Dedekind
-
remove previouslyStopped
Nick Dedekind (nick-dedekind) wrote : | # |
> I don't see the use for that previouslyStopped var in
> qml/Panel/
>
> Couldn't it just be like this?
> http://
old code from when we were using a signal.
removed.
Nick Dedekind (nick-dedekind) wrote : | # |
> > I don't see the use for that previouslyStopped var in
> > qml/Panel/
> >
> > Couldn't it just be like this?
> > http://
> if velocityAboveTh
> during it, then your patch won't work..
It will. the timer gets started if velocityAboveTh
MichaĆ Sawicz (saviq) wrote : | # |
There's a problem with the SIM unlock notification:
https:/
Also, the white highlight "lags" behind the indicator in expanded state, try turning the flight mode on/off.
- 1327. By Nick Dedekind
-
full screen notifications don't include panel
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1326
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
ScrollCalculator looks pretty specific to the indicators panel problem.
So I think it would be better to have it in qml/Panel dir than in qml/Components.
Daniel d'Andrada (dandrader) wrote : | # |
Didn't take the time properly understand all the code but didn't find anything else that looked wrong.
Glad to see that we have tests for all those Panel subcomponents.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1327
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1328. By Nick Dedekind
-
remove/add item fixes
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1328
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1329. By Nick Dedekind
-
fixed edge demo
- 1330. By Nick Dedekind
-
Expanded visible indicators.
- 1331. By Nick Dedekind
-
fixed root action state visible
Nick Dedekind (nick-dedekind) wrote : | # |
I've updated this so that indicators marked as "non-visible" show up when you expand the indicator.
Also fixed the edge demo.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1330
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: 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:1331
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: 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:1331
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1332. By Nick Dedekind
-
isIndicatorVisi
ble->indicatorV isible - 1333. By Nick Dedekind
-
merge with sharedunitymenu
model branch
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1332
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: 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:1333
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1334. By Nick Dedekind
-
more efficient delegate draws
Michael Terry (mterry) wrote : | # |
Two bugs seen that I'm trying to be able to reproduce:
- Once, the battery and datetime indicators had no menucontent. We confirmed that the services were running and exporting their menus though.
- Once, I got a u8 crash when playing with flight mode and the menu indicator. When it crashed, there were three icons for the network indicator, when usually there are at most two. I don't remember which three.
Working on finding out if these are branch specific or what.
Michael Terry (mterry) wrote : | # |
The crash can be reproduced by simply toggling Flight Mode a bunch. The three icons I saw were the airplane, SIM card, and Wi-Fi. Those three can be seen to appear briefly sometimes when enabling Flight Mode (the SIM card immediately disappears down to two icons though). But in this crash, it seems we crash before the SIM card icon disappears.
Here's the stacktrace for the crash: http://
- 1335. By Nick Dedekind
-
fixed indicator realignment
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1334
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1336. By Nick Dedekind
-
re-add commit line for redrag
Michael Terry (mterry) wrote : | # |
OK, was able to reproduce an almost identical crash with the utopic debs. So not a new crash with this image.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1335
http://
Executed test runs:
FAILURE: http://
UNSTABLE: http://
SUCCESS: 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:1336
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1337. By Nick Dedekind
-
better indicator switch detection
- 1338. By Nick Dedekind
-
more required to shed lock
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1338
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1339. By Nick Dedekind
-
fix async object creation missing unitymenumodel signal
Michael Terry (mterry) wrote : | # |
OK looks good enough! Let's get 'er done.
* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes
* Did CI run pass? If not, please explain why.
No, for usual reasons.
* Did you make sure that the branch does not contain spurious tags?
Yes
- 1340. By Nick Dedekind
-
removed StopAtBounds
Michael Terry (mterry) wrote : | # |
Nick wanted me to re-approve after his change. Still looks fine.
Michael Terry (mterry) : | # |
Preview Diff
1 | === modified file 'plugins/Unity/Indicators/Indicators.qmltypes' |
2 | --- plugins/Unity/Indicators/Indicators.qmltypes 2014-10-21 21:16:04 +0000 |
3 | +++ plugins/Unity/Indicators/Indicators.qmltypes 2014-10-21 21:16:05 +0000 |
4 | @@ -99,10 +99,8 @@ |
5 | values: { |
6 | "Identifier": 0, |
7 | "Position": 1, |
8 | - "WidgetSource": 2, |
9 | - "PageSource": 3, |
10 | - "IndicatorProperties": 4, |
11 | - "IsVisible": 5 |
12 | + "IndicatorProperties": 2, |
13 | + "IsVisible": 3 |
14 | } |
15 | } |
16 | } |
17 | |
18 | === modified file 'plugins/Unity/Indicators/indicators.h' |
19 | --- plugins/Unity/Indicators/indicators.h 2013-09-17 12:31:19 +0000 |
20 | +++ plugins/Unity/Indicators/indicators.h 2014-10-21 21:16:05 +0000 |
21 | @@ -74,8 +74,6 @@ |
22 | enum Roles { |
23 | Identifier = 0, |
24 | Position, |
25 | - WidgetSource, |
26 | - PageSource, |
27 | IndicatorProperties, |
28 | IsVisible |
29 | }; |
30 | |
31 | === modified file 'plugins/Unity/Indicators/indicatorsmodel.cpp' |
32 | --- plugins/Unity/Indicators/indicatorsmodel.cpp 2014-01-30 14:54:01 +0000 |
33 | +++ plugins/Unity/Indicators/indicatorsmodel.cpp 2014-10-21 21:16:05 +0000 |
34 | @@ -202,8 +202,6 @@ |
35 | { |
36 | roles[IndicatorsModelRole::Identifier] = "identifier"; |
37 | roles[IndicatorsModelRole::Position] = "position"; |
38 | - roles[IndicatorsModelRole::WidgetSource] = "widgetSource"; |
39 | - roles[IndicatorsModelRole::PageSource] = "pageSource"; |
40 | roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties"; |
41 | } |
42 | return roles; |
43 | @@ -248,10 +246,6 @@ |
44 | return QVariant(indicator->indicatorProperties()); |
45 | } |
46 | break; |
47 | - case IndicatorsModelRole::WidgetSource: |
48 | - return qmlDirectory()+"/Panel/Indicators/DefaultIndicatorWidget.qml"; |
49 | - case IndicatorsModelRole::PageSource: |
50 | - return qmlDirectory()+"/Panel/Indicators/DefaultIndicatorPage.qml"; |
51 | default: |
52 | break; |
53 | } |
54 | |
55 | === modified file 'plugins/Unity/Indicators/rootactionstate.cpp' |
56 | --- plugins/Unity/Indicators/rootactionstate.cpp 2014-08-26 08:14:44 +0000 |
57 | +++ plugins/Unity/Indicators/rootactionstate.cpp 2014-10-21 21:16:05 +0000 |
58 | @@ -156,7 +156,7 @@ |
59 | return m_cachedState.value("accessible-desc", QVariant::fromValue(QString())).toString(); |
60 | } |
61 | |
62 | -bool RootActionState::isVisible() const |
63 | +bool RootActionState::indicatorVisible() const |
64 | { |
65 | if (!isValid()) return false; |
66 | |
67 | |
68 | === modified file 'plugins/Unity/Indicators/rootactionstate.h' |
69 | --- plugins/Unity/Indicators/rootactionstate.h 2013-10-11 14:32:29 +0000 |
70 | +++ plugins/Unity/Indicators/rootactionstate.h 2014-10-21 21:16:05 +0000 |
71 | @@ -37,7 +37,7 @@ |
72 | Q_PROPERTY(QString rightLabel READ rightLabel NOTIFY rightLabelChanged) |
73 | Q_PROPERTY(QStringList icons READ icons NOTIFY iconsChanged) |
74 | Q_PROPERTY(QString accessibleName READ accessibleName NOTIFY accessibleNameChanged) |
75 | - Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged) |
76 | + Q_PROPERTY(bool indicatorVisible READ indicatorVisible NOTIFY indicatorVisibleChanged) |
77 | public: |
78 | RootActionState(QObject *parent = 0); |
79 | virtual ~RootActionState(); |
80 | @@ -54,10 +54,10 @@ |
81 | QString rightLabel() const; |
82 | QStringList icons() const; |
83 | QString accessibleName() const; |
84 | - bool isVisible() const; |
85 | + bool indicatorVisible() const; |
86 | |
87 | // from ActionStateParser |
88 | - virtual QVariant toQVariant(GVariant* state) const; |
89 | + virtual QVariant toQVariant(GVariant* state) const override; |
90 | |
91 | Q_SIGNALS: |
92 | void updated(); |
93 | @@ -71,7 +71,7 @@ |
94 | void rightLabelChanged(); |
95 | void iconsChanged(); |
96 | void accessibleNameChanged(); |
97 | - void visibleChanged(); |
98 | + void indicatorVisibleChanged(); |
99 | |
100 | private Q_SLOTS: |
101 | void onModelRowsAdded(const QModelIndex& parent, int start, int end); |
102 | |
103 | === modified file 'plugins/Unity/Indicators/sharedunitymenumodel.cpp' |
104 | --- plugins/Unity/Indicators/sharedunitymenumodel.cpp 2014-10-21 21:16:04 +0000 |
105 | +++ plugins/Unity/Indicators/sharedunitymenumodel.cpp 2014-10-21 21:16:05 +0000 |
106 | @@ -18,6 +18,8 @@ |
107 | #include "sharedunitymenumodel.h" |
108 | #include "unitymenumodelcache.h" |
109 | |
110 | +#include <unitymenumodel.h> |
111 | + |
112 | SharedUnityMenuModel::SharedUnityMenuModel(QObject* parent) |
113 | : QObject(parent) |
114 | { |
115 | @@ -78,8 +80,11 @@ |
116 | Q_EMIT modelChanged(); |
117 | } |
118 | } else { |
119 | - QSharedPointer<UnityMenuModel> model = UnityMenuModelCache::singleton()->model(m_busName, m_menuObjectPath, m_actions); |
120 | + QSharedPointer<UnityMenuModel> model = UnityMenuModelCache::singleton()->model(m_menuObjectPath); |
121 | if (model != m_model) { |
122 | + if (model->busName() != m_busName) model->setBusName(m_busName); |
123 | + if (model->actions() != m_actions) model->setActions(m_actions); |
124 | + |
125 | m_model = model; |
126 | Q_EMIT modelChanged(); |
127 | } |
128 | |
129 | === modified file 'plugins/Unity/Indicators/unitymenumodelcache.cpp' |
130 | --- plugins/Unity/Indicators/unitymenumodelcache.cpp 2014-10-21 21:16:04 +0000 |
131 | +++ plugins/Unity/Indicators/unitymenumodelcache.cpp 2014-10-21 21:16:05 +0000 |
132 | @@ -37,9 +37,7 @@ |
133 | { |
134 | } |
135 | |
136 | -QSharedPointer<UnityMenuModel> UnityMenuModelCache::model(const QByteArray& bus, |
137 | - const QByteArray& path, |
138 | - const QVariantMap& actions) |
139 | +QSharedPointer<UnityMenuModel> UnityMenuModelCache::model(const QByteArray& path) |
140 | { |
141 | if (m_registry.contains(path)) |
142 | return m_registry[path]; |
143 | @@ -60,9 +58,7 @@ |
144 | }); |
145 | m_registry[path] = menuModel.toWeakRef(); |
146 | |
147 | - menuModel->setBusName(bus); |
148 | menuModel->setMenuObjectPath(path); |
149 | - menuModel->setActions(actions); |
150 | return menuModel; |
151 | } |
152 | |
153 | |
154 | === modified file 'plugins/Unity/Indicators/unitymenumodelcache.h' |
155 | --- plugins/Unity/Indicators/unitymenumodelcache.h 2014-10-21 21:16:04 +0000 |
156 | +++ plugins/Unity/Indicators/unitymenumodelcache.h 2014-10-21 21:16:05 +0000 |
157 | @@ -37,9 +37,7 @@ |
158 | |
159 | static UnityMenuModelCache* singleton(); |
160 | |
161 | - virtual QSharedPointer<UnityMenuModel> model(const QByteArray& bus, |
162 | - const QByteArray& path, |
163 | - const QVariantMap& actions); |
164 | + virtual QSharedPointer<UnityMenuModel> model(const QByteArray& path); |
165 | |
166 | // for tests use |
167 | Q_INVOKABLE virtual bool contains(const QByteArray& path); |
168 | |
169 | === modified file 'plugins/Unity/Indicators/visibleindicatorsmodel.cpp' |
170 | --- plugins/Unity/Indicators/visibleindicatorsmodel.cpp 2013-09-17 12:31:19 +0000 |
171 | +++ plugins/Unity/Indicators/visibleindicatorsmodel.cpp 2014-10-21 21:16:05 +0000 |
172 | @@ -33,8 +33,6 @@ |
173 | { |
174 | roles[IndicatorsModelRole::Identifier] = "identifier"; |
175 | roles[IndicatorsModelRole::Position] = "position"; |
176 | - roles[IndicatorsModelRole::WidgetSource] = "widgetSource"; |
177 | - roles[IndicatorsModelRole::PageSource] = "pageSource"; |
178 | roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties"; |
179 | roles[IndicatorsModelRole::IsVisible] = "isVisible"; |
180 | } |
181 | |
182 | === modified file 'qml/Components/DragHandle.qml' |
183 | --- qml/Components/DragHandle.qml 2014-10-01 13:20:32 +0000 |
184 | +++ qml/Components/DragHandle.qml 2014-10-21 21:16:05 +0000 |
185 | @@ -68,6 +68,7 @@ |
186 | } |
187 | |
188 | property real hintDisplacement: 0 |
189 | + property var overrideStartValue: undefined |
190 | SmoothedAnimation { |
191 | id: hintingAnimation |
192 | target: hintingAnimation |
193 | @@ -196,7 +197,11 @@ |
194 | } else /* Undecided || Recognized */ { |
195 | if (d.previousStatus === DirectionalDragArea.WaitingForTouch) { |
196 | dragEvaluator.reset(); |
197 | - d.startValue = parent[d.targetProp]; |
198 | + if (overrideStartValue !== undefined) { |
199 | + d.startValue = overrideStartValue; |
200 | + } else { |
201 | + d.startValue = parent[d.targetProp]; |
202 | + } |
203 | |
204 | if (hintDisplacement > 0) { |
205 | hintingAnimation.targetValue = d.startValue; |
206 | |
207 | === modified file 'qml/Components/EdgeDemo.qml' |
208 | --- qml/Components/EdgeDemo.qml 2014-08-06 14:33:50 +0000 |
209 | +++ qml/Components/EdgeDemo.qml 2014-10-21 21:16:05 +0000 |
210 | @@ -23,7 +23,7 @@ |
211 | |
212 | property Item greeter |
213 | property Item launcher |
214 | - property Item indicators |
215 | + property Item panel |
216 | property Item stages |
217 | |
218 | property bool launcherEnabled: true |
219 | @@ -139,11 +139,11 @@ |
220 | function startTopEdgeDemo() { |
221 | demo.panelEnabled = true; |
222 | if (demo.stages) { |
223 | - d.topEdgeDemo = d.overlay.createObject(demo.stages, { |
224 | + d.topEdgeDemo = d.overlay.createObject(demo.panel, { |
225 | "edge": "top", |
226 | "title": i18n.tr("Top edge"), |
227 | "text": i18n.tr("Try swiping from the top edge to access the indicators"), |
228 | - "anchors.fill": demo.stages, |
229 | + "anchors.fill": demo.panel, |
230 | }); |
231 | } |
232 | if (d.topEdgeDemo) { |
233 | @@ -154,9 +154,9 @@ |
234 | } |
235 | |
236 | Connections { |
237 | - target: demo.indicators |
238 | + target: demo.panel.indicators |
239 | onFullyOpenedChanged: { |
240 | - if (d.topEdgeDemo && d.topEdgeDemo.available && demo.indicators.fullyOpened) { |
241 | + if (d.topEdgeDemo && d.topEdgeDemo.available && demo.panel.indicators.fullyOpened) { |
242 | d.topEdgeDemo.hideNow() |
243 | startBottomEdgeDemo() |
244 | } |
245 | @@ -164,12 +164,12 @@ |
246 | } |
247 | |
248 | function startBottomEdgeDemo() { |
249 | - if (demo.indicators) { |
250 | - d.bottomEdgeDemo = d.overlay.createObject(demo.indicators, { |
251 | + if (demo.panel.indicators) { |
252 | + d.bottomEdgeDemo = d.overlay.createObject(demo.panel.indicators, { |
253 | "edge": "bottom", |
254 | "title": i18n.tr("Close"), |
255 | "text": i18n.tr("Swipe up again to close the settings screen"), |
256 | - "anchors.fill": demo.indicators.content, |
257 | + "anchors.fill": demo.panel.indicators, |
258 | }); |
259 | } |
260 | if (d.bottomEdgeDemo) { |
261 | @@ -180,9 +180,12 @@ |
262 | } |
263 | |
264 | Connections { |
265 | - target: demo.indicators |
266 | + target: demo.panel.indicators |
267 | onPartiallyOpenedChanged: { |
268 | - if (d.bottomEdgeDemo && d.bottomEdgeDemo.available && !demo.indicators.partiallyOpened && !demo.indicators.fullyOpened) { |
269 | + if (d.bottomEdgeDemo && |
270 | + d.bottomEdgeDemo.available && |
271 | + !demo.panel.indicators.partiallyOpened && |
272 | + !demo.panel.indicators.fullyOpened) { |
273 | d.bottomEdgeDemo.hideNow() |
274 | startLeftEdgeDemo() |
275 | } |
276 | |
277 | === removed file 'qml/Components/ListItems/VerticalThinDivider.qml' |
278 | --- qml/Components/ListItems/VerticalThinDivider.qml 2013-06-05 22:03:08 +0000 |
279 | +++ qml/Components/ListItems/VerticalThinDivider.qml 1970-01-01 00:00:00 +0000 |
280 | @@ -1,26 +0,0 @@ |
281 | -/* |
282 | - * Copyright (C) 2012 Canonical, Ltd. |
283 | - * |
284 | - * This program is free software; you can redistribute it and/or modify |
285 | - * it under the terms of the GNU General Public License as published by |
286 | - * the Free Software Foundation; version 3. |
287 | - * |
288 | - * This program is distributed in the hope that it will be useful, |
289 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
290 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
291 | - * GNU General Public License for more details. |
292 | - * |
293 | - * You should have received a copy of the GNU General Public License |
294 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
295 | - */ |
296 | - |
297 | -import QtQuick 2.0 |
298 | - |
299 | -Image { |
300 | - anchors { |
301 | - top: (parent) ? parent.top : null |
302 | - bottom: (parent) ? parent.bottom : null |
303 | - } |
304 | - width: (visible) ? units.dp(2) : 0 |
305 | - source: "graphics/ListItemDividerVertical.png" |
306 | -} |
307 | |
308 | === removed file 'qml/Components/ListItems/graphics/ListItemDividerVertical@18.png' |
309 | Binary files qml/Components/ListItems/graphics/ListItemDividerVertical@18.png 2013-06-05 22:03:08 +0000 and qml/Components/ListItems/graphics/ListItemDividerVertical@18.png 1970-01-01 00:00:00 +0000 differ |
310 | === added file 'qml/Components/ScrollCalculator.qml' |
311 | --- qml/Components/ScrollCalculator.qml 1970-01-01 00:00:00 +0000 |
312 | +++ qml/Components/ScrollCalculator.qml 2014-10-21 21:16:05 +0000 |
313 | @@ -0,0 +1,81 @@ |
314 | +/* |
315 | + * Copyright (C) 2014 Canonical, Ltd. |
316 | + * |
317 | + * This program is free software; you can redistribute it and/or modify |
318 | + * it under the terms of the GNU General Public License as published by |
319 | + * the Free Software Foundation; version 3. |
320 | + * |
321 | + * This program is distributed in the hope that it will be useful, |
322 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
323 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
324 | + * GNU General Public License for more details. |
325 | + * |
326 | + * You should have received a copy of the GNU General Public License |
327 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
328 | + */ |
329 | + |
330 | +import QtQuick 2.2 |
331 | +import Ubuntu.Components 1.1 |
332 | + |
333 | +Item { |
334 | + id: scrollArea |
335 | + |
336 | + readonly property bool areaActive: lateralPosition >= 0 |
337 | + property real stopScrollThreshold: units.gu(2) |
338 | + property int direction: Qt.LeftToRight |
339 | + property real baseScrollAmount: units.dp(3) |
340 | + property real maximumScrollAmount: units.dp(8) |
341 | + property real lateralPosition: -1 |
342 | + property real forceScrollingPercentage: 0.4 |
343 | + |
344 | + signal scroll(real scrollAmount) |
345 | + |
346 | + width: units.gu(5) |
347 | + rotation: direction === Qt.LeftToRight ? 0 : 180 |
348 | + |
349 | + onAreaActiveChanged: areaActive ? handleEnter() : handleExit() |
350 | + |
351 | + function handleEnter() { |
352 | + d.thresholdAreaX = -scrollArea.stopScrollThreshold; |
353 | + scrollTimer.restart(); |
354 | + } |
355 | + |
356 | + function handleExit() { |
357 | + d.thresholdAreaX = -scrollArea.stopScrollThreshold; |
358 | + scrollTimer.stop(); |
359 | + } |
360 | + |
361 | + onLateralPositionChanged: { |
362 | + if (scrollArea.areaActive) { |
363 | + if (lateralPosition > width * (1 - forceScrollingPercentage)) { |
364 | + d.thresholdAreaX = width * (1 - forceScrollingPercentage); |
365 | + if (!scrollTimer.running) scrollTimer.restart(); |
366 | + } else if (lateralPosition > d.thresholdAreaX + scrollArea.stopScrollThreshold) { |
367 | + d.thresholdAreaX = lateralPosition - scrollArea.stopScrollThreshold; |
368 | + if (!scrollTimer.running) scrollTimer.restart(); |
369 | + } else if (lateralPosition < d.thresholdAreaX) { |
370 | + d.thresholdAreaX = lateralPosition; |
371 | + scrollTimer.stop(); |
372 | + } |
373 | + |
374 | + d.progression = lateralPosition / width; |
375 | + } |
376 | + } |
377 | + |
378 | + Timer { |
379 | + id: scrollTimer |
380 | + interval: 16 |
381 | + repeat: true |
382 | + |
383 | + onTriggered: { |
384 | + var scrollAmount = scrollArea.baseScrollAmount + scrollArea.maximumScrollAmount * d.progression; |
385 | + scrollArea.scroll(scrollAmount); |
386 | + } |
387 | + } |
388 | + |
389 | + QtObject { |
390 | + id: d |
391 | + property real progression: 0 |
392 | + property real thresholdAreaX: -scrollArea.stopScrollThreshold |
393 | + } |
394 | +} |
395 | |
396 | === added file 'qml/Panel/Handle.qml' |
397 | --- qml/Panel/Handle.qml 1970-01-01 00:00:00 +0000 |
398 | +++ qml/Panel/Handle.qml 2014-10-21 21:16:05 +0000 |
399 | @@ -0,0 +1,43 @@ |
400 | +/* |
401 | + * Copyright (C) 2014 Canonical, Ltd. |
402 | + * |
403 | + * This program is free software; you can redistribute it and/or modify |
404 | + * it under the terms of the GNU General Public License as published by |
405 | + * the Free Software Foundation; version 3. |
406 | + * |
407 | + * This program is distributed in the hope that it will be useful, |
408 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
409 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
410 | + * GNU General Public License for more details. |
411 | + * |
412 | + * You should have received a copy of the GNU General Public License |
413 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
414 | + */ |
415 | + |
416 | +import QtQuick 2.2 |
417 | +import Ubuntu.Components 1.1 |
418 | + |
419 | +Rectangle { |
420 | + id: handle |
421 | + color: "#333333" |
422 | + height: units.gu(2) |
423 | + property bool active: false |
424 | + |
425 | + Row { |
426 | + id: dots |
427 | + width: childrenRect.width |
428 | + height: childrenRect.height |
429 | + anchors.centerIn: parent |
430 | + spacing: units.gu(0.5) |
431 | + Repeater { |
432 | + model: 3 |
433 | + delegate: Rectangle { |
434 | + id: dot |
435 | + width: units.dp(3) |
436 | + height: width |
437 | + color: handle.active ? "#de4814" : "#717171" |
438 | + radius: units.dp(1) |
439 | + } |
440 | + } |
441 | + } |
442 | +} |
443 | |
444 | === removed file 'qml/Panel/IndicatorItem.qml' |
445 | --- qml/Panel/IndicatorItem.qml 2014-09-29 10:24:58 +0000 |
446 | +++ qml/Panel/IndicatorItem.qml 1970-01-01 00:00:00 +0000 |
447 | @@ -1,53 +0,0 @@ |
448 | -/* |
449 | - * Copyright (C) 2013 Canonical, Ltd. |
450 | - * |
451 | - * This program is free software; you can redistribute it and/or modify |
452 | - * it under the terms of the GNU General Public License as published by |
453 | - * the Free Software Foundation; version 3. |
454 | - * |
455 | - * This program is distributed in the hope that it will be useful, |
456 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
457 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
458 | - * GNU General Public License for more details. |
459 | - * |
460 | - * You should have received a copy of the GNU General Public License |
461 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
462 | - */ |
463 | - |
464 | -import QtQuick 2.0 |
465 | -import Ubuntu.Components 0.1 |
466 | -import Unity.Indicators 0.1 as Indicators |
467 | -import "../Components" |
468 | - |
469 | -Loader { |
470 | - id: root |
471 | - |
472 | - property alias widgetSource: root.source |
473 | - property bool dimmed: false |
474 | - property var indicatorProperties: undefined |
475 | - property bool indicatorVisible: item ? item.enabled : false |
476 | - property string identifier |
477 | - |
478 | - opacity: dimmed ? 0.4 : 1 |
479 | - Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration } } |
480 | - |
481 | - onLoaded: { |
482 | - for(var pName in indicatorProperties) { |
483 | - if (item.hasOwnProperty(pName)) { |
484 | - item[pName] = indicatorProperties[pName]; |
485 | - } |
486 | - } |
487 | - } |
488 | - |
489 | - Binding { |
490 | - target: item |
491 | - property: "identifier" |
492 | - value: identifier |
493 | - } |
494 | - |
495 | - Binding { |
496 | - target: item |
497 | - property: "objectName" |
498 | - value: identifier + "-widget" |
499 | - } |
500 | -} |
501 | |
502 | === added file 'qml/Panel/IndicatorItemRow.qml' |
503 | --- qml/Panel/IndicatorItemRow.qml 1970-01-01 00:00:00 +0000 |
504 | +++ qml/Panel/IndicatorItemRow.qml 2014-10-21 21:16:05 +0000 |
505 | @@ -0,0 +1,297 @@ |
506 | +/* |
507 | + * Copyright (C) 2013-2014 Canonical, Ltd. |
508 | + * |
509 | + * This program is free software; you can redistribute it and/or modify |
510 | + * it under the terms of the GNU General Public License as published by |
511 | + * the Free Software Foundation; version 3. |
512 | + * |
513 | + * This program is distributed in the hope that it will be useful, |
514 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
515 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
516 | + * GNU General Public License for more details. |
517 | + * |
518 | + * You should have received a copy of the GNU General Public License |
519 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
520 | + */ |
521 | + |
522 | +import QtQuick 2.2 |
523 | +import Ubuntu.Components 1.1 |
524 | + |
525 | +Item { |
526 | + id: root |
527 | + width: row.width |
528 | + height: units.gu(3) |
529 | + |
530 | + property QtObject indicatorsModel: null |
531 | + property real overFlowWidth: width |
532 | + property bool expanded: false |
533 | + property var currentItem |
534 | + readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1 |
535 | + |
536 | + property real unitProgress: 0.0 |
537 | + property real selectionChangeBuffer: units.gu(2) |
538 | + property bool enableLateralChanges: false |
539 | + property color hightlightColor: "#ededed" |
540 | + |
541 | + property real lateralPosition: -1 |
542 | + onLateralPositionChanged: { |
543 | + updateItemFromLateralPosition(); |
544 | + } |
545 | + |
546 | + onEnableLateralChangesChanged: { |
547 | + updateItemFromLateralPosition(); |
548 | + } |
549 | + |
550 | + function updateItemFromLateralPosition() { |
551 | + if (currentItem && !enableLateralChanges) return; |
552 | + if (lateralPosition === -1) return; |
553 | + |
554 | + if (!currentItem) { |
555 | + selectItemAt(lateralPosition); |
556 | + return; |
557 | + } |
558 | + |
559 | + var maximumBufferOffset = selectionChangeBuffer * unitProgress; |
560 | + var proposedItem = indicatorAt(lateralPosition, 0); |
561 | + if (proposedItem) { |
562 | + var bufferExceeded = false; |
563 | + |
564 | + if (proposedItem !== currentItem) { |
565 | + // Proposed item is not directly adjacent to current? |
566 | + if (Math.abs(proposedItem.ownIndex - currentItem.ownIndex) > 1) { |
567 | + bufferExceeded = true; |
568 | + } else { // no |
569 | + var currentItemLateralPosition = root.mapToItem(proposedItem, lateralPosition, 0).x; |
570 | + |
571 | + // Is the distance into proposed item greater than max buffer? |
572 | + // Proposed item is before current item |
573 | + if (proposedItem.x < currentItem.x) { |
574 | + bufferExceeded = (proposedItem.width - currentItemLateralPosition) > maximumBufferOffset; |
575 | + } else { // After |
576 | + bufferExceeded = currentItemLateralPosition > maximumBufferOffset; |
577 | + } |
578 | + } |
579 | + if (bufferExceeded) { |
580 | + selectItemAt(lateralPosition); |
581 | + } |
582 | + } |
583 | + } else { |
584 | + selectItemAt(lateralPosition); |
585 | + } |
586 | + } |
587 | + |
588 | + function indicatorAt(x, y) { |
589 | + var item = row.childAt(x, y); |
590 | + return item && item.hasOwnProperty("ownIndex") ? item : null; |
591 | + } |
592 | + |
593 | + function resetCurrentItem() { |
594 | + d.firstItemSwitch = true; |
595 | + d.previousItem = undefined; |
596 | + currentItem = undefined; |
597 | + } |
598 | + |
599 | + function setCurrentItemIndex(index) { |
600 | + for (var i = 0; i < row.children.length; i++) { |
601 | + var item = row.children[i]; |
602 | + if (item.hasOwnProperty("ownIndex") && item.ownIndex === index) { |
603 | + if (currentItem !== item) currentItem = item; |
604 | + break; |
605 | + } |
606 | + } |
607 | + } |
608 | + |
609 | + function selectItemAt(lateralPosition) { |
610 | + var item = indicatorAt(lateralPosition, 0); |
611 | + if (item && item.opacity > 0) { |
612 | + currentItem = item; |
613 | + } else { |
614 | + // Select default item. |
615 | + var searchIndex = lateralPosition > width ? repeater.count - 1 : 0; |
616 | + |
617 | + for (var i = 0; i < row.children.length; i++) { |
618 | + if (row.children[i].hasOwnProperty("ownIndex") && row.children[i].ownIndex === searchIndex) { |
619 | + item = row.children[i]; |
620 | + break; |
621 | + } |
622 | + } |
623 | + if (currentItem !== item) currentItem = item; |
624 | + } |
625 | + } |
626 | + |
627 | + QtObject { |
628 | + id: d |
629 | + property bool firstItemSwitch: true |
630 | + property var previousItem |
631 | + property bool forceAlignmentAnimationDisabled: false |
632 | + } |
633 | + |
634 | + onCurrentItemChanged: { |
635 | + if (d.previousItem) { |
636 | + d.firstItemSwitch = false; |
637 | + } |
638 | + d.previousItem = currentItem; |
639 | + } |
640 | + |
641 | + Row { |
642 | + id: row |
643 | + anchors { |
644 | + top: parent.top |
645 | + bottom: parent.bottom |
646 | + } |
647 | + |
648 | + // TODO: make this better |
649 | + // when the width changes, the highlight will lag behind due to animation, so we need to disable the animation |
650 | + // and adjust the highlight X immediately. |
651 | + width: implicitWidth |
652 | + Behavior on width { |
653 | + SequentialAnimation { |
654 | + ScriptAction { |
655 | + script: { |
656 | + d.forceAlignmentAnimationDisabled = true; |
657 | + highlight.currentItemX = Qt.binding(function() { return currentItem ? currentItem.x : 0 }); |
658 | + d.forceAlignmentAnimationDisabled = false; |
659 | + } |
660 | + } |
661 | + } |
662 | + } |
663 | + |
664 | + Repeater { |
665 | + id: repeater |
666 | + model: indicatorsModel |
667 | + visible: false |
668 | + |
669 | + onItemRemoved: { |
670 | + // current item removed. |
671 | + if (currentItem === item) { |
672 | + var i = 0; |
673 | + while (i < row.children.length) { |
674 | + var childItem = row.children[i]; |
675 | + if (childItem !== item) { |
676 | + setCurrentItemIndex(i); |
677 | + break; |
678 | + } |
679 | + i++; |
680 | + } |
681 | + } |
682 | + } |
683 | + |
684 | + |
685 | + delegate: IndicatorItem { |
686 | + id: indicatorItem |
687 | + objectName: identifier+"-panelItem" |
688 | + |
689 | + property int ownIndex: index |
690 | + property bool overflow: row.width - x > overFlowWidth |
691 | + property bool hidden: !expanded && (overflow || !indicatorVisible) |
692 | + |
693 | + height: row.height |
694 | + expanded: root.expanded |
695 | + selected: currentItem === this |
696 | + |
697 | + identifier: model.identifier |
698 | + busName: indicatorProperties.busName |
699 | + actionsObjectPath: indicatorProperties.actionsObjectPath |
700 | + menuObjectPath: indicatorProperties.menuObjectPath |
701 | + |
702 | + opacity: hidden ? 0.0 : 1.0 |
703 | + Behavior on opacity { |
704 | + NumberAnimation { duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing } |
705 | + } |
706 | + |
707 | + width: (expanded || indicatorVisible) ? implicitWidth : 0 |
708 | + |
709 | + Behavior on width { |
710 | + NumberAnimation { duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing } |
711 | + } |
712 | + |
713 | + Component.onDestruction: { |
714 | + // current item removed. |
715 | + if (currentItem === this) { |
716 | + var i = 0; |
717 | + while (i < row.children.length) { |
718 | + var childItem = row.children[i]; |
719 | + if (childItem !== this) { |
720 | + setCurrentItemIndex(i); |
721 | + break; |
722 | + } |
723 | + i++; |
724 | + } |
725 | + } |
726 | + } |
727 | + } |
728 | + } |
729 | + } |
730 | + |
731 | + Rectangle { |
732 | + id: highlight |
733 | + objectName: "highlight" |
734 | + |
735 | + anchors.bottom: row.bottom |
736 | + height: units.dp(2) |
737 | + color: root.hightlightColor |
738 | + visible: currentItem !== undefined |
739 | + opacity: 0.0 |
740 | + |
741 | + width: currentItem ? currentItem.width : 0 |
742 | + Behavior on width { |
743 | + enabled: !d.firstItemSwitch && expanded |
744 | + UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
745 | + } |
746 | + |
747 | + // micromovements of the highlight line when user moves the finger across the items while pulling |
748 | + // the handle downwards. |
749 | + property real highlightCenterOffset: { |
750 | + if (!currentItem || lateralPosition == -1 || !enableLateralChanges) return 0; |
751 | + |
752 | + var itemMapped = root.mapToItem(currentItem, lateralPosition, 0); |
753 | + |
754 | + var distanceFromCenter = itemMapped.x - currentItem.width / 2; |
755 | + if (distanceFromCenter > 0) { |
756 | + distanceFromCenter = Math.max(0, distanceFromCenter - currentItem.width / 8); |
757 | + } else { |
758 | + distanceFromCenter = Math.min(0, distanceFromCenter + currentItem.width / 8); |
759 | + } |
760 | + |
761 | + if (currentItem && currentItem.ownIndex === 0 && distanceFromCenter < 0) { |
762 | + return 0; |
763 | + } else if (currentItem && currentItem.ownIndex === repeater.count-1 & distanceFromCenter > 0) { |
764 | + return 0; |
765 | + } |
766 | + return (distanceFromCenter / (currentItem.width / 4)) * units.gu(1); |
767 | + } |
768 | + Behavior on highlightCenterOffset { |
769 | + NumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
770 | + } |
771 | + |
772 | + property real currentItemX: currentItem ? currentItem.x : 0 |
773 | + Behavior on currentItemX { |
774 | + id: currentItemXBehavior |
775 | + enabled: !d.firstItemSwitch && expanded && !d.forceAlignmentAnimationDisabled |
776 | + NumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
777 | + } |
778 | + x: currentItemX + highlightCenterOffset |
779 | + } |
780 | + |
781 | + states: [ |
782 | + State { |
783 | + name: "minimised" |
784 | + when: !expanded |
785 | + }, |
786 | + State { |
787 | + name: "expanded" |
788 | + when: expanded |
789 | + PropertyChanges { target: highlight; opacity: 0.9 } |
790 | + } |
791 | + ] |
792 | + |
793 | + transitions: [ |
794 | + Transition { |
795 | + PropertyAnimation { |
796 | + properties: "opacity"; |
797 | + duration: UbuntuAnimation.SnapDuration |
798 | + easing: UbuntuAnimation.StandardEasing |
799 | + } |
800 | + } |
801 | + ] |
802 | +} |
803 | |
804 | === renamed file 'qml/Panel/Indicators/DefaultIndicatorPage.qml' => 'qml/Panel/IndicatorPage.qml' |
805 | --- qml/Panel/Indicators/DefaultIndicatorPage.qml 2014-10-10 11:13:26 +0000 |
806 | +++ qml/Panel/IndicatorPage.qml 2014-10-21 21:16:05 +0000 |
807 | @@ -1,5 +1,5 @@ |
808 | /* |
809 | - * Copyright 2013 Canonical Ltd. |
810 | + * Copyright 2013-2014 Canonical Ltd. |
811 | * |
812 | * This program is free software; you can redistribute it and/or modify |
813 | * it under the terms of the GNU Lesser General Public License as published by |
814 | @@ -12,16 +12,13 @@ |
815 | * |
816 | * You should have received a copy of the GNU Lesser General Public License |
817 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
818 | - * |
819 | - * Authors: |
820 | - * Renato Araujo Oliveira Filho <renato@canonical.com> |
821 | - * Nick Dedekind <nick.dedekind@canonical.com> |
822 | */ |
823 | |
824 | import QtQuick 2.0 |
825 | import Ubuntu.Components 0.1 as Components |
826 | import Unity.Indicators 0.1 as Indicators |
827 | -import "../../Components/Flickables" as Flickables |
828 | +import "Indicators" |
829 | +import "../Components/Flickables" as Flickables |
830 | |
831 | IndicatorBase { |
832 | id: main |
833 | @@ -52,13 +49,13 @@ |
834 | |
835 | Connections { |
836 | target: menuStack.tail |
837 | - onRowsInserted: { |
838 | - if (menuStack.rootMenu !== menuStack.tail && menuStack.tail.get(0, "type") === rootMenuType) { |
839 | - menuStack.rootMenu = menuStack.tail.submenu(0); |
840 | - menuStack.push(menuStack.rootMenu, 0); |
841 | - } |
842 | - } |
843 | - onModelReset: { |
844 | + |
845 | + // fix async creation with signal from model before it's finished. |
846 | + Component.onCompleted: update(); |
847 | + onRowsInserted: update(); |
848 | + onModelReset: update(); |
849 | + |
850 | + function update() { |
851 | if (menuStack.rootMenu !== menuStack.tail && menuStack.tail.get(0, "type") === rootMenuType) { |
852 | menuStack.rootMenu = menuStack.tail.submenu(0); |
853 | menuStack.push(menuStack.rootMenu, 0); |
854 | @@ -92,8 +89,6 @@ |
855 | |
856 | // Only allow flicking if the content doesn't fit on the page |
857 | interactive: contentHeight > height |
858 | - // FIXME - https://bugreports.qt-project.org/browse/QTBUG-41207 |
859 | - boundsBehavior: Flickable.StopAtBounds |
860 | |
861 | property int selectedIndex: -1 |
862 | property bool blockCurrentIndexChange: false |
863 | @@ -126,7 +121,6 @@ |
864 | delegate: Loader { |
865 | id: loader |
866 | objectName: "menuItem" + index |
867 | - asynchronous: true |
868 | width: ListView.view.width |
869 | visible: status == Loader.Ready |
870 | |
871 | |
872 | === removed file 'qml/Panel/IndicatorRow.qml' |
873 | --- qml/Panel/IndicatorRow.qml 2014-09-05 15:23:43 +0000 |
874 | +++ qml/Panel/IndicatorRow.qml 1970-01-01 00:00:00 +0000 |
875 | @@ -1,163 +0,0 @@ |
876 | -/* |
877 | - * Copyright (C) 2013 Canonical, Ltd. |
878 | - * |
879 | - * This program is free software; you can redistribute it and/or modify |
880 | - * it under the terms of the GNU General Public License as published by |
881 | - * the Free Software Foundation; version 3. |
882 | - * |
883 | - * This program is distributed in the hope that it will be useful, |
884 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
885 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
886 | - * GNU General Public License for more details. |
887 | - * |
888 | - * You should have received a copy of the GNU General Public License |
889 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
890 | - */ |
891 | - |
892 | -import QtQuick 2.0 |
893 | -import Ubuntu.Components 0.1 |
894 | -import Unity.Indicators 0.1 as Indicators |
895 | -import "../Components" |
896 | -import "../Components/Flickables" as Flickables |
897 | - |
898 | -Item { |
899 | - id: indicatorRow |
900 | - |
901 | - readonly property alias currentItem : itemView.currentItem |
902 | - readonly property alias currentItemIndex: itemView.currentIndex |
903 | - readonly property alias row: itemView |
904 | - property QtObject indicatorsModel: null |
905 | - property int overFlowWidth: width |
906 | - property bool showAll: false |
907 | - property real currentItemOffset: 0.0 |
908 | - property real unitProgress: 0.0 |
909 | - |
910 | - width: units.gu(40) |
911 | - height: units.gu(3) |
912 | - |
913 | - function setDefaultItem() { |
914 | - // The leftmost indicator |
915 | - setCurrentItemIndex(0); |
916 | - } |
917 | - |
918 | - function setCurrentItemIndex(index) { |
919 | - itemView.currentIndex = index; |
920 | - } |
921 | - |
922 | - function setCurrentItem(item) { |
923 | - if (item && item.hasOwnProperty("ownIndex")) { |
924 | - itemView.currentIndex = item.ownIndex; |
925 | - } else { |
926 | - itemView.currentIndex = -1; |
927 | - } |
928 | - } |
929 | - |
930 | - Timer { |
931 | - id: allVisible |
932 | - interval: 1000 |
933 | - |
934 | - onTriggered: { |
935 | - showAll = false; |
936 | - } |
937 | - } |
938 | - |
939 | - Flickables.ListView { |
940 | - id: itemView |
941 | - objectName: "indicatorRowItems" |
942 | - interactive: false |
943 | - model: indicatorsModel ? indicatorsModel : null |
944 | - |
945 | - width: childrenRect.width |
946 | - height: indicatorRow.height |
947 | - anchors.right: parent.right |
948 | - orientation: ListView.Horizontal |
949 | - |
950 | - property int lastCount: 0 |
951 | - onCountChanged: { |
952 | - if (lastCount < count) { |
953 | - showAll = true; |
954 | - allVisible.start(); |
955 | - } |
956 | - lastCount = count; |
957 | - } |
958 | - |
959 | - delegate: Item { |
960 | - id: itemWrapper |
961 | - objectName: "item" + index |
962 | - height: indicatorRow.height |
963 | - width: indicatorItem.width |
964 | - opacity: 1 - indicatorRow.unitProgress |
965 | - y: 0 |
966 | - state: "standard" |
967 | - |
968 | - property int ownIndex: index |
969 | - property bool highlighted: indicatorRow.unitProgress > 0 ? ListView.isCurrentItem : false |
970 | - property bool dimmed: indicatorRow.unitProgress > 0 ? !ListView.isCurrentItem : false |
971 | - |
972 | - property bool hidden: !showAll && !highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit") |
973 | - property bool overflow: row.width - itemWrapper.x > overFlowWidth |
974 | - |
975 | - IndicatorItem { |
976 | - id: indicatorItem |
977 | - identifier: model.identifier |
978 | - height: parent.height |
979 | - |
980 | - dimmed: itemWrapper.dimmed |
981 | - |
982 | - widgetSource: model.widgetSource |
983 | - indicatorProperties : model.indicatorProperties |
984 | - } |
985 | - |
986 | - states: [ |
987 | - State { |
988 | - name: "standard" |
989 | - when: !hidden && !overflow && !highlighted |
990 | - }, |
991 | - State { |
992 | - name: "highlighted" |
993 | - when: highlighted |
994 | - PropertyChanges { target: itemWrapper; opacity: 1.0 } |
995 | - }, |
996 | - State { |
997 | - name: "hidden" |
998 | - when: hidden || overflow |
999 | - PropertyChanges { target: itemWrapper; opacity: 0.0 } |
1000 | - } |
1001 | - ] |
1002 | - |
1003 | - Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration } } |
1004 | - } |
1005 | - } |
1006 | - |
1007 | - |
1008 | - Rectangle { |
1009 | - id: highlight |
1010 | - color: Theme.palette.selected.foreground |
1011 | - objectName: "highlight" |
1012 | - height: units.dp(2) |
1013 | - anchors.top: row.bottom |
1014 | - visible: indicatorRow.currentItem != null |
1015 | - |
1016 | - property real intendedX: row.x + (indicatorRow.currentItem != null ? (indicatorRow.currentItem.x - row.originX) + centerOffset : 0) |
1017 | - x: intendedX >= row.x ? (intendedX + width <= row.x + row.width ? intendedX : row.x + row.width - width) : row.x // listview boundaries |
1018 | - width: indicatorRow.currentItem != null ? indicatorRow.currentItem.width : 0 |
1019 | - |
1020 | - property real centerOffset: { |
1021 | - if (indicatorRow.currentItemOffset > 0.1) { |
1022 | - return (indicatorRow.currentItemOffset - 0.1) * units.gu(0.4); |
1023 | - } else if (indicatorRow.currentItemOffset < -0.1) { |
1024 | - return (indicatorRow.currentItemOffset + 0.1) * units.gu(0.4); |
1025 | - } |
1026 | - return 0.0; |
1027 | - } |
1028 | - |
1029 | - Behavior on width { |
1030 | - enabled: unitProgress > 0; |
1031 | - UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration } |
1032 | - } |
1033 | - Behavior on x { |
1034 | - enabled: unitProgress > 0; |
1035 | - UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration } |
1036 | - } |
1037 | - } |
1038 | -} |
1039 | |
1040 | === removed file 'qml/Panel/Indicators.qml' |
1041 | --- qml/Panel/Indicators.qml 2014-09-09 13:40:41 +0000 |
1042 | +++ qml/Panel/Indicators.qml 1970-01-01 00:00:00 +0000 |
1043 | @@ -1,415 +0,0 @@ |
1044 | -/* |
1045 | - * Copyright (C) 2013 Canonical, Ltd. |
1046 | - * |
1047 | - * This program is free software; you can redistribute it and/or modify |
1048 | - * it under the terms of the GNU General Public License as published by |
1049 | - * the Free Software Foundation; version 3. |
1050 | - * |
1051 | - * This program is distributed in the hope that it will be useful, |
1052 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1053 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1054 | - * GNU General Public License for more details. |
1055 | - * |
1056 | - * You should have received a copy of the GNU General Public License |
1057 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1058 | - */ |
1059 | - |
1060 | -import QtQuick 2.0 |
1061 | -import Ubuntu.Components 0.1 |
1062 | -import Ubuntu.Gestures 0.1 |
1063 | -import Unity.Indicators 0.1 as Indicators |
1064 | - |
1065 | -import "../Components" |
1066 | -import "../Components/ListItems" |
1067 | -import "Indicators" |
1068 | - |
1069 | -Showable { |
1070 | - id: indicators |
1071 | - |
1072 | - property real openedHeight: units.gu(71) |
1073 | - property int panelHeight: units.gu(3) |
1074 | - property alias overFlowWidth: indicatorRow.overFlowWidth |
1075 | - property alias showAll: indicatorRow.showAll |
1076 | - // TODO: This should be sourced by device type (eg "desktop", "tablet", "phone"...) |
1077 | - property string profile: indicatorProfile |
1078 | - |
1079 | - readonly property real hintValue: panelHeight + menuContent.headerHeight |
1080 | - readonly property int lockThreshold: openedHeight / 2 |
1081 | - property bool fullyOpened: height == openedHeight |
1082 | - property bool partiallyOpened: height > panelHeight && !fullyOpened |
1083 | - property bool fullyClosed: height <= panelHeight |
1084 | - property bool contentEnabled: true |
1085 | - property bool initalizeItem: true |
1086 | - readonly property alias content: menuContent |
1087 | - property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight) |
1088 | - property bool enableHint: true |
1089 | - property real showHintBottomMargin: 0 |
1090 | - |
1091 | - signal showTapped(point position) |
1092 | - |
1093 | - // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to |
1094 | - // use its own values. Need to ask design about this. |
1095 | - showAnimation: StandardAnimation { |
1096 | - property: "height" |
1097 | - to: openedHeight |
1098 | - } |
1099 | - |
1100 | - hideAnimation: StandardAnimation { |
1101 | - property: "height" |
1102 | - duration: 350 |
1103 | - to: panelHeight |
1104 | - easing.type: Easing.OutCubic |
1105 | - } |
1106 | - |
1107 | - onOpenedHeightChanged: { |
1108 | - if (showAnimation.running) { |
1109 | - showAnimation.restart(); |
1110 | - } else if (indicators.shown) { |
1111 | - height = openedHeight; |
1112 | - } |
1113 | - } |
1114 | - |
1115 | - height: panelHeight |
1116 | - onHeightChanged: updateRevealProgressState(indicators.height - panelHeight - showHintBottomMargin, true) |
1117 | - |
1118 | - function updateRevealProgressState(revealProgress, enableRelease) { |
1119 | - if (!showAnimation.running && !hideAnimation.running) { |
1120 | - if (revealProgress === 0) { |
1121 | - indicators.state = "initial"; |
1122 | - } else if (enableHint && revealProgress > 0 && revealProgress <= hintValue) { |
1123 | - indicators.state = "hint"; |
1124 | - } else if ((!enableHint || revealProgress > hintValue) && revealProgress < lockThreshold) { |
1125 | - indicators.state = "reveal"; |
1126 | - } else if (revealProgress >= lockThreshold && lockThreshold > 0) { |
1127 | - indicators.state = "locked"; |
1128 | - } |
1129 | - } |
1130 | - } |
1131 | - |
1132 | - function calculateCurrentItem(xValue, useBuffer) { |
1133 | - var rowCoordinates; |
1134 | - var itemCoordinates; |
1135 | - var currentItem; |
1136 | - var distanceFromRightEdge; |
1137 | - var bufferExceeded = false; |
1138 | - |
1139 | - if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return; |
1140 | - |
1141 | - /* |
1142 | - If user drags the indicator handle bar down a distance hintValue or less, this is 0. |
1143 | - If bar is dragged down a distance greater than or equal to lockThreshold, this is 1. |
1144 | - Otherwise it contains the bar's location as a fraction of the distance between hintValue (is 0) and lockThreshold (is 1). |
1145 | - */ |
1146 | - var verticalProgress = |
1147 | - MathUtils.clamp((indicators.height - handle.height - hintValue) / |
1148 | - (lockThreshold - hintValue), 0, 1); |
1149 | - |
1150 | - /* |
1151 | - Vertical velocity check. Don't change the indicator if we're moving too quickly. |
1152 | - */ |
1153 | - var verticalSpeed = Math.abs(yVelocityCalculator.calculate()); |
1154 | - if (verticalSpeed >= 0.05 && !initalizeItem) { |
1155 | - return; |
1156 | - } |
1157 | - |
1158 | - /* |
1159 | - Percentage of an indicator icon's width the user's press can stray horizontally from the |
1160 | - focused icon before we change focus to another icon. E.g. a value of 0.5 means you must |
1161 | - go right a distance of half an icon's width before focus moves to the icon on the right |
1162 | - */ |
1163 | - var maxBufferThreshold = 0.5; |
1164 | - |
1165 | - /* |
1166 | - To help users find the indicator of their choice while opening the indicators, we add logic to add a |
1167 | - left/right buffer to each icon so it is harder for the focus to be moved accidentally to another icon, |
1168 | - as the user moves their finger down, but yet allows them to switch indicator if they want. |
1169 | - This buffer is wider the further the user's finger is from the top of the screen. |
1170 | - */ |
1171 | - var effectiveBufferThreshold = maxBufferThreshold * verticalProgress; |
1172 | - |
1173 | - rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0); |
1174 | - // get the current delegate |
1175 | - currentItem = indicatorRow.row.itemAt(rowCoordinates.x, 0); |
1176 | - if (currentItem) { |
1177 | - itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0); |
1178 | - distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width); |
1179 | - if (currentItem != indicatorRow.currentItem) { |
1180 | - if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) { |
1181 | - bufferExceeded = true; |
1182 | - } else { |
1183 | - if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) { |
1184 | - bufferExceeded = true; |
1185 | - } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) { |
1186 | - bufferExceeded = true; |
1187 | - } |
1188 | - } |
1189 | - if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItemIndex < 0 || indicatorRow.currentItem == null) { |
1190 | - indicatorRow.setCurrentItem(currentItem); |
1191 | - } |
1192 | - |
1193 | - // need to re-init the distanceFromRightEdge for offset calculation |
1194 | - itemCoordinates = indicatorRow.row.mapToItem(indicatorRow.currentItem, rowCoordinates.x, 0); |
1195 | - distanceFromRightEdge = (indicatorRow.currentItem.width - itemCoordinates.x) / (indicatorRow.currentItem.width); |
1196 | - } |
1197 | - indicatorRow.currentItemOffset = 1 - (distanceFromRightEdge * 2); |
1198 | - } else if (initalizeItem) { |
1199 | - indicatorRow.setDefaultItem(); |
1200 | - indicatorRow.currentItemOffset = 0; |
1201 | - } |
1202 | - initalizeItem = indicatorRow.currentItem == null; |
1203 | - } |
1204 | - |
1205 | - // eater |
1206 | - MouseArea { |
1207 | - anchors { |
1208 | - top: parent.top |
1209 | - bottom: handle.bottom |
1210 | - left: parent.left |
1211 | - right: parent.right |
1212 | - } |
1213 | - } |
1214 | - |
1215 | - VisibleIndicators { |
1216 | - id: visibleIndicators |
1217 | - } |
1218 | - |
1219 | - MenuContent { |
1220 | - id: menuContent |
1221 | - objectName: "menuContent" |
1222 | - |
1223 | - anchors { |
1224 | - left: parent.left |
1225 | - right: parent.right |
1226 | - top: indicatorRow.bottom |
1227 | - bottom: handle.top |
1228 | - } |
1229 | - indicatorsModel: visibleIndicators.model |
1230 | - visible: indicators.partiallyOpened || indicators.fullyOpened |
1231 | - clip: indicators.partiallyOpened |
1232 | - enabled: contentEnabled |
1233 | - |
1234 | - //small shadow gradient at bottom of menu |
1235 | - Rectangle { |
1236 | - anchors { |
1237 | - left: parent.left |
1238 | - right: parent.right |
1239 | - bottom: parent.bottom |
1240 | - } |
1241 | - height: units.gu(0.5) |
1242 | - gradient: Gradient { |
1243 | - GradientStop { position: 0.0; color: "transparent" } |
1244 | - GradientStop { position: 1.0; color: "black" } |
1245 | - } |
1246 | - opacity: 0.4 |
1247 | - } |
1248 | - } |
1249 | - |
1250 | - Rectangle { |
1251 | - id: handle |
1252 | - |
1253 | - color: menuContent.color |
1254 | - |
1255 | - anchors { |
1256 | - left: parent.left |
1257 | - right: parent.right |
1258 | - bottom: parent.bottom |
1259 | - } |
1260 | - height: Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0) |
1261 | - clip: height < handleImage.height |
1262 | - visible: menuContent.visible |
1263 | - |
1264 | - BorderImage { |
1265 | - id: handleImage |
1266 | - source: "graphics/handle.sci" |
1267 | - height: panelHeight |
1268 | - anchors { |
1269 | - left: parent.left |
1270 | - right: parent.right |
1271 | - bottom: parent.bottom |
1272 | - } |
1273 | - } |
1274 | - MouseArea { //prevent clicks passing through |
1275 | - anchors.fill: parent |
1276 | - } |
1277 | - } |
1278 | - |
1279 | - IndicatorRow { |
1280 | - id: indicatorRow |
1281 | - objectName: "indicatorRow" |
1282 | - anchors { |
1283 | - left: parent.left |
1284 | - right: parent.right |
1285 | - } |
1286 | - height: indicators.panelHeight |
1287 | - indicatorsModel: visibleIndicators.model |
1288 | - state: indicators.state |
1289 | - unitProgress: indicators.unitProgress |
1290 | - |
1291 | - EdgeDragArea { |
1292 | - id: rowDragArea |
1293 | - anchors.fill: indicatorRow |
1294 | - direction: Direction.Downwards |
1295 | - maxSilenceTime: 2000 |
1296 | - distanceThreshold: 0 |
1297 | - |
1298 | - enabled: fullyOpened |
1299 | - onDraggingChanged: { |
1300 | - if (dragging) { |
1301 | - initalizeItem = true; |
1302 | - updateRevealProgressState(Math.max(touchSceneY - panelHeight, hintValue), false); |
1303 | - indicators.calculateCurrentItem(touchX, false); |
1304 | - } else { |
1305 | - indicators.state = "commit"; |
1306 | - indicatorRow.currentItemOffset = 0; |
1307 | - } |
1308 | - } |
1309 | - |
1310 | - onTouchXChanged: { |
1311 | - indicators.calculateCurrentItem(touchX, true); |
1312 | - } |
1313 | - onTouchSceneYChanged: { |
1314 | - updateRevealProgressState(Math.max(touchSceneY - panelHeight, hintValue), false); |
1315 | - yVelocityCalculator.trackedPosition = touchSceneY; |
1316 | - } |
1317 | - } |
1318 | - } |
1319 | - |
1320 | - Connections { |
1321 | - target: showAnimation |
1322 | - onRunningChanged: { |
1323 | - if (showAnimation.running) { |
1324 | - indicators.state = "commit"; |
1325 | - indicatorRow.currentItemOffset = 0; |
1326 | - } |
1327 | - } |
1328 | - } |
1329 | - |
1330 | - Connections { |
1331 | - target: hideAnimation |
1332 | - onRunningChanged: { |
1333 | - if (hideAnimation.running) { |
1334 | - indicators.state = "initial"; |
1335 | - initalizeItem = true; |
1336 | - indicatorRow.currentItemOffset = 0; |
1337 | - } |
1338 | - } |
1339 | - } |
1340 | - |
1341 | - QtObject { |
1342 | - id: d |
1343 | - property bool enableIndexChangeSignal: true |
1344 | - property var activeDragHandle: showDragHandle.dragging ? showDragHandle : hideDragHandle.dragging ? hideDragHandle : null |
1345 | - } |
1346 | - |
1347 | - Connections { |
1348 | - target: menuContent |
1349 | - onCurrentMenuIndexChanged: { |
1350 | - var oldActive = d.enableIndexChangeSignal; |
1351 | - if (!oldActive) return; |
1352 | - d.enableIndexChangeSignal = false; |
1353 | - |
1354 | - indicatorRow.setCurrentItemIndex(menuContent.currentMenuIndex); |
1355 | - |
1356 | - d.enableIndexChangeSignal = oldActive; |
1357 | - } |
1358 | - } |
1359 | - |
1360 | - Connections { |
1361 | - target: indicatorRow |
1362 | - onCurrentItemIndexChanged: { |
1363 | - var oldActive = d.enableIndexChangeSignal; |
1364 | - if (!oldActive) return; |
1365 | - d.enableIndexChangeSignal = false; |
1366 | - |
1367 | - menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex, fullyOpened || partiallyOpened); |
1368 | - |
1369 | - d.enableIndexChangeSignal = oldActive; |
1370 | - } |
1371 | - } |
1372 | - // connections to the active drag handle |
1373 | - Connections { |
1374 | - target: d.activeDragHandle |
1375 | - onTouchXChanged: { |
1376 | - indicators.calculateCurrentItem(d.activeDragHandle.touchX, true); |
1377 | - } |
1378 | - onTouchSceneYChanged: { |
1379 | - yVelocityCalculator.trackedPosition = d.activeDragHandle.touchSceneY; |
1380 | - } |
1381 | - } |
1382 | - |
1383 | - DragHandle { |
1384 | - id: showDragHandle |
1385 | - anchors.bottom: parent.bottom |
1386 | - // go beyond parent so that it stays reachable, at the top of the screen. |
1387 | - anchors.bottomMargin: showHintBottomMargin |
1388 | - anchors.left: parent.left |
1389 | - anchors.right: parent.right |
1390 | - height: panelHeight |
1391 | - direction: Direction.Downwards |
1392 | - enabled: !indicators.shown && indicators.available |
1393 | - hintDisplacement: enableHint ? indicators.hintValue : 0 |
1394 | - autoCompleteDragThreshold: maxTotalDragDistance / 2 |
1395 | - stretch: true |
1396 | - maxTotalDragDistance: openedHeight - panelHeight |
1397 | - distanceThreshold: panelHeight |
1398 | - |
1399 | - onTapped: showTapped(Qt.point(touchSceneX, touchSceneY)); |
1400 | - } |
1401 | - |
1402 | - DragHandle { |
1403 | - id: hideDragHandle |
1404 | - anchors.fill: handle |
1405 | - direction: Direction.Upwards |
1406 | - enabled: indicators.shown && indicators.available |
1407 | - hintDisplacement: indicators.hintValue |
1408 | - autoCompleteDragThreshold: maxTotalDragDistance / 6 |
1409 | - stretch: true |
1410 | - maxTotalDragDistance: openedHeight - panelHeight |
1411 | - distanceThreshold: 0 |
1412 | - } |
1413 | - |
1414 | - AxisVelocityCalculator { |
1415 | - id: yVelocityCalculator |
1416 | - } |
1417 | - |
1418 | - states: [ |
1419 | - State { |
1420 | - name: "initial" |
1421 | - }, |
1422 | - State { |
1423 | - name: "hint" |
1424 | - StateChangeScript { |
1425 | - script: { |
1426 | - if (d.activeDragHandle) { |
1427 | - calculateCurrentItem(d.activeDragHandle.touchX, false); |
1428 | - } |
1429 | - } |
1430 | - } |
1431 | - }, |
1432 | - State { |
1433 | - name: "reveal" |
1434 | - extend: "hint" |
1435 | - }, |
1436 | - State { |
1437 | - name: "locked" |
1438 | - extend: "hint" |
1439 | - }, |
1440 | - State { |
1441 | - name: "commit" |
1442 | - extend: "hint" |
1443 | - } |
1444 | - ] |
1445 | - state: "initial" |
1446 | - |
1447 | - transitions: [ |
1448 | - Transition { |
1449 | - NumberAnimation {targets: [indicatorRow, menuContent]; property: "y"; duration: 300; easing.type: Easing.OutCubic} |
1450 | - } |
1451 | - ] |
1452 | - |
1453 | - Component.onCompleted: initialise(); |
1454 | - function initialise() { |
1455 | - visibleIndicators.load(profile); |
1456 | - indicatorRow.setDefaultItem(); |
1457 | - } |
1458 | -} |
1459 | |
1460 | === removed file 'qml/Panel/Indicators/DefaultIndicatorWidget.qml' |
1461 | --- qml/Panel/Indicators/DefaultIndicatorWidget.qml 2014-08-20 08:39:09 +0000 |
1462 | +++ qml/Panel/Indicators/DefaultIndicatorWidget.qml 1970-01-01 00:00:00 +0000 |
1463 | @@ -1,119 +0,0 @@ |
1464 | -/* |
1465 | - * Copyright 2013 Canonical Ltd. |
1466 | - * |
1467 | - * This program is free software; you can redistribute it and/or modify |
1468 | - * it under the terms of the GNU Lesser General Public License as published by |
1469 | - * the Free Software Foundation; version 3. |
1470 | - * |
1471 | - * This program is distributed in the hope that it will be useful, |
1472 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1473 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1474 | - * GNU Lesser General Public License for more details. |
1475 | - * |
1476 | - * You should have received a copy of the GNU Lesser General Public License |
1477 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1478 | - * |
1479 | - * Authors: |
1480 | - * Nick Dedekind <nick.dedekind@canonical.com> |
1481 | - */ |
1482 | - |
1483 | -import QtQuick 2.0 |
1484 | -import Ubuntu.Components 0.1 |
1485 | -import Ubuntu.Settings.Components 0.1 |
1486 | - |
1487 | -IndicatorBase { |
1488 | - id: indicatorWidget |
1489 | - |
1490 | - property int iconSize: units.gu(2) |
1491 | - property alias leftLabel: itemLeftLabel.text |
1492 | - property alias rightLabel: itemRightLabel.text |
1493 | - property var icons: undefined |
1494 | - |
1495 | - width: itemRow.width |
1496 | - enabled: false |
1497 | - |
1498 | - // FIXME: For now we will enable led indicator support only for messaging indicator |
1499 | - // in the future we should export a led API insted of doing that, |
1500 | - Loader { |
1501 | - id: indicatorLed |
1502 | - // only load source Component if the icons contains the new message icon |
1503 | - source: (indicatorWidget.icons && (String(indicatorWidget.icons).indexOf("indicator-messages-new") != -1)) ? Qt.resolvedUrl("IndicatorsLight.qml") : "" |
1504 | - } |
1505 | - |
1506 | - Row { |
1507 | - id: itemRow |
1508 | - objectName: "itemRow" |
1509 | - anchors { |
1510 | - top: parent.top |
1511 | - bottom: parent.bottom |
1512 | - horizontalCenter: parent.horizontalCenter |
1513 | - } |
1514 | - |
1515 | - Label { |
1516 | - id: itemLeftLabel |
1517 | - width: contentWidth + units.gu(1) |
1518 | - objectName: "leftLabel" |
1519 | - color: Theme.palette.selected.backgroundText |
1520 | - opacity: 0.8 |
1521 | - font.family: "Ubuntu" |
1522 | - fontSize: "medium" |
1523 | - anchors.verticalCenter: parent.verticalCenter |
1524 | - visible: text != "" |
1525 | - horizontalAlignment: Text.AlignHCenter |
1526 | - } |
1527 | - |
1528 | - Row { |
1529 | - id: iconRow |
1530 | - anchors { |
1531 | - top: parent.top |
1532 | - bottom: parent.bottom |
1533 | - } |
1534 | - |
1535 | - Repeater { |
1536 | - model: indicatorWidget.icons |
1537 | - |
1538 | - Item { |
1539 | - width: itemImage.width + units.gu(1) |
1540 | - height: iconRow.height |
1541 | - |
1542 | - StatusIcon { |
1543 | - id: itemImage |
1544 | - height: indicatorWidget.iconSize |
1545 | - anchors.centerIn: parent |
1546 | - source: modelData |
1547 | - sets: ["status", "actions"] |
1548 | - color: "#CCCCCC" |
1549 | - } |
1550 | - } |
1551 | - } |
1552 | - } |
1553 | - |
1554 | - Label { |
1555 | - id: itemRightLabel |
1556 | - width: contentWidth + units.gu(1) |
1557 | - objectName: "rightLabel" |
1558 | - color: Theme.palette.selected.backgroundText |
1559 | - opacity: 0.8 |
1560 | - font.family: "Ubuntu" |
1561 | - fontSize: "medium" |
1562 | - anchors.verticalCenter: parent.verticalCenter |
1563 | - visible: text != "" |
1564 | - horizontalAlignment: Text.AlignHCenter |
1565 | - } |
1566 | - } |
1567 | - |
1568 | - onRootActionStateChanged: { |
1569 | - if (rootActionState == undefined) { |
1570 | - leftLabel = ""; |
1571 | - rightLabel = ""; |
1572 | - icons = undefined; |
1573 | - enabled = false; |
1574 | - return; |
1575 | - } |
1576 | - |
1577 | - leftLabel = rootActionState.leftLabel ? rootActionState.leftLabel : ""; |
1578 | - rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : ""; |
1579 | - icons = rootActionState.icons; |
1580 | - enabled = rootActionState.visible; |
1581 | - } |
1582 | -} |
1583 | |
1584 | === modified file 'qml/Panel/Indicators/IndicatorBase.qml' |
1585 | --- qml/Panel/Indicators/IndicatorBase.qml 2014-10-21 21:16:04 +0000 |
1586 | +++ qml/Panel/Indicators/IndicatorBase.qml 2014-10-21 21:16:05 +0000 |
1587 | @@ -23,8 +23,6 @@ |
1588 | Item { |
1589 | id: indicatorItem |
1590 | |
1591 | - enabled: menuObjectPath != "" |
1592 | - |
1593 | //const |
1594 | property string identifier |
1595 | property string busName |
1596 | @@ -32,8 +30,6 @@ |
1597 | property string menuObjectPath |
1598 | property string rootMenuType: "com.canonical.indicator.root" |
1599 | |
1600 | - property string deviceMenuObjectPath: menuObjectPath |
1601 | - |
1602 | property alias menuModel: cachedModel.model |
1603 | property alias rootActionState: rootAction |
1604 | |
1605 | @@ -41,7 +37,7 @@ |
1606 | id: cachedModel |
1607 | busName: indicatorItem.busName |
1608 | actions: { "indicator": indicatorItem.actionsObjectPath } |
1609 | - menuObjectPath: indicatorItem.deviceMenuObjectPath |
1610 | + menuObjectPath: indicatorItem.menuObjectPath |
1611 | } |
1612 | |
1613 | RootActionState { |
1614 | |
1615 | === modified file 'qml/Panel/Indicators/IndicatorDelegate.qml' |
1616 | --- qml/Panel/Indicators/IndicatorDelegate.qml 2014-07-25 17:52:39 +0000 |
1617 | +++ qml/Panel/Indicators/IndicatorDelegate.qml 2014-10-21 21:16:05 +0000 |
1618 | @@ -20,6 +20,6 @@ |
1619 | import QtQuick 2.0 |
1620 | |
1621 | IndicatorBase { |
1622 | - enabled: rootActionState.visible |
1623 | - property string title: rootActionState.title |
1624 | + readonly property bool indicatorVisible: rootActionState.indicatorVisible |
1625 | + readonly property string title: rootActionState.title |
1626 | } |
1627 | |
1628 | === modified file 'qml/Panel/Indicators/VisibleIndicators.qml' |
1629 | --- qml/Panel/Indicators/VisibleIndicators.qml 2014-09-29 10:24:58 +0000 |
1630 | +++ qml/Panel/Indicators/VisibleIndicators.qml 2014-10-21 21:16:05 +0000 |
1631 | @@ -24,6 +24,10 @@ |
1632 | Item { |
1633 | property SortFilterProxyModel model: filterModel |
1634 | |
1635 | + function initialise(profile) { |
1636 | + indicatorsModel.load(profile); |
1637 | + } |
1638 | + |
1639 | SortFilterProxyModel { |
1640 | id: filterModel |
1641 | filterRole: Indicators.IndicatorsModelRole.IsVisible |
1642 | @@ -36,7 +40,6 @@ |
1643 | } |
1644 | } |
1645 | |
1646 | - |
1647 | Indicators.IndicatorsModel { |
1648 | id: indicatorsModel |
1649 | } |
1650 | @@ -78,8 +81,4 @@ |
1651 | } |
1652 | } |
1653 | } |
1654 | - |
1655 | - function load(profile) { |
1656 | - indicatorsModel.load(profile); |
1657 | - } |
1658 | } |
1659 | |
1660 | === renamed file 'qml/Panel/Indicators/client/IndicatorsPage.qml' => 'qml/Panel/Indicators/client/IndicatorRepresentation.qml' |
1661 | --- qml/Panel/Indicators/client/IndicatorsPage.qml 2013-08-14 09:07:45 +0000 |
1662 | +++ qml/Panel/Indicators/client/IndicatorRepresentation.qml 2014-10-21 21:16:05 +0000 |
1663 | @@ -21,13 +21,13 @@ |
1664 | import QtQuick 2.0 |
1665 | import Ubuntu.Components 0.1 |
1666 | import Ubuntu.Components.ListItems 0.1 as ListItem |
1667 | +import "../.." |
1668 | |
1669 | Page { |
1670 | - id: page |
1671 | + id: root |
1672 | |
1673 | title: indicatorProperties && indicatorProperties.title ? indicatorProperties.title : "" |
1674 | property variant indicatorProperties |
1675 | - property string pageSource : pageLoader.source |
1676 | |
1677 | anchors.fill: parent |
1678 | |
1679 | @@ -44,6 +44,7 @@ |
1680 | id: pageLoader |
1681 | objectName: "pageLoader" |
1682 | clip:true |
1683 | + asynchronous: true |
1684 | |
1685 | Rectangle { |
1686 | anchors.fill: pageLoader |
1687 | @@ -58,15 +59,25 @@ |
1688 | topMargin: units.gu(2) |
1689 | bottomMargin: units.gu(2) |
1690 | } |
1691 | - source : visualCheck.checked ? page.pageSource : "IndicatorsTree.qml" |
1692 | + sourceComponent: visualCheck.checked ? page : tree |
1693 | |
1694 | - onLoaded: { |
1695 | - for(var pName in indicatorProperties) { |
1696 | - if (item.hasOwnProperty(pName)) { |
1697 | - item[pName] = indicatorProperties[pName]; |
1698 | - } |
1699 | - } |
1700 | - item.start(); |
1701 | + Component { |
1702 | + id: page |
1703 | + IndicatorPage { |
1704 | + identifier: model.identifier |
1705 | + busName: indicatorProperties.busName |
1706 | + actionsObjectPath: indicatorProperties.actionsObjectPath |
1707 | + menuObjectPath: indicatorProperties.menuObjectPath |
1708 | + } |
1709 | + } |
1710 | + Component { |
1711 | + id: tree |
1712 | + IndicatorsTree { |
1713 | + identifier: model.identifier |
1714 | + busName: indicatorProperties.busName |
1715 | + actionsObjectPath: indicatorProperties.actionsObjectPath |
1716 | + menuObjectPath: indicatorProperties.menuObjectPath |
1717 | + } |
1718 | } |
1719 | } |
1720 | |
1721 | @@ -85,7 +96,7 @@ |
1722 | left: parent.left |
1723 | } |
1724 | text: "Back" |
1725 | - onClicked: page.pageStack.reset() |
1726 | + onClicked: root.pageStack.reset() |
1727 | } |
1728 | } |
1729 | } |
1730 | |
1731 | === modified file 'qml/Panel/Indicators/client/IndicatorsList.qml' |
1732 | --- qml/Panel/Indicators/client/IndicatorsList.qml 2014-09-05 15:23:43 +0000 |
1733 | +++ qml/Panel/Indicators/client/IndicatorsList.qml 2014-10-21 21:16:05 +0000 |
1734 | @@ -58,8 +58,8 @@ |
1735 | text: identifier |
1736 | |
1737 | onClicked: { |
1738 | - var new_page = Qt.createComponent("IndicatorsPage.qml"); |
1739 | - page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource}); |
1740 | + var new_page = Qt.createComponent("IndicatorRepresentation.qml"); |
1741 | + page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties }); |
1742 | } |
1743 | } |
1744 | } |
1745 | |
1746 | === modified file 'qml/Panel/Indicators/client/IndicatorsTree.qml' |
1747 | --- qml/Panel/Indicators/client/IndicatorsTree.qml 2014-09-05 15:23:43 +0000 |
1748 | +++ qml/Panel/Indicators/client/IndicatorsTree.qml 2014-10-21 21:16:05 +0000 |
1749 | @@ -20,37 +20,15 @@ |
1750 | import QtQuick 2.0 |
1751 | import Ubuntu.Components 0.1 |
1752 | import Unity.Indicators 0.1 as Indicators |
1753 | -import QMenuModel 0.1 |
1754 | -import Ubuntu.Components.ListItems 0.1 as ListItem |
1755 | +import ".." |
1756 | import "../../../Components/Flickables" as Flickables |
1757 | |
1758 | -Page { |
1759 | - id: page |
1760 | - anchors.fill: parent |
1761 | - |
1762 | - property string busName: unityModel.busName |
1763 | - property string actionsObjectPath |
1764 | - property string menuObjectPath |
1765 | - |
1766 | - property string deviceMenuObjectPath: menuObjectPath |
1767 | - |
1768 | - function start() { |
1769 | - } |
1770 | - |
1771 | - UnityMenuModel { |
1772 | - id: unityModel |
1773 | - busName: page.busName |
1774 | - actions: { "indicator": page.actionsObjectPath } |
1775 | - menuObjectPath: page.deviceMenuObjectPath |
1776 | - } |
1777 | - |
1778 | - Indicators.RootActionState { |
1779 | - menu: unityModel |
1780 | - } |
1781 | +IndicatorBase { |
1782 | + id: root |
1783 | |
1784 | Indicators.ModelPrinter { |
1785 | id: printer |
1786 | - model: unityModel |
1787 | + model: root.menuModel |
1788 | } |
1789 | |
1790 | Flickables.Flickable { |
1791 | |
1792 | === added file 'qml/Panel/IndicatorsBar.qml' |
1793 | --- qml/Panel/IndicatorsBar.qml 1970-01-01 00:00:00 +0000 |
1794 | +++ qml/Panel/IndicatorsBar.qml 2014-10-21 21:16:05 +0000 |
1795 | @@ -0,0 +1,269 @@ |
1796 | +/* |
1797 | + * Copyright (C) 2014 Canonical, Ltd. |
1798 | + * |
1799 | + * This program is free software; you can redistribute it and/or modify |
1800 | + * it under the terms of the GNU General Public License as published by |
1801 | + * the Free Software Foundation; version 3. |
1802 | + * |
1803 | + * This program is distributed in the hope that it will be useful, |
1804 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1805 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1806 | + * GNU General Public License for more details. |
1807 | + * |
1808 | + * You should have received a copy of the GNU General Public License |
1809 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1810 | + */ |
1811 | + |
1812 | +import QtQuick 2.2 |
1813 | +import Ubuntu.Components 1.1 |
1814 | +import "../Components" |
1815 | + |
1816 | +Item { |
1817 | + id: root |
1818 | + property alias expanded: row.expanded |
1819 | + property alias interactive: flickable.interactive |
1820 | + property alias indicatorsModel: row.indicatorsModel |
1821 | + property alias unitProgress: row.unitProgress |
1822 | + property alias enableLateralChanges: row.enableLateralChanges |
1823 | + property alias overFlowWidth: row.overFlowWidth |
1824 | + readonly property alias currentItemIndex: row.currentItemIndex |
1825 | + property real lateralPosition: -1 |
1826 | + |
1827 | + function selectItemAt(lateralPosition) { |
1828 | + if (!expanded) { |
1829 | + row.resetCurrentItem(); |
1830 | + } |
1831 | + var mapped = root.mapToItem(row, lateralPosition, 0); |
1832 | + row.selectItemAt(mapped.x); |
1833 | + } |
1834 | + |
1835 | + function setCurrentItemIndex(index) { |
1836 | + if (!expanded) { |
1837 | + row.resetCurrentItem(); |
1838 | + } |
1839 | + row.setCurrentItemIndex(index); |
1840 | + } |
1841 | + |
1842 | + function addScrollOffset(scrollAmmout) { |
1843 | + if (scrollAmmout < 0) { // left scroll |
1844 | + if (flickable.contentX < 0) return; // already off the left. |
1845 | + if (flickable.contentX + scrollAmmout < 0) scrollAmmout = -flickable.contentX; // going to be off the left |
1846 | + } else { // right scroll |
1847 | + if (flickable.contentX + flickable.width > row.width) return; // already off the right. |
1848 | + if (flickable.contentX + flickable.width + scrollAmmout > row.width) { // going to be off the right |
1849 | + scrollAmmout = row.width - (flickable.contentX + flickable.width); |
1850 | + } |
1851 | + } |
1852 | + d.scrollOffset = d.scrollOffset + scrollAmmout; |
1853 | + } |
1854 | + |
1855 | + QtObject { |
1856 | + id: d |
1857 | + property var initialItem |
1858 | + // the non-expanded distance from row offset to center of initial item |
1859 | + property real originalDistanceFromRight: -1 |
1860 | + |
1861 | + // calculate the distance from row offset to center of initial item |
1862 | + property real distanceFromRight: { |
1863 | + if (originalDistanceFromRight == -1) return 0; |
1864 | + if (!initialItem) return 0; |
1865 | + return row.width - initialItem.x - initialItem.width /2; |
1866 | + } |
1867 | + |
1868 | + // offset to the intially selected expanded item |
1869 | + property real rowOffset: 0 |
1870 | + property real scrollOffset: 0 |
1871 | + property real alignmentAdjustment: 0 |
1872 | + property real combinedOffset: 0 |
1873 | + |
1874 | + // when the scroll offset changes, we need to reclaculate the relative lateral position |
1875 | + onScrollOffsetChanged: root.lateralPositionChanged() |
1876 | + |
1877 | + onInitialItemChanged: { |
1878 | + originalDistanceFromRight = initialItem ? (row.width - initialItem.x - initialItem.width/2) : -1; |
1879 | + } |
1880 | + |
1881 | + Behavior on alignmentAdjustment { |
1882 | + NumberAnimation { duration: UbuntuAnimation.BriskDuration; easing: UbuntuAnimation.StandardEasing} |
1883 | + } |
1884 | + |
1885 | + function alignIndicators() { |
1886 | + flickable.resetContentXComponents(); |
1887 | + |
1888 | + if (expanded && !flickable.moving) { |
1889 | + |
1890 | + // gap between left and row? |
1891 | + if (flickable.contentX < 0) { |
1892 | + d.alignmentAdjustment += flickable.contentX; |
1893 | + // gap between right and row? |
1894 | + } else if (flickable.contentX + flickable.width > row.width) { |
1895 | + // row width is less than flickable |
1896 | + if (row.width < flickable.width) { |
1897 | + d.alignmentAdjustment += flickable.contentX; |
1898 | + } else { |
1899 | + d.alignmentAdjustment += ((flickable.contentX + flickable.width) - row.width); |
1900 | + } |
1901 | + // current item overlap on left |
1902 | + } else if (row.currentItem && row.currentItem.x < flickable.contentX) { |
1903 | + d.alignmentAdjustment -= (row.currentItem.x - flickable.contentX); |
1904 | + // current item overlap on right |
1905 | + } else if (row.currentItem && row.currentItem.x + row.currentItem.width > flickable.contentX + flickable.width) { |
1906 | + d.alignmentAdjustment -= ((row.currentItem.x + row.currentItem.width) - (flickable.contentX + flickable.width)); |
1907 | + } |
1908 | + } |
1909 | + } |
1910 | + } |
1911 | + |
1912 | + Rectangle { |
1913 | + id: grayLine |
1914 | + height: units.dp(2) |
1915 | + width: parent.width |
1916 | + anchors.bottom: parent.bottom |
1917 | + |
1918 | + color: "#4c4c4c" |
1919 | + opacity: expanded ? 1.0 : 0.0 |
1920 | + Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } } |
1921 | + } |
1922 | + |
1923 | + Item { |
1924 | + id: rowContainer |
1925 | + anchors.fill: parent |
1926 | + clip: expanded || row.width > rowContainer.width |
1927 | + |
1928 | + Flickable { |
1929 | + id: flickable |
1930 | + objectName: "flickable" |
1931 | + |
1932 | + anchors.fill: parent |
1933 | + contentWidth: row.width |
1934 | + interactive: false |
1935 | + // align right + offset from row selection + scrolling |
1936 | + contentX: row.width - flickable.width - d.combinedOffset |
1937 | + |
1938 | + // contentX can change by user interaction as well as user offset changes |
1939 | + // This function re-aligns the offsets so that the offsets match the contentX |
1940 | + function resetContentXComponents() { |
1941 | + d.scrollOffset += (flickable.contentX - (row.width - flickable.width - d.combinedOffset)); |
1942 | + } |
1943 | + |
1944 | + rebound: Transition { |
1945 | + NumberAnimation { |
1946 | + properties: "x" |
1947 | + duration: 600 |
1948 | + easing.type: Easing.OutCubic |
1949 | + } |
1950 | + } |
1951 | + |
1952 | + IndicatorItemRow { |
1953 | + id: row |
1954 | + objectName: "indicatorItemRow" |
1955 | + anchors { |
1956 | + top: parent.top |
1957 | + bottom: parent.bottom |
1958 | + } |
1959 | + |
1960 | + lateralPosition: { |
1961 | + if (root.lateralPosition == -1) return -1; |
1962 | + |
1963 | + var mapped = root.mapToItem(row, root.lateralPosition, 0); |
1964 | + return Math.min(Math.max(mapped.x, 0), row.width); |
1965 | + } |
1966 | + |
1967 | + onCurrentItemChanged: { |
1968 | + if (!currentItem) d.initialItem = undefined; |
1969 | + else if (!d.initialItem) d.initialItem = currentItem; |
1970 | + } |
1971 | + |
1972 | + MouseArea { |
1973 | + anchors.fill: parent |
1974 | + enabled: root.expanded |
1975 | + onClicked: { |
1976 | + row.selectItemAt(mouse.x); |
1977 | + d.alignIndicators(); |
1978 | + } |
1979 | + } |
1980 | + } |
1981 | + |
1982 | + } |
1983 | + } |
1984 | + |
1985 | + Timer { |
1986 | + id: alignmentTimer |
1987 | + interval: UbuntuAnimation.FastDuration // enough for row animation. |
1988 | + repeat: false |
1989 | + |
1990 | + onTriggered: d.alignIndicators(); |
1991 | + } |
1992 | + |
1993 | + states: [ |
1994 | + State { |
1995 | + name: "minimized" |
1996 | + when: !expanded |
1997 | + PropertyChanges { |
1998 | + target: d |
1999 | + rowOffset: 0 |
2000 | + scrollOffset: 0 |
2001 | + alignmentAdjustment: 0 |
2002 | + combinedOffset: 0 |
2003 | + restoreEntryValues: false |
2004 | + } |
2005 | + }, |
2006 | + State { |
2007 | + name: "expanded" |
2008 | + when: expanded && !interactive |
2009 | + |
2010 | + PropertyChanges { |
2011 | + target: d |
2012 | + combinedOffset: rowOffset + alignmentAdjustment - scrollOffset |
2013 | + } |
2014 | + PropertyChanges { |
2015 | + target: d |
2016 | + rowOffset: { |
2017 | + if (!initialItem) return 0; |
2018 | + if (distanceFromRight - initialItem.width <= 0) return 0; |
2019 | + |
2020 | + var rowOffset = distanceFromRight - originalDistanceFromRight; |
2021 | + return rowOffset; |
2022 | + } |
2023 | + restoreEntryValues: false |
2024 | + } |
2025 | + } |
2026 | + , State { |
2027 | + name: "interactive" |
2028 | + when: expanded && interactive |
2029 | + |
2030 | + StateChangeScript { |
2031 | + script: { |
2032 | + // don't use row offset anymore. |
2033 | + d.scrollOffset -= d.rowOffset; |
2034 | + d.rowOffset = 0; |
2035 | + d.initialItem = undefined; |
2036 | + alignmentTimer.start(); |
2037 | + } |
2038 | + } |
2039 | + PropertyChanges { |
2040 | + target: d |
2041 | + combinedOffset: rowOffset + alignmentAdjustment - scrollOffset |
2042 | + restoreEntryValues: false |
2043 | + } |
2044 | + } |
2045 | + ] |
2046 | + |
2047 | + transitions: [ |
2048 | + Transition { |
2049 | + from: "expanded" |
2050 | + to: "minimized" |
2051 | + PropertyAction { |
2052 | + target: d |
2053 | + properties: "rowOffset, scrollOffset, alignmentAdjustment" |
2054 | + value: 0 |
2055 | + } |
2056 | + PropertyAnimation { |
2057 | + target: d |
2058 | + properties: "combinedOffset" |
2059 | + duration: UbuntuAnimation.SnapDuration |
2060 | + easing: UbuntuAnimation.StandardEasing |
2061 | + } |
2062 | + } |
2063 | + ] |
2064 | +} |
2065 | |
2066 | === added file 'qml/Panel/IndicatorsMenu.qml' |
2067 | --- qml/Panel/IndicatorsMenu.qml 1970-01-01 00:00:00 +0000 |
2068 | +++ qml/Panel/IndicatorsMenu.qml 2014-10-21 21:16:05 +0000 |
2069 | @@ -0,0 +1,318 @@ |
2070 | +/* |
2071 | + * Copyright (C) 2014 Canonical, Ltd. |
2072 | + * |
2073 | + * This program is free software; you can redistribute it and/or modify |
2074 | + * it under the terms of the GNU General Public License as published by |
2075 | + * the Free Software Foundation; version 3. |
2076 | + * |
2077 | + * This program is distributed in the hope that it will be useful, |
2078 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2079 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2080 | + * GNU General Public License for more details. |
2081 | + * |
2082 | + * You should have received a copy of the GNU General Public License |
2083 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2084 | + */ |
2085 | + |
2086 | +import QtQuick 2.2 |
2087 | +import Ubuntu.Components 1.1 |
2088 | +import Ubuntu.Gestures 0.1 |
2089 | +import "../Components" |
2090 | + |
2091 | +Showable { |
2092 | + id: root |
2093 | + property alias indicatorsModel: bar.indicatorsModel |
2094 | + property alias showDragHandle: __showDragHandle |
2095 | + property alias hideDragHandle: __hideDragHandle |
2096 | + property alias overFlowWidth: bar.overFlowWidth |
2097 | + property alias verticalVelocityThreshold: yVelocityCalculator.velocityThreshold |
2098 | + property int minimizedPanelHeight: units.gu(3) |
2099 | + property int expandedPanelHeight: units.gu(7) |
2100 | + property real openedHeight: units.gu(71) |
2101 | + readonly property real unitProgress: Math.max(0, (height - minimizedPanelHeight) / (openedHeight - minimizedPanelHeight)) |
2102 | + readonly property bool fullyOpened: unitProgress >= 1 |
2103 | + readonly property bool partiallyOpened: unitProgress > 0 && unitProgress < 1.0 |
2104 | + readonly property bool fullyClosed: unitProgress == 0 |
2105 | + property bool enableHint: true |
2106 | + property bool contentEnabled: true |
2107 | + property color panelColor: "black" |
2108 | + |
2109 | + signal showTapped(point position) |
2110 | + |
2111 | + // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to |
2112 | + // use its own values. Need to ask design about this. |
2113 | + showAnimation: StandardAnimation { |
2114 | + property: "height" |
2115 | + to: openedHeight |
2116 | + duration: UbuntuAnimation.BriskDuration |
2117 | + easing.type: Easing.OutCubic |
2118 | + } |
2119 | + |
2120 | + hideAnimation: StandardAnimation { |
2121 | + property: "height" |
2122 | + to: minimizedPanelHeight |
2123 | + duration: UbuntuAnimation.BriskDuration |
2124 | + easing.type: Easing.OutCubic |
2125 | + } |
2126 | + |
2127 | + height: minimizedPanelHeight |
2128 | + |
2129 | + onUnitProgressChanged: d.updateState() |
2130 | + clip: root.partiallyOpened |
2131 | + |
2132 | + // eater |
2133 | + MouseArea { |
2134 | + anchors.fill: parent |
2135 | + } |
2136 | + |
2137 | + MenuContent { |
2138 | + id: content |
2139 | + objectName: "menuContent" |
2140 | + |
2141 | + anchors { |
2142 | + left: parent.left |
2143 | + right: parent.right |
2144 | + top: bar.bottom |
2145 | + } |
2146 | + height: openedHeight - bar.height - handle.height |
2147 | + indicatorsModel: root.indicatorsModel |
2148 | + visible: root.unitProgress > 0 |
2149 | + enabled: contentEnabled |
2150 | + currentMenuIndex: bar.currentItemIndex |
2151 | + } |
2152 | + |
2153 | + Handle { |
2154 | + id: handle |
2155 | + anchors { |
2156 | + left: parent.left |
2157 | + right: parent.right |
2158 | + bottom: parent.bottom |
2159 | + } |
2160 | + height: units.gu(2) |
2161 | + active: d.activeDragHandle ? true : false |
2162 | + |
2163 | + //small shadow gradient at bottom of menu |
2164 | + Rectangle { |
2165 | + anchors { |
2166 | + left: parent.left |
2167 | + right: parent.right |
2168 | + bottom: parent.top |
2169 | + } |
2170 | + height: units.gu(0.5) |
2171 | + gradient: Gradient { |
2172 | + GradientStop { position: 0.0; color: "transparent" } |
2173 | + GradientStop { position: 1.0; color: "black" } |
2174 | + } |
2175 | + opacity: 0.3 |
2176 | + } |
2177 | + } |
2178 | + |
2179 | + Rectangle { |
2180 | + anchors.fill: bar |
2181 | + color: panelColor |
2182 | + } |
2183 | + |
2184 | + IndicatorsBar { |
2185 | + id: bar |
2186 | + objectName: "indicatorsBar" |
2187 | + |
2188 | + anchors { |
2189 | + left: parent.left |
2190 | + right: parent.right |
2191 | + } |
2192 | + expanded: false |
2193 | + enableLateralChanges: false |
2194 | + lateralPosition: -1 |
2195 | + unitProgress: root.unitProgress |
2196 | + |
2197 | + height: expanded ? expandedPanelHeight : minimizedPanelHeight |
2198 | + Behavior on height { NumberAnimation { duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing } } |
2199 | + } |
2200 | + |
2201 | + ScrollCalculator { |
2202 | + id: leftScroller |
2203 | + width: units.gu(5) |
2204 | + anchors.left: bar.left |
2205 | + height: bar.height |
2206 | + |
2207 | + forceScrollingPercentage: 0.33 |
2208 | + stopScrollThreshold: units.gu(0.75) |
2209 | + direction: Qt.RightToLeft |
2210 | + lateralPosition: -1 |
2211 | + |
2212 | + onScroll: bar.addScrollOffset(-scrollAmount); |
2213 | + } |
2214 | + |
2215 | + ScrollCalculator { |
2216 | + id: rightScroller |
2217 | + width: units.gu(5) |
2218 | + anchors.right: bar.right |
2219 | + height: bar.height |
2220 | + |
2221 | + forceScrollingPercentage: 0.33 |
2222 | + stopScrollThreshold: units.gu(0.75) |
2223 | + direction: Qt.LeftToRight |
2224 | + lateralPosition: -1 |
2225 | + |
2226 | + onScroll: bar.addScrollOffset(scrollAmount); |
2227 | + } |
2228 | + |
2229 | + DragHandle { |
2230 | + id: __showDragHandle |
2231 | + anchors.bottom: parent.bottom |
2232 | + anchors.left: parent.left |
2233 | + anchors.right: parent.right |
2234 | + height: minimizedPanelHeight |
2235 | + direction: Direction.Downwards |
2236 | + enabled: !root.shown && root.available |
2237 | + autoCompleteDragThreshold: maxTotalDragDistance / 2 |
2238 | + stretch: true |
2239 | + distanceThreshold: minimizedPanelHeight |
2240 | + onTapped: showTapped(Qt.point(touchSceneX, touchSceneY)); |
2241 | + |
2242 | + // using hint regulates minimum to hint displacement, but in fullscreen mode, we need to do it manually. |
2243 | + overrideStartValue: enableHint ? minimizedPanelHeight : expandedPanelHeight + handle.height |
2244 | + maxTotalDragDistance: openedHeight - (enableHint ? minimizedPanelHeight : expandedPanelHeight + handle.height) |
2245 | + hintDisplacement: enableHint ? expandedPanelHeight - minimizedPanelHeight + handle.height : 0 |
2246 | + } |
2247 | + |
2248 | + DragHandle { |
2249 | + id: __hideDragHandle |
2250 | + anchors.fill: handle |
2251 | + direction: Direction.Upwards |
2252 | + enabled: root.shown && root.available |
2253 | + hintDisplacement: units.gu(3) |
2254 | + autoCompleteDragThreshold: maxTotalDragDistance / 6 |
2255 | + stretch: true |
2256 | + maxTotalDragDistance: openedHeight - expandedPanelHeight - handle.height |
2257 | + distanceThreshold: 0 |
2258 | + |
2259 | + onTouchSceneXChanged: { |
2260 | + if (root.state === "locked") { |
2261 | + d.xDisplacementSinceLock += (touchSceneX - d.lastHideTouchSceneX) |
2262 | + d.lastHideTouchSceneX = touchSceneX; |
2263 | + } |
2264 | + } |
2265 | + } |
2266 | + |
2267 | + PanelVelocityCalculator { |
2268 | + id: yVelocityCalculator |
2269 | + velocityThreshold: d.hasCommitted ? 0.1 : 0.3 |
2270 | + trackedValue: d.activeDragHandle ? d.activeDragHandle.touchSceneY : 0 |
2271 | + |
2272 | + onVelocityAboveThresholdChanged: d.updateState() |
2273 | + } |
2274 | + |
2275 | + Connections { |
2276 | + target: showAnimation |
2277 | + onRunningChanged: { |
2278 | + if (showAnimation.running) { |
2279 | + root.state = "commit"; |
2280 | + } |
2281 | + } |
2282 | + } |
2283 | + |
2284 | + Connections { |
2285 | + target: hideAnimation |
2286 | + onRunningChanged: { |
2287 | + if (hideAnimation.running) { |
2288 | + root.state = "initial"; |
2289 | + } |
2290 | + } |
2291 | + } |
2292 | + |
2293 | + QtObject { |
2294 | + id: d |
2295 | + property var activeDragHandle: showDragHandle.dragging ? showDragHandle : hideDragHandle.dragging ? hideDragHandle : null |
2296 | + property bool hasCommitted: false |
2297 | + property real lastHideTouchSceneX: 0 |
2298 | + property real xDisplacementSinceLock: 0 |
2299 | + onXDisplacementSinceLockChanged: d.updateState() |
2300 | + |
2301 | + property real rowMappedLateralPosition: { |
2302 | + if (!d.activeDragHandle) return -1; |
2303 | + return d.activeDragHandle.mapToItem(bar, d.activeDragHandle.touchX, 0).x; |
2304 | + } |
2305 | + |
2306 | + function updateState() { |
2307 | + if (!showAnimation.running && !hideAnimation.running) { |
2308 | + if (unitProgress <= 0) { |
2309 | + root.state = "initial"; |
2310 | + // lock indicator if we've been committed and aren't moving too much laterally or too fast up. |
2311 | + } else if (d.hasCommitted && (Math.abs(d.xDisplacementSinceLock) < units.gu(2) || yVelocityCalculator.velocityAboveThreshold)) { |
2312 | + root.state = "locked"; |
2313 | + } else { |
2314 | + root.state = "reveal"; |
2315 | + } |
2316 | + } |
2317 | + } |
2318 | + } |
2319 | + |
2320 | + states: [ |
2321 | + State { |
2322 | + name: "initial" |
2323 | + PropertyChanges { target: d; hasCommitted: false; restoreEntryValues: false } |
2324 | + }, |
2325 | + State { |
2326 | + name: "reveal" |
2327 | + StateChangeScript { |
2328 | + script: { |
2329 | + yVelocityCalculator.reset(); |
2330 | + // initial item selection |
2331 | + if (!d.hasCommitted) bar.selectItemAt(d.activeDragHandle ? d.activeDragHandle.touchX : -1); |
2332 | + d.hasCommitted = false; |
2333 | + } |
2334 | + } |
2335 | + PropertyChanges { |
2336 | + target: bar |
2337 | + expanded: true |
2338 | + // changes to lateral touch position effect which indicator is selected |
2339 | + lateralPosition: d.rowMappedLateralPosition |
2340 | + // vertical velocity determines if changes in lateral position has an effect |
2341 | + enableLateralChanges: d.activeDragHandle && |
2342 | + !yVelocityCalculator.velocityAboveThreshold |
2343 | + } |
2344 | + // left scroll bar handling |
2345 | + PropertyChanges { |
2346 | + target: leftScroller |
2347 | + lateralPosition: { |
2348 | + if (!d.activeDragHandle) return -1; |
2349 | + var mapped = d.activeDragHandle.mapToItem(leftScroller, d.activeDragHandle.touchX, 0); |
2350 | + return mapped.x; |
2351 | + } |
2352 | + } |
2353 | + // right scroll bar handling |
2354 | + PropertyChanges { |
2355 | + target: rightScroller |
2356 | + lateralPosition: { |
2357 | + if (!d.activeDragHandle) return -1; |
2358 | + var mapped = d.activeDragHandle.mapToItem(rightScroller, d.activeDragHandle.touchX, 0); |
2359 | + return mapped.x; |
2360 | + } |
2361 | + } |
2362 | + }, |
2363 | + State { |
2364 | + name: "locked" |
2365 | + StateChangeScript { |
2366 | + script: { |
2367 | + d.xDisplacementSinceLock = 0; |
2368 | + d.lastHideTouchSceneX = hideDragHandle.touchSceneX; |
2369 | + } |
2370 | + } |
2371 | + PropertyChanges { target: bar; expanded: true } |
2372 | + }, |
2373 | + State { |
2374 | + name: "commit" |
2375 | + extend: "locked" |
2376 | + PropertyChanges { target: bar; interactive: true } |
2377 | + PropertyChanges { |
2378 | + target: d; |
2379 | + hasCommitted: true |
2380 | + lastHideTouchSceneX: 0 |
2381 | + xDisplacementSinceLock: 0 |
2382 | + restoreEntryValues: false |
2383 | + } |
2384 | + } |
2385 | + ] |
2386 | + state: "initial" |
2387 | +} |
2388 | |
2389 | === modified file 'qml/Panel/MenuContent.qml' |
2390 | --- qml/Panel/MenuContent.qml 2014-10-10 11:13:26 +0000 |
2391 | +++ qml/Panel/MenuContent.qml 2014-10-21 21:16:05 +0000 |
2392 | @@ -1,5 +1,5 @@ |
2393 | /* |
2394 | - * Copyright (C) 2013 Canonical, Ltd. |
2395 | + * Copyright (C) 2013-2014 Canonical, Ltd. |
2396 | * |
2397 | * This program is free software; you can redistribute it and/or modify |
2398 | * it under the terms of the GNU General Public License as published by |
2399 | @@ -14,126 +14,69 @@ |
2400 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2401 | */ |
2402 | |
2403 | -import QtQuick 2.0 |
2404 | +import QtQuick 2.2 |
2405 | import QtQuick.Layouts 1.1 |
2406 | import Ubuntu.Components 1.1 |
2407 | import Unity.Indicators 0.1 as Indicators |
2408 | import Utils 0.1 |
2409 | import "../Components" |
2410 | import "../Components/Flickables" as Flickables |
2411 | -import "Indicators" |
2412 | |
2413 | Rectangle { |
2414 | id: content |
2415 | |
2416 | property QtObject indicatorsModel: null |
2417 | - readonly property alias currentMenuIndex: listViewHeader.currentIndex |
2418 | + property int currentMenuIndex: -1 |
2419 | color: "#221e1c" // FIXME not in palette yet |
2420 | - property real headerHeight: listViewHeader.height |
2421 | |
2422 | width: units.gu(40) |
2423 | height: units.gu(42) |
2424 | |
2425 | - function setCurrentMenuIndex(index, animate) { |
2426 | - // FIXME - https://bugreports.qt-project.org/browse/QTBUG-41229 |
2427 | - listViewHeader.currentIndex = -1; |
2428 | - listViewHeader.currentIndex = index; |
2429 | - } |
2430 | - |
2431 | - Flickables.ListView { |
2432 | - id: listViewHeader |
2433 | - objectName: "indicatorsHeaderListView" |
2434 | - model: content.indicatorsModel |
2435 | - clip: true |
2436 | - |
2437 | - anchors { |
2438 | - left: parent.left |
2439 | - right: parent.right |
2440 | - } |
2441 | - height: units.gu(8.5) |
2442 | - |
2443 | - highlightFollowsCurrentItem: true |
2444 | - highlightMoveDuration: 0 |
2445 | - |
2446 | - orientation: ListView.Horizontal |
2447 | - snapMode: ListView.SnapOneItem |
2448 | - highlightRangeMode: ListView.StrictlyEnforceRange |
2449 | - boundsBehavior: Flickable.StopAtBounds |
2450 | - // Load all the indicator menus (a big number) |
2451 | - cacheBuffer: 1073741823 |
2452 | - |
2453 | - delegate: Header { |
2454 | - width: ListView.view.width |
2455 | - height: implicitHeight |
2456 | - |
2457 | - title: indicatorDelegate.title !== "" ? indicatorDelegate.title : identifier |
2458 | - |
2459 | - IndicatorDelegate { |
2460 | - id: indicatorDelegate |
2461 | - Component.onCompleted: { |
2462 | - for(var pName in indicatorProperties) { |
2463 | - if (indicatorDelegate.hasOwnProperty(pName)) { |
2464 | - indicatorDelegate[pName] = indicatorProperties[pName]; |
2465 | - } |
2466 | - } |
2467 | - } |
2468 | - } |
2469 | - } |
2470 | + onCurrentMenuIndexChanged: { |
2471 | + listViewContent.currentIndex = currentMenuIndex; |
2472 | } |
2473 | |
2474 | Flickables.ListView { |
2475 | id: listViewContent |
2476 | objectName: "indicatorsContentListView" |
2477 | - anchors { |
2478 | - left: parent.left |
2479 | - right: parent.right |
2480 | - top: listViewHeader.bottom |
2481 | - bottom: parent.bottom |
2482 | - } |
2483 | + anchors.fill: parent |
2484 | model: content.indicatorsModel |
2485 | - clip: true |
2486 | |
2487 | - currentIndex: listViewHeader.currentIndex |
2488 | + highlightFollowsCurrentItem: true |
2489 | interactive: false |
2490 | highlightMoveDuration: 0 |
2491 | orientation: ListView.Horizontal |
2492 | // Load all the indicator menus (a big number) |
2493 | cacheBuffer: 1073741823 |
2494 | |
2495 | + // for additions/removals. |
2496 | + onCountChanged: { |
2497 | + listViewContent.currentIndex = content.currentMenuIndex; |
2498 | + } |
2499 | + |
2500 | delegate: Loader { |
2501 | id: loader |
2502 | + |
2503 | width: ListView.view.width |
2504 | height: ListView.view.height |
2505 | objectName: identifier |
2506 | - |
2507 | - source: pageSource |
2508 | asynchronous: true |
2509 | + visible: ListView.isCurrentItem |
2510 | + |
2511 | + sourceComponent: IndicatorPage { |
2512 | + objectName: identifier + "-page" |
2513 | + |
2514 | + identifier: model.identifier |
2515 | + busName: indicatorProperties.busName |
2516 | + actionsObjectPath: indicatorProperties.actionsObjectPath |
2517 | + menuObjectPath: indicatorProperties.menuObjectPath |
2518 | + } |
2519 | |
2520 | onVisibleChanged: { |
2521 | // Reset the indicator states |
2522 | - if (!visible && item && item["reset"]) { |
2523 | - item.reset() |
2524 | - } |
2525 | - } |
2526 | - |
2527 | - onLoaded: { |
2528 | - for(var pName in indicatorProperties) { |
2529 | - if (item.hasOwnProperty(pName)) { |
2530 | - item[pName] = indicatorProperties[pName] |
2531 | - } |
2532 | - } |
2533 | - } |
2534 | - |
2535 | - Binding { |
2536 | - target: loader.item |
2537 | - property: "identifier" |
2538 | - value: identifier |
2539 | - } |
2540 | - |
2541 | - Binding { |
2542 | - target: loader.item |
2543 | - property: "objectName" |
2544 | - value: identifier + "-page" |
2545 | + if (!visible && status == Loader.Ready) { |
2546 | + item.reset(); |
2547 | + } |
2548 | } |
2549 | } |
2550 | } |
2551 | |
2552 | === removed file 'qml/Panel/Panel.qml' |
2553 | --- qml/Panel/Panel.qml 2014-07-10 13:36:41 +0000 |
2554 | +++ qml/Panel/Panel.qml 1970-01-01 00:00:00 +0000 |
2555 | @@ -1,191 +0,0 @@ |
2556 | -/* |
2557 | - * Copyright (C) 2013 Canonical, Ltd. |
2558 | - * |
2559 | - * This program is free software; you can redistribute it and/or modify |
2560 | - * it under the terms of the GNU General Public License as published by |
2561 | - * the Free Software Foundation; version 3. |
2562 | - * |
2563 | - * This program is distributed in the hope that it will be useful, |
2564 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2565 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2566 | - * GNU General Public License for more details. |
2567 | - * |
2568 | - * You should have received a copy of the GNU General Public License |
2569 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2570 | - */ |
2571 | - |
2572 | -import QtQuick 2.0 |
2573 | -import Ubuntu.Components 0.1 |
2574 | -import Unity.Application 0.1 |
2575 | -import "../Components" |
2576 | -import "../Components/ListItems" |
2577 | - |
2578 | -Item { |
2579 | - id: root |
2580 | - readonly property real panelHeight: indicatorArea.y + d.indicatorHeight |
2581 | - property alias indicators: __indicators |
2582 | - property alias callHint: __callHint |
2583 | - property bool fullscreenMode: false |
2584 | - |
2585 | - Rectangle { |
2586 | - id: darkenedArea |
2587 | - property real darkenedOpacity: 0.6 |
2588 | - anchors { |
2589 | - top: parent.top |
2590 | - topMargin: panelHeight |
2591 | - left: parent.left |
2592 | - right: parent.right |
2593 | - bottom: parent.bottom |
2594 | - } |
2595 | - color: "black" |
2596 | - opacity: indicators.unitProgress * darkenedOpacity |
2597 | - |
2598 | - MouseArea { |
2599 | - anchors.fill: parent |
2600 | - enabled: indicators.shown |
2601 | - onClicked: if (indicators.fullyOpened) indicators.hide(); |
2602 | - } |
2603 | - } |
2604 | - |
2605 | - Item { |
2606 | - id: indicatorArea |
2607 | - objectName: "indicatorArea" |
2608 | - |
2609 | - anchors.fill: parent |
2610 | - |
2611 | - Behavior on anchors.topMargin { StandardAnimation {} } |
2612 | - |
2613 | - BorderImage { |
2614 | - id: dropShadow |
2615 | - anchors { |
2616 | - fill: indicators |
2617 | - leftMargin: -units.gu(1) |
2618 | - bottomMargin: -units.gu(1) |
2619 | - } |
2620 | - visible: indicators.height > indicators.panelHeight |
2621 | - source: "graphics/rectangular_dropshadow.sci" |
2622 | - } |
2623 | - |
2624 | - VerticalThinDivider { |
2625 | - id: indicatorDividor |
2626 | - anchors { |
2627 | - top: indicators.top |
2628 | - bottom: indicators.bottom |
2629 | - right: indicators.left |
2630 | - |
2631 | - topMargin: indicatorArea.anchors.topMargin + indicators.panelHeight |
2632 | - } |
2633 | - |
2634 | - width: units.dp(2) |
2635 | - source: "graphics/VerticalDivider.png" |
2636 | - } |
2637 | - |
2638 | - Rectangle { |
2639 | - id: indicatorAreaBackground |
2640 | - color: callHint.visible ? "green" : "black" |
2641 | - anchors { |
2642 | - top: parent.top |
2643 | - left: parent.left |
2644 | - right: parent.right |
2645 | - } |
2646 | - height: indicators.panelHeight |
2647 | - |
2648 | - Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration } } |
2649 | - } |
2650 | - |
2651 | - PanelSeparatorLine { |
2652 | - id: nonIndicatorAreaSeparatorLine |
2653 | - anchors { |
2654 | - top: indicatorAreaBackground.bottom |
2655 | - left: parent.left |
2656 | - right: indicators.left |
2657 | - } |
2658 | - saturation: 1 - indicators.unitProgress |
2659 | - } |
2660 | - |
2661 | - MouseArea { |
2662 | - anchors { |
2663 | - top: parent.top |
2664 | - left: parent.left |
2665 | - right: indicators.left |
2666 | - } |
2667 | - height: indicators.panelHeight |
2668 | - enabled: callHint.visible |
2669 | - onClicked: callHint.showLiveCall() |
2670 | - } |
2671 | - |
2672 | - Indicators { |
2673 | - id: __indicators |
2674 | - objectName: "indicators" |
2675 | - |
2676 | - anchors { |
2677 | - top: parent.top |
2678 | - right: parent.right |
2679 | - } |
2680 | - |
2681 | - width: root.width |
2682 | - shown: false |
2683 | - panelHeight: units.gu(3) |
2684 | - openedHeight: root.height |
2685 | - overFlowWidth: { |
2686 | - if (callHint.visible) { |
2687 | - return Math.max(root.width - (callHint.width + units.gu(2)), 0) |
2688 | - } |
2689 | - return root.width |
2690 | - } |
2691 | - |
2692 | - enableHint: !callHint.active && !fullscreenMode |
2693 | - showHintBottomMargin: fullscreenMode ? -panelHeight : 0 |
2694 | - |
2695 | - onShowTapped: { |
2696 | - if (callHint.active) { |
2697 | - callHint.showLiveCall(); |
2698 | - } |
2699 | - } |
2700 | - } |
2701 | - |
2702 | - ActiveCallHint { |
2703 | - id: __callHint |
2704 | - anchors { |
2705 | - top: parent.top |
2706 | - left: parent.left |
2707 | - } |
2708 | - height: indicators.panelHeight |
2709 | - visible: active && indicators.state == "initial" |
2710 | - } |
2711 | - |
2712 | - PanelSeparatorLine { |
2713 | - id: indicatorsSeparatorLine |
2714 | - visible: true |
2715 | - anchors { |
2716 | - top: indicators.bottom |
2717 | - left: indicatorDividor.left |
2718 | - right: indicators.right |
2719 | - } |
2720 | - } |
2721 | - } |
2722 | - |
2723 | - QtObject { |
2724 | - id: d |
2725 | - readonly property real indicatorHeight: indicators.panelHeight + indicatorsSeparatorLine.height |
2726 | - } |
2727 | - |
2728 | - states: [ |
2729 | - State { |
2730 | - name: "onscreen" //fully opaque and visible at top edge of screen |
2731 | - when: !fullscreenMode |
2732 | - PropertyChanges { |
2733 | - target: indicatorArea; |
2734 | - anchors.topMargin: 0 |
2735 | - } |
2736 | - }, |
2737 | - State { |
2738 | - name: "offscreen" //pushed off screen |
2739 | - when: fullscreenMode |
2740 | - PropertyChanges { |
2741 | - target: indicatorArea; |
2742 | - anchors.topMargin: indicators.state === "initial" ? -d.indicatorHeight : 0 |
2743 | - } |
2744 | - } |
2745 | - ] |
2746 | -} |
2747 | |
2748 | === added file 'qml/Panel/PanelVelocityCalculator.qml' |
2749 | --- qml/Panel/PanelVelocityCalculator.qml 1970-01-01 00:00:00 +0000 |
2750 | +++ qml/Panel/PanelVelocityCalculator.qml 2014-10-21 21:16:05 +0000 |
2751 | @@ -0,0 +1,54 @@ |
2752 | +/* |
2753 | + * Copyright (C) 2014 Canonical, Ltd. |
2754 | + * |
2755 | + * This program is free software; you can redistribute it and/or modify |
2756 | + * it under the terms of the GNU General Public License as published by |
2757 | + * the Free Software Foundation; version 3. |
2758 | + * |
2759 | + * This program is distributed in the hope that it will be useful, |
2760 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2761 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2762 | + * GNU General Public License for more details. |
2763 | + * |
2764 | + * You should have received a copy of the GNU General Public License |
2765 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2766 | + */ |
2767 | + |
2768 | +import QtQuick 2.2 |
2769 | +import Ubuntu.Gestures 0.1 |
2770 | + |
2771 | +Item { |
2772 | + id: root |
2773 | + property real trackedValue: 0 |
2774 | + property bool velocityAboveThreshold: false |
2775 | + property real velocityThreshold: 0.4 |
2776 | + |
2777 | + function reset() { |
2778 | + velocityTimer.stop(); |
2779 | + velocityAboveThreshold = false; |
2780 | + calc.reset(); |
2781 | + } |
2782 | + |
2783 | + function update() { |
2784 | + calc.trackedPosition = trackedValue; |
2785 | + velocityAboveThreshold = Math.abs(calc.calculate()) > velocityThreshold; |
2786 | + |
2787 | + if (velocityAboveThreshold) { // only start timer if we're above the threshold. |
2788 | + velocityTimer.start(); |
2789 | + } else { |
2790 | + velocityTimer.stop(); |
2791 | + } |
2792 | + } |
2793 | + |
2794 | + onTrackedValueChanged: update(); |
2795 | + |
2796 | + AxisVelocityCalculator { |
2797 | + id: calc |
2798 | + } |
2799 | + |
2800 | + Timer { |
2801 | + id: velocityTimer |
2802 | + interval: 50 |
2803 | + onTriggered: update(); |
2804 | + } |
2805 | +} |
2806 | |
2807 | === modified file 'qml/Shell.qml' |
2808 | --- qml/Shell.qml 2014-10-13 15:41:29 +0000 |
2809 | +++ qml/Shell.qml 2014-10-21 21:16:05 +0000 |
2810 | @@ -36,6 +36,7 @@ |
2811 | import "Components" |
2812 | import "Notifications" |
2813 | import "Stages" |
2814 | +import "Panel/Indicators" |
2815 | import Unity.Notifications 1.0 as NotificationBackend |
2816 | import Unity.Session 0.1 |
2817 | import Unity.DashCommunicator 0.1 |
2818 | @@ -243,7 +244,7 @@ |
2819 | target: applicationsDisplayLoader.item |
2820 | property: "maximizedAppTopMargin" |
2821 | // Not just using panel.panelHeight as that changes depending on the focused app. |
2822 | - value: panel.indicators.panelHeight |
2823 | + value: panel.indicators.minimizedPanelHeight + units.dp(2) // dp(2) for orange line |
2824 | } |
2825 | Binding { |
2826 | target: applicationsDisplayLoader.item |
2827 | @@ -646,7 +647,17 @@ |
2828 | available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && !greeter.hasLockedApp |
2829 | contentEnabled: edgeDemo.panelContentEnabled |
2830 | width: parent.width > units.gu(60) ? units.gu(40) : parent.width |
2831 | - panelHeight: units.gu(3) |
2832 | + |
2833 | + minimizedPanelHeight: units.gu(3) |
2834 | + expandedPanelHeight: units.gu(7) |
2835 | + |
2836 | + indicatorsModel: visibleIndicators.model |
2837 | + } |
2838 | + |
2839 | + VisibleIndicators { |
2840 | + id: visibleIndicators |
2841 | + // TODO: This should be sourced by device type (eg "desktop", "tablet", "phone"...) |
2842 | + Component.onCompleted: initialise(indicatorProfile) |
2843 | } |
2844 | |
2845 | property bool topmostApplicationIsFullscreen: |
2846 | @@ -709,9 +720,9 @@ |
2847 | model: NotificationBackend.Model |
2848 | margin: units.gu(1) |
2849 | |
2850 | - y: panel.panelHeight |
2851 | + y: topmostIsFullscreen ? 0 : panel.panelHeight |
2852 | width: parent.width |
2853 | - height: parent.height - panel.panelHeight |
2854 | + height: parent.height - (topmostIsFullscreen ? 0 : panel.panelHeight) |
2855 | |
2856 | states: [ |
2857 | State { |
2858 | @@ -763,7 +774,7 @@ |
2859 | paused: Powerd.status === Powerd.Off // Saves power |
2860 | greeter: greeter |
2861 | launcher: launcher |
2862 | - indicators: panel.indicators |
2863 | + panel: panel |
2864 | stages: stages |
2865 | } |
2866 | |
2867 | |
2868 | === modified file 'tests/autopilot/unity8/indicators/tests/test_indicators.py' |
2869 | --- tests/autopilot/unity8/indicators/tests/test_indicators.py 2014-10-09 13:57:46 +0000 |
2870 | +++ tests/autopilot/unity8/indicators/tests/test_indicators.py 2014-10-21 21:16:05 +0000 |
2871 | @@ -61,7 +61,7 @@ |
2872 | self.skipTest('Nexus 10 does not have bluetooth at the moment.') |
2873 | |
2874 | def test_indicator_exists(self): |
2875 | - self.main_window._get_indicator_widget( |
2876 | + self.main_window._get_indicator_panel_item( |
2877 | self.indicator_name |
2878 | ) |
2879 | |
2880 | |
2881 | === modified file 'tests/autopilot/unity8/shell/emulators/main_window.py' |
2882 | --- tests/autopilot/unity8/shell/emulators/main_window.py 2014-08-12 17:30:05 +0000 |
2883 | +++ tests/autopilot/unity8/shell/emulators/main_window.py 2014-10-21 21:16:05 +0000 |
2884 | @@ -75,15 +75,15 @@ |
2885 | def get_pinentryField(self): |
2886 | return self.select_single(objectName="pinentryField") |
2887 | |
2888 | - def _get_indicator_widget(self, indicator_name): |
2889 | + def _get_indicator_panel_item(self, indicator_name): |
2890 | return self.select_single( |
2891 | - 'DefaultIndicatorWidget', |
2892 | - objectName=indicator_name+'-widget' |
2893 | + 'IndicatorItem', |
2894 | + objectName=indicator_name+'-panelItem' |
2895 | ) |
2896 | |
2897 | def _get_indicator_page(self, indicator_name): |
2898 | return self.select_single( |
2899 | - 'DefaultIndicatorPage', |
2900 | + 'IndicatorPage', |
2901 | objectName=indicator_name+'-page' |
2902 | ) |
2903 | |
2904 | @@ -93,12 +93,12 @@ |
2905 | |
2906 | :returns: The indicator page. |
2907 | """ |
2908 | - widget = self._get_indicator_widget(indicator_name) |
2909 | + widget = self._get_indicator_panel_item(indicator_name) |
2910 | start_x, start_y = input.get_center_point(widget) |
2911 | end_x = start_x |
2912 | end_y = self.height |
2913 | self.pointing_device.drag(start_x, start_y, end_x, end_y) |
2914 | - self.wait_select_single('Indicators', fullyOpened=True) |
2915 | + self.wait_select_single('IndicatorsMenu', fullyOpened=True) |
2916 | return self._get_indicator_page(indicator_name) |
2917 | |
2918 | @autopilot_logging.log_action(logger.info) |
2919 | |
2920 | === modified file 'tests/mocks/Unity/Indicators/Indicators.qmltypes' |
2921 | --- tests/mocks/Unity/Indicators/Indicators.qmltypes 2014-10-21 21:16:04 +0000 |
2922 | +++ tests/mocks/Unity/Indicators/Indicators.qmltypes 2014-10-21 21:16:05 +0000 |
2923 | @@ -105,10 +105,8 @@ |
2924 | values: { |
2925 | "Identifier": 0, |
2926 | "Position": 1, |
2927 | - "WidgetSource": 2, |
2928 | - "PageSource": 3, |
2929 | - "IndicatorProperties": 4, |
2930 | - "IsVisible": 5 |
2931 | + "IndicatorProperties": 2, |
2932 | + "IsVisible": 3 |
2933 | } |
2934 | } |
2935 | } |
2936 | |
2937 | === modified file 'tests/mocks/Unity/Indicators/IndicatorsModel.qml' |
2938 | --- tests/mocks/Unity/Indicators/IndicatorsModel.qml 2014-10-21 21:16:04 +0000 |
2939 | +++ tests/mocks/Unity/Indicators/IndicatorsModel.qml 2014-10-21 21:16:05 +0000 |
2940 | @@ -20,42 +20,97 @@ |
2941 | Indicators.FakeIndicatorsModel { |
2942 | id: root |
2943 | |
2944 | - Component.onCompleted: { |
2945 | - Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake1", |
2946 | - "/com/canonical/indicators/fake1", |
2947 | - "/com/canonical/indicators/fake1", |
2948 | + property var originalModelData: [ |
2949 | + { |
2950 | + "identifier": "fake-indicator-bluetooth", |
2951 | + "indicatorProperties": { |
2952 | + "enabled": true, |
2953 | + "busName": "com.canonical.indicators.fake1", |
2954 | + "menuObjectPath": "/com/canonical/indicators/fake1", |
2955 | + "actionsObjectPath": "/com/canonical/indicators/fake1" |
2956 | + } |
2957 | + }, |
2958 | + { |
2959 | + "identifier": "fake-indicator-network", |
2960 | + "indicatorProperties": { |
2961 | + "enabled": true, |
2962 | + "busName": "com.canonical.indicators.fake2", |
2963 | + "menuObjectPath": "/com/canonical/indicators/fake2", |
2964 | + "actionsObjectPath": "/com/canonical/indicators/fake2" |
2965 | + } |
2966 | + }, |
2967 | + { |
2968 | + "identifier": "fake-indicator-messages", |
2969 | + "indicatorProperties": { |
2970 | + "enabled": true, |
2971 | + "busName": "com.canonical.indicators.fake3", |
2972 | + "menuObjectPath": "/com/canonical/indicators/fake3", |
2973 | + "actionsObjectPath": "/com/canonical/indicators/fake3" |
2974 | + } |
2975 | + }, |
2976 | + { |
2977 | + "identifier": "fake-indicator-sound", |
2978 | + "indicatorProperties": { |
2979 | + "enabled": true, |
2980 | + "busName": "com.canonical.indicators.fake4", |
2981 | + "menuObjectPath": "/com/canonical/indicators/fake4", |
2982 | + "actionsObjectPath": "/com/canonical/indicators/fake4" |
2983 | + } |
2984 | + }, |
2985 | + { |
2986 | + "identifier": "fake-indicator-power", |
2987 | + "indicatorProperties": { |
2988 | + "enabled": true, |
2989 | + "busName": "com.canonical.indicators.fake5", |
2990 | + "menuObjectPath": "/com/canonical/indicators/fake5", |
2991 | + "actionsObjectPath": "/com/canonical/indicators/fake5" |
2992 | + } |
2993 | + }, |
2994 | + { |
2995 | + "identifier": "fake-indicator-datetime", |
2996 | + "indicatorProperties": { |
2997 | + "enabled": true, |
2998 | + "busName": "com.canonical.indicators.fake6", |
2999 | + "menuObjectPath": "/com/canonical/indicators/fake6", |
3000 | + "actionsObjectPath": "/com/canonical/indicators/fake6" |
3001 | + } |
3002 | + } |
3003 | + ] |
3004 | + |
3005 | + function load(profile) { |
3006 | + unload(); |
3007 | + root.modelData = originalModelData; |
3008 | + |
3009 | + Indicators.UnityMenuModelCache.setCachedModelData("/com/canonical/indicators/fake1", |
3010 | getUnityMenuModelData("fake-indicator-bluetooth", |
3011 | "Bluetooth (F)", |
3012 | "", |
3013 | [ "image://theme/bluetooth-active" ])); |
3014 | - Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake2", |
3015 | - "/com/canonical/indicators/fake2", |
3016 | - "/com/canonical/indicators/fake2", |
3017 | + Indicators.UnityMenuModelCache.setCachedModelData("/com/canonical/indicators/fake2", |
3018 | getUnityMenuModelData("fake-indicator-network", |
3019 | "Network (F)", |
3020 | "", |
3021 | [ "image://theme/simcard-error", "image://theme/wifi-high" ])); |
3022 | - Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake3", |
3023 | - "/com/canonical/indicators/fake3", |
3024 | - "/com/canonical/indicators/fake3", |
3025 | - getUnityMenuModelData("fake-indicator-sound", |
3026 | + Indicators.UnityMenuModelCache.setCachedModelData("/com/canonical/indicators/fake3", |
3027 | + getUnityMenuModelData("fake-indicator-messages", |
3028 | "Messages (F)", |
3029 | "", |
3030 | [ "image://theme/messages-new" ])); |
3031 | - Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake4", |
3032 | - "/com/canonical/indicators/fake4", |
3033 | - "/com/canonical/indicators/fake4", |
3034 | - getUnityMenuModelData("fake-indicator-power", |
3035 | + Indicators.UnityMenuModelCache.setCachedModelData("/com/canonical/indicators/fake4", |
3036 | + getUnityMenuModelData("fake-indicator-sound", |
3037 | "Sound (F)", |
3038 | "", |
3039 | [ "image://theme/audio-volume-high" ])); |
3040 | - Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake5", |
3041 | - "/com/canonical/indicators/fake5", |
3042 | - "/com/canonical/indicators/fake5", |
3043 | + Indicators.UnityMenuModelCache.setCachedModelData("/com/canonical/indicators/fake5", |
3044 | getUnityMenuModelData("fake-indicator-power", |
3045 | "Battery (F)", |
3046 | "", |
3047 | [ "image://theme/battery-020" ])); |
3048 | + Indicators.UnityMenuModelCache.setCachedModelData("/com/canonical/indicators/fake6", |
3049 | + getUnityMenuModelData("fake-indicator-datetime", |
3050 | + "Upcoming Events (F)", |
3051 | + "12:04", |
3052 | + [])); |
3053 | } |
3054 | |
3055 | function getUnityMenuModelData(identifier, title, label, icons) { |
3056 | @@ -71,11 +126,12 @@ |
3057 | "actionState": { |
3058 | "title": title, |
3059 | "label": label, |
3060 | - "icons": icons |
3061 | + "icons": icons, |
3062 | + "visible": true |
3063 | }, |
3064 | "isCheck": false, |
3065 | "isRadio": false, |
3066 | - "isToggled": false, |
3067 | + "isToggled": false |
3068 | }, |
3069 | "submenu": [] |
3070 | }]; |
3071 | @@ -94,7 +150,7 @@ |
3072 | "actionState": {}, |
3073 | "isCheck": false, |
3074 | "isRadio": false, |
3075 | - "isToggled": false, |
3076 | + "isToggled": false |
3077 | }}; |
3078 | submenus.push(submenu); |
3079 | } |
3080 | @@ -103,66 +159,20 @@ |
3081 | return root; |
3082 | } |
3083 | |
3084 | - property var originalModelData: [ |
3085 | - { |
3086 | - "identifier": "indicator-fake1", |
3087 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
3088 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
3089 | - "indicatorProperties": { |
3090 | - "enabled": true, |
3091 | - "busName": "com.canonical.indicators.fake1", |
3092 | - "menuObjectPath": "/com/canonical/indicators/fake1", |
3093 | - "actionsObjectPath": "/com/canonical/indicators/fake1" |
3094 | - } |
3095 | - }, |
3096 | - { |
3097 | - "identifier": "indicator-fake2", |
3098 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
3099 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
3100 | - "indicatorProperties": { |
3101 | - "enabled": true, |
3102 | - "busName": "com.canonical.indicators.fake2", |
3103 | - "menuObjectPath": "/com/canonical/indicators/fake2", |
3104 | - "actionsObjectPath": "/com/canonical/indicators/fake2" |
3105 | - } |
3106 | - }, |
3107 | - { |
3108 | - "identifier": "indicator-fake3", |
3109 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
3110 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
3111 | - "indicatorProperties": { |
3112 | - "enabled": true, |
3113 | - "busName": "com.canonical.indicators.fake3", |
3114 | - "menuObjectPath": "/com/canonical/indicators/fake3", |
3115 | - "actionsObjectPath": "/com/canonical/indicators/fake3" |
3116 | - } |
3117 | - }, |
3118 | - { |
3119 | - "identifier": "indicator-fake4", |
3120 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
3121 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
3122 | - "indicatorProperties": { |
3123 | - "enabled": true, |
3124 | - "busName": "com.canonical.indicators.fake4", |
3125 | - "menuObjectPath": "/com/canonical/indicators/fake4", |
3126 | - "actionsObjectPath": "/com/canonical/indicators/fake4" |
3127 | - } |
3128 | - }, |
3129 | - { |
3130 | - "identifier": "indicator-fake5", |
3131 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
3132 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
3133 | - "indicatorProperties": { |
3134 | - "enabled": true, |
3135 | - "busName": "com.canonical.indicators.fake5", |
3136 | - "menuObjectPath": "/com/canonical/indicators/fake5", |
3137 | - "actionsObjectPath": "/com/canonical/indicators/fake5" |
3138 | + function setIndicatorVisible(identifier, visible) { |
3139 | + for (var i = 0; i < originalModelData.length; i++) { |
3140 | + if (originalModelData[i]["identifier"] === identifier) { |
3141 | + var data = Indicators.UnityMenuModelCache.getCachedModelData( |
3142 | + originalModelData[i]["indicatorProperties"]["menuObjectPath"]); |
3143 | + |
3144 | + data[0]["rowData"]["actionState"]["visible"] = visible; |
3145 | + |
3146 | + Indicators.UnityMenuModelCache.setCachedModelData( |
3147 | + originalModelData[i]["indicatorProperties"]["menuObjectPath"], |
3148 | + data); |
3149 | + break; |
3150 | } |
3151 | } |
3152 | - ] |
3153 | |
3154 | - function load(profile) { |
3155 | - unload(); |
3156 | - root.modelData = originalModelData; |
3157 | } |
3158 | } |
3159 | |
3160 | === modified file 'tests/mocks/Unity/Indicators/RootActionState.qml' |
3161 | --- tests/mocks/Unity/Indicators/RootActionState.qml 2014-10-21 21:16:04 +0000 |
3162 | +++ tests/mocks/Unity/Indicators/RootActionState.qml 2014-10-21 21:16:05 +0000 |
3163 | @@ -27,7 +27,7 @@ |
3164 | property string rightLabel: cachedState && cachedState.hasOwnProperty("label") ? cachedState["label"] : "" |
3165 | property var icons: cachedState && cachedState.hasOwnProperty("icons") ? cachedState["icons"] : [] |
3166 | property string accessibleName: cachedState && cachedState.hasOwnProperty("accessible-desc") ? cachedState["accessible-desc"] : "" |
3167 | - visible: cachedState && cachedState.hasOwnProperty("visible") ? cachedState["visible"] : true |
3168 | + property bool indicatorVisible: cachedState && cachedState.hasOwnProperty("visible") ? cachedState["visible"] : true |
3169 | |
3170 | property var cachedState: menu ? menu.get(0, "actionState") : undefined |
3171 | Connections { |
3172 | @@ -45,5 +45,5 @@ |
3173 | onRightLabelChanged: updated() |
3174 | onIconsChanged: updated() |
3175 | onAccessibleNameChanged: updated() |
3176 | - onVisibleChanged: updated() |
3177 | + onIndicatorVisibleChanged: updated() |
3178 | } |
3179 | |
3180 | === modified file 'tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp' |
3181 | --- tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp 2014-10-21 21:16:04 +0000 |
3182 | +++ tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp 2014-10-21 21:16:05 +0000 |
3183 | @@ -110,8 +110,6 @@ |
3184 | { |
3185 | roles[IndicatorsModelRole::Identifier] = "identifier"; |
3186 | roles[IndicatorsModelRole::Position] = "position"; |
3187 | - roles[IndicatorsModelRole::WidgetSource] = "widgetSource"; |
3188 | - roles[IndicatorsModelRole::PageSource] = "pageSource"; |
3189 | roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties"; |
3190 | } |
3191 | return roles; |
3192 | |
3193 | === modified file 'tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cpp' |
3194 | --- tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cpp 2014-10-21 21:16:04 +0000 |
3195 | +++ tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cpp 2014-10-21 21:16:05 +0000 |
3196 | @@ -32,11 +32,9 @@ |
3197 | { |
3198 | } |
3199 | |
3200 | -QSharedPointer<UnityMenuModel> FakeUnityMenuModelCache::model(const QByteArray& bus, |
3201 | - const QByteArray& path, |
3202 | - const QVariantMap& actions) |
3203 | +QSharedPointer<UnityMenuModel> FakeUnityMenuModelCache::model(const QByteArray& path) |
3204 | { |
3205 | - return UnityMenuModelCache::singleton()->model(bus, path, actions); |
3206 | + return UnityMenuModelCache::singleton()->model(path); |
3207 | } |
3208 | |
3209 | bool FakeUnityMenuModelCache::contains(const QByteArray& path) |
3210 | @@ -44,14 +42,18 @@ |
3211 | return UnityMenuModelCache::singleton()->contains(path); |
3212 | } |
3213 | |
3214 | -void FakeUnityMenuModelCache::setCachedModelData(const QByteArray& bus, |
3215 | - const QByteArray& path, |
3216 | - const QVariantMap& actions, |
3217 | +void FakeUnityMenuModelCache::setCachedModelData(const QByteArray& path, |
3218 | const QVariant& data) |
3219 | { |
3220 | // keep a ref forever! |
3221 | if (!m_models.contains(path)) { |
3222 | - m_models[path] = model(bus, path, actions); |
3223 | + m_models[path] = model(path); |
3224 | } |
3225 | m_models[path]->setModelData(data); |
3226 | } |
3227 | + |
3228 | +QVariant FakeUnityMenuModelCache::getCachedModelData(const QByteArray& path) |
3229 | +{ |
3230 | + QSharedPointer<UnityMenuModel> model = this->model(path); |
3231 | + return model.isNull() ? QVariant() : model->modelData(); |
3232 | +} |
3233 | |
3234 | === modified file 'tests/mocks/Unity/Indicators/fakeunitymenumodelcache.h' |
3235 | --- tests/mocks/Unity/Indicators/fakeunitymenumodelcache.h 2014-10-21 21:16:04 +0000 |
3236 | +++ tests/mocks/Unity/Indicators/fakeunitymenumodelcache.h 2014-10-21 21:16:05 +0000 |
3237 | @@ -29,18 +29,14 @@ |
3238 | |
3239 | static FakeUnityMenuModelCache* singleton(); |
3240 | |
3241 | - QSharedPointer<UnityMenuModel> model(const QByteArray& bus, |
3242 | - const QByteArray& path, |
3243 | - const QVariantMap& actions) override; |
3244 | + QSharedPointer<UnityMenuModel> model(const QByteArray& path) override; |
3245 | bool contains(const QByteArray& path) override; |
3246 | |
3247 | - |
3248 | - |
3249 | - Q_INVOKABLE void setCachedModelData(const QByteArray& bus, |
3250 | - const QByteArray& path, |
3251 | - const QVariantMap& actions, |
3252 | + Q_INVOKABLE void setCachedModelData(const QByteArray& path, |
3253 | const QVariant& data = QVariant()); |
3254 | |
3255 | + Q_INVOKABLE QVariant getCachedModelData(const QByteArray& path); |
3256 | + |
3257 | private: |
3258 | static QPointer<FakeUnityMenuModelCache> theFakeCache; |
3259 | QHash<QByteArray, QSharedPointer<UnityMenuModel>> m_models; |
3260 | |
3261 | === modified file 'tests/qmltests/CMakeLists.txt' |
3262 | --- tests/qmltests/CMakeLists.txt 2014-10-21 21:16:04 +0000 |
3263 | +++ tests/qmltests/CMakeLists.txt 2014-10-21 21:16:05 +0000 |
3264 | @@ -12,7 +12,6 @@ |
3265 | set(qmltest_DEFAULT_TARGETS qmlunittests) |
3266 | set(qmltest_DEFAULT_NO_ADD_TEST FALSE) |
3267 | set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal") |
3268 | -add_qml_test(Panel IndicatorItem) |
3269 | add_qml_test(utils/Unity/Test UnityTest) |
3270 | |
3271 | set(qmltest_DEFAULT_TARGETS qmluitests) |
3272 | @@ -72,13 +71,14 @@ |
3273 | add_qml_test(Notifications Notifications) |
3274 | add_qml_test(Notifications VisualSnapDecisionsQueue) |
3275 | add_qml_test(Panel ActiveCallHint) |
3276 | -add_qml_test(Panel IndicatorRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3277 | -add_qml_test(Panel Indicators ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3278 | +add_qml_test(Panel IndicatorItem) |
3279 | +add_qml_test(Panel IndicatorItemRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3280 | +add_qml_test(Panel IndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3281 | +add_qml_test(Panel IndicatorsBar ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3282 | +add_qml_test(Panel IndicatorsMenu ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3283 | add_qml_test(Panel MenuContent ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3284 | add_qml_test(Panel Panel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3285 | add_qml_test(Panel SearchIndicator) |
3286 | -add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3287 | -add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
3288 | # These MenuItemFactory tests need the test/mocks/ to come before plugins/ |
3289 | add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS}) |
3290 | add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS}) |
3291 | |
3292 | === modified file 'tests/qmltests/Greeter/tst_Clock.qml' |
3293 | --- tests/qmltests/Greeter/tst_Clock.qml 2014-10-21 21:16:04 +0000 |
3294 | +++ tests/qmltests/Greeter/tst_Clock.qml 2014-10-21 21:16:05 +0000 |
3295 | @@ -37,9 +37,7 @@ |
3296 | } |
3297 | |
3298 | function updateDatetimeModelTime(label) { |
3299 | - Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicator.datetime", |
3300 | - "/com/canonical/indicator/datetime/phone", |
3301 | - "/com/canonical/indicator/datetime", |
3302 | + Indicators.UnityMenuModelCache.setCachedModelData("/com/canonical/indicator/datetime/phone", |
3303 | [{ |
3304 | "rowData": { |
3305 | "actionState": { "label": label } |
3306 | |
3307 | === added file 'tests/qmltests/Panel/IndicatorTest.qml' |
3308 | --- tests/qmltests/Panel/IndicatorTest.qml 1970-01-01 00:00:00 +0000 |
3309 | +++ tests/qmltests/Panel/IndicatorTest.qml 2014-10-21 21:16:05 +0000 |
3310 | @@ -0,0 +1,80 @@ |
3311 | +/* |
3312 | + * Copyright 2014 Canonical Ltd. |
3313 | + * |
3314 | + * This program is free software; you can redistribute it and/or modify |
3315 | + * it under the terms of the GNU General Public License as published by |
3316 | + * the Free Software Foundation; version 3. |
3317 | + * |
3318 | + * This program is distributed in the hope that it will be useful, |
3319 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3320 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3321 | + * GNU General Public License for more details. |
3322 | + * |
3323 | + * You should have received a copy of the GNU General Public License |
3324 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3325 | + */ |
3326 | + |
3327 | +import QtQuick 2.1 |
3328 | +import QtQuick.Layouts 1.1 |
3329 | +import QtTest 1.0 |
3330 | +import "../../../qml/Panel" |
3331 | +import Ubuntu.Components 0.1 |
3332 | +import Unity.Test 0.1 as UT |
3333 | +import Unity.Indicators 0.1 as Indicators |
3334 | + |
3335 | +Rectangle { |
3336 | + id: root |
3337 | + color: "white" |
3338 | + |
3339 | + property alias indicatorsModel: __visibleIndicatorsModel |
3340 | + property alias originalModelData: __indicatorsModel.originalModelData |
3341 | + |
3342 | + Indicators.VisibleIndicatorsModel { |
3343 | + id: __visibleIndicatorsModel |
3344 | + |
3345 | + model: __indicatorsModel |
3346 | + } |
3347 | + |
3348 | + Indicators.IndicatorsModel { |
3349 | + id: __indicatorsModel |
3350 | + Component.onCompleted: load(); |
3351 | + } |
3352 | + |
3353 | + function insertIndicator(index) { |
3354 | + var i; |
3355 | + var insertIndex = 0; |
3356 | + var done = false; |
3357 | + for (i = index; !done && i >= 1; i--) { |
3358 | + |
3359 | + var lookFor = __indicatorsModel.originalModelData[i-1]["identifier"] |
3360 | + |
3361 | + var j; |
3362 | + for (j = __indicatorsModel.modelData.length-1; !done && j >= 0; j--) { |
3363 | + if (__indicatorsModel.modelData[j]["identifier"] === lookFor) { |
3364 | + insertIndex = j+1; |
3365 | + done = true; |
3366 | + } |
3367 | + } |
3368 | + } |
3369 | + __indicatorsModel.insert(insertIndex, __indicatorsModel.originalModelData[index]); |
3370 | + } |
3371 | + |
3372 | + function removeIndicator(index) { |
3373 | + var i; |
3374 | + for (i = 0; i < __indicatorsModel.modelData.length; i++) { |
3375 | + if (__indicatorsModel.modelData[i]["identifier"] === __indicatorsModel.originalModelData[index]["identifier"]) { |
3376 | + __indicatorsModel.remove(i); |
3377 | + break; |
3378 | + } |
3379 | + } |
3380 | + } |
3381 | + |
3382 | + function setIndicatorVisible(index, visible) { |
3383 | + var identifier = __indicatorsModel.originalModelData[index]["identifier"]; |
3384 | + __indicatorsModel.setIndicatorVisible(identifier, visible); |
3385 | + } |
3386 | + |
3387 | + function resetData() { |
3388 | + __indicatorsModel.load(); |
3389 | + } |
3390 | +} |
3391 | |
3392 | === removed file 'tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml' |
3393 | --- tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml 2014-10-21 21:16:04 +0000 |
3394 | +++ tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml 1970-01-01 00:00:00 +0000 |
3395 | @@ -1,52 +0,0 @@ |
3396 | -/* |
3397 | - * Copyright 2013 Canonical Ltd. |
3398 | - * |
3399 | - * This program is free software; you can redistribute it and/or modify |
3400 | - * it under the terms of the GNU General Public License as published by |
3401 | - * the Free Software Foundation; version 3. |
3402 | - * |
3403 | - * This program is distributed in the hope that it will be useful, |
3404 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3405 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3406 | - * GNU General Public License for more details. |
3407 | - * |
3408 | - * You should have received a copy of the GNU General Public License |
3409 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3410 | - */ |
3411 | - |
3412 | -import QtQuick 2.0 |
3413 | -import QtTest 1.0 |
3414 | -import Unity.Test 0.1 as UT |
3415 | -import QMenuModel 0.1 |
3416 | -import "../../../../qml/Panel/Indicators" |
3417 | - |
3418 | -Item { |
3419 | - id: testView |
3420 | - width: units.gu(40) |
3421 | - height: units.gu(70) |
3422 | - |
3423 | - DefaultIndicatorWidget { |
3424 | - id: widget |
3425 | - |
3426 | - anchors { |
3427 | - left: parent.left |
3428 | - top: parent.top |
3429 | - } |
3430 | - |
3431 | - busName: "test" |
3432 | - actionsObjectPath: "test" |
3433 | - deviceMenuObjectPath: "test" |
3434 | - |
3435 | - rootMenuType: "" |
3436 | - |
3437 | - iconSize: units.gu(3.2) |
3438 | - height: units.gu(3) |
3439 | - } |
3440 | - |
3441 | - UT.UnityTestCase { |
3442 | - name: "DefaultIndicatorWidget" |
3443 | - when: windowShown |
3444 | - |
3445 | - // FIXME: add tests |
3446 | - } |
3447 | -} |
3448 | |
3449 | === modified file 'tests/qmltests/Panel/tst_ActiveCallHint.qml' |
3450 | --- tests/qmltests/Panel/tst_ActiveCallHint.qml 2014-09-11 14:53:35 +0000 |
3451 | +++ tests/qmltests/Panel/tst_ActiveCallHint.qml 2014-10-21 21:16:05 +0000 |
3452 | @@ -19,7 +19,6 @@ |
3453 | import Unity.Test 0.1 as UT |
3454 | import Ubuntu.Telephony 0.1 as Telephony |
3455 | import Unity.Application 0.1 |
3456 | -import ".." |
3457 | import "../../../qml/Panel" |
3458 | |
3459 | Item { |
3460 | |
3461 | === added file 'tests/qmltests/Panel/tst_IndicatorItem.qml' |
3462 | --- tests/qmltests/Panel/tst_IndicatorItem.qml 1970-01-01 00:00:00 +0000 |
3463 | +++ tests/qmltests/Panel/tst_IndicatorItem.qml 2014-10-21 21:16:05 +0000 |
3464 | @@ -0,0 +1,205 @@ |
3465 | +/* |
3466 | + * Copyright 2013-2014 Canonical Ltd. |
3467 | + * |
3468 | + * This program is free software; you can redistribute it and/or modify |
3469 | + * it under the terms of the GNU General Public License as published by |
3470 | + * the Free Software Foundation; version 3. |
3471 | + * |
3472 | + * This program is distributed in the hope that it will be useful, |
3473 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3474 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3475 | + * GNU General Public License for more details. |
3476 | + * |
3477 | + * You should have received a copy of the GNU General Public License |
3478 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3479 | + */ |
3480 | + |
3481 | +import QtQuick 2.1 |
3482 | +import QtQuick.Layouts 1.1 |
3483 | +import QtTest 1.0 |
3484 | +import Ubuntu.Components 0.1 |
3485 | +import Unity.Test 0.1 as UT |
3486 | +import "../../../qml/Panel" |
3487 | + |
3488 | +Rectangle { |
3489 | + width: units.gu(80) |
3490 | + height: units.gu(30) |
3491 | + color: "white" |
3492 | + |
3493 | + RowLayout { |
3494 | + anchors.fill: parent |
3495 | + anchors.margins: units.gu(1) |
3496 | + |
3497 | + Rectangle { |
3498 | + id: itemArea |
3499 | + color: "blue" |
3500 | + Layout.fillWidth: true |
3501 | + Layout.fillHeight: true |
3502 | + |
3503 | + Rectangle { |
3504 | + color: "black" |
3505 | + anchors.fill: indicatorItem |
3506 | + } |
3507 | + |
3508 | + IndicatorItem { |
3509 | + id: indicatorItem |
3510 | + height: expanded ? units.gu(7) : units.gu(3) |
3511 | + anchors.centerIn: parent |
3512 | + identifier: "indicator-test" |
3513 | + |
3514 | + rootActionState { |
3515 | + title: titleLabel.text |
3516 | + leftLabel : leftLabel.text |
3517 | + rightLabel : rightLabel.text |
3518 | + icons : { |
3519 | + var icons = []; |
3520 | + var i = 0; |
3521 | + if (iconEnabled.checked) { |
3522 | + for (i = 0; i < String(iconCount.text); i++) { |
3523 | + icons.push("image://theme/audio-volume-high"); |
3524 | + } |
3525 | + } |
3526 | + return icons; |
3527 | + } |
3528 | + } |
3529 | + |
3530 | + Behavior on height { |
3531 | + NumberAnimation { |
3532 | + id: heightAnimation |
3533 | + duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing |
3534 | + } |
3535 | + } |
3536 | + } |
3537 | + } |
3538 | + |
3539 | + ColumnLayout { |
3540 | + Layout.alignment: Qt.AlignTop |
3541 | + Layout.fillWidth: false |
3542 | + |
3543 | + Button { |
3544 | + id: expandButton |
3545 | + Layout.fillWidth: true |
3546 | + text: indicatorItem.expanded ? "Collapse" : "Expand" |
3547 | + onClicked: indicatorItem.expanded = !indicatorItem.expanded |
3548 | + } |
3549 | + |
3550 | + Button { |
3551 | + id: selectButton |
3552 | + Layout.fillWidth: true |
3553 | + text: indicatorItem.selected ? "Unselect" : "Select" |
3554 | + onClicked: indicatorItem.selected = !indicatorItem.selected |
3555 | + } |
3556 | + |
3557 | + Rectangle { |
3558 | + Layout.preferredHeight: units.dp(1); |
3559 | + Layout.fillWidth: true; |
3560 | + color: "black" |
3561 | + } |
3562 | + |
3563 | + RowLayout { |
3564 | + CheckBox { id: iconEnabled; checked: true } |
3565 | + Label { text: "icons Count:" } |
3566 | + TextField { id: iconCount; text: "1"; enabled: iconEnabled.checked } |
3567 | + } |
3568 | + |
3569 | + RowLayout { |
3570 | + Label { text: "Left Label:" } |
3571 | + TextField { id: leftLabel; text: "Left"} |
3572 | + } |
3573 | + |
3574 | + RowLayout { |
3575 | + Label { text: "Right Label:" } |
3576 | + TextField { id: rightLabel; text: "Right"} |
3577 | + } |
3578 | + |
3579 | + RowLayout { |
3580 | + Label { text: "Title:" } |
3581 | + TextField { id: titleLabel; text: "Title"} |
3582 | + } |
3583 | + } |
3584 | + } |
3585 | + |
3586 | + UT.UnityTestCase { |
3587 | + name: "IndicatorItem" |
3588 | + when: windowShown |
3589 | + |
3590 | + function init() { |
3591 | + indicatorItem.selected = false; |
3592 | + indicatorItem.expanded = false; |
3593 | + indicatorItem.rootActionState.title = "Test Title"; |
3594 | + indicatorItem.rootActionState.leftLabel = "TestLeftLabel"; |
3595 | + indicatorItem.rootActionState.rightLabel = "TestRightLabel"; |
3596 | + indicatorItem.rootActionState.icons = [ "image://theme/audio-volume-high" ]; |
3597 | + |
3598 | + tryCompare(heightAnimation, "running", false); |
3599 | + } |
3600 | + |
3601 | + function test_expand() { |
3602 | + indicatorItem.expanded = true; |
3603 | + tryCompare(indicatorItem, "height", units.gu(7)); |
3604 | + indicatorItem.expanded = false; |
3605 | + tryCompare(indicatorItem, "height", units.gu(3)); |
3606 | + } |
3607 | + |
3608 | + function test_minimizedVisibility() { |
3609 | + compare(findChild(indicatorItem, "leftLabel").opacity, 1.0); |
3610 | + compare(findChild(indicatorItem, "rightLabel").opacity, 1.0); |
3611 | + compare(findChild(indicatorItem, "icons").opacity, 1.0); |
3612 | + compare(findChild(indicatorItem, "indicatorName").opacity, 0.0); |
3613 | + } |
3614 | + |
3615 | + function test_expandIcon() { |
3616 | + indicatorItem.expanded = true; |
3617 | + |
3618 | + tryCompare(findChild(indicatorItem, "leftLabel"), "opacity", 0.0); |
3619 | + tryCompare(findChild(indicatorItem, "rightLabel"), "opacity", 0.0); |
3620 | + tryCompare(findChild(indicatorItem, "icons"), "opacity", 1.0); |
3621 | + tryCompare(findChild(indicatorItem, "indicatorName"), "opacity", 1.0); |
3622 | + } |
3623 | + |
3624 | + function test_expandRightLabel() { |
3625 | + indicatorItem.expanded = true; |
3626 | + |
3627 | + indicatorItem.rootActionState.icons = []; |
3628 | + |
3629 | + tryCompare(findChild(indicatorItem, "leftLabel"), "opacity", 0.0); |
3630 | + tryCompare(findChild(indicatorItem, "rightLabel"), "opacity", 1.0); |
3631 | + tryCompare(findChild(indicatorItem, "icons"), "opacity", 0.0); |
3632 | + tryCompare(findChild(indicatorItem, "indicatorName"), "opacity", 1.0); |
3633 | + } |
3634 | + |
3635 | + function test_expandLeftLabel() { |
3636 | + indicatorItem.expanded = true; |
3637 | + |
3638 | + indicatorItem.rootActionState.rightLabel = ""; |
3639 | + indicatorItem.rootActionState.icons = []; |
3640 | + |
3641 | + tryCompare(findChild(indicatorItem, "rightLabel"), "opacity", 0.0); |
3642 | + tryCompare(findChild(indicatorItem, "leftLabel"), "opacity", 1.0); |
3643 | + tryCompare(findChild(indicatorItem, "icons"), "opacity", 0.0); |
3644 | + tryCompare(findChild(indicatorItem, "indicatorName"), "opacity", 1.0); |
3645 | + } |
3646 | + |
3647 | + function test_select() { |
3648 | + tryCompare(findChild(indicatorItem, "icon0"), "color", "#ededed"); |
3649 | + tryCompare(findChild(indicatorItem, "icon0"), "opacity", 1.0); |
3650 | + tryCompare(findChild(indicatorItem, "leftLabel"), "color", "#ededed"); |
3651 | + tryCompare(findChild(indicatorItem, "rightLabel"), "color", "#ededed"); |
3652 | + tryCompare(findChild(indicatorItem, "indicatorName"), "color", "#ededed"); |
3653 | + |
3654 | + indicatorItem.expanded = true; |
3655 | + tryCompare(findChild(indicatorItem, "icon0"), "color", "#4c4c4c"); |
3656 | + tryCompare(findChild(indicatorItem, "icon0"), "opacity", 0.6); |
3657 | + tryCompare(findChild(indicatorItem, "leftLabel"), "color", "#4c4c4c"); |
3658 | + tryCompare(findChild(indicatorItem, "rightLabel"), "color", "#4c4c4c"); |
3659 | + tryCompare(findChild(indicatorItem, "indicatorName"), "color", "#4c4c4c"); |
3660 | + |
3661 | + indicatorItem.selected = true; |
3662 | + tryCompare(findChild(indicatorItem, "icon0"), "color", "#ededed"); |
3663 | + tryCompare(findChild(indicatorItem, "icon0"), "opacity", 1.0); |
3664 | + tryCompare(findChild(indicatorItem, "leftLabel"), "color", "#ededed"); |
3665 | + tryCompare(findChild(indicatorItem, "rightLabel"), "color", "#ededed"); |
3666 | + tryCompare(findChild(indicatorItem, "indicatorName"), "color", "#ededed"); |
3667 | + } |
3668 | + } |
3669 | +} |
3670 | |
3671 | === removed file 'tests/qmltests/Panel/tst_IndicatorItem.qml' |
3672 | --- tests/qmltests/Panel/tst_IndicatorItem.qml 2014-10-21 21:16:04 +0000 |
3673 | +++ tests/qmltests/Panel/tst_IndicatorItem.qml 1970-01-01 00:00:00 +0000 |
3674 | @@ -1,50 +0,0 @@ |
3675 | -/* |
3676 | - * Copyright 2013 Canonical Ltd. |
3677 | - * |
3678 | - * This program is free software; you can redistribute it and/or modify |
3679 | - * it under the terms of the GNU General Public License as published by |
3680 | - * the Free Software Foundation; version 3. |
3681 | - * |
3682 | - * This program is distributed in the hope that it will be useful, |
3683 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3684 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3685 | - * GNU General Public License for more details. |
3686 | - * |
3687 | - * You should have received a copy of the GNU General Public License |
3688 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3689 | - */ |
3690 | - |
3691 | -import QtQuick 2.0 |
3692 | -import QtTest 1.0 |
3693 | -import ".." |
3694 | -import "../../../qml/Panel" |
3695 | -import Ubuntu.Components 0.1 |
3696 | -import Unity.Test 0.1 as UT |
3697 | - |
3698 | -Rectangle { |
3699 | - width: units.gu(10) |
3700 | - height: units.gu(5) |
3701 | - color: "black" |
3702 | - |
3703 | - IndicatorItem { |
3704 | - id: indicatorItem |
3705 | - anchors.fill: parent |
3706 | - } |
3707 | - |
3708 | - UT.UnityTestCase { |
3709 | - name: "IndicatorItem" |
3710 | - |
3711 | - function test_dimmed() { |
3712 | - indicatorItem.dimmed = false; |
3713 | - tryCompareFunction(function(){return indicatorItem.opacity}, 1.0); |
3714 | - indicatorItem.dimmed = true; |
3715 | - tryCompareFunction(function(){return indicatorItem.opacity < 1.0}, true); |
3716 | - } |
3717 | - |
3718 | - function test_empty() { |
3719 | - compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible."); |
3720 | - indicatorItem.widgetSource = "../../../qml/Panel/Indicators/DefaultIndicatorWidget.qml"; |
3721 | - tryCompare(indicatorItem, "indicatorVisible", true); |
3722 | - } |
3723 | - } |
3724 | -} |
3725 | |
3726 | === added file 'tests/qmltests/Panel/tst_IndicatorItemRow.qml' |
3727 | --- tests/qmltests/Panel/tst_IndicatorItemRow.qml 1970-01-01 00:00:00 +0000 |
3728 | +++ tests/qmltests/Panel/tst_IndicatorItemRow.qml 2014-10-21 21:16:05 +0000 |
3729 | @@ -0,0 +1,290 @@ |
3730 | +/* |
3731 | + * Copyright 2013-2014 Canonical Ltd. |
3732 | + * |
3733 | + * This program is free software; you can redistribute it and/or modify |
3734 | + * it under the terms of the GNU General Public License as published by |
3735 | + * the Free Software Foundation; version 3. |
3736 | + * |
3737 | + * This program is distributed in the hope that it will be useful, |
3738 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3739 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3740 | + * GNU General Public License for more details. |
3741 | + * |
3742 | + * You should have received a copy of the GNU General Public License |
3743 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3744 | + */ |
3745 | + |
3746 | +import QtQuick 2.1 |
3747 | +import QtQuick.Layouts 1.1 |
3748 | +import QtTest 1.0 |
3749 | +import "../../../qml/Panel" |
3750 | +import Ubuntu.Components 0.1 |
3751 | +import Unity.Test 0.1 as UT |
3752 | +import Unity.Indicators 0.1 as Indicators |
3753 | + |
3754 | +IndicatorTest { |
3755 | + id: root |
3756 | + width: units.gu(120) |
3757 | + height: units.gu(40) |
3758 | + color: "white" |
3759 | + |
3760 | + RowLayout { |
3761 | + anchors.fill: parent |
3762 | + anchors.margins: units.gu(1) |
3763 | + |
3764 | + Rectangle { |
3765 | + Layout.fillWidth: true |
3766 | + Layout.fillHeight: true |
3767 | + |
3768 | + id: itemArea |
3769 | + color: "blue" |
3770 | + |
3771 | + Rectangle { |
3772 | + color: "black" |
3773 | + anchors.fill: indicatorsRow |
3774 | + } |
3775 | + |
3776 | + IndicatorItemRow { |
3777 | + id: indicatorsRow |
3778 | + height: expanded ? units.gu(7) : units.gu(3) |
3779 | + anchors.centerIn: parent |
3780 | + indicatorsModel: root.indicatorsModel |
3781 | + enableLateralChanges: ma.pressed |
3782 | + |
3783 | + Behavior on height { |
3784 | + NumberAnimation { |
3785 | + id: heightAnimation |
3786 | + duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing |
3787 | + } |
3788 | + } |
3789 | + |
3790 | + MouseArea { |
3791 | + id: ma |
3792 | + anchors.fill: parent |
3793 | + onPositionChanged: { |
3794 | + indicatorsRow.lateralPosition = mouse.x; |
3795 | + } |
3796 | + onPressed: { |
3797 | + if (pressed) { |
3798 | + indicatorsRow.lateralPosition = mouse.x; |
3799 | + indicatorsRow.selectItemAt(mouse.x); |
3800 | + } |
3801 | + } |
3802 | + } |
3803 | + } |
3804 | + } |
3805 | + |
3806 | + ColumnLayout { |
3807 | + Layout.alignment: Qt.AlignTop |
3808 | + Layout.fillWidth: false |
3809 | + |
3810 | + Button { |
3811 | + Layout.fillWidth: true |
3812 | + text: indicatorsRow.expanded ? "Collapse" : "Expand" |
3813 | + onClicked: indicatorsRow.expanded = !indicatorsRow.expanded |
3814 | + } |
3815 | + |
3816 | + Rectangle { |
3817 | + Layout.preferredHeight: units.dp(1); |
3818 | + Layout.fillWidth: true; |
3819 | + color: "black" |
3820 | + } |
3821 | + |
3822 | + Repeater { |
3823 | + model: root.originalModelData |
3824 | + RowLayout { |
3825 | + CheckBox { |
3826 | + checked: true |
3827 | + onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index); |
3828 | + } |
3829 | + Label { |
3830 | + Layout.fillWidth: true |
3831 | + text: modelData["identifier"] |
3832 | + } |
3833 | + |
3834 | + CheckBox { |
3835 | + checked: true |
3836 | + onCheckedChanged: setIndicatorVisible(index, checked); |
3837 | + } |
3838 | + Label { |
3839 | + text: "visible" |
3840 | + } |
3841 | + } |
3842 | + } |
3843 | + } |
3844 | + } |
3845 | + |
3846 | + UT.UnityTestCase { |
3847 | + name: "IndicatorItemRow" |
3848 | + when: windowShown |
3849 | + |
3850 | + function init() { |
3851 | + root.resetData(); |
3852 | + |
3853 | + indicatorsRow.resetCurrentItem(); |
3854 | + indicatorsRow.lateralPosition = -1; |
3855 | + |
3856 | + indicatorsRow.expanded = false; |
3857 | + tryCompare(heightAnimation, "running", false); |
3858 | + tryCompare(findChild(indicatorsRow, "highlight"), "highlightCenterOffset", 0); |
3859 | + wait(1); // row seems to take a bit of time for item x values to update. |
3860 | + } |
3861 | + |
3862 | + function wait_for_expansion_to_settle() { |
3863 | + tryCompare(heightAnimation, "running", false); |
3864 | + wait(200); // put a little extra wait in for things to settle |
3865 | + } |
3866 | + |
3867 | + function test_indicatorRowChanges_data() { |
3868 | + return [ |
3869 | + { remove: [0, 2] }, |
3870 | + { remove: [0, 1, 2, 3, 4] }, |
3871 | + ]; |
3872 | + } |
3873 | + |
3874 | + // test the changes in the available indicators updates the |
3875 | + // indicators that are visible. |
3876 | + function test_indicatorRowChanges(data) { |
3877 | + var i; |
3878 | + var item; |
3879 | + var itemsToRemove = [0, 2]; |
3880 | + |
3881 | + verify(root.originalModelData.length > 0); |
3882 | + for (i = 0; i < root.originalModelData.length; i++) { |
3883 | + item = findChild(indicatorsRow, root.originalModelData[i]["identifier"] + "-panelItem"); |
3884 | + verify(item); |
3885 | + |
3886 | + compare(item.ownIndex, i, "Item at incorrect index"); |
3887 | + } |
3888 | + |
3889 | + for (i = data.remove.length-1; i >= 0; i--) { |
3890 | + removeIndicator(data.remove[i]); |
3891 | + } |
3892 | + |
3893 | + // test removals |
3894 | + for (i = 0; i < root.originalModelData.length; i++) { |
3895 | + item = findChild(indicatorsRow, root.originalModelData[i]["identifier"] + "-panelItem"); |
3896 | + |
3897 | + verify(data.remove.indexOf(i) !== -1 ? (item === null) : (item !== null)); |
3898 | + } |
3899 | + |
3900 | + // test insertion |
3901 | + for (i = 0; i < data.remove.length; i++) { |
3902 | + insertIndicator(data.remove[i]); |
3903 | + } |
3904 | + |
3905 | + for (i = 0; i < root.originalModelData.length; i++) { |
3906 | + item = findChild(indicatorsRow, root.originalModelData[i]["identifier"] + "-panelItem"); |
3907 | + verify(item); |
3908 | + |
3909 | + compare(item.ownIndex, i, "Item at incorrect index"); |
3910 | + } |
3911 | + } |
3912 | + |
3913 | + function test_validCurrentItem_data() { |
3914 | + return [ |
3915 | + { index: 0 }, |
3916 | + { index: 2 }, |
3917 | + { index: 4 } |
3918 | + ]; |
3919 | + } |
3920 | + |
3921 | + // test selecting the item at it's position sets the current item of the row. |
3922 | + function test_validCurrentItem(data) { |
3923 | + var dataItem = findChild(indicatorsRow, root.originalModelData[data.index]["identifier"] + "-panelItem"); |
3924 | + verify(dataItem !== null); |
3925 | + |
3926 | + indicatorsRow.selectItemAt(dataItem.x + dataItem.width/2); |
3927 | + compare(indicatorsRow.currentItem, dataItem); |
3928 | + } |
3929 | + |
3930 | + // tests item default selection (no item at position X) |
3931 | + function test_invalidCurrentItem() { |
3932 | + indicatorsRow.selectItemAt(-100); |
3933 | + var item = findChild(indicatorsRow, root.originalModelData[0]["identifier"] + "-panelItem"); |
3934 | + compare(indicatorsRow.currentItem, item); |
3935 | + } |
3936 | + |
3937 | + // testing that changing the lateral position offset of the row changes the current item. |
3938 | + function test_lateralPositionChangesCurrentItem_data() { |
3939 | + return [ |
3940 | + { tag: "0 -> 4", from: 0, to: 4 }, |
3941 | + { tag: "3 -> 1", from: 3, to: 1 } |
3942 | + ]; |
3943 | + } |
3944 | + |
3945 | + function test_lateralPositionChangesCurrentItem(data) { |
3946 | + indicatorsRow.expanded = true; |
3947 | + wait_for_expansion_to_settle(); |
3948 | + |
3949 | + var fromItem = findChild(indicatorsRow, root.originalModelData[data.from]["identifier"] + "-panelItem"); |
3950 | + verify(fromItem !== null); |
3951 | + |
3952 | + var toItem = findChild(indicatorsRow, root.originalModelData[data.to]["identifier"] + "-panelItem"); |
3953 | + verify(toItem !== null); |
3954 | + |
3955 | + var fromPosition = indicatorsRow.mapFromItem(fromItem, fromItem.width/2, fromItem.height/2); |
3956 | + var toPosition = indicatorsRow.mapFromItem(toItem, toItem.width/2, toItem.height/2); |
3957 | + |
3958 | + mousePress(indicatorsRow, fromPosition.x, fromPosition.y); |
3959 | + compare(indicatorsRow.currentItem, fromItem, "Initial item not selected"); |
3960 | + |
3961 | + // this uses the MouseArea above to change the indicatorRow lateralPosition |
3962 | + mouseFlick(indicatorsRow, fromPosition.x, fromPosition.y, toPosition.x, toPosition.y, false, false, units.gu(5), 30); |
3963 | + |
3964 | + mouseRelease(indicatorsRow, fromPosition.x, fromPosition.y); |
3965 | + compare(indicatorsRow.currentItem, toItem, "Current item did not change to expected item"); |
3966 | + } |
3967 | + |
3968 | + // testing that positive changes to the lateral position offset shifts the highlight offset to the right |
3969 | + function test_positiveLateralPositionChangesHighlightOffset() { |
3970 | + indicatorsRow.expanded = true; |
3971 | + wait_for_expansion_to_settle(); |
3972 | + |
3973 | + var highlight = findChild(indicatorsRow, "highlight"); |
3974 | + var item = findChild(indicatorsRow, root.originalModelData[2]["identifier"] + "-panelItem"); |
3975 | + verify(item !== null); |
3976 | + var mappedPosition = indicatorsRow.mapFromItem(item, item.width/2, item.height/2); |
3977 | + |
3978 | + mousePress(indicatorsRow, mappedPosition.x, mappedPosition.y); |
3979 | + var originalHightlightX = highlight.x; |
3980 | + var offset = 1; |
3981 | + while((highlight.x - originalHightlightX) <= units.gu(0.5) && offset < units.gu(10)) { |
3982 | + mouseMove(indicatorsRow, mappedPosition.x + offset, mappedPosition.y, 10); |
3983 | + offset = offset + 2; |
3984 | + } |
3985 | + // verify that we hit the offset |
3986 | + verify((highlight.x - originalHightlightX) >= units.gu(0.5)); |
3987 | + mouseRelease(indicatorsRow); |
3988 | + |
3989 | + // should go back to 0 |
3990 | + tryCompare(highlight, "highlightCenterOffset", 0); |
3991 | + } |
3992 | + |
3993 | + // testing that negative changes to the lateral position offset shifts the highlight offset to the left |
3994 | + function test_negativeLateralPositionChangesHighlightOffset() { |
3995 | + indicatorsRow.expanded = true; |
3996 | + wait_for_expansion_to_settle(); |
3997 | + |
3998 | + var highlight = findChild(indicatorsRow, "highlight"); |
3999 | + var item = findChild(indicatorsRow, root.originalModelData[2]["identifier"] + "-panelItem"); |
4000 | + verify(item !== null); |
4001 | + var mappedPosition = indicatorsRow.mapFromItem(item, item.width/2, item.height/2); |
4002 | + |
4003 | + mousePress(indicatorsRow, mappedPosition.x, mappedPosition.y); |
4004 | + var originalHightlightX = highlight.x; |
4005 | + var offset = 1; |
4006 | + while((highlight.x - originalHightlightX) >= -units.gu(0.5) && offset < units.gu(10)) { |
4007 | + mouseMove(indicatorsRow, mappedPosition.x - offset, mappedPosition.y, 10); |
4008 | + offset = offset + 2; |
4009 | + } |
4010 | + |
4011 | + // verify that we hit the offset |
4012 | + verify((highlight.x - originalHightlightX) <= -units.gu(0.5)); |
4013 | + mouseRelease(indicatorsRow); |
4014 | + |
4015 | + // should go back to 0 |
4016 | + tryCompare(findChild(indicatorsRow, "highlight"), "highlightCenterOffset", 0); |
4017 | + } |
4018 | + } |
4019 | +} |
4020 | |
4021 | === renamed file 'tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml' => 'tests/qmltests/Panel/tst_IndicatorPage.qml' |
4022 | --- tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml 2014-10-21 21:16:04 +0000 |
4023 | +++ tests/qmltests/Panel/tst_IndicatorPage.qml 2014-10-21 21:16:05 +0000 |
4024 | @@ -1,5 +1,5 @@ |
4025 | /* |
4026 | - * Copyright 2013 Canonical Ltd. |
4027 | + * Copyright 2013-2014 Canonical Ltd. |
4028 | * |
4029 | * This program is free software; you can redistribute it and/or modify |
4030 | * it under the terms of the GNU General Public License as published by |
4031 | @@ -18,14 +18,14 @@ |
4032 | import QtTest 1.0 |
4033 | import Unity.Test 0.1 as UT |
4034 | import Unity.Indicators 0.1 as Indicators |
4035 | -import "../../../../qml/Panel/Indicators" |
4036 | +import "../../../qml/Panel" |
4037 | |
4038 | Item { |
4039 | id: testView |
4040 | width: units.gu(40) |
4041 | height: units.gu(70) |
4042 | |
4043 | - DefaultIndicatorPage { |
4044 | + IndicatorPage { |
4045 | id: page |
4046 | anchors.fill: parent |
4047 | |
4048 | @@ -110,14 +110,12 @@ |
4049 | }]; // end row 1 |
4050 | |
4051 | function initializeMenuData(data) { |
4052 | - Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicator.test", |
4053 | - "/com/canonical/indicator/test", |
4054 | - "/com/canonical/indicator/test", |
4055 | + Indicators.UnityMenuModelCache.setCachedModelData("/com/canonical/indicator/test", |
4056 | data); |
4057 | } |
4058 | |
4059 | UT.UnityTestCase { |
4060 | - name: "DefaultIndicatorPage" |
4061 | + name: "IndicatorPage" |
4062 | |
4063 | function init() { |
4064 | initializeMenuData([]); |
4065 | |
4066 | === removed file 'tests/qmltests/Panel/tst_IndicatorRow.qml' |
4067 | --- tests/qmltests/Panel/tst_IndicatorRow.qml 2014-10-21 21:16:04 +0000 |
4068 | +++ tests/qmltests/Panel/tst_IndicatorRow.qml 1970-01-01 00:00:00 +0000 |
4069 | @@ -1,158 +0,0 @@ |
4070 | -/* |
4071 | - * Copyright 2013 Canonical Ltd. |
4072 | - * |
4073 | - * This program is free software; you can redistribute it and/or modify |
4074 | - * it under the terms of the GNU General Public License as published by |
4075 | - * the Free Software Foundation; version 3. |
4076 | - * |
4077 | - * This program is distributed in the hope that it will be useful, |
4078 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4079 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4080 | - * GNU General Public License for more details. |
4081 | - * |
4082 | - * You should have received a copy of the GNU General Public License |
4083 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4084 | - */ |
4085 | - |
4086 | -import QtQuick 2.0 |
4087 | -import QtTest 1.0 |
4088 | -import Unity.Test 0.1 as UT |
4089 | -import ".." |
4090 | -import "../../../qml/Panel" |
4091 | -import Unity.Indicators 0.1 as Indicators |
4092 | - |
4093 | -/* |
4094 | - This tests the IndicatorRow component by using a fake model to stage data in the indicators |
4095 | - A view will show with indicators at the top, as does in the shell. |
4096 | -*/ |
4097 | -Item { |
4098 | - id: rootItem |
4099 | - width: units.gu(40) |
4100 | - height: units.gu(60) |
4101 | - |
4102 | - PanelBackground { |
4103 | - anchors.fill: indicatorRow |
4104 | - } |
4105 | - |
4106 | - IndicatorRow { |
4107 | - id: indicatorRow |
4108 | - anchors { |
4109 | - left: parent.left |
4110 | - right: parent.right |
4111 | - } |
4112 | - |
4113 | - indicatorsModel: indicatorModel |
4114 | - |
4115 | - Component.onCompleted: indicatorModel.load("test1") |
4116 | - } |
4117 | - |
4118 | - Indicators.IndicatorsModel { |
4119 | - id: indicatorModel |
4120 | - } |
4121 | - |
4122 | - UT.UnityTestCase { |
4123 | - name: "IndicatorRow" |
4124 | - when: windowShown |
4125 | - |
4126 | - function init() { |
4127 | - indicatorModel.load("test1"); |
4128 | - |
4129 | - indicatorRow.state = "initial"; |
4130 | - indicatorRow.setCurrentItemIndex(-1); |
4131 | - indicatorRow.unitProgress = 0.0; |
4132 | - } |
4133 | - |
4134 | - function get_indicator_item(index) { |
4135 | - return findChild(indicatorRow.row, "item" + index); |
4136 | - } |
4137 | - |
4138 | - function test_set_current_item() { |
4139 | - indicatorRow.setCurrentItemIndex(0); |
4140 | - compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), |
4141 | - "indicator-fake1", |
4142 | - "Incorrect item at position 0"); |
4143 | - |
4144 | - indicatorRow.setCurrentItemIndex(1); |
4145 | - compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), |
4146 | - "indicator-fake2", |
4147 | - "Incorrect item at position 1"); |
4148 | - |
4149 | - indicatorRow.setCurrentItemIndex(2); |
4150 | - compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), |
4151 | - "indicator-fake3", |
4152 | - "Incorrect item at position 2"); |
4153 | - } |
4154 | - |
4155 | - function test_highlight_data() { |
4156 | - return [ |
4157 | - { index: 0, progress: 0.0, current: false, other: false }, |
4158 | - { index: 0, progress: 0.1, current: true, other: false }, |
4159 | - { index: 0, progress: 0.5, current: true, other: false }, |
4160 | - { index: 0, progress: 1.0, current: true, other: false }, |
4161 | - { index: 2, progress: 0.0, current: false, other: false }, |
4162 | - { index: 2, progress: 0.1, current: true, other: false }, |
4163 | - { index: 2, progress: 0.5, current: true, other: false }, |
4164 | - { index: 2, progress: 1.0, current: true, other: false } |
4165 | - ]; |
4166 | - } |
4167 | - |
4168 | - function test_highlight(data) { |
4169 | - indicatorRow.unitProgress = data.progress; |
4170 | - indicatorRow.setCurrentItemIndex(data.index); |
4171 | - |
4172 | - compare(indicatorRow.currentItem.highlighted, data.current, "Indicator hightlight did not match for current item"); |
4173 | - |
4174 | - for (var i = 0; i < indicatorRow.row.count; i++) { |
4175 | - compare(get_indicator_item(i).highlighted, i === data.index ? data.current: data.other, "Indicator hightlight did not match for item iter"); |
4176 | - } |
4177 | - } |
4178 | - |
4179 | - function test_opacity_data() { |
4180 | - return [ |
4181 | - { index: 0, progress: 0.0, current: 1.0, other: 1.0 }, |
4182 | - { index: 0, progress: 0.1, current: 1.0, other: 0.9 }, |
4183 | - { index: 0, progress: 0.5, current: 1.0, other: 0.5 }, |
4184 | - { index: 0, progress: 1.0, current: 1.0, other: 0.0 }, |
4185 | - { index: 2, progress: 0.0, current: 1.0, other: 1.0 }, |
4186 | - { index: 2, progress: 0.1, current: 1.0, other: 0.9 }, |
4187 | - { index: 2, progress: 0.5, current: 1.0, other: 0.5 }, |
4188 | - { index: 2, progress: 1.0, current: 1.0, other: 0.0 } |
4189 | - ]; |
4190 | - } |
4191 | - |
4192 | - function test_opacity(data) { |
4193 | - indicatorRow.unitProgress = data.progress; |
4194 | - indicatorRow.setCurrentItemIndex(data.index); |
4195 | - |
4196 | - tryCompare(indicatorRow.currentItem, "opacity", data.current); |
4197 | - |
4198 | - for (var i = 0; i < indicatorRow.row.count; i++) { |
4199 | - tryCompare(get_indicator_item(i), "opacity", i === data.index ? data.current: data.other); |
4200 | - } |
4201 | - } |
4202 | - |
4203 | - function test_dimmed_data() { |
4204 | - return [ |
4205 | - { index: 0, progress: 0.0, current: false, other: false }, |
4206 | - { index: 0, progress: 0.1, current: false, other: true }, |
4207 | - { index: 0, progress: 0.5, current: false, other: true }, |
4208 | - { index: 0, progress: 1.0, current: false, other: true }, |
4209 | - { index: 2, progress: 0.0, current: false, other: false }, |
4210 | - { index: 2, progress: 0.1, current: false, other: true }, |
4211 | - { index: 2, progress: 0.5, current: false, other: true }, |
4212 | - { index: 2, progress: 1.0, current: false, other: true } |
4213 | - ]; |
4214 | - } |
4215 | - |
4216 | - function test_dimmed(data) { |
4217 | - indicatorRow.unitProgress = data.progress; |
4218 | - indicatorRow.setCurrentItemIndex(data.index); |
4219 | - |
4220 | - compare(indicatorRow.currentItem.dimmed, data.current, "Indicator dim did not match for current item"); |
4221 | - |
4222 | - for (var i = 0; i < indicatorRow.row.count; i++) { |
4223 | - compare(get_indicator_item(i).dimmed, i === data.index ? data.current: data.other, "Indicator dim did not match for item iter"); |
4224 | - } |
4225 | - } |
4226 | - } |
4227 | -} |
4228 | |
4229 | === removed file 'tests/qmltests/Panel/tst_Indicators.qml' |
4230 | --- tests/qmltests/Panel/tst_Indicators.qml 2014-10-21 21:16:04 +0000 |
4231 | +++ tests/qmltests/Panel/tst_Indicators.qml 1970-01-01 00:00:00 +0000 |
4232 | @@ -1,231 +0,0 @@ |
4233 | -/* |
4234 | - * Copyright 2013 Canonical Ltd. |
4235 | - * |
4236 | - * This program is free software; you can redistribute it and/or modify |
4237 | - * it under the terms of the GNU General Public License as published by |
4238 | - * the Free Software Foundation; version 3. |
4239 | - * |
4240 | - * This program is distributed in the hope that it will be useful, |
4241 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4242 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4243 | - * GNU General Public License for more details. |
4244 | - * |
4245 | - * You should have received a copy of the GNU General Public License |
4246 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4247 | - */ |
4248 | - |
4249 | -import QtQuick 2.0 |
4250 | -import QtTest 1.0 |
4251 | -import Unity.Test 0.1 as UT |
4252 | -import Ubuntu.Components 0.1 as UC |
4253 | -import ".." |
4254 | -import "../../../qml/Panel" |
4255 | -import "../../../qml/Components" |
4256 | - |
4257 | -/* |
4258 | - This tests the Indicators component by using a fake model to stage data in the indicators |
4259 | - A view will show with indicators at the top, as does in the shell. There is a clickable area |
4260 | - marked "Click Me" which can be used to expose the indicators. |
4261 | -*/ |
4262 | -Item { |
4263 | - id: shell |
4264 | - width: units.gu(40) |
4265 | - height: units.gu(80) |
4266 | - |
4267 | - PanelBackground { |
4268 | - anchors.fill: indicators |
4269 | - } |
4270 | - |
4271 | - Indicators { |
4272 | - id: indicators |
4273 | - anchors { |
4274 | - right: parent.right |
4275 | - } |
4276 | - width: (shell.width > units.gu(60)) ? units.gu(40) : shell.width |
4277 | - y: 0 |
4278 | - shown: false |
4279 | - profile: "test1" |
4280 | - |
4281 | - openedHeight: parent.height - button.height |
4282 | - } |
4283 | - |
4284 | - UC.Button { |
4285 | - id: button |
4286 | - text: indicators.shown ? "Hide" : "Show" |
4287 | - anchors { |
4288 | - bottom: shell.bottom |
4289 | - left: parent.left |
4290 | - right: parent.right |
4291 | - } |
4292 | - height: 50 |
4293 | - |
4294 | - onClicked: { |
4295 | - if (!indicators.shown) { |
4296 | - indicators.show(); |
4297 | - } else { |
4298 | - indicators.hide(); |
4299 | - } |
4300 | - } |
4301 | - } |
4302 | - |
4303 | - UT.UnityTestCase { |
4304 | - name: "Indicators" |
4305 | - when: windowShown |
4306 | - |
4307 | - function init() { |
4308 | - indicators.initialise(); |
4309 | - |
4310 | - indicators.hide(); |
4311 | - tryCompare(indicators.hideAnimation, "running", false); |
4312 | - tryCompare(indicators, "state", "initial"); |
4313 | - } |
4314 | - |
4315 | - // Showing the indicators should fully open the indicator panel. |
4316 | - function test_show() { |
4317 | - indicators.show() |
4318 | - tryCompare(indicators, "fullyOpened", true); |
4319 | - } |
4320 | - |
4321 | - // Test the change in the revealer lateral position changes the current panel menu to fit the position |
4322 | - // of the indicator in the row. |
4323 | - function test_change_revealer_lateral_position() |
4324 | - { |
4325 | - // tests changing the lateral position of the revealer activates the correct indicator items. |
4326 | - |
4327 | - var indicatorRow = findChild(indicators, "indicatorRow") |
4328 | - verify(indicatorRow !== null); |
4329 | - var indicatorRowItems = findChild(indicatorRow, "indicatorRowItems"); |
4330 | - verify(indicatorRowItems !== null); |
4331 | - |
4332 | - for (var i = 0; i < indicatorRowItems.count; i++) { |
4333 | - var indicatorItem = findChild(indicatorRowItems, "item" + i); |
4334 | - |
4335 | - if (!indicatorItem.visible) |
4336 | - continue; |
4337 | - |
4338 | - var indicatorPosition = indicators.mapFromItem(indicatorItem, |
4339 | - indicatorItem.width/2, indicatorItem.height/2); |
4340 | - |
4341 | - touchFlick(indicators, |
4342 | - indicatorPosition.x, indicatorPosition.y, |
4343 | - indicatorPosition.x, indicators.openedHeight * 0.4, |
4344 | - true /* beginTouch */, false /* endTouch */); |
4345 | - |
4346 | - compare(indicatorRow.currentItem, indicatorItem, |
4347 | - "Incorrect item activated at position " + i); |
4348 | - |
4349 | - touchFlick(indicators, |
4350 | - indicatorPosition.x, indicators.openedHeight * 0.4, |
4351 | - indicatorPosition.x, indicatorPosition.y, |
4352 | - false /* beginTouch */, true /* endTouch */); |
4353 | - |
4354 | - // wait until fully closed |
4355 | - tryCompare(indicators, "height", indicators.panelHeight); |
4356 | - } |
4357 | - } |
4358 | - |
4359 | - // values for specific state changes are subject to internal decisions, so we can't |
4360 | - // determine the true height value which would cause the state to change without making |
4361 | - // too many assuptyions |
4362 | - // However, we can assume that a partially opened panel will not be initial, and fully |
4363 | - // opened panel will be locked. |
4364 | - |
4365 | - function test_progress_changes_state_to_not_initial() { |
4366 | - indicators.height = indicators.openedHeight / 2 |
4367 | - compare(indicators.state!="initial", true, |
4368 | - "Indicators should not be in initial state when partially opened."); |
4369 | - } |
4370 | - |
4371 | - function test_progress_changes_state_to_locked() { |
4372 | - indicators.height = indicators.openedHeight - indicators.panelHeight |
4373 | - compare(indicators.state, "locked", "Indicators should be locked when fully opened."); |
4374 | - } |
4375 | - |
4376 | - function test_partially_open() { |
4377 | - indicators.height = indicators.openedHeight / 2 |
4378 | - compare(indicators.partiallyOpened, true, |
4379 | - "Indicator should show as partially opened when height is half of openedHeight"); |
4380 | - compare(indicators.fullyOpened, false, |
4381 | - "Indicator should not show as fully opened when height is half of openedHeight"); |
4382 | - } |
4383 | - |
4384 | - function test_fully_open() { |
4385 | - indicators.height = indicators.openedHeight |
4386 | - compare(indicators.partiallyOpened, false); |
4387 | - compare(indicators.fullyOpened, true); |
4388 | - } |
4389 | - |
4390 | - function init_invisible_indicator(identifier) { |
4391 | - tryCompareFunction(function() { return findChild(indicators, identifier+"-delegate") !== undefined }, true); |
4392 | - var item = findChild(indicators, identifier+"-delegate"); |
4393 | - verify(item !== null); |
4394 | - |
4395 | - item.enabled = false; |
4396 | - } |
4397 | - |
4398 | - function test_row_visible_menuContent_visible_data() { return [ |
4399 | - {tag: "first", visible: [false, true, true, true, true] }, |
4400 | - {tag: "adjacent", visible: [true, false, false, true, true] }, |
4401 | - {tag: "bounds", visible: [false, true, true, true, false] }, |
4402 | - {tag: "disjoint", visible: [true, false, true, false, true] }, |
4403 | - {tag: "last", visible: [true, true, true, true, false] }]; |
4404 | - } |
4405 | - |
4406 | - function test_row_visible_menuContent_visible(data) { |
4407 | - indicators.show(); |
4408 | - |
4409 | - var contentListView = findChild(indicators, "indicatorsContentListView"); |
4410 | - var indicatorRowItems = findChild(indicators, "indicatorRowItems"); |
4411 | - |
4412 | - var count = data.visible.length |
4413 | - for (var i = 0; i< data.visible.length; i++) { |
4414 | - if (data.visible[i] === false) { |
4415 | - init_invisible_indicator("indicator-fake" + (i + 1)); |
4416 | - count--; |
4417 | - } |
4418 | - } |
4419 | - |
4420 | - tryCompare(indicatorRowItems, "count", count); |
4421 | - |
4422 | - for (i = 0; i < data.visible.length; i++) { |
4423 | - var widgetName = "indicator-fake" + (i + 1 + "-widget"); |
4424 | - var pageName = "indicator-fake" + (i + 1 + "-page"); |
4425 | - |
4426 | - // check for item |
4427 | - tryCompareFunction(function() { return findChild(indicatorRowItems, widgetName) !== null }, data.visible[i]); |
4428 | - |
4429 | - // check for tab |
4430 | - tryCompareFunction(function() { return findChild(contentListView, pageName) !== null }, data.visible[i]); |
4431 | - } |
4432 | - } |
4433 | - |
4434 | - function test_indicator_visible_correct_menu_data() { return [ |
4435 | - {tag: "current-first", currentIndex: 0, visible: [false, true, true, true, true], expectedIndex: 0, expextedMenu: "indicator-fake2" }, |
4436 | - {tag: "current-last", currentIndex: 4, visible: [true, true, true, true, false], expectedIndex: 3, expextedMenu: "indicator-fake4" }, |
4437 | - {tag: "after", currentIndex: 0, visible: [true, false, true, true, true], expectedIndex: 0, expextedMenu: "indicator-fake1" }, |
4438 | - {tag: "before", currentIndex: 1, visible: [false, true, true, true, true], expectedIndex: 1, expextedMenu: "indicator-fake2" }]; |
4439 | - } |
4440 | - |
4441 | - function test_indicator_visible_correct_menu(data) { |
4442 | - var contentListView = findChild(indicators, "indicatorsContentListView"); |
4443 | - var indicatorRow = findChild(indicators, "indicatorRow"); |
4444 | - |
4445 | - indicators.show(); |
4446 | - indicatorRow.setCurrentItemIndex(data.currentIndex); |
4447 | - tryCompare(indicators, "fullyOpened", true); |
4448 | - |
4449 | - for (var i = 0; i< data.visible.length; i++) { |
4450 | - if (data.visible[i] === false) { |
4451 | - init_invisible_indicator("indicator-fake" + (i + 1)); |
4452 | - } |
4453 | - } |
4454 | - |
4455 | - // check for current selected item |
4456 | - tryCompare(indicatorRow, "currentItemIndex", data.expectedIndex); |
4457 | - |
4458 | - // check for current selected tab |
4459 | - tryCompareFunction(function() { return findChild(contentListView, data.expextedMenu) === contentListView.currentItem }, true); |
4460 | - |
4461 | - } |
4462 | - } |
4463 | -} |
4464 | |
4465 | === added file 'tests/qmltests/Panel/tst_IndicatorsBar.qml' |
4466 | --- tests/qmltests/Panel/tst_IndicatorsBar.qml 1970-01-01 00:00:00 +0000 |
4467 | +++ tests/qmltests/Panel/tst_IndicatorsBar.qml 2014-10-21 21:16:05 +0000 |
4468 | @@ -0,0 +1,224 @@ |
4469 | +/* |
4470 | + * Copyright 2013-2014 Canonical Ltd. |
4471 | + * |
4472 | + * This program is free software; you can redistribute it and/or modify |
4473 | + * it under the terms of the GNU General Public License as published by |
4474 | + * the Free Software Foundation; version 3. |
4475 | + * |
4476 | + * This program is distributed in the hope that it will be useful, |
4477 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4478 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4479 | + * GNU General Public License for more details. |
4480 | + * |
4481 | + * You should have received a copy of the GNU General Public License |
4482 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4483 | + */ |
4484 | + |
4485 | +import QtQuick 2.1 |
4486 | +import QtQuick.Layouts 1.1 |
4487 | +import QtTest 1.0 |
4488 | +import "../../../qml/Panel" |
4489 | +import Ubuntu.Components 0.1 |
4490 | +import Unity.Test 0.1 as UT |
4491 | +import Unity.Indicators 0.1 as Indicators |
4492 | + |
4493 | +IndicatorTest { |
4494 | + id: root |
4495 | + width: units.gu(100) |
4496 | + height: units.gu(40) |
4497 | + |
4498 | + |
4499 | + RowLayout { |
4500 | + anchors.fill: parent |
4501 | + anchors.margins: units.gu(1) |
4502 | + |
4503 | + Rectangle { |
4504 | + id: itemArea |
4505 | + color: "blue" |
4506 | + Layout.fillWidth: true |
4507 | + Layout.fillHeight: true |
4508 | + |
4509 | + Rectangle { |
4510 | + color: "black" |
4511 | + anchors.fill: indicatorsBar |
4512 | + } |
4513 | + |
4514 | + IndicatorsBar { |
4515 | + id: indicatorsBar |
4516 | + height: expanded ? units.gu(7) : units.gu(3) |
4517 | + width: units.gu(30) |
4518 | + anchors.centerIn: parent |
4519 | + indicatorsModel: root.indicatorsModel |
4520 | + interactive: expanded && height === units.gu(7) |
4521 | + |
4522 | + Behavior on height { |
4523 | + NumberAnimation { |
4524 | + id: heightAnimation |
4525 | + duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing |
4526 | + } |
4527 | + } |
4528 | + |
4529 | + MouseArea { |
4530 | + anchors.fill: parent |
4531 | + enabled: !indicatorsBar.expanded |
4532 | + onPressed: { |
4533 | + indicatorsBar.selectItemAt(mouse.x); |
4534 | + indicatorsBar.expanded = true |
4535 | + } |
4536 | + } |
4537 | + } |
4538 | + } |
4539 | + |
4540 | + ColumnLayout { |
4541 | + Layout.alignment: Qt.AlignTop |
4542 | + Layout.fillWidth: false |
4543 | + |
4544 | + Button { |
4545 | + Layout.fillWidth: true |
4546 | + text: indicatorsBar.expanded ? "Collapse" : "Expand" |
4547 | + onClicked: indicatorsBar.expanded = !indicatorsBar.expanded |
4548 | + } |
4549 | + |
4550 | + Rectangle { |
4551 | + Layout.preferredHeight: units.dp(1); |
4552 | + Layout.fillWidth: true; |
4553 | + color: "black" |
4554 | + } |
4555 | + |
4556 | + Repeater { |
4557 | + model: root.originalModelData |
4558 | + RowLayout { |
4559 | + CheckBox { |
4560 | + checked: true |
4561 | + onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index); |
4562 | + } |
4563 | + Label { |
4564 | + Layout.fillWidth: true |
4565 | + text: modelData["identifier"] |
4566 | + } |
4567 | + |
4568 | + CheckBox { |
4569 | + checked: true |
4570 | + onCheckedChanged: setIndicatorVisible(index, checked); |
4571 | + } |
4572 | + Label { |
4573 | + text: "visible" |
4574 | + } |
4575 | + } |
4576 | + } |
4577 | + } |
4578 | + } |
4579 | + |
4580 | + UT.UnityTestCase { |
4581 | + name: "IndicatorsBar" |
4582 | + when: windowShown |
4583 | + |
4584 | + function init() { |
4585 | + indicatorsBar.expanded = false; |
4586 | + wait_for_expansion_to_settle(); |
4587 | + } |
4588 | + |
4589 | + function test_expandSelectedItem_data() { |
4590 | + return [ |
4591 | + { index: 0 }, |
4592 | + { index: 2 }, |
4593 | + { index: 4 } |
4594 | + ]; |
4595 | + } |
4596 | + |
4597 | + function wait_for_expansion_to_settle() { |
4598 | + tryCompare(heightAnimation, "running", false); |
4599 | + wait(UbuntuAnimation.SnapDuration); // put a little extra wait in for things to settle |
4600 | + } |
4601 | + |
4602 | + // Rough check that expanding a selected item keeps it within the area of the original item. |
4603 | + function test_expandSelectedItem(data) { |
4604 | + var dataItem = findChild(indicatorsBar, root.originalModelData[data.index]["identifier"] + "-panelItem"); |
4605 | + verify(dataItem !== null); |
4606 | + |
4607 | + var mappedPosition = indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2); |
4608 | + |
4609 | + indicatorsBar.selectItemAt(mappedPosition.x); |
4610 | + indicatorsBar.expanded = true; |
4611 | + wait_for_expansion_to_settle(); |
4612 | + |
4613 | + |
4614 | + // mappedPosition contained within mappedRect |
4615 | + tryCompareFunction(function() { |
4616 | + var mappedRect = indicatorsBar.mapFromItem(dataItem, 0, 0, dataItem.width, dataItem.height); |
4617 | + return mappedRect.x <= mappedPosition.x; }, |
4618 | + true); |
4619 | + tryCompareFunction(function() { |
4620 | + var mappedRect = indicatorsBar.mapFromItem(dataItem, 0, 0, dataItem.width, dataItem.height); |
4621 | + return mappedRect.x + mappedRect.width >= mappedPosition.x; |
4622 | + }, true); |
4623 | + } |
4624 | + |
4625 | + function test_scrollOffset() { |
4626 | + indicatorsBar.expanded = true; |
4627 | + wait_for_expansion_to_settle(); |
4628 | + |
4629 | + var lastItemIndex = root.originalModelData.length-1; |
4630 | + var dataItem = findChild(indicatorsBar, root.originalModelData[lastItemIndex]["identifier"] + "-panelItem"); |
4631 | + verify(dataItem !== null); |
4632 | + |
4633 | + var row = findChild(indicatorsBar, "indicatorItemRow"); |
4634 | + // test will not work without these conditions |
4635 | + verify(row.width >= indicatorsBar.width + dataItem.width); |
4636 | + |
4637 | + var mappedPosition = indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2); |
4638 | + indicatorsBar.addScrollOffset(-dataItem.width); |
4639 | + var newMappedPosition = indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2); |
4640 | + |
4641 | + compare(mappedPosition.x, newMappedPosition.x - dataItem.width); |
4642 | + } |
4643 | + |
4644 | + function test_selectItemWhenExpanded_data() { |
4645 | + return [ |
4646 | + { index: 3 }, |
4647 | + { index: 4 } |
4648 | + ]; |
4649 | + } |
4650 | + |
4651 | + function test_selectItemWhenExpanded(data) { |
4652 | + indicatorsBar.expanded = true; |
4653 | + wait_for_expansion_to_settle(); |
4654 | + |
4655 | + var dataItem = findChild(indicatorsBar, root.originalModelData[data.index]["identifier"] + "-panelItem"); |
4656 | + if (indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2).x < 0) { |
4657 | + skip("Out of bounds"); |
4658 | + } |
4659 | + mouseClick(dataItem, dataItem.width/2, dataItem.height/2); |
4660 | + verify(dataItem.selected === true); |
4661 | + } |
4662 | + |
4663 | + function test_visibleIndicators_data() { |
4664 | + return [ |
4665 | + { visible: [true, false, true, false, true, true] }, |
4666 | + { visible: [false, false, false, false, false, false] } |
4667 | + ]; |
4668 | + } |
4669 | + |
4670 | + function test_visibleIndicators(data) { |
4671 | + for (var i = 0; i < data.visible.length; i++) { |
4672 | + var visible = data.visible[i]; |
4673 | + root.setIndicatorVisible(i, visible); |
4674 | + |
4675 | + var dataItem = findChild(indicatorsBar, root.originalModelData[i]["identifier"] + "-panelItem"); |
4676 | + tryCompare(dataItem, "opacity", visible ? 1.0 : 0.0); |
4677 | + tryCompareFunction(function() { return dataItem.width > 0.0; }, visible); |
4678 | + } |
4679 | + |
4680 | + indicatorsBar.expanded = true; |
4681 | + wait_for_expansion_to_settle(); |
4682 | + |
4683 | + for (var i = 0; i < data.visible.length; i++) { |
4684 | + root.setIndicatorVisible(i, data.visible[i]); |
4685 | + |
4686 | + var dataItem = findChild(indicatorsBar, root.originalModelData[i]["identifier"] + "-panelItem"); |
4687 | + tryCompareFunction(function() { return dataItem.opacity > 0.0; }, true); |
4688 | + tryCompareFunction(function() { return dataItem.width > 0.0; }, true); |
4689 | + } |
4690 | + } |
4691 | + } |
4692 | +} |
4693 | |
4694 | === added file 'tests/qmltests/Panel/tst_IndicatorsMenu.qml' |
4695 | --- tests/qmltests/Panel/tst_IndicatorsMenu.qml 1970-01-01 00:00:00 +0000 |
4696 | +++ tests/qmltests/Panel/tst_IndicatorsMenu.qml 2014-10-21 21:16:05 +0000 |
4697 | @@ -0,0 +1,258 @@ |
4698 | +/* |
4699 | + * Copyright 2013-2014 Canonical Ltd. |
4700 | + * |
4701 | + * This program is free software; you can redistribute it and/or modify |
4702 | + * it under the terms of the GNU General Public License as published by |
4703 | + * the Free Software Foundation; version 3. |
4704 | + * |
4705 | + * This program is distributed in the hope that it will be useful, |
4706 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4707 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4708 | + * GNU General Public License for more details. |
4709 | + * |
4710 | + * You should have received a copy of the GNU General Public License |
4711 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4712 | + */ |
4713 | + |
4714 | +import QtQuick 2.1 |
4715 | +import QtQuick.Layouts 1.1 |
4716 | +import QtTest 1.0 |
4717 | +import "../../../qml/Panel" |
4718 | +import Ubuntu.Components 0.1 |
4719 | +import Unity.Test 0.1 as UT |
4720 | +import Unity.Indicators 0.1 as Indicators |
4721 | + |
4722 | +IndicatorTest { |
4723 | + id: root |
4724 | + width: units.gu(80) |
4725 | + height: units.gu(71) |
4726 | + color: "white" |
4727 | + |
4728 | + property string indicatorProfile: "phone" |
4729 | + |
4730 | + RowLayout { |
4731 | + anchors.fill: parent |
4732 | + anchors.margins: units.gu(1) |
4733 | + |
4734 | + Rectangle { |
4735 | + Layout.fillWidth: true |
4736 | + Layout.fillHeight: true |
4737 | + |
4738 | + id: itemArea |
4739 | + color: "blue" |
4740 | + |
4741 | + IndicatorsMenu { |
4742 | + id: indicatorsMenu |
4743 | + width: units.gu(40) |
4744 | + anchors { |
4745 | + top: parent.top |
4746 | + right: parent.right |
4747 | + } |
4748 | + minimizedPanelHeight: units.gu(3) |
4749 | + expandedPanelHeight: units.gu(7) |
4750 | + openedHeight: parent.height |
4751 | + indicatorsModel: root.indicatorsModel |
4752 | + shown: false |
4753 | + } |
4754 | + } |
4755 | + |
4756 | + ColumnLayout { |
4757 | + Layout.alignment: Qt.AlignTop |
4758 | + Layout.fillWidth: false |
4759 | + |
4760 | + Button { |
4761 | + Layout.fillWidth: true |
4762 | + text: indicatorsMenu.shown ? "Hide" : "Show" |
4763 | + onClicked: { |
4764 | + if (indicatorsMenu.shown) { |
4765 | + indicatorsMenu.hide(); |
4766 | + } else { |
4767 | + indicatorsMenu.show(); |
4768 | + } |
4769 | + } |
4770 | + } |
4771 | + |
4772 | + Rectangle { |
4773 | + Layout.preferredHeight: units.dp(1); |
4774 | + Layout.fillWidth: true; |
4775 | + color: "black" |
4776 | + } |
4777 | + |
4778 | + Repeater { |
4779 | + model: root.originalModelData |
4780 | + RowLayout { |
4781 | + CheckBox { |
4782 | + checked: true |
4783 | + onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index); |
4784 | + } |
4785 | + Label { |
4786 | + Layout.fillWidth: true |
4787 | + text: modelData["identifier"] |
4788 | + } |
4789 | + |
4790 | + CheckBox { |
4791 | + checked: true |
4792 | + onCheckedChanged: setIndicatorVisible(index, checked); |
4793 | + } |
4794 | + Label { |
4795 | + text: "visible" |
4796 | + } |
4797 | + } |
4798 | + } |
4799 | + } |
4800 | + } |
4801 | + |
4802 | + UT.UnityTestCase { |
4803 | + id: testCase |
4804 | + name: "IndicatorsMenu" |
4805 | + when: windowShown |
4806 | + |
4807 | + function init() { |
4808 | + indicatorsMenu.hide(); |
4809 | + tryCompare(indicatorsMenu.hideAnimation, "running", false); |
4810 | + compare(indicatorsMenu.state, "initial"); |
4811 | + |
4812 | + indicatorsMenu.verticalVelocityThreshold = 0.5 |
4813 | + } |
4814 | + |
4815 | + function get_indicator_item(index) { |
4816 | + var indicatorItem = findChild(indicatorsMenu, root.originalModelData[index]["identifier"] + "-panelItem"); |
4817 | + verify(indicatorItem !== null); |
4818 | + |
4819 | + return indicatorItem; |
4820 | + } |
4821 | + |
4822 | + // Showing the indicators should fully open the indicator panel. |
4823 | + function test_showAndHide() { |
4824 | + indicatorsMenu.show(); |
4825 | + tryCompare(indicatorsMenu, "fullyOpened", true); |
4826 | + |
4827 | + indicatorsMenu.hide(); |
4828 | + tryCompare(indicatorsMenu, "fullyClosed", true); |
4829 | + } |
4830 | + |
4831 | + // Test that closing the indicators ends up in the correct position. |
4832 | + function test_hideEndsInCorrectPosition() { |
4833 | + var indicatorsBar = findChild(indicatorsMenu, "indicatorsBar"); |
4834 | + var flickable = findChild(indicatorsBar, "flickable"); |
4835 | + |
4836 | + var originalContentX = flickable.contentX; |
4837 | + |
4838 | + indicatorsMenu.show(); |
4839 | + indicatorsBar.setCurrentItemIndex(0); |
4840 | + tryCompare(indicatorsMenu, "fullyOpened", true); |
4841 | + |
4842 | + indicatorsMenu.hide(); |
4843 | + tryCompare(flickable, "contentX", originalContentX); |
4844 | + } |
4845 | + |
4846 | + function test_progress_changes_state_to_reveal() { |
4847 | + indicatorsMenu.height = indicatorsMenu.openedHeight / 2; |
4848 | + compare(indicatorsMenu.state, "reveal", "Indicators should be revealing when partially opened."); |
4849 | + |
4850 | + indicatorsMenu.height = indicatorsMenu.openedHeight; |
4851 | + compare(indicatorsMenu.state, "reveal", "Indicators should still be revealing when fully opened."); |
4852 | + } |
4853 | + |
4854 | + function test_open_state() { |
4855 | + compare(indicatorsMenu.fullyClosed, true, "Indicator should show as fully closed."); |
4856 | + compare(indicatorsMenu.partiallyOpened, false, "Indicator should not show as partially opened"); |
4857 | + compare(indicatorsMenu.fullyOpened, false, "Indicator should not show as fully opened"); |
4858 | + |
4859 | + indicatorsMenu.height = indicatorsMenu.openedHeight / 2 |
4860 | + compare(indicatorsMenu.fullyClosed, false, "Indicator should not show as fully closed."); |
4861 | + compare(indicatorsMenu.partiallyOpened, true, "Indicator should show as partially opened"); |
4862 | + compare(indicatorsMenu.fullyOpened, false, "Indicator should not show as fully opened"); |
4863 | + |
4864 | + indicatorsMenu.height = indicatorsMenu.openedHeight; |
4865 | + compare(indicatorsMenu.fullyClosed, false, "Indicator should not show as fully closed."); |
4866 | + compare(indicatorsMenu.partiallyOpened, false, "Indicator should show as partially opened"); |
4867 | + compare(indicatorsMenu.fullyOpened, true, "Indicator should not show as fully opened"); |
4868 | + } |
4869 | + |
4870 | + // Pressing on the indicator panel should activate the indicator hints |
4871 | + // and expose the header |
4872 | + function test_hint() { |
4873 | + var indicatorItem = get_indicator_item(0); |
4874 | + var mappedPosition = root.mapFromItem(indicatorItem, indicatorItem.width/2, indicatorItem.height/2); |
4875 | + |
4876 | + touchPress(indicatorsMenu, mappedPosition.x, indicatorsMenu.minimizedPanelHeight / 2); |
4877 | + |
4878 | + // hint animation should be run, meaning that indicators will move downwards |
4879 | + // by hintValue pixels without any drag taking place |
4880 | + tryCompareFunction(function() { return indicatorsMenu.height }, indicatorsMenu.expandedPanelHeight + units.gu(2)); |
4881 | + tryCompare(indicatorsMenu, "partiallyOpened", true); |
4882 | + |
4883 | + touchRelease(indicatorsMenu, mappedPosition.x, indicatorsMenu.minimizedPanelHeight / 2); |
4884 | + } |
4885 | + |
4886 | + // tests swiping on an indicator item activates the correct item. |
4887 | + function test_swipeForCurrentItem() |
4888 | + { |
4889 | + var indicatorItemRow = findChild(indicatorsMenu, "indicatorItemRow"); |
4890 | + verify(indicatorItemRow !== null); |
4891 | + |
4892 | + for (var i = 0; i < root.originalModelData.length; i++) { |
4893 | + var indicatorItem = get_indicator_item(i); |
4894 | + |
4895 | + var mappedPosition = root.mapFromItem(indicatorItem, indicatorItem.width/2, indicatorItem.height/2); |
4896 | + |
4897 | + touchFlick(indicatorsMenu, |
4898 | + mappedPosition.x, mappedPosition.y, |
4899 | + mappedPosition.x, indicatorsMenu.openedHeight / 2, |
4900 | + true /* beginTouch */, false /* endTouch */); |
4901 | + |
4902 | + compare(indicatorItemRow.currentItem, indicatorItem, |
4903 | + "Incorrect item activated at position " + i); |
4904 | + |
4905 | + touchFlick(indicatorItemRow, |
4906 | + mappedPosition.x, indicatorsMenu.openedHeight / 2, |
4907 | + mappedPosition.x, mappedPosition.y, |
4908 | + false /* beginTouch */, true /* endTouch */); |
4909 | + |
4910 | + // wait until fully closed |
4911 | + tryCompare(indicatorsMenu, "fullyClosed", true); |
4912 | + } |
4913 | + } |
4914 | + |
4915 | + // Test the vertical velocity check when flicking the indicators open at an angle. |
4916 | + // If the vertical velocity is above a specific point, we shouldnt change active indicators |
4917 | + // if the x position changes |
4918 | + function test_verticalVelocityDetector() { |
4919 | + indicatorsMenu.verticalVelocityThreshold = 0; |
4920 | + verify(root.originalModelData.length >= 2); |
4921 | + |
4922 | + var indicatorItemRow = findChild(indicatorsMenu, "indicatorItemRow"); |
4923 | + verify(indicatorItemRow !== null); |
4924 | + |
4925 | + // Get the first indicator |
4926 | + var firstItem = get_indicator_item(0); |
4927 | + var firstItemMappedPosition = root.mapFromItem(firstItem, firstItem.width/2, firstItem.height/2); |
4928 | + |
4929 | + // 1) Drag the mouse down to hint a bit |
4930 | + touchFlick(indicatorsMenu, |
4931 | + firstItemMappedPosition.x, indicatorsMenu.minimizedPanelHeight / 2, |
4932 | + firstItemMappedPosition.x, indicatorsMenu.minimizedPanelHeight * 2, |
4933 | + true /* beginTouch */, false /* endTouch */); |
4934 | + |
4935 | + tryCompare(indicatorItemRow, "currentItem", firstItem) |
4936 | + |
4937 | + // next time position will have moved. |
4938 | + var nextItem = get_indicator_item(1); |
4939 | + var nextItemMappedPosition = root.mapFromItem(nextItem, nextItem.width/2, nextItem.height/2); |
4940 | + |
4941 | + // 1) Flick mouse down to bottom |
4942 | + touchFlick(indicatorsMenu, |
4943 | + firstItemMappedPosition.x, indicatorsMenu.minimizedPanelHeight * 2, |
4944 | + nextItemMappedPosition.x, indicatorsMenu.openedHeight / 3, |
4945 | + false /* beginTouch */, false /* endTouch */, |
4946 | + units.gu(50) /* speed */, 5 /* iterations */); // more samples needed for accurate velocity |
4947 | + |
4948 | + compare(indicatorItemRow.currentItem, firstItem, "First indicator should still be the current item"); |
4949 | + // after waiting in the same spot with touch down, it should update to the next item. |
4950 | + tryCompare(indicatorItemRow, "currentItem", nextItem); |
4951 | + |
4952 | + touchRelease(indicatorsMenu, nextItemMappedPosition.x, indicatorsMenu.openedHeight / 3); |
4953 | + } |
4954 | + } |
4955 | +} |
4956 | |
4957 | === modified file 'tests/qmltests/Panel/tst_MenuContent.qml' |
4958 | --- tests/qmltests/Panel/tst_MenuContent.qml 2014-10-21 21:16:04 +0000 |
4959 | +++ tests/qmltests/Panel/tst_MenuContent.qml 2014-10-21 21:16:05 +0000 |
4960 | @@ -1,5 +1,5 @@ |
4961 | /* |
4962 | - * Copyright 2013 Canonical Ltd. |
4963 | + * Copyright 2013-2014 Canonical Ltd. |
4964 | * |
4965 | * This program is free software; you can redistribute it and/or modify |
4966 | * it under the terms of the GNU General Public License as published by |
4967 | @@ -17,12 +17,11 @@ |
4968 | import QtQuick 2.0 |
4969 | import QtTest 1.0 |
4970 | import Unity.Test 0.1 as UT |
4971 | -import ".." |
4972 | import "../../../qml/Panel" |
4973 | import Unity.Indicators 0.1 as Indicators |
4974 | |
4975 | -Item { |
4976 | - id: shell |
4977 | +IndicatorTest { |
4978 | + id: root |
4979 | width: units.gu(40) |
4980 | height: units.gu(70) |
4981 | |
4982 | @@ -30,15 +29,9 @@ |
4983 | Item { id: greeter } |
4984 | Item { id: handle } |
4985 | |
4986 | - |
4987 | - Indicators.IndicatorsModel { |
4988 | - id: indicatorsModel |
4989 | - Component.onCompleted: load("test1") |
4990 | - } |
4991 | - |
4992 | MenuContent { |
4993 | id: menuContent |
4994 | - indicatorsModel: indicatorsModel |
4995 | + indicatorsModel: root.indicatorsModel |
4996 | height: parent.height - 50 |
4997 | } |
4998 | |
4999 | @@ -70,12 +63,12 @@ |
5000 | if (menuContent.currentMenuIndex == -1) |
FAILED: Continuous integration, rev:1294 jenkins. qa.ubuntu. com/job/ unity8- ci/4515/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/5580 jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- utopic/ 1500 jenkins. qa.ubuntu. com/job/ unity8- utopic- amd64-ci/ 1609 jenkins. qa.ubuntu. com/job/ unity8- utopic- i386-ci/ 1609 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/5273 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/6832 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/6832/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 14250
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/4515/ rebuild
http://