Merge lp:~bzoltan/ubuntu-ui-toolkit/landing-2015-09-04 into lp:ubuntu-ui-toolkit
- landing-2015-09-04
- Merge into trunk
Proposed by
Zoltan Balogh
Status: | Merged |
---|---|
Approved by: | Zoltan Balogh |
Approved revision: | 1629 |
Merged at revision: | 1224 |
Proposed branch: | lp:~bzoltan/ubuntu-ui-toolkit/landing-2015-09-04 |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
9558 lines (+6169/-1099) 129 files modified
.bzrignore (+11/-11) .qmake.conf (+4/-0) components.api (+44/-31) debian/changelog (+58/-0) debian/control (+5/-0) documentation/documentation.pro (+1/-1) documentation/ubuntu-ui-toolkit-common.qdocconf (+1/-1) examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml (+23/-2) features/ubuntu_enable_testing.prf (+1/-1) features/ubuntu_qml_plugin.prf (+52/-51) po/po.pro (+1/-1) src/Ubuntu/Components/1.1/Haptics.qml (+0/-91) src/Ubuntu/Components/1.2/ActionItem.qml (+0/-96) src/Ubuntu/Components/1.2/TextField.qml (+1/-1) src/Ubuntu/Components/1.2/TextInputPopover.qml (+1/-0) src/Ubuntu/Components/1.2/ToolbarButton.qml (+1/-0) src/Ubuntu/Components/1.3/AbstractButton.qml (+0/-109) src/Ubuntu/Components/1.3/ActionItem.qml (+0/-96) src/Ubuntu/Components/1.3/AdaptivePageLayout.qml (+266/-30) src/Ubuntu/Components/1.3/AppHeader.qml (+1/-6) src/Ubuntu/Components/1.3/Button.qml (+1/-1) src/Ubuntu/Components/1.3/ComboButton.qml (+1/-0) src/Ubuntu/Components/1.3/Header.qml (+0/-39) src/Ubuntu/Components/1.3/MainView.qml (+0/-3) src/Ubuntu/Components/1.3/MainViewBase.qml (+24/-27) src/Ubuntu/Components/1.3/PageColumn.qml (+16/-11) src/Ubuntu/Components/1.3/PageColumnsLayout.qml (+115/-0) src/Ubuntu/Components/1.3/PageWrapper.qml (+25/-2) src/Ubuntu/Components/1.3/PageWrapperUtils.js (+167/-0) src/Ubuntu/Components/1.3/TextField.qml (+2/-2) src/Ubuntu/Components/ComponentModule.pro (+7/-8) src/Ubuntu/Components/ListItems/1.3/SingleControl.qml (+2/-1) src/Ubuntu/Components/Popups/1.3/Popover.qml (+1/-1) src/Ubuntu/Components/Themes/Ambiance/1.2/ListItemStyle.qml (+14/-1) src/Ubuntu/Components/Themes/Ambiance/1.3/ActionBarStyle.qml (+0/-2) src/Ubuntu/Components/Themes/Ambiance/1.3/HeadDividerStyle.qml (+0/-56) src/Ubuntu/Components/Themes/Ambiance/1.3/HeaderStyle.qml (+0/-124) src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml (+65/-0) src/Ubuntu/Components/Themes/Ambiance/1.3/OverflowPanel.qml (+1/-1) src/Ubuntu/Components/Themes/Ambiance/Ambiance.pro (+0/-2) src/Ubuntu/Components/plugin/adapters/actionsproxy_p.cpp (+7/-7) src/Ubuntu/Components/plugin/adapters/actionsproxy_p.h (+1/-1) src/Ubuntu/Components/plugin/i18n.cpp (+74/-0) src/Ubuntu/Components/plugin/i18n.h (+1/-0) src/Ubuntu/Components/plugin/plugin.cpp (+18/-0) src/Ubuntu/Components/plugin/plugin.pri (+9/-2) src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp (+2/-3) src/Ubuntu/Components/plugin/privates/listitemdragarea.h (+1/-1) src/Ubuntu/Components/plugin/privates/listitemexpansion.cpp (+106/-0) src/Ubuntu/Components/plugin/sortfiltermodel.cpp (+6/-3) src/Ubuntu/Components/plugin/timeutils_p.h (+24/-0) src/Ubuntu/Components/plugin/ucabstractbutton.cpp (+156/-0) src/Ubuntu/Components/plugin/ucabstractbutton.h (+64/-0) src/Ubuntu/Components/plugin/ucaction.cpp (+5/-5) src/Ubuntu/Components/plugin/ucaction.h (+8/-7) src/Ubuntu/Components/plugin/ucactioncontext.cpp (+6/-1) src/Ubuntu/Components/plugin/ucactioncontext.h (+3/-2) src/Ubuntu/Components/plugin/ucactionitem.cpp (+316/-0) src/Ubuntu/Components/plugin/ucactionitem.h (+79/-0) src/Ubuntu/Components/plugin/uchaptics.cpp (+179/-0) src/Ubuntu/Components/plugin/uchaptics.h (+78/-0) src/Ubuntu/Components/plugin/uclistitem.cpp (+134/-22) src/Ubuntu/Components/plugin/uclistitem.h (+76/-1) src/Ubuntu/Components/plugin/uclistitem_p.h (+15/-6) src/Ubuntu/Components/plugin/uclistitemstyle.cpp (+38/-9) src/Ubuntu/Components/plugin/uclistitemstyle.h (+6/-0) src/Ubuntu/Components/plugin/ucqquickimageextension.cpp (+23/-3) src/Ubuntu/Components/plugin/ucstatesaver.cpp (+2/-2) src/Ubuntu/Components/plugin/ucubuntushape.cpp (+45/-34) src/Ubuntu/Components/plugin/ucubuntushape.h (+0/-1) src/Ubuntu/Components/plugin/ucunits.cpp (+46/-5) src/Ubuntu/Components/plugin/ucunits.h (+1/-0) src/Ubuntu/Components/plugin/ucviewitemsattached.cpp (+141/-1) src/Ubuntu/Components/qmldir (+2/-8) tests/apicheck/apicheck.cpp (+8/-4) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_tabbar.py (+6/-1) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textarea.py (+16/-20) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py (+34/-48) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_toolbar.py (+1/-1) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py (+5/-1) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.1.3.qml (+62/-0) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.new_header.1.3.qml (+43/-0) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py (+6/-0) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.1.0.qml (+37/-0) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.1.3.qml (+37/-0) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py (+15/-31) tests/resources/listitems/ListItemExpansion.qml (+121/-0) tests/unit/add_makecheck.pri (+12/-1) tests/unit/custom_qpa/README (+15/-0) tests/unit/custom_qpa/custom.json (+3/-0) tests/unit/custom_qpa/custom_qpa.pro (+15/-0) tests/unit/custom_qpa/main.cpp (+54/-0) tests/unit/custom_qpa/qcustombackingstore.cpp (+64/-0) tests/unit/custom_qpa/qcustombackingstore.h (+55/-0) tests/unit/custom_qpa/qcustomintegration.cpp (+112/-0) tests/unit/custom_qpa/qcustomintegration.h (+74/-0) tests/unit/runtest.sh (+2/-0) tests/unit/tst_components/tst_action.qml (+16/-0) tests/unit/tst_components/tst_actionitem.qml (+13/-5) tests/unit/tst_i18n/tst_i18n.pro (+3/-18) tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/LocalizedApp.qml (+43/-1) tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/tst_i18n_LocalizedApp.cpp (+5/-5) tests/unit/tst_i18n/tst_i18n_LocalizedApp/tst_i18n_LocalizedApp.pro (+17/-0) tests/unit/tst_i18n/tst_i18n_RelativeTime/po/en_US.po (+54/-0) tests/unit/tst_i18n/tst_i18n_RelativeTime/src/RelativeTime.qml (+71/-0) tests/unit/tst_i18n/tst_i18n_RelativeTime/src/tst_i18n_RelativeTime.cpp (+202/-0) tests/unit/tst_i18n/tst_i18n_RelativeTime/tst_i18n_RelativeTime.pro (+17/-0) tests/unit/tst_performance/AbstractButton13Grid.qml (+30/-0) tests/unit/tst_performance/AbstractButtonGrid.qml (+30/-0) tests/unit/tst_performance/tst_performance.cpp (+2/-0) tests/unit/tst_performance/tst_performance.pro (+3/-1) tests/unit/tst_units/dpr1/dpr1.pro (+3/-0) tests/unit/tst_units/dpr2/dpr2.pro (+3/-0) tests/unit/tst_units/dpr2/tst_units_dpr2.cpp (+143/-0) tests/unit/tst_units/dpr3/dpr3.pro (+3/-0) tests/unit/tst_units/dpr3/tst_units_dpr3.cpp (+88/-0) tests/unit/tst_units/tst_units.pro (+6/-3) tests/unit/unit.pro (+3/-1) tests/unit_x11/tst_components/ListItemTestCase.qml (+6/-0) tests/unit_x11/tst_components/ListItemTestCase13.qml (+143/-0) tests/unit_x11/tst_components/tst_abstractbutton13.qml (+115/-0) tests/unit_x11/tst_components/tst_adaptivepagelayout.qml (+63/-0) tests/unit_x11/tst_components/tst_adaptivepagelayout_configuration.qml (+229/-0) tests/unit_x11/tst_components/tst_listitem.qml (+1/-21) tests/unit_x11/tst_components/tst_listitem13.qml (+1211/-0) tests/unit_x11/tst_components/tst_listitem_expansion.qml (+199/-0) tests/unit_x11/tst_components/tst_listitem_extras.qml (+28/-2) tests/unit_x11/tst_components/tst_multicolumnheader.qml (+37/-1) ubuntu-sdk.pro (+1/-1) |
To merge this branch: | bzr merge lp:~bzoltan/ubuntu-ui-toolkit/landing-2015-09-04 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu SDK team | Pending | ||
Review via email: mp+270197@code.launchpad.net |
Commit message
Landing 2015.09.04
Description of the change
Landing 2015.09.04
To post a comment you must log in.
- 1630. By Zoltan Balogh
-
Cope with different AbstractButton class name in 1.3
- 1631. By Zoltan Balogh
-
license fix
- 1632. By Zoltan Balogh
-
update
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2015-05-20 14:47:16 +0000 |
3 | +++ .bzrignore 2015-09-08 04:09:38 +0000 |
4 | @@ -1,25 +1,25 @@ |
5 | +.obj |
6 | +.pch |
7 | +.qmake.cache |
8 | +.rcc |
9 | +qml |
10 | + |
11 | Makefile* |
12 | -src/Makefile* |
13 | -src/Ubuntu/Components/Makefile* |
14 | -src/Ubuntu/Components/plugin/Makefile* |
15 | -src/Ubuntu/Components/plugin/qrc_plugin.cpp |
16 | -src/Ubuntu/Components/Themes/Makefile* |
17 | -src/Ubuntu/Components/Layouts/Makefile* |
18 | -src/Ubuntu/Components/PerformanceMetrics/Makefile* |
19 | -src/Ubuntu/Test/Makefile* |
20 | documentation/html/* |
21 | *.moc |
22 | moc_*.cpp |
23 | qrc_tst_*.cpp |
24 | tests/test_tst_*.xml |
25 | tests/tst_*.qml.xml |
26 | -tests/unit*/tst_*/tst_[^.]* |
27 | +tests/unit*/tst_*/tst_* |
28 | +tests/unit/tst_*/tst_*/tst_* |
29 | tests/unit*/testparser/testparser |
30 | plugins.qmltypes |
31 | po/*.mo |
32 | examples/ubuntu-ui-toolkit-gallery/po/*.mo |
33 | -tests/unit/tst_i18n/locale/en/LC_MESSAGES/*.mo |
34 | +tests/unit/tst_i18n/tst_*/*/share/locale/en/LC_MESSAGES/*.mo |
35 | +tests/unit/tst_i18n/*/share/locale/en/LC_MESSAGES/*.mo |
36 | +tests/unit/tst_units/dpr*/dpr* |
37 | tests/apicheck/apicheck |
38 | tests/launcher/launcher |
39 | build_paths.inc |
40 | -tests/unit/tst_i18n/localizedApp/share/locale/en/LC_MESSAGES/localizedApp.mo |
41 | |
42 | === modified file '.qmake.conf' |
43 | --- .qmake.conf 2015-05-18 09:53:55 +0000 |
44 | +++ .qmake.conf 2015-09-08 04:09:38 +0000 |
45 | @@ -12,3 +12,7 @@ |
46 | |
47 | ROOT_SOURCE_DIR=$$PWD |
48 | ROOT_BUILD_DIR=$$shadowed($$PWD) |
49 | + |
50 | +exists($$PWD/../qt.pro) { |
51 | + CONFIG += build_with_qt |
52 | +} |
53 | |
54 | === modified file 'components.api' |
55 | --- components.api 2015-08-12 09:55:50 +0000 |
56 | +++ components.api 2015-09-08 04:09:38 +0000 |
57 | @@ -4,10 +4,10 @@ |
58 | signal pressAndHold() |
59 | property bool pressed |
60 | Ubuntu.Components.AbstractButton 1.3: ActionItem |
61 | - property bool hovered |
62 | + readonly property bool hovered |
63 | signal clicked() |
64 | signal pressAndHold() |
65 | - property bool pressed |
66 | + readonly property bool pressed |
67 | Ubuntu.Components.Action 1.3 1.0 0.1: QtObject |
68 | property string description |
69 | property bool enabled |
70 | @@ -43,14 +43,8 @@ |
71 | property string iconName |
72 | property url iconSource |
73 | signal triggered(var value) |
74 | - function var trigger(var value) |
75 | - property string text |
76 | -Ubuntu.Components.ActionItem 1.3: StyledItem |
77 | - property Action action |
78 | - property string iconName |
79 | - property url iconSource |
80 | - signal triggered(var value) |
81 | - function var trigger(var value) |
82 | + function trigger(var value) |
83 | + function trigger() |
84 | property string text |
85 | Ubuntu.Components.ActionList 1.0 0.1: QtObject |
86 | readonly property Action actions |
87 | @@ -82,6 +76,8 @@ |
88 | property bool onScreen |
89 | property bool running |
90 | Ubuntu.Components.AdaptivePageLayout 1.3: PageTreeNode |
91 | + readonly property int columns |
92 | + readonly property PageColumnsLayout layouts |
93 | function var addPageToCurrentColumn(var sourcePage, var page, var properties) |
94 | function var addPageToNextColumn(var sourcePage, var page, var properties) |
95 | function var removePages(var page) |
96 | @@ -92,6 +88,7 @@ |
97 | property bool enabled |
98 | readonly property int error |
99 | property string message |
100 | + signal statusChanged(Operation operation) |
101 | function save() |
102 | function cancel() |
103 | function reset() |
104 | @@ -305,6 +302,9 @@ |
105 | Ubuntu.Components.ListItems.Divider 1.0 0.1: QQuickImageBase |
106 | property FillMode fillMode |
107 | property HAlignment horizontalAlignment |
108 | + signal horizontalAlignmentChanged(HAlignment alignment) |
109 | + signal verticalAlignmentChanged(VAlignment alignment) |
110 | + signal mipmapChanged(bool ) |
111 | property bool mipmap |
112 | readonly property double paintedHeight |
113 | readonly property double paintedWidth |
114 | @@ -312,6 +312,9 @@ |
115 | Ubuntu.Components.ListItems.Divider 1.3: QQuickImageBase |
116 | property FillMode fillMode |
117 | property HAlignment horizontalAlignment |
118 | + signal horizontalAlignmentChanged(HAlignment alignment) |
119 | + signal verticalAlignmentChanged(VAlignment alignment) |
120 | + signal mipmapChanged(bool ) |
121 | property bool mipmap |
122 | readonly property double paintedHeight |
123 | readonly property double paintedWidth |
124 | @@ -361,10 +364,11 @@ |
125 | Ubuntu.Components.FilterBehavior 1.1: QtObject |
126 | property QRegExp pattern |
127 | property string property |
128 | -Ubuntu.Components.Haptics 1.0 0.1: Object singleton |
129 | - readonly property HapticsEffect effect |
130 | +Ubuntu.Components.Haptics 1.0 0.1: QtObject singleton |
131 | + readonly property QtObject effect |
132 | readonly property bool enabled |
133 | - function var play(var customEffect) |
134 | + function play(var customEffect) |
135 | + function play() |
136 | Ubuntu.Components.ListItems.Header 1.0 0.1: Item |
137 | property string text |
138 | Ubuntu.Components.Header 1.0 0.1: AppHeader |
139 | @@ -385,22 +389,6 @@ |
140 | property bool useDeprecatedToolbar |
141 | Ubuntu.Components.ListItems.Header 1.3: Item |
142 | property string text |
143 | -Ubuntu.Components.Header 1.3: AppHeader |
144 | - property string _for_autopilot |
145 | - property var actions |
146 | - property bool animate |
147 | - property QtObject config |
148 | - property Item contents |
149 | - property color dividerColor |
150 | - property Flickable flickable |
151 | - function var show() |
152 | - function var hide() |
153 | - readonly property bool moving |
154 | - property var pageStack |
155 | - property color panelColor |
156 | - property var tabsModel |
157 | - property string title |
158 | - property bool useDeprecatedToolbar |
159 | Ubuntu.Components.Icon 1.0 0.1: Item |
160 | property color color |
161 | property color keyColor |
162 | @@ -466,6 +454,7 @@ |
163 | property bool selected |
164 | property ListItemActions trailingActions |
165 | Ubuntu.Components.ListItem 1.3: ListItem |
166 | + readonly property UCListItemExpansion expansion |
167 | Ubuntu.Components.ListItemActions 1.2: QtObject |
168 | readonly property Action actions |
169 | default readonly property QtObject data |
170 | @@ -485,6 +474,7 @@ |
171 | readonly property bool animatePanels |
172 | property Item dragPanel |
173 | property PropertyAnimation dropAnimation |
174 | + readonly property Flickable flickable 1.3 |
175 | readonly property int listItemIndex 1.3 |
176 | function swipeEvent(SwipeEvent event) |
177 | function rebound() |
178 | @@ -528,6 +518,7 @@ |
179 | signal clicked(QQuickMouseEvent mouse, Item host) |
180 | signal pressAndHold(QQuickMouseEvent mouse, Item host) |
181 | signal doubleClicked(QQuickMouseEvent mouse, Item host) |
182 | + signal positionChanged(QQuickMouseEvent mouse, Item host) |
183 | signal entered(QQuickMouseEvent event, Item host) |
184 | signal exited(QQuickMouseEvent event, Item host) |
185 | property Priority priority |
186 | @@ -603,6 +594,14 @@ |
187 | property Flickable flickable |
188 | readonly property PageHeadConfiguration head |
189 | property string title |
190 | +Ubuntu.Components.PageColumn 1.3: QtObject |
191 | + property bool fillWidth |
192 | + property double maximumWidth |
193 | + property double minimumWidth |
194 | + property double preferredWidth |
195 | +Ubuntu.Components.PageColumnsLayout 1.3: QtObject |
196 | + default readonly property PageColumn data |
197 | + property bool when |
198 | Ubuntu.Components.PageHeadConfiguration 1.1: Object |
199 | readonly property Action actions |
200 | property Action backAction |
201 | @@ -1222,14 +1221,16 @@ |
202 | property string iconName |
203 | property url iconSource |
204 | signal triggered(var value) |
205 | - function var trigger(var value) |
206 | + function trigger(var value) |
207 | + function trigger() |
208 | property string text |
209 | Ubuntu.Components.ToolbarButton 1.3: StyledItem |
210 | property Action action |
211 | property string iconName |
212 | property url iconSource |
213 | signal triggered(var value) |
214 | - function var trigger(var value) |
215 | + function trigger(var value) |
216 | + function trigger() |
217 | property string text |
218 | Ubuntu.Components.ToolbarItems 1.0 0.1: Item |
219 | property Item back |
220 | @@ -1246,6 +1247,9 @@ |
221 | UCListItemDivider: Item |
222 | property color colorFrom |
223 | property color colorTo |
224 | +UCListItemExpansion: QtObject |
225 | + property bool expanded |
226 | + property double height |
227 | UCStateSaverAttached: QtObject |
228 | property bool enabled |
229 | property string properties |
230 | @@ -1393,6 +1397,14 @@ |
231 | signal dragUpdated(ListItemDrag event) |
232 | property bool selectMode |
233 | property QList<int> selectedIndices |
234 | +Ubuntu.Components.ViewItems 1.3: ViewItems |
235 | + property QList<int> expandedIndices |
236 | + property int expansionFlags |
237 | + signal expandedIndicesChanged(QList<int> indices) |
238 | +Ubuntu.Components.ViewItems.ExpansionFlag: Enum |
239 | + CollapseOnOutsidePress |
240 | + Exclusive |
241 | + UnlockExpanded |
242 | Ubuntu.Components.i18n 1.0 0.1: QtObject |
243 | property string domain |
244 | property string language |
245 | @@ -1405,3 +1417,4 @@ |
246 | function string dctr(string domain, string context, string text) |
247 | function string tag(string text) |
248 | function string tag(string context, string text) |
249 | + function string relativeDateTime(QDateTime datetime) |
250 | |
251 | === modified file 'debian/changelog' |
252 | --- debian/changelog 2015-08-24 20:49:45 +0000 |
253 | +++ debian/changelog 2015-09-08 04:09:38 +0000 |
254 | @@ -1,3 +1,61 @@ |
255 | +ubuntu-ui-toolkit (1.3.1627+15.10.20150904-0ubuntu1) UNRELEASED; urgency=medium |
256 | + |
257 | + [ Zsombor Egri ] |
258 | + * Implement list item expansion. |
259 | + * Turn AdaptivePageLayout page creation to be asynchronous. |
260 | + * Fix ListItem swipe handling when gesture is initiated over an overlay |
261 | + MouseArea which does not accept pressed event. Fixes LP: #1484545 |
262 | + * AbstractButton to C++. Fixes LP: #1365471, LP: #1458028 |
263 | + * Haptics singleton moved to C++. |
264 | + * ActionItem moved to C++. |
265 | + * Making columns resizable in an AdaptivePageLayout. |
266 | + * Introducing column configuration into AdaptivePageLayout. |
267 | + |
268 | + [ Benjamin Zeller ] |
269 | + * Fix build inside qt and shadowbuild. |
270 | + |
271 | + [ Tim Peeters ] |
272 | + * Remove old and unused header-related files, and update unit test filenames. |
273 | + * Don't unset the subheader style when Page.head changes because that unsets |
274 | + the parent of Page.head.contents. Fixes LP: #1488922 |
275 | + * Fix the theming of the MainView. |
276 | + * Fix the background color of the overflow panel. |
277 | + |
278 | + [ Christian Dywan ] |
279 | + * Include change signals with arguments in .api. |
280 | + * A public QML type with no version is an error. Rather than silently breaking |
281 | + as QML does normally at least apicheck can make this fatal. |
282 | + * UbuntuShape shouldn't emit redundant deprecation warnings. Fixes LP: #1481791 |
283 | + * Update .bzrignore to new upstream style layout. Fixes LP: #1433308 |
284 | + * Revert unnecessary change of Popover minimumWidth. Fixes LP: #1483708 |
285 | + |
286 | + [ Ken VanDine ] |
287 | + * Fixed a few typos in the api docs for StateSaver. |
288 | + |
289 | + [ Olivier Tilloy ] |
290 | + * Take custom key indexes into account to allow sorting on custom roles. |
291 | + Fixes LP: #1485674 |
292 | + |
293 | + [ Albert Astals Cid ] |
294 | + * Properly free shapeTextures[index] The old code assumes that the UbuntuShape |
295 | + will still be around when the opengl context is destroyed, but that seldom |
296 | + happens so connect the signal to a lambda that will be there and does the |
297 | + cleanup properly. Without this patch testDirectionalDragArea from unity8 was |
298 | + hitting the qFatal because it ran out of space in shapeTextures. |
299 | + |
300 | + [ Richard Huddie ] |
301 | + * Remove all usage of the autopilot simulated keyboard when the OSK is being |
302 | + used. Fixes LP: 31483668 |
303 | + |
304 | + [ Gerry Boland ] |
305 | + * Compensate for Qt's device pixel ratio multiplier. |
306 | + Fixes: LP: #1207270, LP: #1275748, LP: #1468402 |
307 | + |
308 | + [ Nick Dedekind ] |
309 | + * Added relative date time i18n. |
310 | + |
311 | + -- Zoltán Balogh <zoltan@bakter.hu> Fri, 04 Sep 2015 19:25:03 +0300 |
312 | + |
313 | ubuntu-ui-toolkit (1.3.1603+15.10.20150824.1-0ubuntu1) wily; urgency=medium |
314 | |
315 | [ CI Train Bot ] |
316 | |
317 | === modified file 'debian/control' |
318 | --- debian/control 2015-07-10 05:40:21 +0000 |
319 | +++ debian/control 2015-09-08 04:09:38 +0000 |
320 | @@ -45,6 +45,11 @@ |
321 | suru-icon-theme, |
322 | uuid-runtime, |
323 | python3-sphinx, |
324 | + libfontconfig1-dev, |
325 | + libfreetype6-dev, |
326 | + libmtdev-dev, |
327 | + libudev-dev, |
328 | + libxrender-dev |
329 | Standards-Version: 3.9.4 |
330 | Homepage: https://launchpad.net/ubuntu-ui-toolkit |
331 | # If you aren't a member of ~ubuntu-sdk-team but need to upload packaging |
332 | |
333 | === modified file 'documentation/documentation.pro' |
334 | --- documentation/documentation.pro 2015-06-02 15:47:45 +0000 |
335 | +++ documentation/documentation.pro 2015-09-08 04:09:38 +0000 |
336 | @@ -17,7 +17,7 @@ |
337 | generate_docs.commands = cd $$ROOT_SOURCE_DIR; SRC=$$ROOT_SOURCE_DIR/documentation BLD=$$ROOT_BUILD_DIR/documentation $$ROOT_SOURCE_DIR/documentation/docs.sh \'$$QDOC\' \'$$QHELPGENERATOR\' $$DOC_PATH |
338 | |
339 | #install the online docs only when building outside of Qt |
340 | -force_independent: { |
341 | +!build_with_qt{ |
342 | install_docs.files = $$shadowed($$ROOT_SOURCE_DIR)/documentation/html |
343 | install_docs.path = /usr/share/ubuntu-ui-toolkit/doc |
344 | install_docs.CONFIG += no_check_exist directory no_build |
345 | |
346 | === modified file 'documentation/ubuntu-ui-toolkit-common.qdocconf' |
347 | --- documentation/ubuntu-ui-toolkit-common.qdocconf 2015-07-24 18:00:54 +0000 |
348 | +++ documentation/ubuntu-ui-toolkit-common.qdocconf 2015-09-08 04:09:38 +0000 |
349 | @@ -26,7 +26,7 @@ |
350 | sources.fileextensions = "*.qml *.qdoc *.cpp *.js" |
351 | headers.fileextensions = "*.h" |
352 | # exclude qml files that have the component documented in a separate qdoc file |
353 | -excludefiles = $BLD/../src/Ubuntu/Components/MainView.qml |
354 | +excludefiles += $BLD/../src/Ubuntu/Components/1.3/PageWrapperUtils.js |
355 | outputdir = $BLD/html |
356 | outputformats = HTML |
357 | version = 1.2 |
358 | |
359 | === modified file 'examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml' |
360 | --- examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml 2015-08-07 13:48:39 +0000 |
361 | +++ examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml 2015-09-08 04:09:38 +0000 |
362 | @@ -37,6 +37,28 @@ |
363 | anchors.fill: parent |
364 | primaryPage: mainPage |
365 | |
366 | + layouts: [ |
367 | + PageColumnsLayout { |
368 | + when: layout.width > units.gu(80) |
369 | + PageColumn { |
370 | + minimumWidth: units.gu(30) |
371 | + maximumWidth: units.gu(50) |
372 | + preferredWidth: units.gu(40) |
373 | + } |
374 | + PageColumn { |
375 | + fillWidth: true |
376 | + } |
377 | + }, |
378 | + // configure single column mode so we can only size it to minimum 20 GU |
379 | + PageColumnsLayout { |
380 | + when: true |
381 | + PageColumn { |
382 | + minimumWidth: units.gu(20) |
383 | + fillWidth: true |
384 | + } |
385 | + } |
386 | + ] |
387 | + |
388 | Page { |
389 | id: mainPage |
390 | title: "Ubuntu UI Toolkit" |
391 | @@ -74,9 +96,8 @@ |
392 | selected: index === widgetList.currentIndex |
393 | onClicked: { |
394 | var source = Qt.resolvedUrl(model.source); |
395 | - var newPage = layout.addPageToNextColumn(mainPage, source); |
396 | + layout.addPageToNextColumn(mainPage, source, {title: model.label}); |
397 | |
398 | - newPage.title = model.label; |
399 | widgetList.currentIndex = index; |
400 | } |
401 | } |
402 | |
403 | === modified file 'features/ubuntu_enable_testing.prf' |
404 | --- features/ubuntu_enable_testing.prf 2015-05-19 07:55:27 +0000 |
405 | +++ features/ubuntu_enable_testing.prf 2015-09-08 04:09:38 +0000 |
406 | @@ -1,6 +1,6 @@ |
407 | instbase = $$ROOT_BUILD_DIR/qml |
408 | |
409 | -force_independent: { |
410 | +!build_with_qt { |
411 | # These bizarre rules copy the files to the build directory |
412 | |
413 | defineReplace(qmlModStripSrcDir) { |
414 | |
415 | === modified file 'features/ubuntu_qml_plugin.prf' |
416 | --- features/ubuntu_qml_plugin.prf 2015-07-30 13:47:23 +0000 |
417 | +++ features/ubuntu_qml_plugin.prf 2015-09-08 04:09:38 +0000 |
418 | @@ -1,64 +1,65 @@ |
419 | load(qml_plugin) |
420 | CONFIG -= hide_symbols |
421 | |
422 | - |
423 | load(ubuntu_enable_testing) |
424 | |
425 | #hacky hacks to build the qmltypes |
426 | |
427 | -#should be already set by the qml_plugin.prf, but lets be safe |
428 | -isEmpty(IMPORT_VERSION): error("Must set IMPORT_VERSION") |
429 | - |
430 | -load(resolve_target) |
431 | - |
432 | -qml1_target { |
433 | - qmlplugindump = qml1plugindump |
434 | - importpath.name = QML_IMPORT_PATH |
435 | -} else { |
436 | - qmlplugindump = qmlplugindump |
437 | - importpath.name = QML2_IMPORT_PATH |
438 | -} |
439 | - |
440 | -qtPrepareTool(QMLPLUGINDUMP, $$qmlplugindump) |
441 | -importpath.value = |
442 | -for(qmod, QTREPOS) { |
443 | - qml1_target: \ |
444 | - qmod = $$qmod/imports |
445 | - else: \ |
446 | - qmod = $$qmod/qml |
447 | - exists($$qmod): importpath.value += $$shell_path($$qmod) |
448 | -} |
449 | - |
450 | -#add our path, somehow its not added automatically |
451 | -importpath.value += $$shell_path($$instbase) |
452 | -importpath.value = $$unique(importpath.value) |
453 | - |
454 | -membackend.name = ALARM_BACKEND |
455 | -membackend.value = memory |
456 | - |
457 | -qtAddToolEnv(QMLPLUGINDUMP, importpath) |
458 | -qtAddToolEnv(QMLPLUGINDUMP, membackend) |
459 | - |
460 | -TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, ) |
461 | - |
462 | -QMLTYPEFILE = $$instbase/$$TARGETPATH/plugins.qmltypes |
463 | -autobld_qmltypes.target = $$QMLTYPEFILE |
464 | -autobld_qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$replace(TARGETPATHBASE, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE |
465 | -autobld_qmltypes.commands += && sed -i \'s?-1.-1\"?0.1\"?\' $$QMLTYPEFILE |
466 | -autobld_qmltypes.commands += && sed -i \'s?exportMetaObjectRevisions: \\[-1\\]?exportMetaObjectRevisions: [0,0]?\' $$QMLTYPEFILE |
467 | -autobld_qmltypes.depends = $$QMAKE_RESOLVED_TARGET |
468 | - |
469 | -autobld_install_qmltypes.files = $$QMLTYPEFILE |
470 | -autobld_install_qmltypes.depends = $$QMLTYPEFILE |
471 | -autobld_install_qmltypes.path = $$[QT_INSTALL_QML]/$$TARGETPATH |
472 | -autobld_install_qmltypes.CONFIG += no_check_exist |
473 | - |
474 | -INSTALLS+=autobld_install_qmltypes |
475 | -QMAKE_EXTRA_TARGETS += autobld_qmltypes |
476 | +!build_with_qt{ |
477 | + #should be already set by the qml_plugin.prf, but lets be safe |
478 | + isEmpty(IMPORT_VERSION): error("Must set IMPORT_VERSION") |
479 | + |
480 | + load(resolve_target) |
481 | + |
482 | + qml1_target { |
483 | + qmlplugindump = qml1plugindump |
484 | + importpath.name = QML_IMPORT_PATH |
485 | + } else { |
486 | + qmlplugindump = qmlplugindump |
487 | + importpath.name = QML2_IMPORT_PATH |
488 | + } |
489 | + |
490 | + qtPrepareTool(QMLPLUGINDUMP, $$qmlplugindump) |
491 | + importpath.value = |
492 | + for(qmod, QTREPOS) { |
493 | + qml1_target: \ |
494 | + qmod = $$qmod/imports |
495 | + else: \ |
496 | + qmod = $$qmod/qml |
497 | + exists($$qmod): importpath.value += $$shell_path($$qmod) |
498 | + } |
499 | + |
500 | + #add our path, somehow its not added automatically |
501 | + importpath.value += $$shell_path($$instbase) |
502 | + importpath.value = $$unique(importpath.value) |
503 | + |
504 | + membackend.name = ALARM_BACKEND |
505 | + membackend.value = memory |
506 | + |
507 | + qtAddToolEnv(QMLPLUGINDUMP, importpath) |
508 | + qtAddToolEnv(QMLPLUGINDUMP, membackend) |
509 | + |
510 | + TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, ) |
511 | + |
512 | + QMLTYPEFILE = $$instbase/$$TARGETPATH/plugins.qmltypes |
513 | + autobld_qmltypes.target = $$QMLTYPEFILE |
514 | + autobld_qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$replace(TARGETPATHBASE, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE |
515 | + autobld_qmltypes.commands += && sed -i \'s?-1.-1\"?0.1\"?\' $$QMLTYPEFILE |
516 | + autobld_qmltypes.commands += && sed -i \'s?exportMetaObjectRevisions: \\[-1\\]?exportMetaObjectRevisions: [0,0]?\' $$QMLTYPEFILE |
517 | + autobld_qmltypes.depends = $$QMAKE_RESOLVED_TARGET |
518 | + |
519 | + autobld_install_qmltypes.files = $$QMLTYPEFILE |
520 | + autobld_install_qmltypes.depends = $$QMLTYPEFILE |
521 | + autobld_install_qmltypes.path = $$[QT_INSTALL_QML]/$$TARGETPATH |
522 | + autobld_install_qmltypes.CONFIG += no_check_exist |
523 | + |
524 | + INSTALLS+=autobld_install_qmltypes |
525 | + QMAKE_EXTRA_TARGETS += autobld_qmltypes |
526 | +} |
527 | |
528 | # when building against the system Qt we pick up the CXX_FLAGS for a release build |
529 | # reset them to the default debug build flags |
530 | -force_independent: { |
531 | +!build_with_qt: { |
532 | CONFIG(debug, debug|release) { |
533 | QMAKE_CFLAGS = $$QMAKE_CFLAGS_DEBUG |
534 | QMAKE_CXXFLAGS = $$QMAKE_CXXFLAGS_DEBUG |
535 | |
536 | === modified file 'po/po.pro' |
537 | --- po/po.pro 2014-12-02 09:00:30 +0000 |
538 | +++ po/po.pro 2015-09-08 04:09:38 +0000 |
539 | @@ -30,7 +30,7 @@ |
540 | mo_file = $$replace(po_file,.po,.mo) |
541 | system(msgfmt $$po_file -o $$mo_file) |
542 | mo_name = $$replace(mo_file,.mo,) |
543 | - mo_targetpath = $(INSTALL_ROOT)/usr/share/locale/$${mo_name}/LC_MESSAGES |
544 | + mo_targetpath = $(INSTALL_ROOT)$$[QT_INSTALL_PREFIX]/share/locale/$${mo_name}/LC_MESSAGES |
545 | mo_target = $${mo_targetpath}/ubuntu-ui-toolkit.mo |
546 | !isEmpty(install_mo_commands): install_mo_commands += && |
547 | install_mo_commands += test -d $$mo_targetpath || mkdir -p $$mo_targetpath |
548 | |
549 | === modified file 'src/Ubuntu/Components/1.1/Haptics.qml' |
550 | --- src/Ubuntu/Components/1.1/Haptics.qml 2015-07-24 09:54:03 +0000 |
551 | +++ src/Ubuntu/Components/1.1/Haptics.qml 2015-09-08 04:09:38 +0000 |
552 | @@ -14,105 +14,14 @@ |
553 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
554 | */ |
555 | |
556 | -pragma Singleton |
557 | import QtQuick 2.4 |
558 | import QtFeedback 5.0 |
559 | import Ubuntu.Components 1.1 |
560 | |
561 | -/*! |
562 | - \qmltype Haptics |
563 | - \inqmlmodule Ubuntu.Components 1.1 |
564 | - \ingroup ubuntu-services |
565 | - \brief Singleton defining the haptics feedback used in components, where execution |
566 | - of the feedback is controlled by the system settings. |
567 | - |
568 | - Supports global feedback as well as custom feedback. Global feedback can be |
569 | - configured through its properties, and \l play function will play the default |
570 | - configuration, or a custom one if parameter is given. |
571 | - |
572 | - Example of using Haptics: |
573 | - \qml |
574 | - import QtQuick 2.4 |
575 | - import Ubuntu.Components 1.2 |
576 | - |
577 | - Item { |
578 | - implicitWidth: units.gu(20) |
579 | - implicitHeight: units.gu(5) |
580 | - |
581 | - Label { |
582 | - text: "Press me" |
583 | - anchors.fill: parent |
584 | - horizontalAlignment: Text.AlignHCenter |
585 | - verticalAlignment: Text.AlignVCenter |
586 | - } |
587 | - MouseArea { |
588 | - anchors.fill: parent |
589 | - onClicked: Haptics.play() |
590 | - } |
591 | - } |
592 | - \endqml |
593 | - |
594 | - Custom effects can be played as follows: |
595 | - \qml |
596 | - import QtQuick 2.4 |
597 | - import Ubuntu.Components 1.2 |
598 | - |
599 | - Item { |
600 | - implicitWidth: units.gu(20) |
601 | - implicitHeight: units.gu(5) |
602 | - |
603 | - Label { |
604 | - text: "Press me" |
605 | - anchors.fill: parent |
606 | - horizontalAlignment: Text.AlignHCenter |
607 | - verticalAlignment: Text.AlignVCenter |
608 | - } |
609 | - MouseArea { |
610 | - anchors.fill: parent |
611 | - onClicked: Haptics.play({duration: 25, attackIntensity: 0.7}) |
612 | - } |
613 | - } |
614 | - \endqml |
615 | - |
616 | - \note Though the \l effect property exposes \c start, \c stop and \c pause |
617 | - functions, use those only if you want to have feedback independent on what the |
618 | - system setting is. |
619 | - */ |
620 | Object { |
621 | - |
622 | - /*! |
623 | - \qmlproperty bool enabled |
624 | - \readonly |
625 | - The property specifies whether the haptics feedback is enabled or not by the system. |
626 | - */ |
627 | readonly property alias enabled: vibra.otherVibrate |
628 | - |
629 | - /*! |
630 | - \qmlproperty HapticsEffect effect |
631 | - The property defines the settings of the haptics effect used by the component. |
632 | - The default setting is a haptics effect with a duration of 10 milliseconds |
633 | - with an intensity of 1.0, having fading time of 50 millisecods and fading |
634 | - intensity 0.0, and attack time of 50 milliseconds and with an intensity of |
635 | - 0.0. |
636 | - */ |
637 | property alias effect: effect |
638 | |
639 | - /*! |
640 | - \qmlmethod play([customEffect]) |
641 | - The function plays the feedback with the configuration specified in \l effect |
642 | - if no parameter is given. Custom effect can be played by specifying the effect |
643 | - properties in a JSON object in \c customEffect. |
644 | - |
645 | - The function will exit unconditionaly if playing the effects is blocked by |
646 | - system settings. |
647 | - |
648 | - The function will not stop any ongoing haptics effect played, if that one |
649 | - was a default haptics effect. In case of custom effects, the previous effect |
650 | - will be stopped, and settings will be restored before the new haptics will |
651 | - be played. The custom settings properties (the ones which are required to |
652 | - be different from the ones defined in the \l effect) must be specified in |
653 | - the parameter in a JSON object. |
654 | - */ |
655 | function play(customEffect) { |
656 | if (!vibra.otherVibrate) { |
657 | return; |
658 | |
659 | === removed file 'src/Ubuntu/Components/1.2/ActionItem.qml' |
660 | --- src/Ubuntu/Components/1.2/ActionItem.qml 2015-04-30 08:32:44 +0000 |
661 | +++ src/Ubuntu/Components/1.2/ActionItem.qml 1970-01-01 00:00:00 +0000 |
662 | @@ -1,96 +0,0 @@ |
663 | -/* |
664 | - * Copyright 2012 Canonical Ltd. |
665 | - * |
666 | - * This program is free software; you can redistribute it and/or modify |
667 | - * it under the terms of the GNU Lesser General Public License as published by |
668 | - * the Free Software Foundation; version 3. |
669 | - * |
670 | - * This program is distributed in the hope that it will be useful, |
671 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
672 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
673 | - * GNU Lesser General Public License for more details. |
674 | - * |
675 | - * You should have received a copy of the GNU Lesser General Public License |
676 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
677 | - */ |
678 | - |
679 | -import QtQuick 2.4 |
680 | -import Ubuntu.Components 1.2 |
681 | - |
682 | -/*! |
683 | - \qmlabstract ActionItem |
684 | - \inqmlmodule Ubuntu.Components 1.1 |
685 | - \ingroup ubuntu |
686 | - \brief A visual representation of an Action. The API of ActionItem is a |
687 | - copy of the API of \l Action, with additional properties to define |
688 | - visual aspects of the ActionItem. |
689 | - |
690 | - If \l action is set, the values of the other properties will by default |
691 | - be identical to the \l Action's property values. Setting the other properties |
692 | - will override the properties copied from the \l Action. |
693 | - |
694 | - See \l ToolbarItems for examples of how to use \l ToolbarButton or other ActionItems |
695 | - in a toolbar. |
696 | -*/ |
697 | -StyledItem { |
698 | - id: actionItem |
699 | - |
700 | - /*! |
701 | - The \l Action associated with this ActionItem. If action is set, |
702 | - the values of the Action properties are copied to the values of |
703 | - the ActionItem properties. |
704 | - */ |
705 | - property Action action: null |
706 | - |
707 | - visible: action ? action.visible : true |
708 | - enabled: action ? action.enabled : true |
709 | - |
710 | - /*! |
711 | - The title of the actionItem. |
712 | - Default value: action.text |
713 | - */ |
714 | - property string text: action ? action.text : "" |
715 | - |
716 | - /*! |
717 | - The image associated with the actionItem. |
718 | - Default value: action.iconSource. |
719 | - |
720 | - This is the URL of any image file |
721 | - If both iconSource and iconName are defined, iconName will be ignored. |
722 | - */ |
723 | - property url iconSource: action ? action.iconSource : (iconName ? "image://theme/" + iconName : "") |
724 | - |
725 | - /*! |
726 | - The icon associated with the actionItem in the suru icon theme. |
727 | - Default value: action.iconName. |
728 | - |
729 | - \note The complete list of icons available in Ubuntu is not published yet. |
730 | - For now please refer to the folders where the icon themes are installed: |
731 | - \list |
732 | - \li Ubuntu Touch: \l file:/usr/share/icons/suru |
733 | - \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark |
734 | - \endlist |
735 | - These 2 separate icon themes will be merged soon. |
736 | - |
737 | - If both iconSource and iconName are defined, iconName will be ignored. |
738 | - */ |
739 | - property string iconName: action ? action.iconName : "" |
740 | - |
741 | - /*! |
742 | - Called when the actionItem is triggered. |
743 | - */ |
744 | - signal triggered(var value) |
745 | - |
746 | - /*! |
747 | - If \l action is set, this will trigger it. |
748 | - */ |
749 | - onTriggered: if (action) action.trigger(value) |
750 | - |
751 | - /*! |
752 | - Trigger this action item if it is enabled. |
753 | - */ |
754 | - function trigger(value) { |
755 | - var passingValue = value ? value : null |
756 | - if (actionItem.enabled) actionItem.triggered(passingValue); |
757 | - } |
758 | -} |
759 | |
760 | === modified file 'src/Ubuntu/Components/1.2/TextField.qml' |
761 | --- src/Ubuntu/Components/1.2/TextField.qml 2015-05-01 19:38:57 +0000 |
762 | +++ src/Ubuntu/Components/1.2/TextField.qml 2015-09-08 04:09:38 +0000 |
763 | @@ -99,7 +99,7 @@ |
764 | \note During text selection all interactive parent Flickables are turned off. |
765 | */ |
766 | |
767 | -ActionItem { |
768 | +Ubuntu.ActionItem { |
769 | id: control |
770 | |
771 | implicitWidth: units.gu(25) |
772 | |
773 | === modified file 'src/Ubuntu/Components/1.2/TextInputPopover.qml' |
774 | --- src/Ubuntu/Components/1.2/TextInputPopover.qml 2015-07-02 23:33:22 +0000 |
775 | +++ src/Ubuntu/Components/1.2/TextInputPopover.qml 2015-09-08 04:09:38 +0000 |
776 | @@ -88,6 +88,7 @@ |
777 | action.text so we can get the proper button by text, action being not |
778 | accessible. https://bugs.launchpad.net/autopilot/+bug/1334599 |
779 | */ |
780 | + // FIXME: AbstractButton has text property, which is getting the action.text, so no need to override! |
781 | property string text: action.text |
782 | width: Math.max(units.gu(5), implicitWidth) + units.gu(2) |
783 | height: units.gu(6) |
784 | |
785 | === modified file 'src/Ubuntu/Components/1.2/ToolbarButton.qml' |
786 | --- src/Ubuntu/Components/1.2/ToolbarButton.qml 2015-04-30 08:32:44 +0000 |
787 | +++ src/Ubuntu/Components/1.2/ToolbarButton.qml 2015-09-08 04:09:38 +0000 |
788 | @@ -15,6 +15,7 @@ |
789 | */ |
790 | |
791 | import QtQuick 2.4 |
792 | +import Ubuntu.Components 1.2 |
793 | |
794 | /*! |
795 | \qmltype ToolbarButton |
796 | |
797 | === removed file 'src/Ubuntu/Components/1.3/AbstractButton.qml' |
798 | --- src/Ubuntu/Components/1.3/AbstractButton.qml 2015-04-25 08:54:58 +0000 |
799 | +++ src/Ubuntu/Components/1.3/AbstractButton.qml 1970-01-01 00:00:00 +0000 |
800 | @@ -1,109 +0,0 @@ |
801 | -/* |
802 | - * Copyright 2012 Canonical Ltd. |
803 | - * |
804 | - * This program is free software; you can redistribute it and/or modify |
805 | - * it under the terms of the GNU Lesser General Public License as published by |
806 | - * the Free Software Foundation; version 3. |
807 | - * |
808 | - * This program is distributed in the hope that it will be useful, |
809 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
810 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
811 | - * GNU Lesser General Public License for more details. |
812 | - * |
813 | - * You should have received a copy of the GNU Lesser General Public License |
814 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
815 | - */ |
816 | - |
817 | -import QtQuick 2.4 |
818 | -import Ubuntu.Components 1.3 |
819 | - |
820 | -/*! |
821 | - \qmlabstract AbstractButton |
822 | - \inqmlmodule Ubuntu.Components 1.1 |
823 | - \ingroup ubuntu |
824 | - \brief The AbstractButton class defines the behavior of the button. |
825 | - |
826 | - This class defines the behavior of the button: it defines the MouseArea |
827 | - and the states. |
828 | - All components deriving from this class support haptic feedback out of the box. |
829 | -*/ |
830 | -ActionItem { |
831 | - id: button |
832 | - |
833 | - /*! |
834 | - If an action is specified, the button's clicked signal will trigger the action. |
835 | - Subclasses of AbstractButton can use other properties of action (for example |
836 | - the text and iconName). |
837 | - \qmlproperty Action action |
838 | - */ |
839 | - |
840 | - /*! |
841 | - This handler is called when there is a mouse click on the button |
842 | - and the button is not disabled. If \b action is defined, |
843 | - the action will be triggered. |
844 | - */ |
845 | - signal clicked() |
846 | - |
847 | - /*! |
848 | - If a button is clicked, its triggered() signal will automatically be called. |
849 | - */ |
850 | - onClicked: button.trigger() |
851 | - |
852 | - Keys.onEnterPressed: clicked() |
853 | - Keys.onReturnPressed: clicked() |
854 | - |
855 | - /*! |
856 | - This handler is called when there is a long press. |
857 | - */ |
858 | - signal pressAndHold() |
859 | - |
860 | - /*! |
861 | - True if the user presses a mouse button in the button's mouse area. |
862 | - */ |
863 | - property bool pressed: mouseArea.pressed |
864 | - |
865 | - /*! |
866 | - True if the mouse cursor hovers over the button's mouse area. |
867 | - */ |
868 | - property bool hovered: __acceptEvents && mouseArea.containsMouse |
869 | - |
870 | - /*! |
871 | - \internal |
872 | - Disable or enable signal emition by default. |
873 | - Some classes want to emit the signal by themselves (ListItem.Standard) |
874 | - */ |
875 | - property bool __acceptEvents: true |
876 | - |
877 | - /*! |
878 | - \internal |
879 | - To get the properties of the mouse area in subclasses. |
880 | - */ |
881 | - property alias __mouseArea: mouseArea |
882 | - |
883 | - activeFocusOnPress: true |
884 | - |
885 | - MouseArea { |
886 | - id: mouseArea |
887 | - anchors.fill: parent |
888 | - // if mouseArea is given a new value, disable defaultMouseArea |
889 | - // as it might occlude the newly assigned mouse area. |
890 | - hoverEnabled: true |
891 | - |
892 | - // invoke Haptics singleton earlier than we press the button, |
893 | - // so we give some time for the singleton to sync settings with the service |
894 | - property bool hapticsEnabled: Haptics.enabled |
895 | - |
896 | - onClicked: { |
897 | - if (button.__acceptEvents) { |
898 | - // FIXME (Vivid) call this in the style rather than from AbstractButton |
899 | - Haptics.play(); |
900 | - button.clicked() |
901 | - } |
902 | - } |
903 | - onPressAndHold: { |
904 | - if (button.__acceptEvents) { |
905 | - button.pressAndHold() |
906 | - } |
907 | - } |
908 | - } |
909 | -} |
910 | |
911 | === removed file 'src/Ubuntu/Components/1.3/ActionItem.qml' |
912 | --- src/Ubuntu/Components/1.3/ActionItem.qml 2015-04-25 08:54:58 +0000 |
913 | +++ src/Ubuntu/Components/1.3/ActionItem.qml 1970-01-01 00:00:00 +0000 |
914 | @@ -1,96 +0,0 @@ |
915 | -/* |
916 | - * Copyright 2012 Canonical Ltd. |
917 | - * |
918 | - * This program is free software; you can redistribute it and/or modify |
919 | - * it under the terms of the GNU Lesser General Public License as published by |
920 | - * the Free Software Foundation; version 3. |
921 | - * |
922 | - * This program is distributed in the hope that it will be useful, |
923 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
924 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
925 | - * GNU Lesser General Public License for more details. |
926 | - * |
927 | - * You should have received a copy of the GNU Lesser General Public License |
928 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
929 | - */ |
930 | - |
931 | -import QtQuick 2.4 |
932 | -import Ubuntu.Components 1.3 |
933 | - |
934 | -/*! |
935 | - \qmlabstract ActionItem |
936 | - \inqmlmodule Ubuntu.Components 1.1 |
937 | - \ingroup ubuntu |
938 | - \brief A visual representation of an Action. The API of ActionItem is a |
939 | - copy of the API of \l Action, with additional properties to define |
940 | - visual aspects of the ActionItem. |
941 | - |
942 | - If \l action is set, the values of the other properties will by default |
943 | - be identical to the \l Action's property values. Setting the other properties |
944 | - will override the properties copied from the \l Action. |
945 | - |
946 | - See \l ToolbarItems for examples of how to use \l ToolbarButton or other ActionItems |
947 | - in a toolbar. |
948 | -*/ |
949 | -StyledItem { |
950 | - id: actionItem |
951 | - |
952 | - /*! |
953 | - The \l Action associated with this ActionItem. If action is set, |
954 | - the values of the Action properties are copied to the values of |
955 | - the ActionItem properties. |
956 | - */ |
957 | - property Action action: null |
958 | - |
959 | - visible: action ? action.visible : true |
960 | - enabled: action ? action.enabled : true |
961 | - |
962 | - /*! |
963 | - The title of the actionItem. |
964 | - Default value: action.text |
965 | - */ |
966 | - property string text: action ? action.text : "" |
967 | - |
968 | - /*! |
969 | - The image associated with the actionItem. |
970 | - Default value: action.iconSource. |
971 | - |
972 | - This is the URL of any image file |
973 | - If both iconSource and iconName are defined, iconName will be ignored. |
974 | - */ |
975 | - property url iconSource: action ? action.iconSource : (iconName ? "image://theme/" + iconName : "") |
976 | - |
977 | - /*! |
978 | - The icon associated with the actionItem in the suru icon theme. |
979 | - Default value: action.iconName. |
980 | - |
981 | - \note The complete list of icons available in Ubuntu is not published yet. |
982 | - For now please refer to the folders where the icon themes are installed: |
983 | - \list |
984 | - \li Ubuntu Touch: \l file:/usr/share/icons/suru |
985 | - \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark |
986 | - \endlist |
987 | - These 2 separate icon themes will be merged soon. |
988 | - |
989 | - If both iconSource and iconName are defined, iconName will be ignored. |
990 | - */ |
991 | - property string iconName: action ? action.iconName : "" |
992 | - |
993 | - /*! |
994 | - Called when the actionItem is triggered. |
995 | - */ |
996 | - signal triggered(var value) |
997 | - |
998 | - /*! |
999 | - If \l action is set, this will trigger it. |
1000 | - */ |
1001 | - onTriggered: if (action) action.trigger(value) |
1002 | - |
1003 | - /*! |
1004 | - Trigger this action item if it is enabled. |
1005 | - */ |
1006 | - function trigger(value) { |
1007 | - var passingValue = value ? value : null |
1008 | - if (actionItem.enabled) actionItem.triggered(passingValue); |
1009 | - } |
1010 | -} |
1011 | |
1012 | === modified file 'src/Ubuntu/Components/1.3/AdaptivePageLayout.qml' |
1013 | --- src/Ubuntu/Components/1.3/AdaptivePageLayout.qml 2015-07-28 15:04:07 +0000 |
1014 | +++ src/Ubuntu/Components/1.3/AdaptivePageLayout.qml 2015-09-08 04:09:38 +0000 |
1015 | @@ -83,10 +83,85 @@ |
1016 | } |
1017 | \endqml |
1018 | |
1019 | + \note Observe the use of the \c Page::pageStack property in the example above. |
1020 | + The same property is used to share the AdaptivePageLayout instance the Page is |
1021 | + used in, therefore the same page can be used in a PageStack or in an AdaptivePageLayout. |
1022 | + However implementations must make sure the desired PageStack or AdaptivePageLayout |
1023 | + function exists in the instance before using it. |
1024 | + |
1025 | AdaptivePageLayout supports adaptive column handling. When the number of columns changes at |
1026 | runtime the pages are automatically rearranged. |
1027 | |
1028 | - \sa PageStack |
1029 | + By default the component splits the layout in two columns when the width of the |
1030 | + layout exceeds 80 grid units. The first column is sized to 40 grid unit width and |
1031 | + the second one to fill the rest of the remaining space. When the 80 grid unit breakpoint |
1032 | + is reached, the component will switch from one column to two, and vice versa. |
1033 | + These defaults can be overridden through the \l layouts property by defining the |
1034 | + possible layouts, their column sizing and the breakpoints when the layouts should |
1035 | + be activated. PageColumn configurations must appear in the same order (from left |
1036 | + to right) as the columns appear in the layout. If none of the layouts condition |
1037 | + is met, a one column layout will be used. |
1038 | + |
1039 | + \qml |
1040 | + import QtQuick 2.4 |
1041 | + import Ubuntu.Components 1.3 |
1042 | + |
1043 | + MainView { |
1044 | + width: units.gu(100) |
1045 | + height: units.gu(60) |
1046 | + |
1047 | + AdaptivePageLayout { |
1048 | + anchors.fill: parent |
1049 | + primaryPage: page1 |
1050 | + layouts: PageColumnsLayout { |
1051 | + when: width > units.gu(80) |
1052 | + // column #0 |
1053 | + PageColumn { |
1054 | + minimumWidth: units.gu(30) |
1055 | + maximumWidth: units.gu(60) |
1056 | + preferredWidth: units.gu(40) |
1057 | + } |
1058 | + // column #1 |
1059 | + PageColumn { |
1060 | + fillWidth: true |
1061 | + } |
1062 | + } |
1063 | + |
1064 | + Page { |
1065 | + id: page1 |
1066 | + title: "Main page" |
1067 | + Column { |
1068 | + Button { |
1069 | + text: "Add Page2 above " + page1.title |
1070 | + onClicked: page1.pageStack.addPageToCurrentColumn(page1, page2) |
1071 | + } |
1072 | + Button { |
1073 | + text: "Add Page3 next to " + page1.title |
1074 | + onClicked: page1.pageStack.addPageToNextColumn(page1, page3) |
1075 | + } |
1076 | + } |
1077 | + } |
1078 | + Page { |
1079 | + id: page2 |
1080 | + title: "Page #2" |
1081 | + } |
1082 | + Page { |
1083 | + id: page3 |
1084 | + title: "Page #3" |
1085 | + } |
1086 | + } |
1087 | + } |
1088 | + \endqml |
1089 | + |
1090 | + A column is considered to be resizable if the \l PageColumn::minimumWidth and |
1091 | + \l PageColumn::maximumWidth configuration differs. This implies that if a column |
1092 | + is not meant to be resized, it should have \l PageColumn::minimumWidth and |
1093 | + \l PageColumn::maximumWidth set to the same value. In the example above, the |
1094 | + first column can be resized to a minimum of 30, and a maximum of 60 grid units, |
1095 | + and the preferred width is set to 40 grid units. This width is set every time |
1096 | + the layout is activated. |
1097 | + |
1098 | + \sa PageStack, PageColumnsLayout, PageColumn |
1099 | */ |
1100 | |
1101 | PageTreeNode { |
1102 | @@ -113,12 +188,86 @@ |
1103 | property Page primaryPage |
1104 | |
1105 | /*! |
1106 | - \qmlmethod Item addPageToCurrentColumn(Item sourcePage, var page[, var properties]) |
1107 | + \qmlproperty int columns |
1108 | + \readonly |
1109 | + The property holds the number of columns shown in the layout. |
1110 | + */ |
1111 | + readonly property alias columns: d.columns |
1112 | + |
1113 | + /*! |
1114 | + The property holds the different layout configurations overriding the default |
1115 | + configurations. Defaults to an empty list. |
1116 | + \sa PageColumnsLayout |
1117 | + */ |
1118 | + property list<PageColumnsLayout> layouts |
1119 | + |
1120 | + /*! |
1121 | + \qmlmethod object addPageToCurrentColumn(Item sourcePage, var page[, var properties]) |
1122 | Adds a \c page to the column the \c sourcePage resides in and removes all pages |
1123 | from the higher columns. \c page can be a Component or a file. |
1124 | - \c properties is a JSON object containing properties |
1125 | - to be set when page is created. \c sourcePage must be active. Returns the |
1126 | - instance of the page created. |
1127 | + \c properties is a JSON object containing properties to be set when page |
1128 | + is created. \c sourcePage must be active. |
1129 | + |
1130 | + The function creates the new page asynchronously if the new \c page to be |
1131 | + added is a Component or a QML document. In this case the function returns |
1132 | + an incubator which can be used to track the page creation.For more about |
1133 | + incubation in QML and creating components asynchronously, see |
1134 | + \l {http://doc.qt.io/qt-5/qml-qtqml-component.html#incubateObject-method} |
1135 | + {Component.incubateObject()}. |
1136 | + The following example removes an element from the list model whenever the |
1137 | + page opened in the second column is closed. Note, the example must be run |
1138 | + on desktop or on a device with at least 90 grid units screen width. |
1139 | + \qml |
1140 | + import QtQuick 2.4 |
1141 | + import Ubuntu.Components 1.3 |
1142 | + |
1143 | + MainView { |
1144 | + width: units.gu(90) |
1145 | + height: units.gu(70) |
1146 | + |
1147 | + Component { |
1148 | + id: page2Component |
1149 | + Page { |
1150 | + title: "Second Page" |
1151 | + Button { |
1152 | + text: "Close me" |
1153 | + onClicked: pageStack.removePages(pageStack.primaryPage); |
1154 | + } |
1155 | + } |
1156 | + } |
1157 | + |
1158 | + AdaptivePageLayout { |
1159 | + id: pageLayout |
1160 | + anchors.fill: parent |
1161 | + primaryPage: Page { |
1162 | + title: "Primary Page" |
1163 | + ListView { |
1164 | + id: listView |
1165 | + anchors.fill: parent |
1166 | + model: 10 |
1167 | + delegate: ListItem { |
1168 | + Label { text: modelData } |
1169 | + onClicked: { |
1170 | + var incubator = pageLayout.addPageToNextColumn(pageLayout.primaryPage, page2Component); |
1171 | + if (incubator && incubator.status == Component.Loading) { |
1172 | + incubator.onStatusChanged = function(status) { |
1173 | + if (status == Component.Ready) { |
1174 | + // connect page's destruction to decrement model |
1175 | + incubator.object.Component.destruction.connect(function() { |
1176 | + listView.model--; |
1177 | + }); |
1178 | + } |
1179 | + } |
1180 | + } |
1181 | + } |
1182 | + } |
1183 | + } |
1184 | + } |
1185 | + } |
1186 | + } |
1187 | + \endqml |
1188 | + |
1189 | + \sa {http://doc.qt.io/qt-5/qml-qtqml-component.html#incubateObject-method}{Component.incubateObject} |
1190 | */ |
1191 | function addPageToCurrentColumn(sourcePage, page, properties) { |
1192 | var nextColumn = d.columnForPage(sourcePage) + 1; |
1193 | @@ -138,6 +287,7 @@ |
1194 | holds \c sourcePage) and all following columns, and then add \c page to the next column. |
1195 | If \c sourcePage is located in the |
1196 | rightmost column, the new page will be pushed to the same column as \c sourcePage. |
1197 | + The return value is the same as in \l addPageToCurrentColumn case. |
1198 | */ |
1199 | function addPageToNextColumn(sourcePage, page, properties) { |
1200 | var nextColumn = d.columnForPage(sourcePage) + 1; |
1201 | @@ -168,7 +318,12 @@ |
1202 | */ |
1203 | |
1204 | Component.onCompleted: { |
1205 | - d.relayout(); |
1206 | + // check layout configuration |
1207 | + if (layouts.length > 0) { |
1208 | + d.prepareLayouts(); |
1209 | + } else { |
1210 | + d.relayout(); |
1211 | + } |
1212 | d.completed = true; |
1213 | if (primaryPage) { |
1214 | var wrapper = d.createWrapper(primaryPage); |
1215 | @@ -183,6 +338,13 @@ |
1216 | return; |
1217 | } |
1218 | } |
1219 | + onLayoutsChanged: { |
1220 | + if (d.completed) { |
1221 | + // only deal with this if the layouts array changes after completion |
1222 | + // to avoid unnecessary rendering |
1223 | + d.prepareLayouts(); |
1224 | + } |
1225 | + } |
1226 | |
1227 | QtObject { |
1228 | id: d |
1229 | @@ -190,7 +352,12 @@ |
1230 | property bool completed: false |
1231 | property var tree: new Tree.Tree() |
1232 | |
1233 | - property int columns: layout.width >= units.gu(80) ? 2 : 1 |
1234 | + property int columns: !layout.layouts.length ? |
1235 | + (layout.width >= units.gu(80) ? 2 : 1) : |
1236 | + (activeLayout ? activeLayout.data.length : 1) |
1237 | + property PageColumnsLayout activeLayout: null |
1238 | + property list<PageColumnsLayout> prevLayouts |
1239 | + |
1240 | /*! internal */ |
1241 | onColumnsChanged: { |
1242 | if (columns <= 0) { |
1243 | @@ -201,11 +368,10 @@ |
1244 | } |
1245 | property real defaultColumnWidth: units.gu(40) |
1246 | onDefaultColumnWidthChanged: body.applyMetrics() |
1247 | - property list<ColumnMetrics> columnMetrics |
1248 | |
1249 | function createWrapper(page, properties) { |
1250 | var wrapperComponent = Qt.createComponent("PageWrapper.qml"); |
1251 | - var wrapperObject = wrapperComponent.createObject(hiddenPages); |
1252 | + var wrapperObject = wrapperComponent.createObject(hiddenPages, {synchronous: false}); |
1253 | wrapperObject.pageStack = layout; |
1254 | wrapperObject.properties = properties; |
1255 | // set reference last because it will trigger creation of the object |
1256 | @@ -221,7 +387,14 @@ |
1257 | // replace page holder's child |
1258 | var holder = body.children[targetColumn]; |
1259 | holder.detachCurrentPage(); |
1260 | - holder.attachPage(pageWrapper) |
1261 | + if ((pageWrapper.incubator && pageWrapper.incubator.status == Component.Ready) || pageWrapper.object) { |
1262 | + holder.attachPage(pageWrapper); |
1263 | + } else { |
1264 | + // asynchronous, connect to page load completion and attach when page is available |
1265 | + pageWrapper.pageLoaded.connect(function () { |
1266 | + holder.attachPage(pageWrapper); |
1267 | + }); |
1268 | + } |
1269 | } |
1270 | |
1271 | function getWrapper(page) { |
1272 | @@ -279,7 +452,7 @@ |
1273 | newWrapper.parentPage = sourcePage; |
1274 | newWrapper.column = column; |
1275 | d.addWrappedPage(newWrapper); |
1276 | - return newWrapper.object; |
1277 | + return newWrapper.incubator; |
1278 | } |
1279 | |
1280 | // update the page for the specified column |
1281 | @@ -301,6 +474,33 @@ |
1282 | } |
1283 | } |
1284 | |
1285 | + // prepares layout management, listens on layout condition changes and performs re-layouting |
1286 | + function prepareLayouts() { |
1287 | + // disconnect from the previous layouts |
1288 | + for (var i = 0; i < prevLayouts.length; i++) { |
1289 | + prevLayouts[i].whenChanged.disconnect(updateLayout); |
1290 | + } |
1291 | + prevLayouts = layouts; |
1292 | + for (var i = 0; i < layouts.length; i++) { |
1293 | + layouts[i].whenChanged.connect(updateLayout); |
1294 | + } |
1295 | + // first time evaluation |
1296 | + updateLayout(); |
1297 | + } |
1298 | + |
1299 | + // function called when one of the layout condition is satisfied |
1300 | + function updateLayout() { |
1301 | + var newLayout = null; |
1302 | + for (var i = 0; i < layouts.length; i++) { |
1303 | + // get the first affirmative condition |
1304 | + if (layouts[i].when) { |
1305 | + newLayout = layouts[i]; |
1306 | + break; |
1307 | + } |
1308 | + } |
1309 | + d.activeLayout = newLayout; |
1310 | + } |
1311 | + |
1312 | // relayouts when column count changes |
1313 | function relayout() { |
1314 | if (body.children.length == d.columns) return; |
1315 | @@ -357,8 +557,8 @@ |
1316 | // default metrics |
1317 | Component { |
1318 | id: defaultMetrics |
1319 | - ColumnMetrics { |
1320 | - fillWidth: column == d.columns |
1321 | + PageColumn { |
1322 | + fillWidth: __column == d.columns |
1323 | minimumWidth: d.defaultColumnWidth |
1324 | } |
1325 | } |
1326 | @@ -376,13 +576,12 @@ |
1327 | property PageWrapper pageWrapper |
1328 | property int column |
1329 | property alias config: subHeader.config |
1330 | - property ColumnMetrics metrics: setDefaultMetrics() |
1331 | + property PageColumn metrics: getDefaultMetrics() |
1332 | + readonly property real dividerThickness: units.dp(1) |
1333 | |
1334 | Layout.fillWidth: metrics.fillWidth |
1335 | Layout.fillHeight: true |
1336 | - Layout.preferredWidth: metrics.maximumWidth > 0 ? |
1337 | - MathUtils.clamp(d.defaultColumnWidth, metrics.minimumWidth, metrics.maximumWidth) : |
1338 | - d.defaultColumnWidth |
1339 | + Layout.preferredWidth: MathUtils.clamp(metrics.preferredWidth, metrics.minimumWidth, metrics.maximumWidth) |
1340 | Layout.minimumWidth: metrics.minimumWidth |
1341 | Layout.maximumWidth: metrics.maximumWidth |
1342 | |
1343 | @@ -396,7 +595,7 @@ |
1344 | bottom: parent.bottom |
1345 | left: parent.left |
1346 | right: parent.right |
1347 | - rightMargin: verticalDivider.width |
1348 | + rightMargin: dividerThickness |
1349 | } |
1350 | // we need to clip because the header does not have a background |
1351 | clip: true |
1352 | @@ -412,7 +611,7 @@ |
1353 | } |
1354 | height: body.headerHeight |
1355 | |
1356 | - styleName: config ? "PageHeadStyle" : "" |
1357 | + styleName: "PageHeadStyle" |
1358 | theme.version: Ubuntu.toolkitVersion |
1359 | objectName: "Header" + column |
1360 | |
1361 | @@ -457,9 +656,52 @@ |
1362 | top: parent.top |
1363 | bottom: parent.bottom |
1364 | right: parent.right |
1365 | + rightMargin: dividerThickness |
1366 | } |
1367 | width: (column == (d.columns - 1)) || !pageWrapper ? 0 : units.dp(1) |
1368 | - color: subHeader.dividerColor |
1369 | + color: theme.palette.selected.background |
1370 | + MouseArea { |
1371 | + id: resizerSensing |
1372 | + objectName: "Divider" |
1373 | + enabled: verticalDivider.width > 0 |
1374 | + anchors { |
1375 | + fill: parent |
1376 | + leftMargin: enabled ? -units.gu(1) : 0 |
1377 | + rightMargin: enabled ? -units.gu(1) : 0 |
1378 | + } |
1379 | + cursorShape: Qt.SizeHorCursor |
1380 | + drag { |
1381 | + axis: Drag.XAxis |
1382 | + target: resizer |
1383 | + smoothed: false |
1384 | + minimumX: holder.Layout.minimumWidth |
1385 | + maximumX: holder.Layout.maximumWidth |
1386 | + } |
1387 | + onPressed: resizer.x = holder.Layout.preferredWidth |
1388 | + } |
1389 | + states: State { |
1390 | + name: "active" |
1391 | + when: resizerSensing.pressed |
1392 | + PropertyChanges { |
1393 | + target: verticalDivider |
1394 | + color: Qt.darker(theme.palette.normal.background, 1.5) |
1395 | + } |
1396 | + } |
1397 | + transitions: Transition { |
1398 | + from: "" |
1399 | + to: "*" |
1400 | + reversible: true |
1401 | + ColorAnimation { |
1402 | + target: verticalDivider |
1403 | + property: "color" |
1404 | + duration: UbuntuAnimation.SlowDuration |
1405 | + } |
1406 | + } |
1407 | + } |
1408 | + Item { |
1409 | + id: resizer |
1410 | + height: parent.height |
1411 | + onXChanged: holder.Layout.preferredWidth = x |
1412 | } |
1413 | |
1414 | function attachPage(page) { |
1415 | @@ -488,9 +730,9 @@ |
1416 | return wrapper; |
1417 | } |
1418 | |
1419 | - function setDefaultMetrics() { |
1420 | + function getDefaultMetrics() { |
1421 | var result = defaultMetrics.createObject(holder); |
1422 | - result.column = Qt.binding(function() { return holder.column + 1; }); |
1423 | + result.__column = Qt.binding(function() { return holder.column + 1; }); |
1424 | return result; |
1425 | } |
1426 | } |
1427 | @@ -545,15 +787,9 @@ |
1428 | for (var i = 0; i < children.length; i++) { |
1429 | var holder = children[i]; |
1430 | // search for the column metrics |
1431 | - var metrics = null; |
1432 | - for (var j = 0; j < d.columnMetrics.length; j++) { |
1433 | - if (d.columnMetrics[j].column == (i + 1)) { |
1434 | - metrics = d.columnMetrics[j]; |
1435 | - break; |
1436 | - } |
1437 | - } |
1438 | + var metrics = d.activeLayout ? d.activeLayout.data[i] : null; |
1439 | if (!metrics) { |
1440 | - metrics = holder.setDefaultMetrics(); |
1441 | + metrics = holder.getDefaultMetrics(); |
1442 | } |
1443 | holder.metrics = metrics; |
1444 | updateHeaderHeight(0); |
1445 | |
1446 | === modified file 'src/Ubuntu/Components/1.3/AppHeader.qml' |
1447 | --- src/Ubuntu/Components/1.3/AppHeader.qml 2015-08-03 15:02:42 +0000 |
1448 | +++ src/Ubuntu/Components/1.3/AppHeader.qml 2015-09-08 04:09:38 +0000 |
1449 | @@ -184,11 +184,6 @@ |
1450 | } |
1451 | |
1452 | /*! |
1453 | - Set by \l MainView |
1454 | - */ |
1455 | - property bool useDeprecatedToolbar: true |
1456 | - |
1457 | - /*! |
1458 | Configuration of the header. |
1459 | FIXME: Must be of type PageHeadConfiguration. Setting that as the property type |
1460 | however will use the latest version (1.3) and a Page that uses an older |
1461 | @@ -355,5 +350,5 @@ |
1462 | } |
1463 | |
1464 | theme.version: Components.Ubuntu.toolkitVersion |
1465 | - styleName: header.useDeprecatedToolbar ? "HeaderStyle" : "PageHeadStyle" |
1466 | + styleName: "PageHeadStyle" |
1467 | } |
1468 | |
1469 | === modified file 'src/Ubuntu/Components/1.3/Button.qml' |
1470 | --- src/Ubuntu/Components/1.3/Button.qml 2015-05-26 15:05:46 +0000 |
1471 | +++ src/Ubuntu/Components/1.3/Button.qml 2015-09-08 04:09:38 +0000 |
1472 | @@ -105,7 +105,7 @@ |
1473 | /*! |
1474 | The font used for the button's text. |
1475 | */ |
1476 | - property font font: __styleInstance ? __styleInstance.defaultFont : Qt.font({family: "Ubuntu", pixelSize: FontUtils.sizeToPixels("medium")}) |
1477 | + property font font: __styleInstance.defaultFont |
1478 | |
1479 | /*! |
1480 | The position of the icon relative to the text. Options |
1481 | |
1482 | === modified file 'src/Ubuntu/Components/1.3/ComboButton.qml' |
1483 | --- src/Ubuntu/Components/1.3/ComboButton.qml 2015-05-21 10:50:35 +0000 |
1484 | +++ src/Ubuntu/Components/1.3/ComboButton.qml 2015-09-08 04:09:38 +0000 |
1485 | @@ -15,6 +15,7 @@ |
1486 | */ |
1487 | |
1488 | import QtQuick 2.4 |
1489 | +import Ubuntu.Components 1.3 |
1490 | import Ubuntu.Components.Popups 1.3 |
1491 | |
1492 | /*! |
1493 | |
1494 | === removed file 'src/Ubuntu/Components/1.3/Header.qml' |
1495 | --- src/Ubuntu/Components/1.3/Header.qml 2015-04-25 08:54:58 +0000 |
1496 | +++ src/Ubuntu/Components/1.3/Header.qml 1970-01-01 00:00:00 +0000 |
1497 | @@ -1,39 +0,0 @@ |
1498 | -/* |
1499 | - * Copyright 2014 Canonical Ltd. |
1500 | - * |
1501 | - * This program is free software; you can redistribute it and/or modify |
1502 | - * it under the terms of the GNU Lesser General Public License as published by |
1503 | - * the Free Software Foundation; version 3. |
1504 | - * |
1505 | - * This program is distributed in the hope that it will be useful, |
1506 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1507 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1508 | - * GNU Lesser General Public License for more details. |
1509 | - * |
1510 | - * You should have received a copy of the GNU Lesser General Public License |
1511 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1512 | - */ |
1513 | - |
1514 | -import QtQuick 2.4 |
1515 | - |
1516 | -/*! |
1517 | - \qmltype Header |
1518 | - \internal |
1519 | - \deprecated |
1520 | -*/ |
1521 | -AppHeader { |
1522 | - |
1523 | - /*! |
1524 | - \internal |
1525 | - We need this property so QML exposes this class as Header instead of |
1526 | - AppHeader. This way autopilot can select the deprecated header. |
1527 | - */ |
1528 | - property string _for_autopilot |
1529 | - |
1530 | - Component.onCompleted: { |
1531 | - print("WARNING: Header is an internal component of Ubuntu.Components and" + |
1532 | - "its API may change or be removed at any moment." + |
1533 | - "Please use MainView and Page instead." |
1534 | - ); |
1535 | - } |
1536 | -} |
1537 | |
1538 | === modified file 'src/Ubuntu/Components/1.3/MainView.qml' |
1539 | --- src/Ubuntu/Components/1.3/MainView.qml 2015-08-10 15:35:04 +0000 |
1540 | +++ src/Ubuntu/Components/1.3/MainView.qml 2015-09-08 04:09:38 +0000 |
1541 | @@ -191,9 +191,6 @@ |
1542 | window.title = headerItem.title |
1543 | } |
1544 | } |
1545 | - |
1546 | - // Use of the deprecated toolbar is no longer supported in MainView 1.2. |
1547 | - useDeprecatedToolbar: false |
1548 | } |
1549 | |
1550 | Connections { |
1551 | |
1552 | === modified file 'src/Ubuntu/Components/1.3/MainViewBase.qml' |
1553 | --- src/Ubuntu/Components/1.3/MainViewBase.qml 2015-08-06 22:32:02 +0000 |
1554 | +++ src/Ubuntu/Components/1.3/MainViewBase.qml 2015-09-08 04:09:38 +0000 |
1555 | @@ -28,6 +28,8 @@ |
1556 | */ |
1557 | PageTreeNode { |
1558 | id: mainView |
1559 | + styleName: "MainViewStyle" |
1560 | + |
1561 | /*! |
1562 | The property holds the application's name, which must be the same as the |
1563 | desktop file's name. |
1564 | @@ -53,7 +55,7 @@ |
1565 | |
1566 | \sa backgroundColor, footerColor |
1567 | */ |
1568 | - property alias headerColor: background.headerColor |
1569 | + property color headerColor: backgroundColor |
1570 | |
1571 | /*! |
1572 | \qmlproperty color MainView::backgroundColor |
1573 | @@ -80,7 +82,7 @@ |
1574 | |
1575 | \sa footerColor, headerColor |
1576 | */ |
1577 | - property alias backgroundColor: background.backgroundColor |
1578 | + property color backgroundColor: theme.palette.normal.background |
1579 | |
1580 | /*! |
1581 | \qmlproperty color MainView::footerColor |
1582 | @@ -88,22 +90,12 @@ |
1583 | |
1584 | \sa backgroundColor, headerColor |
1585 | */ |
1586 | - property alias footerColor: background.footerColor |
1587 | - |
1588 | - // FIXME: Make sure that the theming is only in the background, and the style |
1589 | - // should not occlude contents of the MainView. When making changes here, make |
1590 | - // sure that bug https://bugs.launchpad.net/manhattan/+bug/1124076 does not come back. |
1591 | - Toolkit.StyledItem { |
1592 | - id: background |
1593 | - anchors.fill: parent |
1594 | - // theme is inherited from PageTreeNode, no need to update versioning |
1595 | - styleName: "MainViewStyle" |
1596 | - |
1597 | - // FIXME: Define the colors in MainViewStyle and get rid of the properties |
1598 | - // in MainViewBase. |
1599 | - property color headerColor: backgroundColor |
1600 | - property color backgroundColor: theme.palette.normal.background |
1601 | - property color footerColor: backgroundColor |
1602 | + property color footerColor: backgroundColor |
1603 | + |
1604 | + Toolkit.Object { |
1605 | + id: autoTheme |
1606 | + // FIXME: Define the background colors in MainViewStyle and get rid of the properties |
1607 | + // in MainViewBase. That removes the need for auto-theming. |
1608 | |
1609 | /* |
1610 | As we don't know the order the property bindings and onXXXChanged signals are evaluated |
1611 | @@ -113,18 +105,23 @@ |
1612 | Qt bug: https://bugreports.qt-project.org/browse/QTBUG-11712 |
1613 | */ |
1614 | |
1615 | - onBackgroundColorChanged: { |
1616 | - if (backgroundColor != theme.palette.normal.background) { |
1617 | - // custom color, proceed with auto-theming |
1618 | - autoThemeName = (ColorUtils.luminance(backgroundColor) >= 0.85) ? |
1619 | - "Ambiance" : "SuruDark"; |
1620 | + Connections { |
1621 | + target: mainView |
1622 | + |
1623 | + onBackgroundColorChanged: { |
1624 | + if (mainView.backgroundColor != theme.palette.normal.background) { |
1625 | + // custom color, proceed with auto-theming |
1626 | + autoTheme.themeName = (ColorUtils.luminance(backgroundColor) >= 0.85) ? |
1627 | + "Ambiance" : "SuruDark"; |
1628 | + } |
1629 | } |
1630 | } |
1631 | - property string autoThemeName |
1632 | - onAutoThemeNameChanged: { |
1633 | + |
1634 | + property string themeName |
1635 | + onThemeNameChanged: { |
1636 | // only change the theme if the current one is a system one. |
1637 | - if (autoThemeName !== "" && (theme.name.search("Ubuntu.Components.Themes") == 0)) { |
1638 | - mainView.theme.name = "Ubuntu.Components.Themes.%1".arg(autoThemeName); |
1639 | + if (themeName !== "" && (theme.name.search("Ubuntu.Components.Themes") == 0)) { |
1640 | + mainView.theme.name = "Ubuntu.Components.Themes.%1".arg(themeName); |
1641 | } |
1642 | } |
1643 | } |
1644 | |
1645 | === renamed file 'src/Ubuntu/Components/1.3/ColumnMetrics.qml' => 'src/Ubuntu/Components/1.3/PageColumn.qml' |
1646 | --- src/Ubuntu/Components/1.3/ColumnMetrics.qml 2015-06-24 16:16:13 +0000 |
1647 | +++ src/Ubuntu/Components/1.3/PageColumn.qml 2015-09-08 04:09:38 +0000 |
1648 | @@ -17,37 +17,42 @@ |
1649 | import QtQuick 2.4 |
1650 | |
1651 | /*! |
1652 | - \qmltype ColumnMetrics |
1653 | + \qmltype PageColumn |
1654 | \inqmlmodule Ubuntu.Components 1.3 |
1655 | \since Ubuntu.Components 1.3 |
1656 | \ingroup ubuntu |
1657 | - \brief Component configuring the metrics of a column in MultiColumnView. |
1658 | - \internal |
1659 | + \brief Component configuring the metrics of a column in AdaptivePageLayout. |
1660 | |
1661 | */ |
1662 | QtObject { |
1663 | /*! |
1664 | 1-based value identifying the column the metrics to be applied to. |
1665 | + \internal |
1666 | */ |
1667 | - property int column |
1668 | + property int __column |
1669 | |
1670 | /*! |
1671 | Specifies whether the width of the column should fill the available space |
1672 | - of the MultiColumnView column or not. Defaults to \a false. |
1673 | + of the AdaptivePageLayout column or not. Defaults to \a false. |
1674 | */ |
1675 | property bool fillWidth: false |
1676 | |
1677 | /*! |
1678 | - Specifies the minimum width of the column. If the value is greater than |
1679 | - \b MultiColumnView::defaultColumnWidth, the value will be set as width for |
1680 | - the column. |
1681 | + Specifies the minimum width of the column. Defaults to 0. |
1682 | */ |
1683 | property real minimumWidth: 0 |
1684 | |
1685 | /*! |
1686 | - Specifies the maximum width of the column. If the value is smaller than |
1687 | - \b MultiColumnView::defaultColumnWidth, the value will be set as width for |
1688 | - the column. A maximum value of 0 will be ignored. |
1689 | + Specifies the maximum width of the column. A maximum value of 0 will be ignored. |
1690 | + Defaults to the maximum positive value. |
1691 | */ |
1692 | property real maximumWidth: Number.POSITIVE_INFINITY |
1693 | + |
1694 | + /*! |
1695 | + Specifies the preferred width of the column when the layout is initialized. |
1696 | + Defaults to 0. AdaptivePageLayout clamps the given value between \l minimumWidth |
1697 | + and \l maximumWidth. The value must be set if the \l fillWidth and \l minimumWidth |
1698 | + are not set. |
1699 | + */ |
1700 | + property real preferredWidth: 0 |
1701 | } |
1702 | |
1703 | === added file 'src/Ubuntu/Components/1.3/PageColumnsLayout.qml' |
1704 | --- src/Ubuntu/Components/1.3/PageColumnsLayout.qml 1970-01-01 00:00:00 +0000 |
1705 | +++ src/Ubuntu/Components/1.3/PageColumnsLayout.qml 2015-09-08 04:09:38 +0000 |
1706 | @@ -0,0 +1,115 @@ |
1707 | +/* |
1708 | + * Copyright 2015 Canonical Ltd. |
1709 | + * |
1710 | + * This program is free software; you can redistribute it and/or modify |
1711 | + * it under the terms of the GNU Lesser General Public License as published by |
1712 | + * the Free Software Foundation; version 3. |
1713 | + * |
1714 | + * This program is distributed in the hope that it will be useful, |
1715 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1716 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1717 | + * GNU Lesser General Public License for more details. |
1718 | + * |
1719 | + * You should have received a copy of the GNU Lesser General Public License |
1720 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1721 | + */ |
1722 | + |
1723 | +import QtQuick 2.4 |
1724 | + |
1725 | +/*! |
1726 | + \qmltype PageColumnsLayout |
1727 | + \inqmlmodule Ubuntu.Components 1.3 |
1728 | + \since Ubuntu.Components 1.3 |
1729 | + \ingroup ubuntu |
1730 | + \brief Component configuring a layout in an AdaptivePageLayout component. |
1731 | + |
1732 | + The component specifies the column configuration of a specific layout. The layout |
1733 | + will have as many columns as many PageColumn elements will be declared. The layout |
1734 | + will be activated when the \l when property evaluates to \c true. There can be |
1735 | + many layouts evaluated to true, only the first one evaluated to true in the |
1736 | + \l AdaptivePageLayout::layouts list will be activated. |
1737 | + |
1738 | + \qml |
1739 | + import QtQuick 2.4 |
1740 | + import Ubuntu.Components 1.3 |
1741 | + |
1742 | + MainView { |
1743 | + width: units.gu(100) |
1744 | + height: units.gu(60) |
1745 | + |
1746 | + AdaptivePageLayout { |
1747 | + anchors.fill: parent |
1748 | + primaryPage: page1 |
1749 | + layouts: [ |
1750 | + PageColumnsLayout { |
1751 | + when: width > units.gu(80) |
1752 | + // column #0 |
1753 | + PageColumn { |
1754 | + minimumWidth: units.gu(30) |
1755 | + maximumWidth: units.gu(60) |
1756 | + preferredWidth: units.gu(40) |
1757 | + } |
1758 | + // column #1 |
1759 | + PageColumn { |
1760 | + fillWidth: true |
1761 | + } |
1762 | + }, |
1763 | + PageColumnsLayout { |
1764 | + when: true |
1765 | + PageColumn { |
1766 | + fillWidth: true |
1767 | + minimumWidth: units.gu(10) |
1768 | + } |
1769 | + } |
1770 | + ] |
1771 | + |
1772 | + Page { |
1773 | + id: page1 |
1774 | + title: "Main page" |
1775 | + Column { |
1776 | + Button { |
1777 | + text: "Add Page2 above " + page1.title |
1778 | + onClicked: page1.pageStack.addPageToCurrentColumn(page1, page2) |
1779 | + } |
1780 | + Button { |
1781 | + text: "Add Page3 next to " + page1.title |
1782 | + onClicked: page1.pageStack.addPageToNextColumn(page1, page3) |
1783 | + } |
1784 | + } |
1785 | + } |
1786 | + Page { |
1787 | + id: page2 |
1788 | + title: "Page #2" |
1789 | + } |
1790 | + Page { |
1791 | + id: page3 |
1792 | + title: "Page #3" |
1793 | + } |
1794 | + } |
1795 | + } |
1796 | + \endqml |
1797 | + In the example above the second PageColumnLayout's condition is always set to |
1798 | + true, which means that that the layout will be always active unless the first |
1799 | + layout's condition evaluates to true. The layout overrides the single column |
1800 | + minimumWidth default value. Note that \l PageColumn::fillWidth must be also set. |
1801 | + |
1802 | + \note When none of the conditions is met, a single column layout will be used. |
1803 | + |
1804 | + \sa PageColumn |
1805 | + */ |
1806 | +QtObject { |
1807 | + id: layout |
1808 | + |
1809 | + /*! |
1810 | + Condition activating the layout. Defaults to false. |
1811 | + */ |
1812 | + property bool when: false |
1813 | + |
1814 | + /*! |
1815 | + \qmlproperty list<PageColumn> data |
1816 | + \default |
1817 | + Default property holding the PageColumn elements configuring each column. |
1818 | + */ |
1819 | + default property alias data: layout.__data |
1820 | + property list<PageColumn> __data |
1821 | +} |
1822 | |
1823 | === modified file 'src/Ubuntu/Components/1.3/PageWrapper.qml' |
1824 | --- src/Ubuntu/Components/1.3/PageWrapper.qml 2015-06-15 07:45:34 +0000 |
1825 | +++ src/Ubuntu/Components/1.3/PageWrapper.qml 2015-09-08 04:09:38 +0000 |
1826 | @@ -15,7 +15,7 @@ |
1827 | */ |
1828 | |
1829 | import QtQuick 2.4 |
1830 | -import "../1.2/PageWrapperUtils.js" as Utils |
1831 | +import "PageWrapperUtils.js" as Utils |
1832 | |
1833 | /*! |
1834 | \internal |
1835 | @@ -66,6 +66,22 @@ |
1836 | property Item pageHolder |
1837 | |
1838 | /*! |
1839 | + Instructs to load the page synchronously or not. Used by AdaptivePageLayout. |
1840 | + True by default to keep PageStack integrity. |
1841 | + */ |
1842 | + property bool synchronous: true |
1843 | + |
1844 | + /*! |
1845 | + Incubator for the asynchronous page creation |
1846 | + */ |
1847 | + property var incubator: null |
1848 | + |
1849 | + /*! |
1850 | + Signal emitted when incubator completes page loading. |
1851 | + */ |
1852 | + signal pageLoaded() |
1853 | + |
1854 | + /*! |
1855 | Returns true if the current PageWrapper is a child of the given page |
1856 | */ |
1857 | function childOf(page) { |
1858 | @@ -114,7 +130,14 @@ |
1859 | if (pageWrapper.object) pageWrapper.object = null; |
1860 | Utils.initPage(pageWrapper); |
1861 | if (pageWrapper.active && reference) { |
1862 | - Utils.activate(pageWrapper); |
1863 | + if ((pageWrapper.incubator && pageWrapper.incubator.status == Component.Ready) || pageWrapper.object) { |
1864 | + Utils.activate(pageWrapper); |
1865 | + } else { |
1866 | + // asynchronous, connect page activation |
1867 | + pageLoaded.connect(function () { |
1868 | + Utils.activate(pageWrapper); |
1869 | + }); |
1870 | + } |
1871 | } |
1872 | } |
1873 | |
1874 | |
1875 | === added file 'src/Ubuntu/Components/1.3/PageWrapperUtils.js' |
1876 | --- src/Ubuntu/Components/1.3/PageWrapperUtils.js 1970-01-01 00:00:00 +0000 |
1877 | +++ src/Ubuntu/Components/1.3/PageWrapperUtils.js 2015-09-08 04:09:38 +0000 |
1878 | @@ -0,0 +1,167 @@ |
1879 | +/* |
1880 | + * Copyright 2015 Canonical Ltd. |
1881 | + * |
1882 | + * This program is free software; you can redistribute it and/or modify |
1883 | + * it under the terms of the GNU Lesser General Public License as published by |
1884 | + * the Free Software Foundation; version 3. |
1885 | + * |
1886 | + * This program is distributed in the hope that it will be useful, |
1887 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1888 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1889 | + * GNU Lesser General Public License for more details. |
1890 | + * |
1891 | + * You should have received a copy of the GNU Lesser General Public License |
1892 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1893 | + */ |
1894 | + |
1895 | +//.pragma library // FIXME: cannot refer to Component.Error if I use this. |
1896 | +// FIXME: ideally we would make this a stateless library, but that breaks applications |
1897 | +// that rely on accessing context variables in pages that were pushed on a PageStack |
1898 | +// by url (PageStack.push("FileName.qml")) because of a Qt bug: |
1899 | +// https://bugreports.qt-project.org/browse/QTBUG-31347 |
1900 | + |
1901 | +/*! |
1902 | + \internal |
1903 | + Incubator wrapper object. Used when page is loaded asynchronously. |
1904 | + */ |
1905 | + |
1906 | +function Incubator(pageWrapper, pageComponent) { |
1907 | + // private variable for QmlIncubatorObject |
1908 | + var incubator = null; |
1909 | + |
1910 | + // public API |
1911 | + this.status = Component.Ready; |
1912 | + this.object = null; |
1913 | + this.onStatusChanged = null; |
1914 | + this.forceCompletion = function () { |
1915 | + if (incubator) { |
1916 | + incubator.forceCompletion(); |
1917 | + } |
1918 | + } |
1919 | + |
1920 | + // internal function to catch status changes |
1921 | + function incubatorStatusChanged(status) { |
1922 | + // update wrapper incubator fields |
1923 | + pageWrapper.incubator.status = status; |
1924 | + pageWrapper.incubator.object = pageWrapper.object = incubator.object; |
1925 | + |
1926 | + // emit pageWrapper's pageLoaded signal to complete page activation and loading |
1927 | + if (status === Component.Ready) { |
1928 | + pageWrapper.pageLoaded(); |
1929 | + } |
1930 | + |
1931 | + // forward state change to the user |
1932 | + if (pageWrapper.incubator.onStatusChanged) { |
1933 | + // call onStatusChanged |
1934 | + pageWrapper.incubator.onStatusChanged(status); |
1935 | + } |
1936 | + |
1937 | + // cleanup of ready or error |
1938 | + if (status !== Component.Loading) { |
1939 | + pageWrapper.incubator = null; |
1940 | + incubator = null; |
1941 | + } |
1942 | + } |
1943 | + |
1944 | + if (pageWrapper.properties) { |
1945 | + incubator = pageComponent.incubateObject(pageWrapper, pageWrapper.properties); |
1946 | + } else { |
1947 | + incubator = pageComponent.incubateObject(pageWrapper); |
1948 | + } |
1949 | + |
1950 | + this.status = incubator.status; |
1951 | + if (incubator.status != Component.Ready) { |
1952 | + incubator.onStatusChanged = incubatorStatusChanged; |
1953 | + } else { |
1954 | + incubatorStatusChanged(incubator.status); |
1955 | + } |
1956 | +} |
1957 | + |
1958 | +/******************************************************* |
1959 | + * |
1960 | + */ |
1961 | +/*! |
1962 | + \internal |
1963 | + Initialize pageWrapper.object. |
1964 | + */ |
1965 | +function initPage(pageWrapper) { |
1966 | + var pageComponent; |
1967 | + |
1968 | + if (pageWrapper.reference.createObject) { |
1969 | + // page reference is a component |
1970 | + pageComponent = pageWrapper.reference; |
1971 | + } else if (typeof pageWrapper.reference == "string") { |
1972 | + // page reference is a string (url) |
1973 | + pageComponent = Qt.createComponent(pageWrapper.reference); |
1974 | + } |
1975 | + |
1976 | + // PageWrapper can override the synchronous loading |
1977 | + var synchronous = pageWrapper.hasOwnProperty("synchronous") ? pageWrapper.synchronous : true; |
1978 | + |
1979 | + if (pageComponent) { |
1980 | + if (pageComponent.status === Component.Error) { |
1981 | + throw new Error("Error while loading page: " + pageComponent.errorString()); |
1982 | + } else { |
1983 | + // create the object |
1984 | + pageWrapper.incubator = new Incubator(pageWrapper, pageComponent); |
1985 | + if (synchronous) { |
1986 | + pageWrapper.incubator.forceCompletion(); |
1987 | + } |
1988 | + pageWrapper.canDestroy = true; |
1989 | + } |
1990 | + } else { |
1991 | + // page reference is an object |
1992 | + pageWrapper.object = pageWrapper.reference; |
1993 | + pageWrapper.object.parent = pageWrapper; |
1994 | + pageWrapper.canDestroy = false; |
1995 | + |
1996 | + // copy the properties to the page object |
1997 | + for (var prop in pageWrapper.properties) { |
1998 | + if (pageWrapper.properties.hasOwnProperty(prop)) { |
1999 | + pageWrapper.object[prop] = pageWrapper.properties[prop]; |
2000 | + } |
2001 | + } |
2002 | + } |
2003 | + |
2004 | + return pageWrapper.object; |
2005 | +} |
2006 | + |
2007 | +/*! |
2008 | + \internal |
2009 | + Create the page object if needed, and make the page object visible. |
2010 | + */ |
2011 | +function activate(pageWrapper) { |
2012 | + if (!pageWrapper.object) { |
2013 | + initPage(pageWrapper); |
2014 | + } |
2015 | + |
2016 | + // Having the same page pushed multiple times on a stack changes |
2017 | + // the parent of the page object. Change it back here. |
2018 | + pageWrapper.object.parent = pageWrapper; |
2019 | + |
2020 | + // Some page objects are invisible initially. Make visible. |
2021 | + |
2022 | + pageWrapper.object.visible = true; |
2023 | + pageWrapper.active = true; |
2024 | +} |
2025 | + |
2026 | +/*! |
2027 | + \internal |
2028 | + Hide page object. |
2029 | + */ |
2030 | +function deactivate(pageWrapper) { |
2031 | + pageWrapper.active = false; |
2032 | +} |
2033 | + |
2034 | +/*! |
2035 | + \internal |
2036 | + Destroy the page object if pageWrapper.canDestroy is true. |
2037 | + Do nothing if pageWrapper.canDestroy is false. |
2038 | + */ |
2039 | +function destroyObject(pageWrapper) { |
2040 | + if (pageWrapper.canDestroy) { |
2041 | + pageWrapper.object.destroy(); |
2042 | + pageWrapper.object = null; |
2043 | + pageWrapper.canDestroy = false; |
2044 | + } |
2045 | +} |
2046 | |
2047 | === modified file 'src/Ubuntu/Components/1.3/TextField.qml' |
2048 | --- src/Ubuntu/Components/1.3/TextField.qml 2015-08-11 17:15:59 +0000 |
2049 | +++ src/Ubuntu/Components/1.3/TextField.qml 2015-09-08 04:09:38 +0000 |
2050 | @@ -99,7 +99,7 @@ |
2051 | \note During text selection all interactive parent Flickables are turned off. |
2052 | */ |
2053 | |
2054 | -ActionItem { |
2055 | +Ubuntu.ActionItem { |
2056 | id: control |
2057 | |
2058 | implicitWidth: units.gu(25) |
2059 | @@ -896,7 +896,7 @@ |
2060 | } |
2061 | } |
2062 | |
2063 | - AbstractButton { |
2064 | + Ubuntu.AbstractButton { |
2065 | id: clearButton |
2066 | objectName: "clear_button" |
2067 | activeFocusOnPress: false |
2068 | |
2069 | === modified file 'src/Ubuntu/Components/ComponentModule.pro' |
2070 | --- src/Ubuntu/Components/ComponentModule.pro 2015-07-29 10:12:07 +0000 |
2071 | +++ src/Ubuntu/Components/ComponentModule.pro 2015-09-08 04:09:38 +0000 |
2072 | @@ -25,7 +25,6 @@ |
2073 | |
2074 | #1.2 |
2075 | QML_FILES += 1.2/AbstractButton.qml \ |
2076 | - 1.2/ActionItem.qml \ |
2077 | 1.2/ActionList.qml \ |
2078 | 1.2/ActivityIndicator.qml \ |
2079 | 1.2/AnimatedItem.qml \ |
2080 | @@ -81,9 +80,7 @@ |
2081 | 1.2/UbuntuNumberAnimation.qml |
2082 | |
2083 | #1.3 |
2084 | -QML_FILES += 1.3/AbstractButton.qml \ |
2085 | - 1.3/ActionBar.qml \ |
2086 | - 1.3/ActionItem.qml \ |
2087 | +QML_FILES += 1.3/ActionBar.qml \ |
2088 | 1.3/ActionList.qml \ |
2089 | 1.3/ActivityIndicator.qml \ |
2090 | 1.3/AdaptivePageLayout.qml \ |
2091 | @@ -92,12 +89,10 @@ |
2092 | 1.3/Button.qml \ |
2093 | 1.3/Captions.qml \ |
2094 | 1.3/CheckBox.qml \ |
2095 | - 1.3/ColumnMetrics.qml \ |
2096 | 1.3/ComboButton.qml \ |
2097 | 1.3/CrossFadeImage.qml \ |
2098 | 1.3/dateUtils.js \ |
2099 | 1.3/DraggingArea.qml \ |
2100 | - 1.3/Header.qml \ |
2101 | 1.3/InputHandler.qml \ |
2102 | 1.3/Label.qml \ |
2103 | 1.3/MainViewBase.qml \ |
2104 | @@ -114,6 +109,7 @@ |
2105 | 1.3/PageTreeNode.qml \ |
2106 | 1.3/pageUtils.js \ |
2107 | 1.3/PageWrapper.qml \ |
2108 | + 1.3/PageWrapperUtils.js \ |
2109 | 1.3/Panel.qml \ |
2110 | 1.3/ProgressBar.qml \ |
2111 | 1.3/PullToRefresh.qml \ |
2112 | @@ -137,9 +133,12 @@ |
2113 | 1.3/UbuntuListView.qml \ |
2114 | 1.3/UbuntuNumberAnimation.qml \ |
2115 | 1.3/ListItemPopover.qml \ |
2116 | - 1.3/BottomEdgeHint.qml |
2117 | + 1.3/BottomEdgeHint.qml \ |
2118 | + 1.3/PageColumn.qml \ |
2119 | + 1.3/PageColumnsLayout.qml |
2120 | |
2121 | -OTHER_FILES+= 1.3/CrossFadeImage.qdoc \ |
2122 | +OTHER_FILES+= qmldir \ |
2123 | + 1.3/CrossFadeImage.qdoc \ |
2124 | 1.3/UbuntuListView11.qdoc \ |
2125 | 1.3/Page.qdoc \ |
2126 | 1.3/PageHeadConfiguration.qdoc \ |
2127 | |
2128 | === modified file 'src/Ubuntu/Components/ListItems/1.3/SingleControl.qml' |
2129 | --- src/Ubuntu/Components/ListItems/1.3/SingleControl.qml 2015-04-29 07:21:29 +0000 |
2130 | +++ src/Ubuntu/Components/ListItems/1.3/SingleControl.qml 2015-09-08 04:09:38 +0000 |
2131 | @@ -54,7 +54,8 @@ |
2132 | |
2133 | /*! \internal */ |
2134 | onClicked: if (control && control.enabled && control.hasOwnProperty("clicked")) control.clicked() |
2135 | - pressed: __mouseArea.pressed || (control && control.hasOwnProperty("pressed") && control.pressed) |
2136 | + /*! \internal */ |
2137 | + property bool pressed: __mouseArea.pressed || (control && control.hasOwnProperty("pressed") && control.pressed) |
2138 | /*! \internal */ |
2139 | onPressedChanged: if (control && control.enabled && control.hasOwnProperty("pressed")) control.pressed = singleControlListItem.pressed |
2140 | |
2141 | |
2142 | === modified file 'src/Ubuntu/Components/Popups/1.3/Popover.qml' |
2143 | --- src/Ubuntu/Components/Popups/1.3/Popover.qml 2015-07-19 17:54:49 +0000 |
2144 | +++ src/Ubuntu/Components/Popups/1.3/Popover.qml 2015-09-08 04:09:38 +0000 |
2145 | @@ -210,7 +210,7 @@ |
2146 | objectName: "popover_foreground" |
2147 | |
2148 | //styling properties |
2149 | - property real minimumWidth: units.gu(25) |
2150 | + property real minimumWidth: units.gu(40) |
2151 | |
2152 | property real maxWidth: dismissArea ? (internal.portrait ? dismissArea.width : dismissArea.width * 3/4) : 0.0 |
2153 | property real maxHeight: dismissArea ? (internal.portrait ? dismissArea.height * 3/4 : dismissArea.height) : 0.0 |
2154 | |
2155 | === modified file 'src/Ubuntu/Components/Themes/Ambiance/1.2/ListItemStyle.qml' |
2156 | --- src/Ubuntu/Components/Themes/Ambiance/1.2/ListItemStyle.qml 2015-07-22 18:57:58 +0000 |
2157 | +++ src/Ubuntu/Components/Themes/Ambiance/1.2/ListItemStyle.qml 2015-09-08 04:09:38 +0000 |
2158 | @@ -25,7 +25,7 @@ |
2159 | * Take over the ListItem's index context property as repeater used in panel |
2160 | * overrides the property. |
2161 | */ |
2162 | - readonly property int listItemIndex: index |
2163 | + readonly property int listItemIndex: (typeof index !== "undefined") ? index : internals.childIndex() |
2164 | |
2165 | /* |
2166 | * Coloring properties |
2167 | @@ -343,6 +343,19 @@ |
2168 | readonly property real threshold: units.gu(1.5) |
2169 | property bool snapIn: false |
2170 | |
2171 | + // returns the child index of the ListItem when not used in model driven view |
2172 | + function childIndex() { |
2173 | + if (styledItem.parent) { |
2174 | + for (var i = 0; i < styledItem.parent.children.length; i++) { |
2175 | + if (styledItem.parent.children[i] == styledItem) { |
2176 | + return i; |
2177 | + } |
2178 | + } |
2179 | + } else { |
2180 | + return -1; |
2181 | + } |
2182 | + } |
2183 | + |
2184 | // update snap direction |
2185 | function updateSnapDirection() { |
2186 | if (prevX < listItemStyle.x && (snapChangerLimit <= listItemStyle.x)) { |
2187 | |
2188 | === modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/ActionBarStyle.qml' |
2189 | --- src/Ubuntu/Components/Themes/Ambiance/1.3/ActionBarStyle.qml 2015-05-22 10:48:49 +0000 |
2190 | +++ src/Ubuntu/Components/Themes/Ambiance/1.3/ActionBarStyle.qml 2015-09-08 04:09:38 +0000 |
2191 | @@ -87,8 +87,6 @@ |
2192 | id: actionsOverflowPopover |
2193 | objectName: "actions_overflow_panel" |
2194 | |
2195 | - backgroundColor: "white" |
2196 | - |
2197 | // Ensure the popover closes when actions change and |
2198 | // the list item below may be destroyed before its |
2199 | // onClicked is executed. See bug |
2200 | |
2201 | === removed file 'src/Ubuntu/Components/Themes/Ambiance/1.3/HeadDividerStyle.qml' |
2202 | --- src/Ubuntu/Components/Themes/Ambiance/1.3/HeadDividerStyle.qml 2015-04-24 14:07:02 +0000 |
2203 | +++ src/Ubuntu/Components/Themes/Ambiance/1.3/HeadDividerStyle.qml 1970-01-01 00:00:00 +0000 |
2204 | @@ -1,56 +0,0 @@ |
2205 | -/* |
2206 | - * Copyright 2014 Canonical Ltd. |
2207 | - * |
2208 | - * This program is free software; you can redistribute it and/or modify |
2209 | - * it under the terms of the GNU Lesser General Public License as published by |
2210 | - * the Free Software Foundation; version 3. |
2211 | - * |
2212 | - * This program is distributed in the hope that it will be useful, |
2213 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2214 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2215 | - * GNU Lesser General Public License for more details. |
2216 | - * |
2217 | - * You should have received a copy of the GNU Lesser General Public License |
2218 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2219 | - */ |
2220 | -import QtQuick 2.4 |
2221 | - |
2222 | -/*! |
2223 | - This component is DEPRECATED and no longer used. The divider is now a simple line. |
2224 | - */ |
2225 | -Item { |
2226 | - id: dividerStyle |
2227 | - |
2228 | - property color color: styledItem.backgroundColor |
2229 | - |
2230 | - // Do not make the following two colors part of the style API as they may be deprecated soon. |
2231 | - property color topColor: Qt.darker(color, 1.1) |
2232 | - property color bottomColor: Qt.lighter(color, 1.2) |
2233 | - |
2234 | - Rectangle { |
2235 | - anchors.fill: parent |
2236 | - color: dividerStyle.color |
2237 | - |
2238 | - gradient: Gradient { |
2239 | - // top shadow |
2240 | - GradientStop { |
2241 | - position: 0.02 |
2242 | - color: dividerStyle.topColor |
2243 | - } |
2244 | - // middle (background) |
2245 | - GradientStop { |
2246 | - position: 0.05 |
2247 | - color: dividerStyle.color |
2248 | - } |
2249 | - GradientStop { |
2250 | - position: 0.95 |
2251 | - color: dividerStyle.color |
2252 | - } |
2253 | - // bottom highlight |
2254 | - GradientStop { |
2255 | - position: 0.98 |
2256 | - color: dividerStyle.bottomColor |
2257 | - } |
2258 | - } |
2259 | - } |
2260 | -} |
2261 | |
2262 | === removed file 'src/Ubuntu/Components/Themes/Ambiance/1.3/HeaderStyle.qml' |
2263 | --- src/Ubuntu/Components/Themes/Ambiance/1.3/HeaderStyle.qml 2015-04-24 14:07:02 +0000 |
2264 | +++ src/Ubuntu/Components/Themes/Ambiance/1.3/HeaderStyle.qml 1970-01-01 00:00:00 +0000 |
2265 | @@ -1,124 +0,0 @@ |
2266 | -/* |
2267 | - * Copyright 2015 Canonical Ltd. |
2268 | - * |
2269 | - * This program is free software; you can redistribute it and/or modify |
2270 | - * it under the terms of the GNU Lesser General Public License as published by |
2271 | - * the Free Software Foundation; version 3. |
2272 | - * |
2273 | - * This program is distributed in the hope that it will be useful, |
2274 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2275 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2276 | - * GNU Lesser General Public License for more details. |
2277 | - * |
2278 | - * You should have received a copy of the GNU Lesser General Public License |
2279 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2280 | - */ |
2281 | -import QtQuick 2.4 |
2282 | -import Ubuntu.Components 1.3 |
2283 | - |
2284 | -Item { |
2285 | - id: headerStyle |
2286 | - /*! |
2287 | - The height of the headercontents, which is the full height of |
2288 | - the header minus the separators shown at the bottom of it. |
2289 | - */ |
2290 | - property real contentHeight: units.gu(7.5) |
2291 | - |
2292 | - /*! |
2293 | - The source of the image that separates the header from the contents of a \l MainView. |
2294 | - The separator will be drawn over the contents. |
2295 | - */ |
2296 | - property url separatorSource: Qt.resolvedUrl("../artwork/PageHeaderBaseDividerLight.sci") |
2297 | - |
2298 | - /*! |
2299 | - The source of an additional image attached to the bottom of the separator. The contents |
2300 | - of the \l MainView will be drawn on top of the separator bottom image. |
2301 | - */ |
2302 | - property url separatorBottomSource: Qt.resolvedUrl("../artwork/PageHeaderBaseDividerBottom.png") |
2303 | - |
2304 | - property int fontWeight: Font.Light |
2305 | - property string fontSize: "x-large" |
2306 | - property color textColor: theme.palette.selected.backgroundText |
2307 | - property real textLeftMargin: units.gu(2) |
2308 | - |
2309 | - implicitHeight: headerStyle.contentHeight + separator.height + separatorBottom.height |
2310 | - |
2311 | - /*! |
2312 | - \internal |
2313 | - Tabs needs to call sync of the TabBar |
2314 | - */ |
2315 | - property TabBar __tabBar: tabBarLoader.sourceComponent ? tabBarLoader.item : null |
2316 | - |
2317 | - BorderImage { |
2318 | - id: separator |
2319 | - anchors { |
2320 | - bottom: parent.bottom |
2321 | - left: parent.left |
2322 | - right: parent.right |
2323 | - } |
2324 | - source: headerStyle.separatorSource |
2325 | - } |
2326 | - Image { |
2327 | - id: separatorBottom |
2328 | - anchors { |
2329 | - top: separator.bottom |
2330 | - left: parent.left |
2331 | - right: parent.right |
2332 | - } |
2333 | - source: headerStyle.separatorBottomSource |
2334 | - } |
2335 | - |
2336 | - Item { |
2337 | - id: foreground |
2338 | - anchors { |
2339 | - left: parent.left |
2340 | - right: parent.right |
2341 | - top: parent.top |
2342 | - } |
2343 | - height: headerStyle.contentHeight |
2344 | - |
2345 | - Label { |
2346 | - LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft |
2347 | - |
2348 | - anchors { |
2349 | - left: parent.left |
2350 | - verticalCenter: parent.verticalCenter |
2351 | - leftMargin: headerStyle.textLeftMargin |
2352 | - } |
2353 | - text: styledItem.title |
2354 | - font.weight: headerStyle.fontWeight |
2355 | - visible: !styledItem.tabsModel && !styledItem.contents |
2356 | - fontSize: headerStyle.fontSize |
2357 | - color: headerStyle.textColor |
2358 | - } |
2359 | - |
2360 | - Binding { |
2361 | - target: styledItem.contents |
2362 | - property: "anchors.fill" |
2363 | - value: foreground |
2364 | - when: styledItem.contents |
2365 | - } |
2366 | - Binding { |
2367 | - target: styledItem.contents |
2368 | - property: "parent" |
2369 | - value: foreground |
2370 | - when: styledItem.contents |
2371 | - } |
2372 | - |
2373 | - Loader { |
2374 | - id: tabBarLoader |
2375 | - sourceComponent: styledItem.tabsModel && !styledItem.contents ? tabBarComponent : null |
2376 | - anchors.fill: parent |
2377 | - } |
2378 | - |
2379 | - Component { |
2380 | - id: tabBarComponent |
2381 | - TabBar { |
2382 | - id: tabBar |
2383 | - anchors.fill: parent |
2384 | - model: styledItem.tabsModel |
2385 | - animate: styledItem.animate |
2386 | - } |
2387 | - } |
2388 | - } |
2389 | -} |
2390 | |
2391 | === modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml' |
2392 | --- src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml 2015-07-22 18:57:58 +0000 |
2393 | +++ src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml 2015-09-08 04:09:38 +0000 |
2394 | @@ -337,6 +337,7 @@ |
2395 | property real snapChangerLimit: 0.0 |
2396 | readonly property real threshold: units.gu(1.5) |
2397 | property bool snapIn: false |
2398 | + property bool completed: false |
2399 | |
2400 | // update snap direction |
2401 | function updateSnapDirection() { |
2402 | @@ -419,4 +420,68 @@ |
2403 | function rebound() { |
2404 | snapAnimation.snapTo(0); |
2405 | } |
2406 | + |
2407 | + // expansion |
2408 | + Component.onCompleted: internals.completed = true |
2409 | + state: (internals.completed && styledItem.expansion.expanded) ? (listItemStyle.flickable ? "expandedWithFlickable" : "expandedNoFlickable") : "" |
2410 | + states: [ |
2411 | + State { |
2412 | + name: "expandedNoFlickable" |
2413 | + PropertyChanges { |
2414 | + target: styledItem |
2415 | + height: styledItem.expansion.height |
2416 | + } |
2417 | + }, |
2418 | + State { |
2419 | + name: "expandedWithFlickable" |
2420 | + PropertyChanges { |
2421 | + target: styledItem |
2422 | + height: styledItem.expansion.height |
2423 | + } |
2424 | + PropertyChanges { |
2425 | + target: listItemStyle.flickable |
2426 | + // we do not need to restore the original values |
2427 | + restoreEntryValues: false |
2428 | + // and we should not get any binding updates even |
2429 | + explicit: true |
2430 | + contentY: { |
2431 | + var bottom = styledItem.y + styledItem.expansion.height - listItemStyle.flickable.contentY + listItemStyle.flickable.originY; |
2432 | + var dy = bottom - listItemStyle.flickable.height; |
2433 | + if (dy > 0) { |
2434 | + return listItemStyle.flickable.contentY + dy - listItemStyle.flickable.originY; |
2435 | + } else { |
2436 | + return listItemStyle.flickable.contentY; |
2437 | + } |
2438 | + } |
2439 | + } |
2440 | + } |
2441 | + ] |
2442 | + transitions: [ |
2443 | + Transition { |
2444 | + from: "" |
2445 | + to: "expandedWithFlickable" |
2446 | + reversible: true |
2447 | + enabled: listItemStyle.animatePanels |
2448 | + ParallelAnimation { |
2449 | + UbuntuNumberAnimation { |
2450 | + target: listItemStyle.flickable |
2451 | + property: "contentY" |
2452 | + } |
2453 | + UbuntuNumberAnimation { |
2454 | + target: styledItem |
2455 | + property: "height" |
2456 | + } |
2457 | + } |
2458 | + }, |
2459 | + Transition { |
2460 | + from: "" |
2461 | + to: "expandedNoFlickable" |
2462 | + reversible: true |
2463 | + enabled: listItemStyle.animatePanels |
2464 | + UbuntuNumberAnimation { |
2465 | + target: styledItem |
2466 | + property: "height" |
2467 | + } |
2468 | + } |
2469 | + ] |
2470 | } |
2471 | |
2472 | === modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/OverflowPanel.qml' |
2473 | --- src/Ubuntu/Components/Themes/Ambiance/1.3/OverflowPanel.qml 2015-04-29 08:55:31 +0000 |
2474 | +++ src/Ubuntu/Components/Themes/Ambiance/1.3/OverflowPanel.qml 2015-09-08 04:09:38 +0000 |
2475 | @@ -32,7 +32,7 @@ |
2476 | /*! |
2477 | The background color of the tabs panel and the actions overflow panel. |
2478 | */ |
2479 | - property color backgroundColor: styledItem.panelColor |
2480 | + property color backgroundColor: theme.palette.normal.background |
2481 | |
2482 | /*! |
2483 | The background color of the tapped item in the panel. |
2484 | |
2485 | === modified file 'src/Ubuntu/Components/Themes/Ambiance/Ambiance.pro' |
2486 | --- src/Ubuntu/Components/Themes/Ambiance/Ambiance.pro 2015-06-18 08:03:55 +0000 |
2487 | +++ src/Ubuntu/Components/Themes/Ambiance/Ambiance.pro 2015-09-08 04:09:38 +0000 |
2488 | @@ -84,8 +84,6 @@ |
2489 | 1.3/DialerHandStyle.qml \ |
2490 | 1.3/DialerStyle.qml \ |
2491 | 1.3/DialogForegroundStyle.qml \ |
2492 | - 1.3/HeadDividerStyle.qml \ |
2493 | - 1.3/HeaderStyle.qml \ |
2494 | 1.3/HighlightMagnifier.qml \ |
2495 | 1.3/ListItemOptionSelectorStyle.qml \ |
2496 | 1.3/ListItemStyle.qml \ |
2497 | |
2498 | === modified file 'src/Ubuntu/Components/plugin/adapters/actionsproxy_p.cpp' |
2499 | --- src/Ubuntu/Components/plugin/adapters/actionsproxy_p.cpp 2014-09-01 06:56:39 +0000 |
2500 | +++ src/Ubuntu/Components/plugin/adapters/actionsproxy_p.cpp 2015-09-08 04:09:38 +0000 |
2501 | @@ -90,18 +90,18 @@ |
2502 | } |
2503 | if (watch) { |
2504 | // connect to action proxy |
2505 | - QObject::connect(context, SIGNAL(activeChanged(bool)), |
2506 | - this, SLOT(handleContextActivation(bool)), |
2507 | + QObject::connect(context, SIGNAL(activeChanged()), |
2508 | + this, SLOT(handleContextActivation()), |
2509 | Qt::DirectConnection); |
2510 | } else { |
2511 | // disconnect |
2512 | - QObject::disconnect(context, SIGNAL(activeChanged(bool)), |
2513 | - this, SLOT(handleContextActivation(bool))); |
2514 | + QObject::disconnect(context, SIGNAL(activeChanged()), |
2515 | + this, SLOT(handleContextActivation())); |
2516 | } |
2517 | } |
2518 | |
2519 | // handles the local context activation |
2520 | -void ActionProxy::handleContextActivation(bool active) |
2521 | +void ActionProxy::handleContextActivation() |
2522 | { |
2523 | // sender is the context changing activation |
2524 | UCActionContext *context = qobject_cast<UCActionContext*>(sender()); |
2525 | @@ -110,7 +110,7 @@ |
2526 | } |
2527 | // deactivate the previous context if any |
2528 | if (!m_activeContext.isNull()) { |
2529 | - if (!active) { |
2530 | + if (!context->active()) { |
2531 | // the slot has been called due to the previous active deactivation, |
2532 | // so perform system cleanup |
2533 | clearContextActions(m_activeContext); |
2534 | @@ -124,7 +124,7 @@ |
2535 | m_activeContext->setActive(false); |
2536 | } |
2537 | } |
2538 | - if (active) { |
2539 | + if (context->active()) { |
2540 | // publish the context's actions to the system |
2541 | publishContextActions(context); |
2542 | context->markActionsPublished(true); |
2543 | |
2544 | === modified file 'src/Ubuntu/Components/plugin/adapters/actionsproxy_p.h' |
2545 | --- src/Ubuntu/Components/plugin/adapters/actionsproxy_p.h 2014-09-01 06:56:39 +0000 |
2546 | +++ src/Ubuntu/Components/plugin/adapters/actionsproxy_p.h 2015-09-08 04:09:38 +0000 |
2547 | @@ -48,7 +48,7 @@ |
2548 | |
2549 | protected Q_SLOTS: |
2550 | void watchContextActivation(UCActionContext *context, bool watch); |
2551 | - void handleContextActivation(bool active); |
2552 | + void handleContextActivation(); |
2553 | virtual void clearContextActions(UCActionContext *context); |
2554 | virtual void publishContextActions(UCActionContext *context); |
2555 | |
2556 | |
2557 | === modified file 'src/Ubuntu/Components/plugin/i18n.cpp' |
2558 | --- src/Ubuntu/Components/plugin/i18n.cpp 2015-03-03 13:47:48 +0000 |
2559 | +++ src/Ubuntu/Components/plugin/i18n.cpp 2015-09-08 04:09:38 +0000 |
2560 | @@ -17,6 +17,7 @@ |
2561 | */ |
2562 | |
2563 | #include "i18n.h" |
2564 | +#include "timeutils_p.h" |
2565 | #include <QtCore/QDir> |
2566 | |
2567 | namespace C { |
2568 | @@ -252,3 +253,76 @@ |
2569 | Q_UNUSED(context); |
2570 | return text; |
2571 | } |
2572 | +/*! |
2573 | + * \qmlmethod string i18n::relativeDateTime(datetime dateTime) |
2574 | + * Translate a datetime based on proximity to current time. |
2575 | + */ |
2576 | +QString UbuntuI18n::relativeDateTime(const QDateTime& datetime) |
2577 | +{ |
2578 | + QDateTime relativeTo(QDateTime::currentDateTime()); |
2579 | + const date_proximity_t prox = getDateProximity(relativeTo, datetime); |
2580 | + |
2581 | + switch (prox) { |
2582 | + case DATE_PROXIMITY_NOW: |
2583 | + /* TRANSLATORS: Time based "this is happening/happened now" */ |
2584 | + return dtr("ubuntu-ui-toolkit", "Now"); |
2585 | + |
2586 | + case DATE_PROXIMITY_HOUR: |
2587 | + { |
2588 | + qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch(); |
2589 | + qint64 minutes = qRound(float(diff) / 60000); |
2590 | + if (minutes < 0) { |
2591 | + return dtr("ubuntu-ui-toolkit", "%1 minute ago", "%1 minutes ago", qAbs(minutes)).arg(qAbs(minutes)); |
2592 | + } |
2593 | + return dtr("ubuntu-ui-toolkit", "%1 minute", "%1 minutes", minutes).arg(minutes); |
2594 | + } |
2595 | + |
2596 | + case DATE_PROXIMITY_TODAY: |
2597 | + /* en_US example: "1:00 PM" */ |
2598 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2599 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2600 | + return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "h:mm ap"): |
2601 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2602 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2603 | + dtr("ubuntu-ui-toolkit", "HH:mm")); |
2604 | + |
2605 | + case DATE_PROXIMITY_YESTERDAY: |
2606 | + /* en_US example: "Yesterday 13:00" */ |
2607 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2608 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2609 | + return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "'Yesterday\u2003'h:mm ap") : |
2610 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2611 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2612 | + dtr("ubuntu-ui-toolkit", "'Yesterday\u2003'HH:mm")); |
2613 | + |
2614 | + case DATE_PROXIMITY_TOMORROW: |
2615 | + /* en_US example: "Tomorrow 1:00 PM" */ |
2616 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2617 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2618 | + return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "'Tomorrow\u2003'h:mm ap") : |
2619 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2620 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2621 | + dtr("ubuntu-ui-toolkit", "'Tomorrow\u2003'HH:mm")); |
2622 | + |
2623 | + case DATE_PROXIMITY_LAST_WEEK: |
2624 | + case DATE_PROXIMITY_NEXT_WEEK: |
2625 | + /* en_US example: "Fri 1:00 PM" */ |
2626 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2627 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2628 | + return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "ddd'\u2003'h:mm ap") : |
2629 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2630 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2631 | + dtr("ubuntu-ui-toolkit", "ddd'\u2003'HH:mm")); |
2632 | + |
2633 | + case DATE_PROXIMITY_FAR_BACK: |
2634 | + case DATE_PROXIMITY_FAR_FORWARD: |
2635 | + default: |
2636 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2637 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2638 | + return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "ddd d MMM'\u2003'h:mm ap") : |
2639 | + /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by |
2640 | + https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */ |
2641 | + dtr("ubuntu-ui-toolkit", "ddd d MMM'\u2003'HH:mm")); |
2642 | + } |
2643 | + return datetime.toString(Qt::DefaultLocaleShortDate); |
2644 | +} |
2645 | |
2646 | === modified file 'src/Ubuntu/Components/plugin/i18n.h' |
2647 | --- src/Ubuntu/Components/plugin/i18n.h 2015-02-03 18:11:32 +0000 |
2648 | +++ src/Ubuntu/Components/plugin/i18n.h 2015-09-08 04:09:38 +0000 |
2649 | @@ -50,6 +50,7 @@ |
2650 | Q_INVOKABLE QString dctr(const QString& domain, const QString& context, const QString& text); |
2651 | Q_INVOKABLE QString tag(const QString& text); |
2652 | Q_INVOKABLE QString tag(const QString& context, const QString& text); |
2653 | + Q_INVOKABLE QString relativeDateTime(const QDateTime& datetime); |
2654 | |
2655 | // getter |
2656 | QString domain() const; |
2657 | |
2658 | === modified file 'src/Ubuntu/Components/plugin/plugin.cpp' |
2659 | --- src/Ubuntu/Components/plugin/plugin.cpp 2015-08-12 09:54:40 +0000 |
2660 | +++ src/Ubuntu/Components/plugin/plugin.cpp 2015-09-08 04:09:38 +0000 |
2661 | @@ -62,6 +62,9 @@ |
2662 | #include "uclistitemstyle.h" |
2663 | #include "ucserviceproperties.h" |
2664 | #include "ucnamespace.h" |
2665 | +#include "ucactionitem.h" |
2666 | +#include "uchaptics.h" |
2667 | +#include "ucabstractbutton.h" |
2668 | |
2669 | #include <sys/types.h> |
2670 | #include <unistd.h> |
2671 | @@ -116,6 +119,14 @@ |
2672 | return new UCNamespaceV13(); |
2673 | } |
2674 | |
2675 | +static QObject *registerHaptics(QQmlEngine *engine, QJSEngine *scriptEngine) |
2676 | +{ |
2677 | + Q_UNUSED(engine) |
2678 | + Q_UNUSED(scriptEngine) |
2679 | + |
2680 | + return new UCHaptics(); |
2681 | +} |
2682 | + |
2683 | void UbuntuComponentsPlugin::initializeBaseUrl() |
2684 | { |
2685 | if (!m_baseUrl.isValid()) { |
2686 | @@ -174,6 +185,8 @@ |
2687 | qmlRegisterSingletonType<UCUriHandler>(uri, major, minor, "UriHandler", registerUriHandler); |
2688 | qmlRegisterType<UCMouse>(uri, major, minor, "Mouse"); |
2689 | qmlRegisterType<UCInverseMouse>(uri, major, minor, "InverseMouse"); |
2690 | + qmlRegisterType<UCActionItem>(uri, major, minor, "ActionItem"); |
2691 | + qmlRegisterSingletonType<UCHaptics>(uri, major, minor, "Haptics", registerHaptics); |
2692 | } |
2693 | |
2694 | void UbuntuComponentsPlugin::registerTypes(const char *uri) |
2695 | @@ -211,6 +224,8 @@ |
2696 | |
2697 | // register 1.3 API |
2698 | qmlRegisterType<UCListItem13>(uri, 1, 3, "ListItem"); |
2699 | + qmlRegisterType<UCListItemExpansion>(); |
2700 | + qmlRegisterUncreatableType<UCViewItemsAttached13>(uri, 1, 3, "ViewItems", "No create"); |
2701 | qmlRegisterType<UCTheme>(uri, 1, 3, "ThemeSettings"); |
2702 | qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItem"); |
2703 | qmlRegisterSingletonType<UCNamespaceV13>(uri, 1, 3, "Ubuntu", registerUbuntuNamespace13); |
2704 | @@ -220,6 +235,7 @@ |
2705 | qmlRegisterType<UCUbuntuShape, 2>(uri, 1, 3, "UbuntuShape"); |
2706 | qmlRegisterType<UCProportionalShape>(uri, 1, 3, "ProportionalShape"); |
2707 | qmlRegisterType<LiveTimer>(uri, 1, 3, "LiveTimer"); |
2708 | + qmlRegisterType<UCAbstractButton>(uri, 1, 3, "AbstractButton"); |
2709 | } |
2710 | |
2711 | void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) |
2712 | @@ -244,6 +260,8 @@ |
2713 | |
2714 | UCDeprecatedTheme::instance().registerToContext(context); |
2715 | |
2716 | + HapticsProxy::instance().setEngine(context->engine()); |
2717 | + |
2718 | context->setContextProperty("i18n", &UbuntuI18n::instance()); |
2719 | ContextPropertyChangeListener *i18nChangeListener = |
2720 | new ContextPropertyChangeListener(context, "i18n"); |
2721 | |
2722 | === modified file 'src/Ubuntu/Components/plugin/plugin.pri' |
2723 | --- src/Ubuntu/Components/plugin/plugin.pri 2015-08-18 22:14:51 +0000 |
2724 | +++ src/Ubuntu/Components/plugin/plugin.pri 2015-09-08 04:09:38 +0000 |
2725 | @@ -80,7 +80,10 @@ |
2726 | $$PWD/ucstylehints.h \ |
2727 | $$PWD/livetimer.h \ |
2728 | $$PWD/livetimer_p.h \ |
2729 | - $$PWD/timeutils_p.h |
2730 | + $$PWD/timeutils_p.h \ |
2731 | + $$PWD/ucactionitem.h \ |
2732 | + $$PWD/uchaptics.h \ |
2733 | + $$PWD/ucabstractbutton.h |
2734 | |
2735 | SOURCES += $$PWD/plugin.cpp \ |
2736 | $$PWD/uctheme.cpp \ |
2737 | @@ -127,12 +130,16 @@ |
2738 | $$PWD/ucserviceproperties.cpp \ |
2739 | $$PWD/privates/listitemdragarea.cpp \ |
2740 | $$PWD/privates/listitemdraghandler.cpp \ |
2741 | + $$PWD/privates/listitemexpansion.cpp \ |
2742 | $$PWD/ucnamespace.cpp \ |
2743 | $$PWD/ucdeprecatedtheme.cpp \ |
2744 | $$PWD/ucdefaulttheme.cpp \ |
2745 | $$PWD/ucstylehints.cpp \ |
2746 | $$PWD/livetimer.cpp \ |
2747 | - $$PWD/livetimer_p.cpp |
2748 | + $$PWD/livetimer_p.cpp \ |
2749 | + $$PWD/ucactionitem.cpp \ |
2750 | + $$PWD/uchaptics.cpp \ |
2751 | + $$PWD/ucabstractbutton.cpp |
2752 | |
2753 | # adapters |
2754 | SOURCES += $$PWD/adapters/alarmsadapter_organizer.cpp |
2755 | |
2756 | === modified file 'src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp' |
2757 | --- src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp 2015-04-13 11:11:59 +0000 |
2758 | +++ src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp 2015-09-08 04:09:38 +0000 |
2759 | @@ -47,13 +47,12 @@ |
2760 | setObjectName("drag_area"); |
2761 | } |
2762 | |
2763 | -void ListItemDragArea::init() |
2764 | +void ListItemDragArea::init(UCViewItemsAttached *viewItems) |
2765 | { |
2766 | setParentItem(static_cast<QQuickItem*>(parent())); |
2767 | QQuickAnchors *anchors = QQuickItemPrivate::get(this)->anchors(); |
2768 | anchors->setFill(parentItem()); |
2769 | - viewAttached = static_cast<UCViewItemsAttached*>( |
2770 | - qmlAttachedPropertiesObject<UCViewItemsAttached>(listView)); |
2771 | + viewAttached = viewItems; |
2772 | reset(); |
2773 | } |
2774 | |
2775 | |
2776 | === modified file 'src/Ubuntu/Components/plugin/privates/listitemdragarea.h' |
2777 | --- src/Ubuntu/Components/plugin/privates/listitemdragarea.h 2015-02-24 15:57:53 +0000 |
2778 | +++ src/Ubuntu/Components/plugin/privates/listitemdragarea.h 2015-09-08 04:09:38 +0000 |
2779 | @@ -27,7 +27,7 @@ |
2780 | Q_OBJECT |
2781 | public: |
2782 | explicit ListItemDragArea(QQuickItem *parent = 0); |
2783 | - void init(); |
2784 | + void init(UCViewItemsAttached *viewItems); |
2785 | void reset(); |
2786 | |
2787 | protected: |
2788 | |
2789 | === added file 'src/Ubuntu/Components/plugin/privates/listitemexpansion.cpp' |
2790 | --- src/Ubuntu/Components/plugin/privates/listitemexpansion.cpp 1970-01-01 00:00:00 +0000 |
2791 | +++ src/Ubuntu/Components/plugin/privates/listitemexpansion.cpp 2015-09-08 04:09:38 +0000 |
2792 | @@ -0,0 +1,106 @@ |
2793 | +/* |
2794 | + * Copyright 2015 Canonical Ltd. |
2795 | + * |
2796 | + * This program is free software; you can redistribute it and/or modify |
2797 | + * it under the terms of the GNU Lesser General Public License as published by |
2798 | + * the Free Software Foundation; version 3. |
2799 | + * |
2800 | + * This program is distributed in the hope that it will be useful, |
2801 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2802 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2803 | + * GNU Lesser General Public License for more details. |
2804 | + * |
2805 | + * You should have received a copy of the GNU Lesser General Public License |
2806 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2807 | + */ |
2808 | + |
2809 | +#include "uclistitem.h" |
2810 | +#include "uclistitem_p.h" |
2811 | + |
2812 | +UCListItemExpansion::UCListItemExpansion(QObject *parent) |
2813 | + : QObject(parent) |
2814 | + , m_listItem(static_cast<UCListItem13*>(parent)) |
2815 | + , m_height(0.0) |
2816 | + , m_filtering(false) |
2817 | +{ |
2818 | +} |
2819 | + |
2820 | +bool UCListItemExpansion::expandedLocked() |
2821 | +{ |
2822 | + UCListItemPrivate *listItem = UCListItemPrivate::get(m_listItem); |
2823 | + UCViewItemsAttachedPrivate *viewItems = UCViewItemsAttachedPrivate::get(listItem->parentAttached); |
2824 | + return expanded() && !((viewItems->expansionFlags & UCViewItemsAttached::UnlockExpanded) == UCViewItemsAttached::UnlockExpanded); |
2825 | +} |
2826 | + |
2827 | +void UCListItemExpansion::enableClickFiltering(bool enable) |
2828 | +{ |
2829 | + if (m_filtering == enable) { |
2830 | + return; |
2831 | + } |
2832 | + m_filtering = enable; |
2833 | + if (m_filtering) { |
2834 | + m_listItem->window()->installEventFilter(this); |
2835 | + } else { |
2836 | + m_listItem->window()->removeEventFilter(this); |
2837 | + } |
2838 | +} |
2839 | + |
2840 | +// event filter for external mouse presses to collapse when pressed outside |
2841 | +bool UCListItemExpansion::eventFilter(QObject *target, QEvent *event) |
2842 | +{ |
2843 | + if (event->type() == QEvent::MouseButtonPress) { |
2844 | + QMouseEvent *mouse = static_cast<QMouseEvent*>(event); |
2845 | + QQuickWindow *window = qobject_cast<QQuickWindow*>(target); |
2846 | + if (window) { |
2847 | + QPointF myPos(window->contentItem()->mapToItem(m_listItem, mouse->localPos())); |
2848 | + if (!m_listItem->contains(myPos)) { |
2849 | + UCListItemPrivate *listItem = UCListItemPrivate::get(m_listItem); |
2850 | + UCViewItemsAttachedPrivate *viewItems = UCViewItemsAttachedPrivate::get(listItem->parentAttached); |
2851 | + if (viewItems) { |
2852 | + // collapse all as there can be only one expanded when the flag is set |
2853 | + viewItems->collapseAll(); |
2854 | + } |
2855 | + } |
2856 | + } |
2857 | + } |
2858 | + return false; |
2859 | +} |
2860 | + |
2861 | + |
2862 | +bool UCListItemExpansion::expanded() |
2863 | +{ |
2864 | + UCListItemPrivate *listItem = UCListItemPrivate::get(m_listItem); |
2865 | + UCViewItemsAttachedPrivate *viewItems = UCViewItemsAttachedPrivate::get(listItem->parentAttached); |
2866 | + return (viewItems && viewItems->expansionList.contains(listItem->index())); |
2867 | +} |
2868 | + |
2869 | +void UCListItemExpansion::setExpanded(bool expanded) |
2870 | +{ |
2871 | + if (this->expanded() == expanded) { |
2872 | + return; |
2873 | + } |
2874 | + UCListItemPrivate *listItem = UCListItemPrivate::get(m_listItem); |
2875 | + UCViewItemsAttachedPrivate *viewItems = UCViewItemsAttachedPrivate::get(listItem->parentAttached); |
2876 | + if (viewItems) { |
2877 | + if (viewItems->expansionFlags & UCViewItemsAttached::Exclusive) { |
2878 | + // collapse all the expanded ones |
2879 | + viewItems->collapseAll(); |
2880 | + } |
2881 | + if (expanded) { |
2882 | + viewItems->expand(listItem->index(), m_listItem); |
2883 | + } else { |
2884 | + viewItems->collapse(listItem->index()); |
2885 | + } |
2886 | + } |
2887 | + UCListItemPrivate::get(m_listItem)->loadStyleItem(); |
2888 | + // no need to emit changed signal, as ViewItems.expandedIndicesChanged is connected to the change signal |
2889 | +} |
2890 | + |
2891 | +void UCListItemExpansion::setHeight(qreal height) |
2892 | +{ |
2893 | + if (m_height == height) { |
2894 | + return; |
2895 | + } |
2896 | + m_height = height; |
2897 | + Q_EMIT heightChanged(); |
2898 | +} |
2899 | |
2900 | === modified file 'src/Ubuntu/Components/plugin/sortfiltermodel.cpp' |
2901 | --- src/Ubuntu/Components/plugin/sortfiltermodel.cpp 2015-03-03 13:47:48 +0000 |
2902 | +++ src/Ubuntu/Components/plugin/sortfiltermodel.cpp 2015-09-08 04:09:38 +0000 |
2903 | @@ -113,9 +113,12 @@ |
2904 | QSortFilterProxyModelQML::roleByName(const QString& roleName) const |
2905 | { |
2906 | const QHash<int, QByteArray> roles = roleNames(); |
2907 | - for(int role = 0; role < roles.count(); role++) |
2908 | - if (roles[role] == roleName) |
2909 | - return role; |
2910 | + QHashIterator<int, QByteArray> i(roles); |
2911 | + while (i.hasNext()) { |
2912 | + i.next(); |
2913 | + if (i.value() == roleName) |
2914 | + return i.key(); |
2915 | + } |
2916 | return 0; |
2917 | } |
2918 | |
2919 | |
2920 | === modified file 'src/Ubuntu/Components/plugin/timeutils_p.h' |
2921 | --- src/Ubuntu/Components/plugin/timeutils_p.h 2015-07-20 15:34:32 +0000 |
2922 | +++ src/Ubuntu/Components/plugin/timeutils_p.h 2015-09-08 04:09:38 +0000 |
2923 | @@ -20,9 +20,33 @@ |
2924 | #include "livetimer.h" |
2925 | |
2926 | #include <QDateTime> |
2927 | +#include <QLocale> |
2928 | #include <QObject> |
2929 | #include <QTimer> |
2930 | |
2931 | +/* Check the system locale setting to see if the format is 24-hour |
2932 | + time or 12-hour time */ |
2933 | +inline bool isLocale12h(void) |
2934 | +{ |
2935 | + QString strTimeFormat = QLocale::system().timeFormat(); |
2936 | + QStringList includes; includes << "AP"; includes << "ap"; |
2937 | + QStringList excludes; excludes << "H"; excludes << "HH"; |
2938 | + |
2939 | + Q_FOREACH(const QString& exclude, excludes) { |
2940 | + if (strTimeFormat.contains(exclude)) { |
2941 | + return false; |
2942 | + } |
2943 | + } |
2944 | + |
2945 | + Q_FOREACH(const QString& include, includes) { |
2946 | + if (strTimeFormat.contains(include)) { |
2947 | + return true; |
2948 | + } |
2949 | + } |
2950 | + |
2951 | + return false; |
2952 | +} |
2953 | + |
2954 | typedef enum |
2955 | { |
2956 | DATE_PROXIMITY_NOW, |
2957 | |
2958 | === added file 'src/Ubuntu/Components/plugin/ucabstractbutton.cpp' |
2959 | --- src/Ubuntu/Components/plugin/ucabstractbutton.cpp 1970-01-01 00:00:00 +0000 |
2960 | +++ src/Ubuntu/Components/plugin/ucabstractbutton.cpp 2015-09-08 04:09:38 +0000 |
2961 | @@ -0,0 +1,156 @@ |
2962 | +/* |
2963 | + * Copyright 2015 Canonical Ltd. |
2964 | + * |
2965 | + * This program is free software; you can redistribute it and/or modify |
2966 | + * it under the terms of the GNU Lesser General Public License as published by |
2967 | + * the Free Software Foundation; version 3. |
2968 | + * |
2969 | + * This program is distributed in the hope that it will be useful, |
2970 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2971 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2972 | + * GNU Lesser General Public License for more details. |
2973 | + * |
2974 | + * You should have received a copy of the GNU Lesser General Public License |
2975 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2976 | + */ |
2977 | + |
2978 | +#include "ucabstractbutton.h" |
2979 | +#include "uchaptics.h" |
2980 | +#include <QtQuick/private/qquickitem_p.h> |
2981 | +#include <QtQuick/private/qquickmousearea_p.h> |
2982 | +#include <QtQml/private/qqmlglobal_p.h> |
2983 | + |
2984 | +/*! |
2985 | + \qmltype AbstractButton |
2986 | + \instantiates UCAbstractButton |
2987 | + \inqmlmodule Ubuntu.Components 1.1 |
2988 | + \ingroup ubuntu |
2989 | + \brief The AbstractButton class defines the behavior of the button. |
2990 | + |
2991 | + This class defines the behavior of the button. All components deriving from |
2992 | + this class support haptic feedback out of the box. |
2993 | + |
2994 | + If an action is specified, the button's clicked signal will trigger the action. |
2995 | + Subclasses of AbstractButton can use other properties of action (for example |
2996 | + the text and iconName). |
2997 | +*/ |
2998 | + |
2999 | +/*! |
3000 | + * |
3001 | + * \qmlsignal AbstractButton::clicked() |
3002 | + * This handler is called when there is a mouse click on the button and the button |
3003 | + * is not disabled. If \l {ActionItem::action}{action} is defined, the action will be triggered. |
3004 | + */ |
3005 | + |
3006 | +/*! |
3007 | + * |
3008 | + * \qmlsignal AbstractButton::pressAndHold() |
3009 | + * This handler is called when there is a long press. |
3010 | + */ |
3011 | + |
3012 | +UCAbstractButton::UCAbstractButton(QQuickItem *parent) |
3013 | + : UCActionItem(parent) |
3014 | + , m_mouseArea(new QQuickMouseArea) |
3015 | + , m_acceptEvents(true) |
3016 | +{ |
3017 | + setActiveFocusOnPress(true); |
3018 | +} |
3019 | + |
3020 | +bool UCAbstractButton::isPressAndHoldConnected() |
3021 | +{ |
3022 | + static QMetaMethod method = QMetaMethod::fromSignal(&UCAbstractButton::pressAndHold); |
3023 | + static int signalIdx = QMetaObjectPrivate::signalIndex(method); |
3024 | + return QObjectPrivate::get(this)->isSignalConnected(signalIdx); |
3025 | +} |
3026 | + |
3027 | +void UCAbstractButton::classBegin() |
3028 | +{ |
3029 | + UCActionItem::classBegin(); |
3030 | + |
3031 | + // make sure we have the haptics set up! |
3032 | + HapticsProxy::instance().initialize(); |
3033 | + |
3034 | + // set up mouse area |
3035 | + QQml_setParent_noEvent(m_mouseArea, this); |
3036 | + m_mouseArea->setParentItem(this); |
3037 | + QQuickAnchors *anchors = QQuickItemPrivate::get(m_mouseArea)->anchors(); |
3038 | + anchors->setFill(this); |
3039 | + m_mouseArea->setHoverEnabled(true); |
3040 | +} |
3041 | + |
3042 | +void UCAbstractButton::componentComplete() |
3043 | +{ |
3044 | + UCActionItem::componentComplete(); |
3045 | + // connect to the right slot, using macros so we get the proper slot |
3046 | + connect(this, SIGNAL(clicked()), this, SLOT(trigger())); |
3047 | + |
3048 | + // bind mouse area |
3049 | + connect(m_mouseArea, &QQuickMouseArea::pressedChanged, this, &UCAbstractButton::pressedChanged); |
3050 | + connect(m_mouseArea, &QQuickMouseArea::hoveredChanged, this, &UCAbstractButton::hoveredChanged); |
3051 | + connect(m_mouseArea, SIGNAL(clicked(QQuickMouseEvent*)), this, SLOT(_q_mouseAreaClicked())); |
3052 | + if (isPressAndHoldConnected()) { |
3053 | + connect(m_mouseArea, SIGNAL(pressAndHold(QQuickMouseEvent*)), this, SLOT(_q_mouseAreaPressAndHold())); |
3054 | + } |
3055 | +} |
3056 | + |
3057 | +// handle mouseClicked with Haptics |
3058 | +void UCAbstractButton::_q_mouseAreaClicked() |
3059 | +{ |
3060 | + // required by the deprecated ListItem module |
3061 | + if (!m_acceptEvents) { |
3062 | + return; |
3063 | + } |
3064 | + // play haptics |
3065 | + HapticsProxy::instance().play(QVariant()); |
3066 | + Q_EMIT clicked(); |
3067 | +} |
3068 | + |
3069 | +// handle pressAndHold |
3070 | +void UCAbstractButton::_q_mouseAreaPressAndHold() |
3071 | +{ |
3072 | + // required by the deprecated ListItem module |
3073 | + if (!m_acceptEvents) { |
3074 | + return; |
3075 | + } |
3076 | + Q_EMIT pressAndHold(); |
3077 | +} |
3078 | + |
3079 | +// emit clicked when Enter/Return is pressed |
3080 | +void UCAbstractButton::keyPressEvent(QKeyEvent *event) |
3081 | +{ |
3082 | + UCActionItem::keyPressEvent(event); |
3083 | + |
3084 | + switch (event->key()) { |
3085 | + case Qt::Key_Enter: |
3086 | + case Qt::Key_Return: |
3087 | + // FIXME: space may also come here, however that depends on the button type |
3088 | + // (i.e default Dialog btn) so we may need to add that to Button |
3089 | + { |
3090 | + Q_EMIT clicked(); |
3091 | + break; |
3092 | + } |
3093 | + } |
3094 | +} |
3095 | + |
3096 | +/*! |
3097 | + * \qmlproperty bool AbstractButton::pressed |
3098 | + * True if the user presses a mouse button in the button's mouse area. |
3099 | + */ |
3100 | +bool UCAbstractButton::pressed() const |
3101 | +{ |
3102 | + return m_mouseArea ? m_mouseArea->pressed() : false; |
3103 | +} |
3104 | + |
3105 | +/*! |
3106 | + * \qmlproperty bool AbstractButton::hovered |
3107 | + * True if the mouse cursor hovers over the button's mouse area. |
3108 | + */ |
3109 | +bool UCAbstractButton::hovered() const |
3110 | +{ |
3111 | + return m_mouseArea ? m_mouseArea->hovered() : false; |
3112 | +} |
3113 | + |
3114 | +QQuickMouseArea *UCAbstractButton::privateMouseArea() const |
3115 | +{ |
3116 | + return m_mouseArea; |
3117 | +} |
3118 | |
3119 | === added file 'src/Ubuntu/Components/plugin/ucabstractbutton.h' |
3120 | --- src/Ubuntu/Components/plugin/ucabstractbutton.h 1970-01-01 00:00:00 +0000 |
3121 | +++ src/Ubuntu/Components/plugin/ucabstractbutton.h 2015-09-08 04:09:38 +0000 |
3122 | @@ -0,0 +1,64 @@ |
3123 | +/* |
3124 | + * Copyright 2015 Canonical Ltd. |
3125 | + * |
3126 | + * This program is free software; you can redistribute it and/or modify |
3127 | + * it under the terms of the GNU Lesser General Public License as published by |
3128 | + * the Free Software Foundation; version 3. |
3129 | + * |
3130 | + * This program is distributed in the hope that it will be useful, |
3131 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3132 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3133 | + * GNU Lesser General Public License for more details. |
3134 | + * |
3135 | + * You should have received a copy of the GNU Lesser General Public License |
3136 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3137 | + */ |
3138 | + |
3139 | +#ifndef UCABSTRACTBUTTON_H |
3140 | +#define UCABSTRACTBUTTON_H |
3141 | + |
3142 | +#include "ucactionitem.h" |
3143 | + |
3144 | +class QQuickMouseArea; |
3145 | +class UCAbstractButton : public UCActionItem |
3146 | +{ |
3147 | + Q_OBJECT |
3148 | + Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged) |
3149 | + Q_PROPERTY(bool hovered READ hovered NOTIFY hoveredChanged) |
3150 | + |
3151 | + // internal, declared to support the deprecated ListItem module |
3152 | + Q_PROPERTY(bool __acceptEvents MEMBER m_acceptEvents) |
3153 | + Q_PROPERTY(QQuickMouseArea *__mouseArea READ privateMouseArea CONSTANT) |
3154 | +public: |
3155 | + explicit UCAbstractButton(QQuickItem *parent = 0); |
3156 | + |
3157 | + bool pressed() const; |
3158 | + bool hovered() const; |
3159 | + |
3160 | + bool privateAcceptEvents() const; |
3161 | + void setPrivateAcceptEvents(bool accept); |
3162 | + QQuickMouseArea *privateMouseArea() const; |
3163 | + |
3164 | +protected: |
3165 | + void classBegin(); |
3166 | + void componentComplete(); |
3167 | + void keyPressEvent(QKeyEvent *key); |
3168 | + |
3169 | +Q_SIGNALS: |
3170 | + void pressedChanged(); |
3171 | + void hoveredChanged(); |
3172 | + void clicked(); |
3173 | + void pressAndHold(); |
3174 | + |
3175 | +protected Q_SLOTS: |
3176 | + void _q_mouseAreaClicked(); |
3177 | + void _q_mouseAreaPressAndHold(); |
3178 | + |
3179 | +protected: |
3180 | + QQuickMouseArea *m_mouseArea; |
3181 | + bool m_acceptEvents:1; |
3182 | + |
3183 | + bool isPressAndHoldConnected(); |
3184 | +}; |
3185 | + |
3186 | +#endif // UCABSTRACTBUTTON_H |
3187 | |
3188 | === modified file 'src/Ubuntu/Components/plugin/ucaction.cpp' |
3189 | --- src/Ubuntu/Components/plugin/ucaction.cpp 2015-07-03 19:16:56 +0000 |
3190 | +++ src/Ubuntu/Components/plugin/ucaction.cpp 2015-09-08 04:09:38 +0000 |
3191 | @@ -150,13 +150,12 @@ |
3192 | |
3193 | UCAction::UCAction(QObject *parent) |
3194 | : QObject(parent) |
3195 | + , m_itemHint(Q_NULLPTR) |
3196 | + , m_parameterType(None) |
3197 | , m_factoryIconSource(true) |
3198 | , m_enabled(true) |
3199 | , m_visible(true) |
3200 | , m_published(false) |
3201 | - , m_itemHint(0) |
3202 | - , m_parameterType(None) |
3203 | - , m_shortcut(0) |
3204 | { |
3205 | generateName(); |
3206 | } |
3207 | @@ -288,7 +287,7 @@ |
3208 | qmlInfo(this) << "Invalid shortcut: " << shortcut.toString(); |
3209 | |
3210 | m_shortcut = shortcut; |
3211 | - Q_EMIT shortcutChanged(shortcut); |
3212 | + Q_EMIT shortcutChanged(); |
3213 | } |
3214 | |
3215 | bool UCAction::event(QEvent *event) |
3216 | @@ -302,7 +301,8 @@ |
3217 | return false; |
3218 | } |
3219 | |
3220 | - trigger(); |
3221 | + // do not call trigger() directly but invoke, as it may get overridden in QML |
3222 | + metaObject()->invokeMethod(this, "trigger"); |
3223 | return true; |
3224 | } |
3225 | |
3226 | |
3227 | === modified file 'src/Ubuntu/Components/plugin/ucaction.h' |
3228 | --- src/Ubuntu/Components/plugin/ucaction.h 2015-07-07 13:57:50 +0000 |
3229 | +++ src/Ubuntu/Components/plugin/ucaction.h 2015-09-08 04:09:38 +0000 |
3230 | @@ -70,28 +70,29 @@ |
3231 | void parameterTypeChanged(); |
3232 | void iconSourceChanged(); |
3233 | void visibleChanged(); |
3234 | - void shortcutChanged(const QVariant& shortcut); |
3235 | + void shortcutChanged(); |
3236 | void triggered(const QVariant &value); |
3237 | |
3238 | public Q_SLOTS: |
3239 | void trigger(const QVariant &value = QVariant()); |
3240 | |
3241 | private: |
3242 | - bool m_factoryIconSource:1; |
3243 | - bool m_enabled:1; |
3244 | - bool m_visible:1; |
3245 | - bool m_published:1; |
3246 | - QQmlComponent *m_itemHint; |
3247 | QString m_name; |
3248 | QString m_text; |
3249 | QString m_iconName; |
3250 | QUrl m_iconSource; |
3251 | QString m_description; |
3252 | QString m_keywords; |
3253 | + QVariant m_shortcut; |
3254 | + QQmlComponent *m_itemHint; |
3255 | Type m_parameterType; |
3256 | - QVariant m_shortcut; |
3257 | + bool m_factoryIconSource:1; |
3258 | + bool m_enabled:1; |
3259 | + bool m_visible:1; |
3260 | + bool m_published:1; |
3261 | |
3262 | friend class UCActionContext; |
3263 | + friend class UCActionItem; |
3264 | friend class UCListItemPrivate; |
3265 | friend class UCListItemAttached; |
3266 | friend class UCListItemActionsPrivate; |
3267 | |
3268 | === modified file 'src/Ubuntu/Components/plugin/ucactioncontext.cpp' |
3269 | --- src/Ubuntu/Components/plugin/ucactioncontext.cpp 2015-07-09 17:55:03 +0000 |
3270 | +++ src/Ubuntu/Components/plugin/ucactioncontext.cpp 2015-09-08 04:09:38 +0000 |
3271 | @@ -104,6 +104,11 @@ |
3272 | * sufficient to manage the active local context of the manager and no additional |
3273 | * calls are necessary to manually inactivate the other contexts. |
3274 | */ |
3275 | +bool UCActionContext::active() |
3276 | +{ |
3277 | + return m_active; |
3278 | +} |
3279 | + |
3280 | void UCActionContext::setActive(bool active) |
3281 | { |
3282 | if (m_active == active) { |
3283 | @@ -114,7 +119,7 @@ |
3284 | return; |
3285 | } |
3286 | m_active = active; |
3287 | - Q_EMIT activeChanged(active); |
3288 | + Q_EMIT activeChanged(); |
3289 | } |
3290 | |
3291 | /*! |
3292 | |
3293 | === modified file 'src/Ubuntu/Components/plugin/ucactioncontext.h' |
3294 | --- src/Ubuntu/Components/plugin/ucactioncontext.h 2015-07-09 17:55:03 +0000 |
3295 | +++ src/Ubuntu/Components/plugin/ucactioncontext.h 2015-09-08 04:09:38 +0000 |
3296 | @@ -29,7 +29,7 @@ |
3297 | Q_OBJECT |
3298 | Q_INTERFACES(QQmlParserStatus) |
3299 | Q_PROPERTY(QQmlListProperty<UCAction> actions READ actions) |
3300 | - Q_PROPERTY(bool active MEMBER m_active WRITE setActive NOTIFY activeChanged) |
3301 | + Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) |
3302 | Q_CLASSINFO("DefaultProperty", "actions") |
3303 | public: |
3304 | explicit UCActionContext(QObject *parent = 0); |
3305 | @@ -41,10 +41,11 @@ |
3306 | |
3307 | QQmlListProperty<UCAction> actions(); |
3308 | |
3309 | + bool active(); |
3310 | void setActive(bool active); |
3311 | |
3312 | Q_SIGNALS: |
3313 | - void activeChanged(bool); |
3314 | + void activeChanged(); |
3315 | |
3316 | public Q_SLOTS: |
3317 | void addAction(UCAction *action); |
3318 | |
3319 | === added file 'src/Ubuntu/Components/plugin/ucactionitem.cpp' |
3320 | --- src/Ubuntu/Components/plugin/ucactionitem.cpp 1970-01-01 00:00:00 +0000 |
3321 | +++ src/Ubuntu/Components/plugin/ucactionitem.cpp 2015-09-08 04:09:38 +0000 |
3322 | @@ -0,0 +1,316 @@ |
3323 | +/* |
3324 | + * Copyright 2015 Canonical Ltd. |
3325 | + * |
3326 | + * This program is free software; you can redistribute it and/or modify |
3327 | + * it under the terms of the GNU Lesser General Public License as published by |
3328 | + * the Free Software Foundation; version 3. |
3329 | + * |
3330 | + * This program is distributed in the hope that it will be useful, |
3331 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3332 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3333 | + * GNU Lesser General Public License for more details. |
3334 | + * |
3335 | + * You should have received a copy of the GNU Lesser General Public License |
3336 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3337 | + */ |
3338 | + |
3339 | +#include "ucactionitem.h" |
3340 | +#include "ucaction.h" |
3341 | + |
3342 | +/*! |
3343 | + * \qmltype ActionItem |
3344 | + * \instantiates UCActionItem |
3345 | + * \inqmlmodule Ubuntu.Components 1.1 |
3346 | + * \ingroup ubuntu |
3347 | + * \brief A visual representation of an Action. The API of ActionItem is a |
3348 | + * copy of the API of \l Action, with additional properties to define |
3349 | + * visual aspects of the ActionItem. |
3350 | + * |
3351 | + * If \l action is set, the values of the other properties will by default |
3352 | + * be identical to the \l Action's property values. Setting the other properties |
3353 | + * will override the properties copied from the \l Action. |
3354 | + */ |
3355 | + |
3356 | +/*! |
3357 | + * \qmlsignal ActionItem::triggered(var value) |
3358 | + * Called when the actionItem is triggered. |
3359 | + */ |
3360 | +UCActionItem::UCActionItem(QQuickItem *parent) |
3361 | + : UCStyledItemBase(parent) |
3362 | + , m_action(Q_NULLPTR) |
3363 | + , m_flags(0) |
3364 | +{ |
3365 | + connect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged); |
3366 | + connect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged); |
3367 | +} |
3368 | + |
3369 | +void UCActionItem::componentComplete() |
3370 | +{ |
3371 | + UCStyledItemBase::componentComplete(); |
3372 | + // make sure we connect to the right signals, so we detach and re-attach actions |
3373 | + // to make sure the SLOT macro picks up the custom trigger() slot |
3374 | + if (m_action) { |
3375 | + attachAction(false); |
3376 | + attachAction(true); |
3377 | + } |
3378 | +} |
3379 | + |
3380 | +void UCActionItem::_q_visibleChanged() |
3381 | +{ |
3382 | + m_flags |= CustomVisible; |
3383 | + disconnect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged); |
3384 | +} |
3385 | + |
3386 | +void UCActionItem::_q_enabledChanged() |
3387 | +{ |
3388 | + m_flags |= CustomEnabled; |
3389 | + disconnect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged); |
3390 | +} |
3391 | + |
3392 | +// update visible property |
3393 | +void UCActionItem::_q_updateVisible() |
3394 | +{ |
3395 | + bool visible = m_action ? m_action->m_visible : true; |
3396 | + setVisible(visible); |
3397 | + // reset flag and reconnect signal handler disconnected by the |
3398 | + m_flags &= ~CustomVisible; |
3399 | + if (m_action) { |
3400 | + connect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged); |
3401 | + } |
3402 | +} |
3403 | + |
3404 | +// update enabled property |
3405 | +void UCActionItem::_q_updateEnabled() |
3406 | +{ |
3407 | + bool enabled = m_action ? m_action->m_enabled : true; |
3408 | + setEnabled(enabled); |
3409 | + // reset flag and reconnect signal handler disconnected by the |
3410 | + m_flags &= ~CustomEnabled; |
3411 | + if (m_action) { |
3412 | + connect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged); |
3413 | + } |
3414 | +} |
3415 | + |
3416 | +void UCActionItem::updateProperties() |
3417 | +{ |
3418 | + if (!(m_flags & CustomText)) { |
3419 | + Q_EMIT textChanged(); |
3420 | + } |
3421 | + if (!(m_flags & CustomIconSource)) { |
3422 | + Q_EMIT iconSourceChanged(); |
3423 | + } |
3424 | + if (!(m_flags & CustomIconName)) { |
3425 | + Q_EMIT iconNameChanged(); |
3426 | + } |
3427 | +} |
3428 | + |
3429 | +void UCActionItem::attachAction(bool attach) |
3430 | +{ |
3431 | + if (attach) { |
3432 | + connect(this, SIGNAL(triggered(QVariant)), |
3433 | + m_action, SLOT(trigger(QVariant)), Qt::DirectConnection); |
3434 | + connect(m_action, &UCAction::visibleChanged, |
3435 | + this, &UCActionItem::_q_updateVisible, Qt::DirectConnection); |
3436 | + connect(m_action, &UCAction::enabledChanged, |
3437 | + this, &UCActionItem::_q_updateEnabled, Qt::DirectConnection); |
3438 | + if (!(m_flags & CustomText)) { |
3439 | + connect(m_action, &UCAction::textChanged, |
3440 | + this, &UCActionItem::textChanged, Qt::DirectConnection); |
3441 | + } |
3442 | + if (!(m_flags & CustomIconSource)) { |
3443 | + connect(m_action, &UCAction::iconSourceChanged, |
3444 | + this, &UCActionItem::iconSourceChanged, Qt::DirectConnection); |
3445 | + } |
3446 | + if (!(m_flags & CustomIconName)) { |
3447 | + connect(m_action, &UCAction::iconNameChanged, |
3448 | + this, &UCActionItem::iconNameChanged, Qt::DirectConnection); |
3449 | + } |
3450 | + } else { |
3451 | + disconnect(this, SIGNAL(triggered(QVariant)), |
3452 | + m_action, SLOT(trigger(QVariant))); |
3453 | + disconnect(m_action, &UCAction::visibleChanged, |
3454 | + this, &UCActionItem::_q_updateVisible); |
3455 | + disconnect(m_action, &UCAction::enabledChanged, |
3456 | + this, &UCActionItem::_q_updateEnabled); |
3457 | + if (!(m_flags & CustomText)) { |
3458 | + disconnect(m_action, &UCAction::textChanged, |
3459 | + this, &UCActionItem::textChanged); |
3460 | + } |
3461 | + if (!(m_flags & CustomIconSource)) { |
3462 | + disconnect(m_action, &UCAction::iconSourceChanged, |
3463 | + this, &UCActionItem::iconSourceChanged); |
3464 | + } |
3465 | + if (!(m_flags & CustomIconName)) { |
3466 | + disconnect(m_action, &UCAction::iconNameChanged, |
3467 | + this, &UCActionItem::iconNameChanged); |
3468 | + } |
3469 | + } |
3470 | +} |
3471 | + |
3472 | +/*! |
3473 | + * \qmlproperty Action ActionItem::action |
3474 | + * The \l Action associated with this ActionItem. If action is set, the values |
3475 | + * of the \l Action properties are copied to the values of the ActionItem |
3476 | + * properties, unless those were previously overridden. |
3477 | + */ |
3478 | +void UCActionItem::setAction(UCAction *action) |
3479 | +{ |
3480 | + if (m_action == action) { |
3481 | + return; |
3482 | + } |
3483 | + if (m_action) { |
3484 | + attachAction(false); |
3485 | + } |
3486 | + m_action = action; |
3487 | + Q_EMIT actionChanged(); |
3488 | + |
3489 | + if (m_action) { |
3490 | + attachAction(true); |
3491 | + } |
3492 | + _q_updateVisible(); |
3493 | + _q_updateEnabled(); |
3494 | + updateProperties(); |
3495 | +} |
3496 | + |
3497 | +/*! |
3498 | + * \qmlproperty string ActionItem::text |
3499 | + * The title of the actionItem. Defaults to the \c action.text. |
3500 | + */ |
3501 | +QString UCActionItem::text() |
3502 | +{ |
3503 | + if (m_flags & CustomText) { |
3504 | + return m_text; |
3505 | + } |
3506 | + return m_action ? m_action->m_text : QString(); |
3507 | +} |
3508 | +void UCActionItem::setText(const QString &text) |
3509 | +{ |
3510 | + if (m_text == text) { |
3511 | + return; |
3512 | + } |
3513 | + m_text = text; |
3514 | + if (m_action && !(m_flags & CustomText)) { |
3515 | + // disconnect change signal from Action |
3516 | + disconnect(m_action, &UCAction::textChanged, |
3517 | + this, &UCActionItem::textChanged); |
3518 | + } |
3519 | + m_flags |= CustomText; |
3520 | + Q_EMIT textChanged(); |
3521 | +} |
3522 | +void UCActionItem::resetText() |
3523 | +{ |
3524 | + m_text.clear(); |
3525 | + m_flags &= ~CustomText; |
3526 | + if (m_action) { |
3527 | + // re-connect change signal from Action |
3528 | + connect(m_action, &UCAction::textChanged, |
3529 | + this, &UCActionItem::textChanged, Qt::DirectConnection); |
3530 | + } |
3531 | + Q_EMIT textChanged(); |
3532 | +} |
3533 | + |
3534 | +/*! |
3535 | + * \qmlproperty url ActionItem::iconSource |
3536 | + * The image associated with the ActionItem. Defaults to \c action.iconSource. |
3537 | + * |
3538 | + * This is the URL of any image file. If both iconSource and \l iconName are defined, |
3539 | + * \l iconName will be ignored. |
3540 | + */ |
3541 | +QUrl UCActionItem::iconSource() |
3542 | +{ |
3543 | + if (m_flags & CustomIconSource) { |
3544 | + return m_iconSource; |
3545 | + } |
3546 | + if (m_action) { |
3547 | + return m_action->m_iconSource; |
3548 | + } |
3549 | + return !iconName().isEmpty() ? QUrl(QString("image://theme/%1").arg(iconName())) : QUrl(); |
3550 | +} |
3551 | +void UCActionItem::setIconSource(const QUrl &iconSource) |
3552 | +{ |
3553 | + if (m_iconSource == iconSource) { |
3554 | + return; |
3555 | + } |
3556 | + m_iconSource = iconSource; |
3557 | + if (m_action && !(m_flags & CustomIconSource)) { |
3558 | + // disconnect change signal from Action |
3559 | + disconnect(m_action, &UCAction::iconSourceChanged, |
3560 | + this, &UCActionItem::iconSourceChanged); |
3561 | + } |
3562 | + m_flags |= CustomIconSource; |
3563 | + Q_EMIT iconSourceChanged(); |
3564 | +} |
3565 | +void UCActionItem::resetIconSource() |
3566 | +{ |
3567 | + m_iconSource.clear(); |
3568 | + m_flags &= ~CustomIconSource; |
3569 | + if (m_action) { |
3570 | + // re-connect change signal from Action |
3571 | + connect(m_action, &UCAction::iconSourceChanged, |
3572 | + this, &UCActionItem::iconSourceChanged, Qt::DirectConnection); |
3573 | + } |
3574 | + Q_EMIT iconSourceChanged(); |
3575 | +} |
3576 | + |
3577 | +/*! |
3578 | + * \qmlproperty string ActionItem::iconName |
3579 | + * The icon associated with the actionItem in the suru icon theme. Defaults to |
3580 | + * \c action.iconName. |
3581 | + * |
3582 | + * \note The complete list of icons available in Ubuntu is not published yet. |
3583 | + * For now please refer to the folders where the icon themes are installed: |
3584 | + * \list |
3585 | + * \li Ubuntu Touch: \l file:/usr/share/icons/suru |
3586 | + * \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark |
3587 | + * \endlist |
3588 | + * These 2 separate icon themes will be merged soon. |
3589 | + * |
3590 | + * If both \l iconSource and iconName are defined, iconName will be ignored. |
3591 | + */ |
3592 | +QString UCActionItem::iconName() |
3593 | +{ |
3594 | + if (m_flags & CustomIconName) { |
3595 | + return m_iconName; |
3596 | + } |
3597 | + return m_action ? m_action->m_iconName : QString(); |
3598 | +} |
3599 | +void UCActionItem::setIconName(const QString &iconName) |
3600 | +{ |
3601 | + if (m_iconName == iconName) { |
3602 | + return; |
3603 | + } |
3604 | + m_iconName = iconName; |
3605 | + if (m_action && !(m_flags & CustomIconName)) { |
3606 | + // disconnect change signal from Action |
3607 | + disconnect(m_action, &UCAction::iconNameChanged, |
3608 | + this, &UCActionItem::iconNameChanged); |
3609 | + } |
3610 | + m_flags |= CustomIconName; |
3611 | + Q_EMIT iconNameChanged(); |
3612 | + // also sync iconSource if that is not a custom one or taken from action |
3613 | + if (!m_action || (m_flags & CustomIconSource)) { |
3614 | + Q_EMIT iconSourceChanged(); |
3615 | + } |
3616 | +} |
3617 | +void UCActionItem::resetIconName() |
3618 | +{ |
3619 | + m_iconName.clear(); |
3620 | + m_flags &= ~CustomIconName; |
3621 | + if (m_action) { |
3622 | + // re-connect change signal from Action |
3623 | + connect(m_action, &UCAction::iconNameChanged, |
3624 | + this, &UCActionItem::iconNameChanged, Qt::DirectConnection); |
3625 | + } |
3626 | + Q_EMIT iconNameChanged(); |
3627 | +} |
3628 | + |
3629 | +/*! |
3630 | + * \qmlmethod void ActionItem::trigger(var value) |
3631 | + * Trigger this action item if it is enabled. |
3632 | + */ |
3633 | +void UCActionItem::trigger(const QVariant &value) |
3634 | +{ |
3635 | + if (isEnabled()) { |
3636 | + Q_EMIT triggered(value); |
3637 | + } |
3638 | +} |
3639 | |
3640 | === added file 'src/Ubuntu/Components/plugin/ucactionitem.h' |
3641 | --- src/Ubuntu/Components/plugin/ucactionitem.h 1970-01-01 00:00:00 +0000 |
3642 | +++ src/Ubuntu/Components/plugin/ucactionitem.h 2015-09-08 04:09:38 +0000 |
3643 | @@ -0,0 +1,79 @@ |
3644 | +/* |
3645 | + * Copyright 2015 Canonical Ltd. |
3646 | + * |
3647 | + * This program is free software; you can redistribute it and/or modify |
3648 | + * it under the terms of the GNU Lesser General Public License as published by |
3649 | + * the Free Software Foundation; version 3. |
3650 | + * |
3651 | + * This program is distributed in the hope that it will be useful, |
3652 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3653 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3654 | + * GNU Lesser General Public License for more details. |
3655 | + * |
3656 | + * You should have received a copy of the GNU Lesser General Public License |
3657 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3658 | + */ |
3659 | +#ifndef UCACTIONITEM_H |
3660 | +#define UCACTIONITEM_H |
3661 | + |
3662 | +#include "ucstyleditembase.h" |
3663 | + |
3664 | +class UCAction; |
3665 | +class UCActionItem : public UCStyledItemBase |
3666 | +{ |
3667 | + Q_OBJECT |
3668 | + Q_PROPERTY(UCAction *action MEMBER m_action WRITE setAction NOTIFY actionChanged FINAL) |
3669 | + Q_PROPERTY(QString text READ text WRITE setText RESET resetText NOTIFY textChanged) |
3670 | + Q_PROPERTY(QUrl iconSource READ iconSource WRITE setIconSource RESET resetIconSource NOTIFY iconSourceChanged) |
3671 | + Q_PROPERTY(QString iconName READ iconName WRITE setIconName RESET resetIconName NOTIFY iconNameChanged) |
3672 | +public: |
3673 | + explicit UCActionItem(QQuickItem *parent = 0); |
3674 | + |
3675 | + void setAction(UCAction *action); |
3676 | + QString text(); |
3677 | + void setText(const QString &text); |
3678 | + void resetText(); |
3679 | + QUrl iconSource(); |
3680 | + void setIconSource(const QUrl &iconSource); |
3681 | + void resetIconSource(); |
3682 | + QString iconName(); |
3683 | + void setIconName(const QString &iconName); |
3684 | + void resetIconName(); |
3685 | + |
3686 | +Q_SIGNALS: |
3687 | + void actionChanged(); |
3688 | + void textChanged(); |
3689 | + void iconSourceChanged(); |
3690 | + void iconNameChanged(); |
3691 | + void triggered(const QVariant &value); |
3692 | + |
3693 | +public Q_SLOTS: |
3694 | + void trigger(const QVariant &value = QVariant()); |
3695 | + |
3696 | +protected Q_SLOTS: |
3697 | + void _q_visibleChanged(); |
3698 | + void _q_enabledChanged(); |
3699 | + void _q_updateVisible(); |
3700 | + void _q_updateEnabled(); |
3701 | + |
3702 | +protected: |
3703 | + enum { |
3704 | + CustomText = 0x01, |
3705 | + CustomIconSource = 0x02, |
3706 | + CustomIconName = 0x04, |
3707 | + CustomVisible = 0x40, |
3708 | + CustomEnabled = 0x80 |
3709 | + }; |
3710 | + QString m_text; |
3711 | + QString m_iconName; |
3712 | + QUrl m_iconSource; |
3713 | + UCAction *m_action; |
3714 | + quint8 m_flags; |
3715 | + |
3716 | + void componentComplete(); |
3717 | + |
3718 | + void updateProperties(); |
3719 | + void attachAction(bool attach); |
3720 | +}; |
3721 | + |
3722 | +#endif // UCACTIONITEM_H |
3723 | |
3724 | === added file 'src/Ubuntu/Components/plugin/uchaptics.cpp' |
3725 | --- src/Ubuntu/Components/plugin/uchaptics.cpp 1970-01-01 00:00:00 +0000 |
3726 | +++ src/Ubuntu/Components/plugin/uchaptics.cpp 2015-09-08 04:09:38 +0000 |
3727 | @@ -0,0 +1,179 @@ |
3728 | +/* |
3729 | + * Copyright 2015 Canonical Ltd. |
3730 | + * |
3731 | + * This program is free software; you can redistribute it and/or modify |
3732 | + * it under the terms of the GNU Lesser General Public License as published by |
3733 | + * the Free Software Foundation; version 3. |
3734 | + * |
3735 | + * This program is distributed in the hope that it will be useful, |
3736 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3737 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3738 | + * GNU Lesser General Public License for more details. |
3739 | + * |
3740 | + * You should have received a copy of the GNU Lesser General Public License |
3741 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3742 | + */ |
3743 | + |
3744 | +#include "uchaptics.h" |
3745 | +#include "plugin.h" |
3746 | +#include <QtQml/QQmlComponent> |
3747 | +#include <QtCore/QUrl> |
3748 | +#include <QDebug> |
3749 | + |
3750 | +/*! |
3751 | + \qmltype Haptics |
3752 | + \instantiates UCHaptics |
3753 | + \inqmlmodule Ubuntu.Components 1.1 |
3754 | + \ingroup ubuntu-services |
3755 | + \brief Singleton defining the haptics feedback used in components, where execution |
3756 | + of the feedback is controlled by the system settings. |
3757 | + |
3758 | + Supports global feedback as well as custom feedback. Global feedback can be |
3759 | + configured through its properties, and \l play function will play the default |
3760 | + configuration, or a custom one if parameter is given. |
3761 | + |
3762 | + Example of using Haptics: |
3763 | + \qml |
3764 | + import QtQuick 2.4 |
3765 | + import Ubuntu.Components 1.3 |
3766 | + |
3767 | + Item { |
3768 | + implicitWidth: units.gu(20) |
3769 | + implicitHeight: units.gu(5) |
3770 | + |
3771 | + Label { |
3772 | + text: "Press me" |
3773 | + anchors.fill: parent |
3774 | + horizontalAlignment: Text.AlignHCenter |
3775 | + verticalAlignment: Text.AlignVCenter |
3776 | + } |
3777 | + MouseArea { |
3778 | + anchors.fill: parent |
3779 | + onClicked: Haptics.play() |
3780 | + } |
3781 | + } |
3782 | + \endqml |
3783 | + |
3784 | + Custom effects can be played as follows: |
3785 | + \qml |
3786 | + import QtQuick 2.4 |
3787 | + import Ubuntu.Components 1.3 |
3788 | + |
3789 | + Item { |
3790 | + implicitWidth: units.gu(20) |
3791 | + implicitHeight: units.gu(5) |
3792 | + |
3793 | + Label { |
3794 | + text: "Press me" |
3795 | + anchors.fill: parent |
3796 | + horizontalAlignment: Text.AlignHCenter |
3797 | + verticalAlignment: Text.AlignVCenter |
3798 | + } |
3799 | + MouseArea { |
3800 | + anchors.fill: parent |
3801 | + onClicked: Haptics.play({duration: 25, attackIntensity: 0.7}) |
3802 | + } |
3803 | + } |
3804 | + \endqml |
3805 | + |
3806 | + \note Though the \l effect property exposes \c start, \c stop and \c pause |
3807 | + functions, use those only if you want to have feedback independent from what the |
3808 | + system setting is. |
3809 | + */ |
3810 | + |
3811 | +UCHaptics::UCHaptics(QObject *parent) |
3812 | + : QObject(parent) |
3813 | +{ |
3814 | + connect(&HapticsProxy::instance(), &HapticsProxy::enabledChanged, |
3815 | + this, &UCHaptics::enabledChanged); |
3816 | +} |
3817 | + |
3818 | +/*! |
3819 | + \qmlproperty bool Haptics::enabled |
3820 | + \readonly |
3821 | + The property specifies whether the haptics feedback is enabled or not by the system. |
3822 | + */ |
3823 | +bool UCHaptics::enabled() const |
3824 | +{ |
3825 | + return HapticsProxy::instance().enabled(); |
3826 | +} |
3827 | + |
3828 | +/*! |
3829 | + \qmlproperty HapticsEffect Haptics::effect |
3830 | + \readonly |
3831 | + The property defines the settings of the haptics effect used by the component. |
3832 | + The default setting is a haptics effect with a duration of 10 milliseconds |
3833 | + with an intensity of 1.0, having fading time of 50 millisecods and fading |
3834 | + intensity 0.0, and attack time of 50 milliseconds and with an intensity of |
3835 | + 0.0. |
3836 | + */ |
3837 | +QObject *UCHaptics::effect() const |
3838 | +{ |
3839 | + return HapticsProxy::instance().effect(); |
3840 | +} |
3841 | + |
3842 | +/*! |
3843 | + \qmlmethod void Haptics::play(var customEffect) |
3844 | + The function plays the feedback with the configuration specified in \l effect |
3845 | + if no parameter is given. Custom effect can be played by specifying the effect |
3846 | + properties in a JSON object in \c customEffect. |
3847 | + |
3848 | + The function will exit unconditionaly if playing the effects is blocked by |
3849 | + system settings. |
3850 | + |
3851 | + The function will not stop any ongoing haptics effect played, if that one |
3852 | + was a default haptics effect. In case of custom effects, the previous effect |
3853 | + will be stopped, and settings will be restored before the new haptics will |
3854 | + be played. The custom settings properties (the ones which are required to |
3855 | + be different from the ones defined in the \l effect) must be specified in |
3856 | + the parameter in a JSON object. |
3857 | + */ |
3858 | +void UCHaptics::play(const QVariant &customEffect) |
3859 | +{ |
3860 | + HapticsProxy::instance().play(customEffect); |
3861 | +} |
3862 | + |
3863 | +/********************************************************* |
3864 | + * Proxy implementation |
3865 | + */ |
3866 | +bool HapticsProxy::enabled() |
3867 | +{ |
3868 | + initialize(); |
3869 | + return (m_proxyObject) ? m_proxyObject->property("enabled").toBool() : false; |
3870 | +} |
3871 | + |
3872 | +QObject *HapticsProxy::effect() |
3873 | +{ |
3874 | + initialize(); |
3875 | + return (m_proxyObject) ? m_proxyObject->property("effect").value<QObject*>() : Q_NULLPTR; |
3876 | +} |
3877 | + |
3878 | +void HapticsProxy::initialize() |
3879 | +{ |
3880 | + if (!m_engine || m_proxyObject) { |
3881 | + return; |
3882 | + } |
3883 | + // load haptics proxy from file system/qrc |
3884 | + QUrl path = UbuntuComponentsPlugin::pluginUrl().resolved(QUrl("1.1/Haptics.qml")); |
3885 | + QQmlComponent component(m_engine, path, QQmlComponent::PreferSynchronous); |
3886 | + if (!component.isError()) { |
3887 | + m_proxyObject = component.create(); |
3888 | + if (m_proxyObject) { |
3889 | + connect(m_proxyObject, SIGNAL(enabledChanged()), this, SIGNAL(enabledChanged())); |
3890 | + } |
3891 | + } else { |
3892 | + qWarning() << qPrintable(component.errorString()); |
3893 | + } |
3894 | +} |
3895 | + |
3896 | +void HapticsProxy::play(const QVariant &customEffect) |
3897 | +{ |
3898 | + if (!m_engine) { |
3899 | + qWarning() << "Engine not specified, haptics won't play"; |
3900 | + } |
3901 | + initialize(); |
3902 | + if (m_proxyObject) { |
3903 | + // invoke play function |
3904 | + m_proxyObject->metaObject()->invokeMethod(m_proxyObject, "play", Q_ARG(QVariant, customEffect)); |
3905 | + } |
3906 | +} |
3907 | |
3908 | === added file 'src/Ubuntu/Components/plugin/uchaptics.h' |
3909 | --- src/Ubuntu/Components/plugin/uchaptics.h 1970-01-01 00:00:00 +0000 |
3910 | +++ src/Ubuntu/Components/plugin/uchaptics.h 2015-09-08 04:09:38 +0000 |
3911 | @@ -0,0 +1,78 @@ |
3912 | +/* |
3913 | + * Copyright 2015 Canonical Ltd. |
3914 | + * |
3915 | + * This program is free software; you can redistribute it and/or modify |
3916 | + * it under the terms of the GNU Lesser General Public License as published by |
3917 | + * the Free Software Foundation; version 3. |
3918 | + * |
3919 | + * This program is distributed in the hope that it will be useful, |
3920 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3921 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3922 | + * GNU Lesser General Public License for more details. |
3923 | + * |
3924 | + * You should have received a copy of the GNU Lesser General Public License |
3925 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3926 | + */ |
3927 | + |
3928 | +#ifndef UCHAPTICS_H |
3929 | +#define UCHAPTICS_H |
3930 | + |
3931 | +#include <QtCore/QObject> |
3932 | +#include <QtCore/QVariant> |
3933 | + |
3934 | +class UCHaptics : public QObject |
3935 | +{ |
3936 | + Q_OBJECT |
3937 | + Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) |
3938 | + Q_PROPERTY(QObject *effect READ effect CONSTANT) |
3939 | +public: |
3940 | + explicit UCHaptics(QObject *parent = 0); |
3941 | + |
3942 | + bool enabled() const; |
3943 | + QObject *effect() const; |
3944 | + |
3945 | +Q_SIGNALS: |
3946 | + void enabledChanged(); |
3947 | + |
3948 | +public Q_SLOTS: |
3949 | + void play(const QVariant &customEffect = QVariant()); |
3950 | +}; |
3951 | + |
3952 | +class QQmlEngine; |
3953 | +class HapticsProxy : public QObject |
3954 | +{ |
3955 | + Q_OBJECT |
3956 | +public: |
3957 | + explicit HapticsProxy(QObject *parent = 0) |
3958 | + : QObject(parent) |
3959 | + , m_proxyObject(Q_NULLPTR) |
3960 | + , m_engine(Q_NULLPTR) |
3961 | + { |
3962 | + } |
3963 | + |
3964 | + static HapticsProxy &instance() |
3965 | + { |
3966 | + static HapticsProxy instance; |
3967 | + return instance; |
3968 | + } |
3969 | + |
3970 | + void setEngine(QQmlEngine *engine) |
3971 | + { |
3972 | + m_engine = engine; |
3973 | + } |
3974 | + |
3975 | + void initialize(); |
3976 | + |
3977 | + bool enabled(); |
3978 | + QObject *effect(); |
3979 | + void play(const QVariant &customEffect); |
3980 | + |
3981 | +Q_SIGNALS: |
3982 | + void enabledChanged(); |
3983 | + |
3984 | +private: |
3985 | + QObject *m_proxyObject; |
3986 | + QQmlEngine *m_engine; |
3987 | +}; |
3988 | + |
3989 | +#endif // UCHAPTICS_H |
3990 | |
3991 | === modified file 'src/Ubuntu/Components/plugin/uclistitem.cpp' |
3992 | --- src/Ubuntu/Components/plugin/uclistitem.cpp 2015-07-30 13:27:32 +0000 |
3993 | +++ src/Ubuntu/Components/plugin/uclistitem.cpp 2015-09-08 04:09:38 +0000 |
3994 | @@ -200,6 +200,7 @@ |
3995 | , leadingActions(0) |
3996 | , trailingActions(0) |
3997 | , mainAction(0) |
3998 | + , expansion(Q_NULLPTR) |
3999 | { |
4000 | } |
4001 | UCListItemPrivate::~UCListItemPrivate() |
4002 | @@ -325,7 +326,7 @@ |
4003 | bool UCListItemPrivate::loadStyleItem(bool animated) |
4004 | { |
4005 | // the style should be loaded only if one of the condition is satisfied |
4006 | - if (!swiped && !selectMode() && !dragMode()) { |
4007 | + if (!swiped && !selectMode() && !dragMode() && !(expansion && expansion->expanded())) { |
4008 | return false; |
4009 | } |
4010 | |
4011 | @@ -339,6 +340,7 @@ |
4012 | preStyleChanged(); |
4013 | return false; |
4014 | } |
4015 | + myStyle->updateFlickable(flickable); |
4016 | // bring the panels foreground |
4017 | styleItem->setZ(0); |
4018 | listItemStyle()->setAnimatePanels(true); |
4019 | @@ -372,23 +374,13 @@ |
4020 | (parentItem ? QQuickItemPrivate::get(parentItem)->childItems.indexOf(q) : -1); |
4021 | } |
4022 | |
4023 | -// returns true if the highlight is possible |
4024 | -bool UCListItemPrivate::canHighlight(QMouseEvent *event) |
4025 | +// returns true if the highlight is possible; the highlight is possible if the |
4026 | +// list item has at least one action, leading/trailing actions set, onClicked |
4027 | +// or onPressAndHold signal handlers set |
4028 | +bool UCListItemPrivate::canHighlight() |
4029 | { |
4030 | - // if automatic, the highlight should not happen if we clicked on an active component; |
4031 | - // localPos is a position relative to ListItem which will give us a child from |
4032 | - // from the original coordinates; therefore we must map the position to the contentItem |
4033 | Q_Q(UCListItem); |
4034 | - QPointF myPos = q->mapToItem(contentItem, event->localPos()); |
4035 | - QQuickItem *child = contentItem->childAt(myPos.x(), myPos.y()); |
4036 | - bool activeComponent = child && (child->acceptedMouseButtons() & event->button()) && |
4037 | - child->isEnabled() && !qobject_cast<QQuickText*>(child); |
4038 | - // do highlight if not pressed above the active component, and the component has either |
4039 | - // action, leading or trailing actions list or at least an active child component declared |
4040 | - QQuickMouseArea *ma = q->findChild<QQuickMouseArea*>(); |
4041 | - bool activeMouseArea = ma && ma->isEnabled(); |
4042 | - return !activeComponent && (isClickedConnected() || isPressAndHoldConnected() || |
4043 | - mainAction || leadingActions || trailingActions || activeMouseArea); |
4044 | + return (isClickedConnected() || isPressAndHoldConnected() || mainAction || leadingActions || trailingActions); |
4045 | } |
4046 | |
4047 | // set highlighted flag and update contentItem |
4048 | @@ -876,8 +868,74 @@ |
4049 | * |
4050 | * \sa ViewItems::dragMode, ViewItems::dragUpdated |
4051 | * |
4052 | + * \section2 Expansion |
4053 | + * Since Ubuntu.Components 1.3, ListItem supports expansion. ListItems declared |
4054 | + * in a view can expand exclusively, having leading and trailing panes locked |
4055 | + * when expanded and to be collapsed when tapping outside of the expanded area. |
4056 | + * The expansion is driven by the \l expansion group property, and the behavior |
4057 | + * by the \l ViewItems::expansionFlags and \l ViewItems::expandedIndices |
4058 | + * attached properties. Each ListItem which is required to expand should set a |
4059 | + * proper height in the \l expansion.height property, which should be bigger |
4060 | + * than the collapsed height of the ListItem is. The expansion itself is driven |
4061 | + * by the \l expansion.expanded property, which can be set freely depending on |
4062 | + * the use case, on click, on long press, etc. |
4063 | + * |
4064 | + * The default expansion behavior is set to be exclusive and locked, meaning |
4065 | + * there can be only one ListItem expanded within a view and neither leading |
4066 | + * nor trailing action panels cannot be swiped in. Expanding an other ListItem |
4067 | + * will collapse the previosuly expanded one. There can be cases when tapping |
4068 | + * outside of the expanded area of a ListItem we woudl need the expanded one |
4069 | + * to collapse automatically. This can be achieved by setting \c ViewItems.CollapseOnOutsidePress |
4070 | + * flag to \l ViewItems::expansionFlags. This flag will also turn on \c ViewItems.Exclusive |
4071 | + * flag, as tapping outside practicly forbids more than one item to be expanded |
4072 | + * at a time. |
4073 | + * \qml |
4074 | + * import QtQuick 2.4 |
4075 | + * import Ubuntu.Components 1.3 |
4076 | + * |
4077 | + * ListView { |
4078 | + * width: units.gu(40) |
4079 | + * height: units.gu(71) |
4080 | + * model: ListModel { |
4081 | + * Component.onCompleted: { |
4082 | + * for (var i = 0; i < 50; i++) { |
4083 | + * append({data: i}); |
4084 | + * } |
4085 | + * } |
4086 | + * } |
4087 | + * ViewItems.expansionFlags: ViewItems.CollapseOnOutsidePress |
4088 | + * delegate: ListItem { |
4089 | + * Label { |
4090 | + * text: "Model item #" + modelData |
4091 | + * } |
4092 | + * trailingActions: ListItemActions { |
4093 | + * actions: [ |
4094 | + * Action { |
4095 | + * icon: "search" |
4096 | + * }, |
4097 | + * Action { |
4098 | + * icon: "edit" |
4099 | + * }, |
4100 | + * Action { |
4101 | + * icon: "copy" |
4102 | + * } |
4103 | + * ] |
4104 | + * } |
4105 | + * expansion.height: units.gu(15) |
4106 | + * onClicked: expansion.expanded = true |
4107 | + * } |
4108 | + * } |
4109 | + * \endqml |
4110 | + * The example above collapses the expanded item whenever it is tapped or mouse |
4111 | + * pressed outside of the expanded list item. |
4112 | + * \note Set 0 to \l ViewItems::expansionFlags if no restrictions on expanded items |
4113 | + * is required (i.e multiple expanded items are allowed, swiping leading/trailing |
4114 | + * actions when expanded). |
4115 | + * \note Do not bind \l expansion.height to the ListItem's height as is will cause |
4116 | + * binding loops. |
4117 | + * |
4118 | * \section2 Note on styling |
4119 | - * ListItem's styling differs from the other component sstyling, as ListItem loads |
4120 | + * ListItem's styling differs from the other components styling, as ListItem loads |
4121 | * the style only when either of the leadin/trailing panels are swiped, or when the |
4122 | * item enters in select- or drag mode. The component does not assume any visuals |
4123 | * to be present in the style. |
4124 | @@ -914,6 +972,11 @@ |
4125 | { |
4126 | } |
4127 | |
4128 | +QObject *UCListItem::attachedViewItems(QObject *object, bool create) |
4129 | +{ |
4130 | + return qmlAttachedPropertiesObject<UCViewItemsAttached>(object, create); |
4131 | +} |
4132 | + |
4133 | void UCListItem::classBegin() |
4134 | { |
4135 | UCStyledItemBase::classBegin(); |
4136 | @@ -966,7 +1029,7 @@ |
4137 | this, SLOT(_q_syncDragMode())); |
4138 | |
4139 | // if selection or drag mode is on, initialize style, with animations turned off |
4140 | - if (d->parentAttached->selectMode() || d->parentAttached->dragMode()) { |
4141 | + if (d->parentAttached->selectMode() || d->parentAttached->dragMode() || (d->expansion && d->expansion->expanded())) { |
4142 | d->loadStyleItem(false); |
4143 | } |
4144 | // set the object name for testing purposes |
4145 | @@ -996,10 +1059,10 @@ |
4146 | QQuickItem *parentAttachee = data.item; |
4147 | if (d->flickable && d->flickable->inherits("QQuickListView")) { |
4148 | // attach to ListView |
4149 | - d->parentAttached = static_cast<UCViewItemsAttached*>(qmlAttachedPropertiesObject<UCViewItemsAttached>(d->flickable)); |
4150 | + d->parentAttached = static_cast<UCViewItemsAttached*>(attachedViewItems(d->flickable, true)); |
4151 | parentAttachee = d->flickable; |
4152 | } else if (data.item) { |
4153 | - d->parentAttached = static_cast<UCViewItemsAttached*>(qmlAttachedPropertiesObject<UCViewItemsAttached>(data.item)); |
4154 | + d->parentAttached = static_cast<UCViewItemsAttached*>(attachedViewItems(data.item, true)); |
4155 | } else { |
4156 | // mark as not ready, so no action should be performed which depends on readyness |
4157 | d->ready = false; |
4158 | @@ -1007,6 +1070,11 @@ |
4159 | d->parentAttached = 0; |
4160 | } |
4161 | |
4162 | + if (d->styleItem) { |
4163 | + UCListItemStyle * myStyle = static_cast<UCListItemStyle*>(d->styleItem); |
4164 | + myStyle->updateFlickable(d->flickable); |
4165 | + } |
4166 | + |
4167 | if (parentAttachee) { |
4168 | QObject::connect(parentAttachee, SIGNAL(widthChanged()), this, SLOT(_q_updateSize()), Qt::DirectConnection); |
4169 | // update size |
4170 | @@ -1081,7 +1149,7 @@ |
4171 | // while moving, we cannot select any items |
4172 | return; |
4173 | } |
4174 | - if (d->canHighlight(event) && !d->highlighted && event->button() == Qt::LeftButton) { |
4175 | + if (d->canHighlight() && !d->highlighted && event->button() == Qt::LeftButton) { |
4176 | d->grabLeftButtonEvents(event); |
4177 | } |
4178 | // accept the event so we get the rest of the events as well |
4179 | @@ -1194,7 +1262,7 @@ |
4180 | Q_D(UCListItem); |
4181 | UCStyledItemBase::mouseMoveEvent(event); |
4182 | |
4183 | - if (d->selectMode() || d->dragMode()) { |
4184 | + if (d->selectMode() || d->dragMode() || (d->expansion && d->expansion->expandedLocked())) { |
4185 | // no move is allowed while selectable mode is on |
4186 | return; |
4187 | } |
4188 | @@ -1672,4 +1740,48 @@ |
4189 | d->defaultThemeVersion = BUILD_VERSION(1, 3); |
4190 | } |
4191 | |
4192 | +QObject *UCListItem13::attachedViewItems(QObject *object, bool create) |
4193 | +{ |
4194 | + return qmlAttachedPropertiesObject<UCViewItemsAttached13>(object, create); |
4195 | +} |
4196 | + |
4197 | +void UCListItem13::itemChange(ItemChange change, const ItemChangeData &data) |
4198 | +{ |
4199 | + UCListItem::itemChange(change, data); |
4200 | + |
4201 | + Q_D(UCListItem); |
4202 | + // ViewItems drives expansion |
4203 | + if (d->parentAttached) { |
4204 | + connect(d->parentAttached.data(), SIGNAL(expandedIndicesChanged(QList<int>)), |
4205 | + this, SLOT(_q_updateExpansion(QList<int>)), Qt::UniqueConnection); |
4206 | + } |
4207 | +} |
4208 | + |
4209 | +/*! |
4210 | + * \qmlpropertygroup ::ListItem::expansion |
4211 | + * \qmlproperty bool ListItem::expansion.expanded |
4212 | + * \qmlproperty real ListItem::expansion.height |
4213 | + * \since Ubuntu.Components 1.3 |
4214 | + * The group drefines the expansion state of the ListItem. |
4215 | + */ |
4216 | +UCListItemExpansion *UCListItem13::expansion() |
4217 | +{ |
4218 | + Q_D(UCListItem); |
4219 | + if (!d->expansion) { |
4220 | + d->expansion = new UCListItemExpansion(this); |
4221 | + } |
4222 | + return d->expansion; |
4223 | +} |
4224 | + |
4225 | +void UCListItem13::_q_updateExpansion(const QList<int> &indices) |
4226 | +{ |
4227 | + Q_UNUSED(indices); |
4228 | + Q_D(UCListItem); |
4229 | + Q_EMIT expansion()->expandedChanged(); |
4230 | + // make sure the style is loaded |
4231 | + if (indices.contains(d->index())) { |
4232 | + d->loadStyleItem(); |
4233 | + } |
4234 | +} |
4235 | + |
4236 | #include "moc_uclistitem.cpp" |
4237 | |
4238 | === modified file 'src/Ubuntu/Components/plugin/uclistitem.h' |
4239 | --- src/Ubuntu/Components/plugin/uclistitem.h 2015-07-28 19:29:19 +0000 |
4240 | +++ src/Ubuntu/Components/plugin/uclistitem.h 2015-09-08 04:09:38 +0000 |
4241 | @@ -62,6 +62,7 @@ |
4242 | void resetHighlightColor(); |
4243 | |
4244 | protected: |
4245 | + virtual QObject *attachedViewItems(QObject *object, bool create); |
4246 | void classBegin(); |
4247 | void componentComplete(); |
4248 | QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data); |
4249 | @@ -109,17 +110,24 @@ |
4250 | Q_PRIVATE_SLOT(d_func(), void _q_syncDragMode()) |
4251 | }; |
4252 | |
4253 | +class UCListItemExpansion; |
4254 | class UCListItem13 : public UCListItem |
4255 | { |
4256 | Q_OBJECT |
4257 | + Q_PROPERTY(UCListItemExpansion* expansion READ expansion CONSTANT) |
4258 | protected: |
4259 | + virtual QObject *attachedViewItems(QObject *object, bool create); |
4260 | + void itemChange(ItemChange change, const ItemChangeData &data); |
4261 | void mousePressEvent(QMouseEvent *event); |
4262 | void mouseReleaseEvent(QMouseEvent *event); |
4263 | private: |
4264 | + Q_SLOT void _q_updateExpansion(const QList<int> &indices); |
4265 | bool shouldShowContextMenu(QMouseEvent *event); |
4266 | void popoverClosed(); |
4267 | public: |
4268 | explicit UCListItem13(QQuickItem *parent = 0); |
4269 | + |
4270 | + UCListItemExpansion *expansion(); |
4271 | }; |
4272 | |
4273 | class UCListItemDividerPrivate; |
4274 | @@ -158,8 +166,15 @@ |
4275 | Q_PROPERTY(bool selectMode READ selectMode WRITE setSelectMode NOTIFY selectModeChanged) |
4276 | Q_PROPERTY(QList<int> selectedIndices READ selectedIndices WRITE setSelectedIndices NOTIFY selectedIndicesChanged) |
4277 | Q_PROPERTY(bool dragMode READ dragMode WRITE setDragMode NOTIFY dragModeChanged) |
4278 | + Q_ENUMS(ExpansionFlag) |
4279 | public: |
4280 | - explicit UCViewItemsAttached(QObject *owner); |
4281 | + enum ExpansionFlag { |
4282 | + Exclusive = 0x01, |
4283 | + UnlockExpanded = 0x02, |
4284 | + CollapseOnOutsidePress = Exclusive | 0x04 |
4285 | + }; |
4286 | + Q_DECLARE_FLAGS(ExpansionFlags, ExpansionFlag) |
4287 | + explicit UCViewItemsAttached(QObject *owner = 0); |
4288 | ~UCViewItemsAttached(); |
4289 | |
4290 | static UCViewItemsAttached *qmlAttachedProperties(QObject *owner); |
4291 | @@ -191,8 +206,68 @@ |
4292 | private: |
4293 | Q_DECLARE_PRIVATE(UCViewItemsAttached) |
4294 | }; |
4295 | +Q_DECLARE_OPERATORS_FOR_FLAGS(UCViewItemsAttached::ExpansionFlags) |
4296 | QML_DECLARE_TYPEINFO(UCViewItemsAttached, QML_HAS_ATTACHED_PROPERTIES) |
4297 | |
4298 | +// FIXME keep the 1.3 properties in a separate class, workaround for bug |
4299 | +// https://bugs.launchpad.net/ubuntu/+source/qtdeclarative-opensource-src/+bug/1389721 |
4300 | +// enums and flag are added to UCViewItemsAttached like normal |
4301 | +class UCViewItemsAttached13 : public UCViewItemsAttached |
4302 | +{ |
4303 | + Q_OBJECT |
4304 | + Q_PROPERTY(QList<int> expandedIndices READ expandedIndices WRITE setExpandedIndices NOTIFY expandedIndicesChanged) |
4305 | + Q_PROPERTY(int expansionFlags READ expansionFlags WRITE setExpansionFlags NOTIFY expansionFlagsChanged) |
4306 | +public: |
4307 | + explicit UCViewItemsAttached13(QObject *owner = 0); |
4308 | + static UCViewItemsAttached13 *qmlAttachedProperties(QObject *owner); |
4309 | + |
4310 | + QList<int> expandedIndices() const; |
4311 | + void setExpandedIndices(QList<int> indices); |
4312 | + int expansionFlags() const; |
4313 | + void setExpansionFlags(int flags); |
4314 | + |
4315 | +Q_SIGNALS: |
4316 | + void expandedIndicesChanged(const QList<int> &indices); |
4317 | + void expansionFlagsChanged(); |
4318 | + |
4319 | +private: |
4320 | + UCViewItemsAttachedPrivate *d_ptr; |
4321 | + Q_DECLARE_PRIVATE_D(d_ptr, UCViewItemsAttached) |
4322 | +}; |
4323 | +QML_DECLARE_TYPEINFO(UCViewItemsAttached13, QML_HAS_ATTACHED_PROPERTIES) |
4324 | + |
4325 | +class UCListItemExpansion : public QObject |
4326 | +{ |
4327 | + Q_OBJECT |
4328 | + Q_PROPERTY(bool expanded READ expanded WRITE setExpanded NOTIFY expandedChanged) |
4329 | + Q_PROPERTY(qreal height MEMBER m_height WRITE setHeight NOTIFY heightChanged) |
4330 | +public: |
4331 | + explicit UCListItemExpansion(QObject *parent = 0); |
4332 | + |
4333 | + bool expandedLocked(); |
4334 | + void enableClickFiltering(bool enable); |
4335 | + |
4336 | + bool expanded(); |
4337 | + void setExpanded(bool expanded); |
4338 | + void setHeight(qreal height); |
4339 | + |
4340 | +Q_SIGNALS: |
4341 | + void expandedChanged(); |
4342 | + void heightChanged(); |
4343 | + |
4344 | +protected: |
4345 | + bool eventFilter(QObject *, QEvent *); |
4346 | + |
4347 | +private: |
4348 | + UCListItem13 *m_listItem; |
4349 | + qreal m_height; |
4350 | + bool m_filtering:1; |
4351 | + |
4352 | + friend class UCListItem; |
4353 | + friend class UCListItem13; |
4354 | + friend class UCListItemPrivate; |
4355 | +}; |
4356 | + |
4357 | class UCDragEvent : public QObject |
4358 | { |
4359 | Q_OBJECT |
4360 | |
4361 | === modified file 'src/Ubuntu/Components/plugin/uclistitem_p.h' |
4362 | --- src/Ubuntu/Components/plugin/uclistitem_p.h 2015-07-30 13:27:32 +0000 |
4363 | +++ src/Ubuntu/Components/plugin/uclistitem_p.h 2015-09-08 04:09:38 +0000 |
4364 | @@ -60,7 +60,7 @@ |
4365 | void _q_syncSelectMode(); |
4366 | void _q_syncDragMode(); |
4367 | int index(); |
4368 | - bool canHighlight(QMouseEvent *event); |
4369 | + bool canHighlight(); |
4370 | void setHighlighted(bool pressed); |
4371 | void listenToRebind(bool listen); |
4372 | void lockContentItem(bool lock); |
4373 | @@ -95,6 +95,7 @@ |
4374 | UCListItemActions *leadingActions; |
4375 | UCListItemActions *trailingActions; |
4376 | UCAction *mainAction; |
4377 | + UCListItemExpansion *expansion; |
4378 | |
4379 | // getters/setters |
4380 | QQmlListProperty<QObject> data(); |
4381 | @@ -147,17 +148,25 @@ |
4382 | bool isDragUpdatedConnected(); |
4383 | void updateSelectedIndices(int fromIndex, int toIndex); |
4384 | |
4385 | + // expansion |
4386 | + void expand(int index, UCListItem13 *listItem, bool emitChangeSignal = true); |
4387 | + void collapse(int index, bool emitChangeSignal = true); |
4388 | + void collapseAll(); |
4389 | + void toggleExpansionFlags(bool enable); |
4390 | + |
4391 | + QSet<int> selectedList; |
4392 | + QMap<int, QPointer<UCListItem13> > expansionList; |
4393 | + QList< QPointer<QQuickFlickable> > flickables; |
4394 | + QList< PropertyChange* > changes; |
4395 | + QPointer<UCListItem> boundItem; |
4396 | + QPointer<UCListItem> disablerItem; |
4397 | QQuickFlickable *listView; |
4398 | ListItemDragArea *dragArea; |
4399 | + UCViewItemsAttached::ExpansionFlags expansionFlags; |
4400 | bool globalDisabled:1; |
4401 | bool selectable:1; |
4402 | bool draggable:1; |
4403 | bool ready:1; |
4404 | - QSet<int> selectedList; |
4405 | - QList< QPointer<QQuickFlickable> > flickables; |
4406 | - QList< PropertyChange* > changes; |
4407 | - QPointer<UCListItem> boundItem; |
4408 | - QPointer<UCListItem> disablerItem; |
4409 | }; |
4410 | |
4411 | #endif // UCVIEWITEM_P_H |
4412 | |
4413 | === modified file 'src/Ubuntu/Components/plugin/uclistitemstyle.cpp' |
4414 | --- src/Ubuntu/Components/plugin/uclistitemstyle.cpp 2015-04-13 13:42:03 +0000 |
4415 | +++ src/Ubuntu/Components/plugin/uclistitemstyle.cpp 2015-09-08 04:09:38 +0000 |
4416 | @@ -21,6 +21,7 @@ |
4417 | #include <QtQml/QQmlContext> |
4418 | #include <QtQml/QQmlInfo> |
4419 | #include <QtQuick/private/qquickanimation_p.h> |
4420 | +#include <QtQuick/private/qquickflickable_p.h> |
4421 | |
4422 | /*! |
4423 | * \qmltype ListItemStyle |
4424 | @@ -41,6 +42,7 @@ |
4425 | , m_snapAnimation(0) |
4426 | , m_dropAnimation(0) |
4427 | , m_dragPanel(0) |
4428 | + , m_flickable(Q_NULLPTR) |
4429 | , m_animatePanels(true) |
4430 | { |
4431 | } |
4432 | @@ -54,21 +56,29 @@ |
4433 | setAnimatePanels(context->contextProperty("animated").toBool()); |
4434 | } |
4435 | m_listItem = qmlContext(this)->contextProperty("styledItem").value<UCListItem*>(); |
4436 | + // get the flickable value |
4437 | + if (m_listItem) { |
4438 | + m_flickable = UCListItemPrivate::get(m_listItem)->flickable.data(); |
4439 | + } |
4440 | } |
4441 | |
4442 | void UCListItemStyle::componentComplete() |
4443 | { |
4444 | QQuickItem::componentComplete(); |
4445 | |
4446 | - // look for overridden slots |
4447 | - for (int i = metaObject()->methodOffset(); i < metaObject()->methodCount(); i++) { |
4448 | - const QMetaMethod method = metaObject()->method(i); |
4449 | - if (method.name() == QByteArrayLiteral("swipeEvent")) { |
4450 | - m_swipeEvent = method; |
4451 | - } else if (method.name() == QByteArrayLiteral("rebound")) { |
4452 | - m_rebound = method; |
4453 | - } |
4454 | - } |
4455 | + // look for overridden slots, indexOfMethod returns th elast index of the overridden method |
4456 | + m_rebound = metaObject()->method(metaObject()->indexOfMethod("rebound()")); |
4457 | + m_swipeEvent = metaObject()->method(metaObject()->indexOfMethod("swipeEvent(QVariant)")); |
4458 | +// qDebug() << m_rebound.isValid() << m_swipeEvent.isValid(); |
4459 | +// for (int i = metaObject()->methodOffset(); i < metaObject()->methodCount(); i++) { |
4460 | +// const QMetaMethod method = metaObject()->method(i); |
4461 | +// if (method.name() == QByteArrayLiteral("swipeEvent")) { |
4462 | +// qDebug() << method.methodSignature(); |
4463 | +// m_swipeEvent = method; |
4464 | +// } else if (method.name() == QByteArrayLiteral("rebound")) { |
4465 | +// m_rebound = method; |
4466 | +// } |
4467 | +// } |
4468 | |
4469 | // connect snapAnimation's stopped() and the owning ListItem's contentMovementeEnded() signals |
4470 | if (m_listItem && m_snapAnimation) { |
4471 | @@ -92,6 +102,25 @@ |
4472 | } |
4473 | |
4474 | /*! |
4475 | + * \qmlproperty Flickable ListItemStyle::flickable |
4476 | + * \readonly |
4477 | + * \since Ubuntu.Components.Styles 1.3 |
4478 | + * The property holds the Flickable (or ListView) holding the ListItem styled. |
4479 | + */ |
4480 | +QQuickFlickable *UCListItemStyle::flickable() |
4481 | +{ |
4482 | + return m_flickable; |
4483 | +} |
4484 | +void UCListItemStyle::updateFlickable(QQuickFlickable *flickable) |
4485 | +{ |
4486 | + if (m_flickable == flickable) { |
4487 | + return; |
4488 | + } |
4489 | + m_flickable = flickable; |
4490 | + Q_EMIT flickableChanged(); |
4491 | +} |
4492 | + |
4493 | +/*! |
4494 | * \qmlmethod ListItemStyle::swipeEvent(SwipeEvent event) |
4495 | * The function is called by the ListItem when a swipe action is performed, i.e. |
4496 | * when the swipe is started, the position is updated or the swipe ends. The |
4497 | |
4498 | === modified file 'src/Ubuntu/Components/plugin/uclistitemstyle.h' |
4499 | --- src/Ubuntu/Components/plugin/uclistitemstyle.h 2015-04-13 13:42:03 +0000 |
4500 | +++ src/Ubuntu/Components/plugin/uclistitemstyle.h 2015-09-08 04:09:38 +0000 |
4501 | @@ -62,6 +62,7 @@ |
4502 | class QQuickPropertyAnimation; |
4503 | class QQuickBehavior; |
4504 | class UCListItem; |
4505 | +class QQuickFlickable; |
4506 | class UCListItemStyle : public QQuickItem |
4507 | { |
4508 | Q_OBJECT |
4509 | @@ -70,6 +71,7 @@ |
4510 | Q_PROPERTY(bool animatePanels READ animatePanels NOTIFY animatePanelsChanged) |
4511 | Q_PROPERTY(QQuickItem *dragPanel MEMBER m_dragPanel NOTIFY dragPanelChanged) |
4512 | Q_PROPERTY(int listItemIndex READ index NOTIFY listItemIndexChanged FINAL REVISION 1) |
4513 | + Q_PROPERTY(QQuickFlickable *flickable READ flickable NOTIFY flickableChanged REVISION 1) |
4514 | public: |
4515 | explicit UCListItemStyle(QQuickItem *parent = 0); |
4516 | |
4517 | @@ -78,6 +80,8 @@ |
4518 | bool animatePanels() const; |
4519 | void setAnimatePanels(bool animate); |
4520 | int index(); |
4521 | + QQuickFlickable *flickable(); |
4522 | + void updateFlickable(QQuickFlickable *flickable); |
4523 | |
4524 | Q_SIGNALS: |
4525 | void snapAnimationChanged(); |
4526 | @@ -85,6 +89,7 @@ |
4527 | void animatePanelsChanged(); |
4528 | void dragPanelChanged(); |
4529 | Q_REVISION(1) void listItemIndexChanged(); |
4530 | + Q_REVISION(1) void flickableChanged(); |
4531 | |
4532 | public Q_SLOTS: |
4533 | void swipeEvent(UCSwipeEvent *event); |
4534 | @@ -102,6 +107,7 @@ |
4535 | QQuickAbstractAnimation *m_snapAnimation; |
4536 | QQuickPropertyAnimation *m_dropAnimation; |
4537 | QQuickItem *m_dragPanel; |
4538 | + QQuickFlickable *m_flickable; |
4539 | bool m_animatePanels:1; |
4540 | |
4541 | friend class UCListItemPrivate; |
4542 | |
4543 | === modified file 'src/Ubuntu/Components/plugin/ucqquickimageextension.cpp' |
4544 | --- src/Ubuntu/Components/plugin/ucqquickimageextension.cpp 2014-11-24 13:14:35 +0000 |
4545 | +++ src/Ubuntu/Components/plugin/ucqquickimageextension.cpp 2015-09-08 04:09:38 +0000 |
4546 | @@ -19,6 +19,7 @@ |
4547 | #include <QtCore/QFile> |
4548 | #include <QtCore/QFileInfo> |
4549 | #include <QtCore/QDir> |
4550 | +#include <QtGui/QGuiApplication> |
4551 | #include <QtQuick/private/qquickimagebase_p.h> |
4552 | |
4553 | #include "ucqquickimageextension.h" |
4554 | @@ -78,8 +79,18 @@ |
4555 | QString selectedFilePath = resolved.mid(separatorPosition+1); |
4556 | |
4557 | if (scaleFactor == "1") { |
4558 | - // No scaling. Just pass the file as is. |
4559 | - m_image->setSource(QUrl::fromLocalFile(selectedFilePath)); |
4560 | + if (qFuzzyCompare(qGuiApp->devicePixelRatio(), (qreal)1.0) |
4561 | + || selectedFilePath.endsWith(".svg") || selectedFilePath.endsWith(".svgz")) { |
4562 | + // No scaling necessary. Just pass the file as is. |
4563 | + m_image->setSource(QUrl::fromLocalFile(selectedFilePath)); |
4564 | + } else { |
4565 | + // Need to scale the pixel-based image to suit the devicePixelRatio setting ourselves. |
4566 | + // If we let Qt do it, Qt will not choose the UITK-supported "@gu" scaled images. |
4567 | + m_image->setSource(QUrl("image://scaling/1/" + selectedFilePath)); |
4568 | + // explicitly set the source size in the QQuickImageBase, this persuades it that the |
4569 | + // supplied image is suitable for the current devicePixelRatio. |
4570 | + m_image->setSourceSize(m_image->sourceSize()); |
4571 | + } |
4572 | } else { |
4573 | // Prepend "image://scaling" for the image to be loaded by UCScalingImageProvider. |
4574 | if (!m_source.path().endsWith(".sci")) { |
4575 | @@ -100,7 +111,13 @@ |
4576 | rewrittenSciFile->setFileTemplate(QDir::tempPath() + QDir::separator() + "XXXXXX.sci"); |
4577 | rewrittenSciFile->open(); |
4578 | QTextStream output(rewrittenSciFile); |
4579 | - rewritten = rewriteSciFile(selectedFilePath, scaleFactor, output); |
4580 | + |
4581 | + if (qFuzzyCompare(qGuiApp->devicePixelRatio(), (qreal)1.0)) { |
4582 | + rewritten = rewriteSciFile(selectedFilePath, scaleFactor, output); |
4583 | + } else { |
4584 | + QString scaleFactorInDevicePixels = QString::number(scaleFactor.toFloat() / qGuiApp->devicePixelRatio()); |
4585 | + rewritten = rewriteSciFile(selectedFilePath, scaleFactorInDevicePixels, output); |
4586 | + } |
4587 | rewrittenSciFile->close(); |
4588 | |
4589 | s_rewrittenSciFiles.insert(m_source, QSharedPointer<QTemporaryFile>(rewrittenSciFile)); |
4590 | @@ -112,6 +129,9 @@ |
4591 | m_image->setSource(m_source); |
4592 | } |
4593 | } |
4594 | + // explicitly set the source size in the QQuickImageBase, this persuades it that the |
4595 | + // supplied image is suitable for the current devicePixelRatio. |
4596 | + m_image->setSourceSize(m_image->sourceSize()); |
4597 | } |
4598 | } |
4599 | |
4600 | |
4601 | === modified file 'src/Ubuntu/Components/plugin/ucstatesaver.cpp' |
4602 | --- src/Ubuntu/Components/plugin/ucstatesaver.cpp 2015-07-22 14:35:48 +0000 |
4603 | +++ src/Ubuntu/Components/plugin/ucstatesaver.cpp 2015-09-08 04:09:38 +0000 |
4604 | @@ -147,7 +147,7 @@ |
4605 | * \instantiates UCStateSaverAttached |
4606 | * \inqmlmodule Ubuntu.Components 1.1 |
4607 | * \ingroup ubuntu-services |
4608 | - * \brief Attached propertyes to save component property states. |
4609 | + * \brief Attached properties to save component property states. |
4610 | * |
4611 | * StateSaver attached object provides the ability to save component property values |
4612 | * that can be restored after an inproper application close. The properties subject |
4613 | @@ -297,7 +297,7 @@ |
4614 | * List of properties to be serialized, separated with commas. Properties must be |
4615 | * writable and can only be \l{http://qt-project.org/doc/qt-5.0/qtqml/qtqml-typesystem-basictypes.html}{QML base types}. |
4616 | * |
4617 | - * A custom singl eline input which saves the text, polaceholderText, font and color would look as follows: |
4618 | + * A custom single line input which saves the text, placeholderText, font and color would look as follows: |
4619 | * \qml |
4620 | * TextField { |
4621 | * id: input |
4622 | |
4623 | === modified file 'src/Ubuntu/Components/plugin/ucubuntushape.cpp' |
4624 | --- src/Ubuntu/Components/plugin/ucubuntushape.cpp 2015-08-24 20:49:41 +0000 |
4625 | +++ src/Ubuntu/Components/plugin/ucubuntushape.cpp 2015-09-08 04:09:38 +0000 |
4626 | @@ -318,10 +318,7 @@ |
4627 | setFlag(ItemHasContents); |
4628 | QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), this, |
4629 | SLOT(_q_gridUnitChanged())); |
4630 | - const float gridUnit = UCUnits::instance().gridUnit(); |
4631 | - setImplicitWidth(implicitWidthGU * gridUnit); |
4632 | - setImplicitHeight(implicitHeightGU * gridUnit); |
4633 | - update(); |
4634 | + _q_gridUnitChanged(); |
4635 | } |
4636 | |
4637 | /*! \qmlproperty string UbuntuShape::radius |
4638 | @@ -803,9 +800,11 @@ |
4639 | */ |
4640 | void UCUbuntuShape::setColor(const QColor& color) |
4641 | { |
4642 | - if (QuickUtils::showDeprecationWarnings()) { |
4643 | - qmlInfo(this) << "'color' is deprecated. Use 'backgroundColor', 'secondaryBackgroundColor' and " |
4644 | - "'backgroundMode' instead."; |
4645 | + static bool loggedOnce = false; |
4646 | + if (!loggedOnce) { |
4647 | + loggedOnce = true; |
4648 | + qmlInfo(this) << "'color' is deprecated. Use 'backgroundColor', 'secondaryBackgroundColor' " |
4649 | + "and 'backgroundMode' instead."; |
4650 | } |
4651 | |
4652 | if (!(m_flags & BackgroundApiSet)) { |
4653 | @@ -834,7 +833,9 @@ |
4654 | */ |
4655 | void UCUbuntuShape::setGradientColor(const QColor& gradientColor) |
4656 | { |
4657 | - if (QuickUtils::showDeprecationWarnings()) { |
4658 | + static bool loggedOnce = false; |
4659 | + if (!loggedOnce) { |
4660 | + loggedOnce = true; |
4661 | qmlInfo(this) << "'gradientColor' is deprecated. Use 'backgroundColor', " |
4662 | "'secondaryBackgroundColor' and 'backgroundMode' instead."; |
4663 | } |
4664 | @@ -863,7 +864,9 @@ |
4665 | */ |
4666 | void UCUbuntuShape::setImage(const QVariant& image) |
4667 | { |
4668 | - if (QuickUtils::showDeprecationWarnings()) { |
4669 | + static bool loggedOnce = false; |
4670 | + if (!loggedOnce) { |
4671 | + loggedOnce = true; |
4672 | qmlInfo(this) << "'image' is deprecated. Use 'source' instead."; |
4673 | } |
4674 | |
4675 | @@ -894,7 +897,9 @@ |
4676 | // maintain it for a while for compatibility reasons. |
4677 | void UCUbuntuShape::setStretched(bool stretched) |
4678 | { |
4679 | - if (QuickUtils::showDeprecationWarnings()) { |
4680 | + static bool loggedOnce = false; |
4681 | + if (!loggedOnce) { |
4682 | + loggedOnce = true; |
4683 | qmlInfo(this) << "'stretched' is deprecated. Use 'sourceFillMode' instead"; |
4684 | } |
4685 | |
4686 | @@ -915,8 +920,11 @@ |
4687 | // Deprecation layer. Same comment as setStretched(). |
4688 | void UCUbuntuShape::setHorizontalAlignment(HAlignment horizontalAlignment) |
4689 | { |
4690 | - if (QuickUtils::showDeprecationWarnings()) { |
4691 | - qmlInfo(this) << "'horizontalAlignment' is deprecated. Use 'sourceHorizontalAlignment' instead"; |
4692 | + static bool loggedOnce = false; |
4693 | + if (!loggedOnce) { |
4694 | + loggedOnce = true; |
4695 | + qmlInfo(this) << "'horizontalAlignment' is deprecated. Use 'sourceHorizontalAlignment' " |
4696 | + "instead"; |
4697 | } |
4698 | |
4699 | if (!(m_flags & SourceApiSet)) { |
4700 | @@ -932,8 +940,11 @@ |
4701 | // Deprecation layer. Same comment as setStretched(). |
4702 | void UCUbuntuShape::setVerticalAlignment(VAlignment verticalAlignment) |
4703 | { |
4704 | - if (QuickUtils::showDeprecationWarnings()) { |
4705 | - qmlInfo(this) << "'horizontalAlignment' is deprecated. Use 'sourceVerticalAlignment' instead"; |
4706 | + static bool loggedOnce = false; |
4707 | + if (!loggedOnce) { |
4708 | + loggedOnce = true; |
4709 | + qmlInfo(this) << "'horizontalAlignment' is deprecated. Use 'sourceVerticalAlignment' " |
4710 | + "instead"; |
4711 | } |
4712 | |
4713 | if (!(m_flags & SourceApiSet)) { |
4714 | @@ -1009,20 +1020,11 @@ |
4715 | updateFromImageProperties(qobject_cast<QQuickItem*>(sender())); |
4716 | } |
4717 | |
4718 | -void UCUbuntuShape::_q_openglContextDestroyed() |
4719 | -{ |
4720 | - // Delete the shape textures that are stored per context and shared by all the shape items. |
4721 | - const int index = getShapeTexturesIndex(qobject_cast<QOpenGLContext*>(sender())); |
4722 | - Q_ASSERT(index >= 0); |
4723 | - shapeTextures[index].openglContext = NULL; |
4724 | - glDeleteTextures(shapeTextureCount, shapeTextures[index].textureId); |
4725 | -} |
4726 | - |
4727 | void UCUbuntuShape::_q_gridUnitChanged() |
4728 | { |
4729 | - const float gridUnit = UCUnits::instance().gridUnit(); |
4730 | - setImplicitWidth(implicitWidthGU * gridUnit); |
4731 | - setImplicitHeight(implicitHeightGU * gridUnit); |
4732 | + const float gridUnitInDevicePixels = UCUnits::instance().gridUnit() / qGuiApp->devicePixelRatio(); |
4733 | + setImplicitWidth(implicitWidthGU * gridUnitInDevicePixels); |
4734 | + setImplicitHeight(implicitHeightGU * gridUnitInDevicePixels); |
4735 | update(); |
4736 | } |
4737 | |
4738 | @@ -1170,8 +1172,10 @@ |
4739 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shapeTextureSize, shapeTextureSize, 0, GL_RGBA, |
4740 | GL_UNSIGNED_BYTE, shapeTextureData[i]); |
4741 | } |
4742 | - QObject::connect(openglContext, SIGNAL(aboutToBeDestroyed()), this, |
4743 | - SLOT(_q_openglContextDestroyed()), Qt::DirectConnection); |
4744 | + connect(openglContext, &QOpenGLContext::aboutToBeDestroyed, [index] { |
4745 | + shapeTextures[index].openglContext = NULL; |
4746 | + glDeleteTextures(shapeTextureCount, shapeTextures[index].textureId); |
4747 | + } ); |
4748 | } |
4749 | const quint32 shapeTextureId = shapeTextures[index].textureId[m_aspect != DropShadow ? 0 : 1]; |
4750 | |
4751 | @@ -1184,13 +1188,15 @@ |
4752 | sourceTextureRect = sourceTexture->normalizedTextureSubRect(); |
4753 | } |
4754 | if (m_flags & DirtySourceTransform) { |
4755 | + const float dpr = qGuiApp->devicePixelRatio(); |
4756 | + |
4757 | if (m_flags & SourceApiSet) { |
4758 | - updateSourceTransform(itemSize.width(), itemSize.height(), m_sourceFillMode, |
4759 | + updateSourceTransform(itemSize.width() * dpr, itemSize.height() * dpr, m_sourceFillMode, |
4760 | m_sourceHorizontalAlignment, m_sourceVerticalAlignment, |
4761 | sourceTexture->textureSize()); |
4762 | } else { |
4763 | FillMode imageFillMode = (m_flags & Stretched) ? Stretch : PreserveAspectCrop; |
4764 | - updateSourceTransform(itemSize.width(), itemSize.height(), imageFillMode, |
4765 | + updateSourceTransform(itemSize.width() * dpr, itemSize.height() * dpr, imageFillMode, |
4766 | m_imageHorizontalAlignment, m_imageVerticalAlignment, |
4767 | sourceTexture->textureSize()); |
4768 | } |
4769 | @@ -1220,13 +1226,15 @@ |
4770 | // accordingly. The shape was using a fixed image for the corner before switching to a |
4771 | // distance field, since the corner wasn't taking the whole image (ending at ~80%) we need |
4772 | // to take that into account when the size is scaled down. |
4773 | - radius = UCUnits::instance().gridUnit() * radiusGuMap[m_radius]; |
4774 | + radius = UCUnits::instance().gridUnit() * radiusGuMap[m_radius] |
4775 | + / qGuiApp->devicePixelRatio(); |
4776 | const float scaledDownRadius = qMin(itemSize.width(), itemSize.height()) * 0.5f * 0.8f; |
4777 | if (radius > scaledDownRadius) { |
4778 | radius = scaledDownRadius; |
4779 | } |
4780 | } else { |
4781 | - radius = qMin(itemSize.width(), itemSize.height()) * 0.5f * (m_relativeRadius * 0.01f); |
4782 | + radius = qMin(itemSize.width(), itemSize.height()) * 0.5f * (m_relativeRadius * 0.01f) |
4783 | + / qGuiApp->devicePixelRatio(); |
4784 | } |
4785 | |
4786 | updateMaterial(node, radius, shapeTextureId, sourceTexture && m_sourceOpacity); |
4787 | @@ -1306,16 +1314,19 @@ |
4788 | materialData->sourceOpacity = 0; |
4789 | } |
4790 | |
4791 | + const float physicalRadius = radius * qGuiApp->devicePixelRatio(); |
4792 | + |
4793 | // Mapping of radius size range from [0, 4] to [0, 1] with clamping, plus quantization. |
4794 | const float start = 0.0f + radiusSizeOffset; |
4795 | const float end = 4.0f + radiusSizeOffset; |
4796 | + |
4797 | materialData->distanceAAFactor = |
4798 | - qMin((radius / (end - start)) - (start / (end - start)), 1.0f) * 255.0f; |
4799 | + qMin((physicalRadius / (end - start)) - (start / (end - start)), 1.0f) * 255.0f; |
4800 | |
4801 | // When the radius is equal to radiusSizeOffset (which means radius size is 0), no aspect is |
4802 | // flagged so that a dedicated (statically flow controlled) shaved off shader can be used for |
4803 | // optimal performance. |
4804 | - if (radius > radiusSizeOffset) { |
4805 | + if (physicalRadius > radiusSizeOffset) { |
4806 | const quint8 aspectFlags[] = { |
4807 | ShapeMaterial::Data::Flat, ShapeMaterial::Data::Inset, ShapeMaterial::Data::DropShadow, |
4808 | ShapeMaterial::Data::Inset | ShapeMaterial::Data::Pressed |
4809 | |
4810 | === modified file 'src/Ubuntu/Components/plugin/ucubuntushape.h' |
4811 | --- src/Ubuntu/Components/plugin/ucubuntushape.h 2015-08-06 13:16:24 +0000 |
4812 | +++ src/Ubuntu/Components/plugin/ucubuntushape.h 2015-09-08 04:09:38 +0000 |
4813 | @@ -296,7 +296,6 @@ |
4814 | |
4815 | private Q_SLOTS: |
4816 | void _q_imagePropertiesChanged(); |
4817 | - void _q_openglContextDestroyed(); |
4818 | void _q_gridUnitChanged(); |
4819 | void _q_providerDestroyed(QObject* object=0); |
4820 | void _q_textureChanged(); |
4821 | |
4822 | === modified file 'src/Ubuntu/Components/plugin/ucunits.cpp' |
4823 | --- src/Ubuntu/Components/plugin/ucunits.cpp 2015-03-03 13:47:48 +0000 |
4824 | +++ src/Ubuntu/Components/plugin/ucunits.cpp 2015-09-08 04:09:38 +0000 |
4825 | @@ -24,6 +24,8 @@ |
4826 | #include <QtCore/QDir> |
4827 | #include <QtCore/QRegularExpression> |
4828 | #include <QtCore/qmath.h> |
4829 | +#include <QtGui/QGuiApplication> |
4830 | +#include <QtGui/QScreen> |
4831 | |
4832 | #define ENV_GRID_UNIT_PX "GRID_UNIT_PX" |
4833 | #define DEFAULT_GRID_UNIT_PX 8 |
4834 | @@ -62,10 +64,46 @@ |
4835 | |
4836 | \sa {Resolution Independence} |
4837 | */ |
4838 | + |
4839 | +/* |
4840 | + * Note on the interaction between GRID_UNIT_PX and QT_DEVICE_PIXEL_RATIO |
4841 | + * |
4842 | + * In Qt5.4 there is a single means to scale the UI: the QT_DEVICE_PIXEL_RATIO environment |
4843 | + * variable. This accepts only integer values, thus allowing a x2 or x3 scaling of any |
4844 | + * Qt-based UI, that includes QWidget as well as any QML UI. |
4845 | + * |
4846 | + * Setting QT_DEVICE_PIXEL_RATIO=2 implies one density-independent pixel corresponds to 2 |
4847 | + * physical pixels. Developers describe their UI in terms of density-independent pixels. |
4848 | + * Qt scales accordingly. |
4849 | + * |
4850 | + * The Ubuntu UI Toolkit has solved the scaling problem with the GRID_UNIT_PX variable. |
4851 | + * It offers more flexibility, but only scales QML applications written to use the UITK |
4852 | + * (since it uses this Units class) as it is built on top of QML. |
4853 | + * |
4854 | + * There are additional areas in Qt where QT_DEVICE_PIXEL_RATIO causes correct scaling which |
4855 | + * GRID_UNIT_PX cannot, for example: |
4856 | + * 1. cacheBuffer for ListView/GridViews - specified in density-independent pixels |
4857 | + * 2. gesture recognition matches what is on screen better, as it is density-independent |
4858 | + * pixel aware |
4859 | + * |
4860 | + * In order to get the best of both worlds, Ubuntu will set both GRID_UNIT_PX and |
4861 | + * QT_DEVICE_PIXEL_RATIO. Thus all Qt apps will scale reasonably well, with UITK-based apps |
4862 | + * scaling perfectly for any desired scale (i.e. non-integer scales). |
4863 | + * |
4864 | + * However UITK developers can just use this Units class as usual, and will be almost totally |
4865 | + * isolated from Qt's own scaling concept. |
4866 | + */ |
4867 | + |
4868 | UCUnits::UCUnits(QObject *parent) : |
4869 | - QObject(parent) |
4870 | + QObject(parent), |
4871 | + m_devicePixelRatio(qGuiApp->devicePixelRatio()) |
4872 | { |
4873 | - m_gridUnit = getenvFloat(ENV_GRID_UNIT_PX, DEFAULT_GRID_UNIT_PX); |
4874 | + // If GRID_UNIT_PX set, always use it. If not, 1GU := DEFAULT_GRID_UNIT_PX * m_devicePixelRatio |
4875 | + if (qEnvironmentVariableIsSet(ENV_GRID_UNIT_PX)) { |
4876 | + m_gridUnit = getenvFloat(ENV_GRID_UNIT_PX, DEFAULT_GRID_UNIT_PX); |
4877 | + } else { |
4878 | + m_gridUnit = DEFAULT_GRID_UNIT_PX * m_devicePixelRatio; |
4879 | + } |
4880 | } |
4881 | |
4882 | /*! |
4883 | @@ -89,14 +127,15 @@ |
4884 | |
4885 | Returns the number of pixels \a value density independent pixels correspond to. |
4886 | */ |
4887 | +// Density-independent pixels (and not physical pixels) because Qt sizes in terms of density-independent pixels. |
4888 | float UCUnits::dp(float value) |
4889 | { |
4890 | const float ratio = m_gridUnit / DEFAULT_GRID_UNIT_PX; |
4891 | if (value <= 2.0) { |
4892 | // for values under 2dp, return only multiples of the value |
4893 | - return qRound(value * qFloor(ratio)); |
4894 | + return qRound(value * qFloor(ratio)) / m_devicePixelRatio; |
4895 | } else { |
4896 | - return qRound(value * ratio); |
4897 | + return qRound(value * ratio) / m_devicePixelRatio; |
4898 | } |
4899 | } |
4900 | |
4901 | @@ -105,9 +144,11 @@ |
4902 | |
4903 | Returns the number of pixels \a value grid units correspond to. |
4904 | */ |
4905 | +// Density-independent pixels (and not physical pixels) because Qt sizes in terms of density-independent pixels. |
4906 | + |
4907 | float UCUnits::gu(float value) |
4908 | { |
4909 | - return qRound(value * m_gridUnit); |
4910 | + return qRound(value * m_gridUnit) / m_devicePixelRatio; |
4911 | } |
4912 | |
4913 | QString UCUnits::resolveResource(const QUrl& url) |
4914 | |
4915 | === modified file 'src/Ubuntu/Components/plugin/ucunits.h' |
4916 | --- src/Ubuntu/Components/plugin/ucunits.h 2013-10-18 08:56:39 +0000 |
4917 | +++ src/Ubuntu/Components/plugin/ucunits.h 2015-09-08 04:09:38 +0000 |
4918 | @@ -53,6 +53,7 @@ |
4919 | float gridUnitSuffixFromFileName(const QString &fileName); |
4920 | |
4921 | private: |
4922 | + float m_devicePixelRatio; |
4923 | float m_gridUnit; |
4924 | }; |
4925 | |
4926 | |
4927 | === modified file 'src/Ubuntu/Components/plugin/ucviewitemsattached.cpp' |
4928 | --- src/Ubuntu/Components/plugin/ucviewitemsattached.cpp 2015-03-17 16:48:59 +0000 |
4929 | +++ src/Ubuntu/Components/plugin/ucviewitemsattached.cpp 2015-09-08 04:09:38 +0000 |
4930 | @@ -104,6 +104,7 @@ |
4931 | : QObjectPrivate() |
4932 | , listView(0) |
4933 | , dragArea(0) |
4934 | + , expansionFlags(UCViewItemsAttached::Exclusive) |
4935 | , globalDisabled(false) |
4936 | , selectable(false) |
4937 | , draggable(false) |
4938 | @@ -556,7 +557,7 @@ |
4939 | return; |
4940 | } |
4941 | dragArea = new ListItemDragArea(listView); |
4942 | - dragArea->init(); |
4943 | + dragArea->init(q_func()); |
4944 | } |
4945 | |
4946 | void UCViewItemsAttachedPrivate::leaveDragMode() |
4947 | @@ -611,3 +612,142 @@ |
4948 | Q_EMIT q->selectedIndicesChanged(); |
4949 | } |
4950 | } |
4951 | + |
4952 | + |
4953 | +UCViewItemsAttached13::UCViewItemsAttached13(QObject *owner) |
4954 | + : UCViewItemsAttached(owner) |
4955 | +{ |
4956 | + d_ptr = UCViewItemsAttachedPrivate::get(this); |
4957 | +} |
4958 | + |
4959 | +UCViewItemsAttached13 *UCViewItemsAttached13::qmlAttachedProperties(QObject *owner) |
4960 | +{ |
4961 | + return new UCViewItemsAttached13(owner); |
4962 | +} |
4963 | + |
4964 | +/*! |
4965 | + * \qmlattachedproperty list<int> ViewItems::expandedIndices |
4966 | + * \since Ubuntu.Components 1.3 |
4967 | + * The property contains the indexes of the ListItems marked as expanded. The |
4968 | + * indexes are model indexes when used in ListView, and child indexes in other |
4969 | + * components. The property being writable, initial expansion configuration |
4970 | + * can be provided for a view, and provides ability to save the expansion state. |
4971 | + * \note If the \l ViewItems::expansionFlags is having \c ViewItems.Exclusive |
4972 | + * flags set, only the last item from the list will be considered and set as |
4973 | + * expanded. |
4974 | + */ |
4975 | +QList<int> UCViewItemsAttached13::expandedIndices() const |
4976 | +{ |
4977 | + Q_D(const UCViewItemsAttached); |
4978 | + return d->expansionList.keys(); |
4979 | +} |
4980 | +void UCViewItemsAttached13::setExpandedIndices(QList<int> indices) |
4981 | +{ |
4982 | + Q_UNUSED(indices); |
4983 | + Q_D(UCViewItemsAttached); |
4984 | + d->collapseAll(); |
4985 | + if (indices.size() > 0) { |
4986 | + if (d->expansionFlags & UCViewItemsAttached::Exclusive) { |
4987 | + // take only the last one from the list |
4988 | + d->expand(indices.last(), QPointer<UCListItem13>(), false); |
4989 | + } else { |
4990 | + for (int i = 0; i < indices.size(); i++) { |
4991 | + d->expand(indices[i], QPointer<UCListItem13>(), false); |
4992 | + } |
4993 | + } |
4994 | + } |
4995 | + Q_EMIT expandedIndicesChanged(d->expansionList.keys()); |
4996 | +} |
4997 | + |
4998 | +// insert listItem into the expanded indices map |
4999 | +void UCViewItemsAttachedPrivate::expand(int index, UCListItem13 *listItem, bool emitChangeSignal) |
5000 | +{ |
The diff has been truncated for viewing.