on xenial help sign in
Merge new-header.
43bbdfbMichał Sawicz
qml/Components/PageHeader.qml+47−55
@@ -19,18 +19,18 @@ import Ubuntu.Components 1.1
19import Ubuntu.Components.Themes.Ambiance 1.1
19import Ubuntu.Components.Themes.Ambiance 1.1
20import Ubuntu.Components.Popups 1.0
20import Ubuntu.Components.Popups 1.0
21import Ubuntu.Components.ListItems 1.0
21import Ubuntu.Components.ListItems 1.0
22+import "SearchHistoryModel"
22
23
23Item {
24Item {
24 id: root
25 id: root
25 implicitHeight: headerContainer.height + units.gu(2) + bottomContainer.height
26 implicitHeight: headerContainer.height + units.gu(2) + bottomContainer.height
26− height: implicitHeight
27
27
28 property bool showBackButton: false
28 property bool showBackButton: false
29 property string title
29 property string title
30 property string imageSource
30 property string imageSource
31
31
32 property bool searchEntryEnabled: false
32 property bool searchEntryEnabled: false
33− property ListModel searchHistory
33+ property ListModel searchHistory: SearchHistoryModel
34 property alias searchQuery: searchTextField.text
34 property alias searchQuery: searchTextField.text
35 property bool searchInProgress: false
35 property bool searchInProgress: false
36
36
@@ -43,18 +43,14 @@ Item {
43 signal backClicked()
43 signal backClicked()
44
44
45 function triggerSearch() {
45 function triggerSearch() {
46− if (searchEntryEnabled) searchTextField.forceActiveFocus()
46+ if (searchEntryEnabled) searchTextField.forceActiveFocus();
47 }
47 }
48
48
49− function resetSearch(unfocusField) {
49+ function resetSearch(keepFocus) {
50− if (unfocusField == undefined) {
51− unfocusField = true;
52− }
53−
54 if (searchHistory) {
50 if (searchHistory) {
55 searchHistory.addQuery(searchTextField.text);
51 searchHistory.addQuery(searchTextField.text);
56 }
52 }
57− if (unfocusField) {
53+ if (!keepFocus) {
58 unfocus();
54 unfocus();
59 }
55 }
60 searchTextField.text = "";
56 searchTextField.text = "";
@@ -65,27 +61,38 @@ Item {
65
61
66 function unfocus() {
62 function unfocus() {
67 searchTextField.focus = false;
63 searchTextField.focus = false;
64+ if (!searchTextField.text) {
65+ headerContainer.showSearch = false;
66+ }
68 }
67 }
69
68
70 function openSearchHistory() {
69 function openSearchHistory() {
71 if (openSearchAnimation.running) {
70 if (openSearchAnimation.running) {
72− openSearchAnimation.openSearchHistory = true
71+ openSearchAnimation.openSearchHistory = true;
73 } else if (root.searchHistory.count > 0 && headerContainer.popover == null) {
72 } else if (root.searchHistory.count > 0 && headerContainer.popover == null) {
74 headerContainer.popover = PopupUtils.open(popoverComponent, searchTextField,
73 headerContainer.popover = PopupUtils.open(popoverComponent, searchTextField,
75− {
74+ {
76− "contentWidth": searchTextField.width,
75+ "contentWidth": searchTextField.width,
77− "edgeMargins": units.gu(1)
76+ "edgeMargins": units.gu(1)
78− }
77+ }
79− )
78+ );
80 }
79 }
81 }
80 }
82
81
83 onImageSourceChanged: {
82 onImageSourceChanged: {
84− if (imageSource.length > 0) {
83+ if (imageSource) {
85 header.contents = imageComponent.createObject();
84 header.contents = imageComponent.createObject();
86 } else {
85 } else {
87 header.contents.destroy();
86 header.contents.destroy();
88− header.contents = null
87+ header.contents = null;
88+ }
89+ }
90+
91+ InverseMouseArea {
92+ anchors.fill: parent
93+ visible: headerContainer.popover !== null
94+ onPressed: {
95+ PopupUtils.close(headerContainer.popover);
89 }
96 }
90 }
97 }
91
98
@@ -110,7 +117,7 @@ Item {
110 onRunningChanged: {
117 onRunningChanged: {
111 if (!running && openSearchAnimation.openSearchHistory) {
118 if (!running && openSearchAnimation.openSearchHistory) {
112 openSearchAnimation.openSearchHistory = false;
119 openSearchAnimation.openSearchHistory = false;
113− root.openSearchHistory()
120+ root.openSearchHistory();
114 }
121 }
115 }
122 }
116 }
123 }
@@ -118,8 +125,7 @@ Item {
118
125
119 Column {
126 Column {
120 id: headersColumn
127 id: headersColumn
121− anchors.fill: parent
128+ anchors { left: parent.left; right: parent.right }
122− height: searchHeader.height + header.height
123
129
124 PageHeadStyle {
130 PageHeadStyle {
125 id: searchHeader
131 id: searchHeader
@@ -127,14 +133,15 @@ Item {
127 height: headerContainer.height
133 height: headerContainer.height
128 contentHeight: height
134 contentHeight: height
129 separatorSource: ""
135 separatorSource: ""
136+ // Required to keep PageHeadStyle noise down as it expects the Page's properties around.
130 property var styledItem: searchHeader
137 property var styledItem: searchHeader
131− property string title: "searchHeader"
138+ property string title
132 property var config: PageHeadConfiguration {
139 property var config: PageHeadConfiguration {
133 backAction: Action {
140 backAction: Action {
134 iconName: "back"
141 iconName: "back"
135 onTriggered: {
142 onTriggered: {
136− root.resetSearch(true)
143+ root.resetSearch();
137− headerContainer.showSearch = false
144+ headerContainer.showSearch = false;
138 }
145 }
139 }
146 }
140 }
147 }
@@ -142,7 +149,7 @@ Item {
142 id: searchTextField
149 id: searchTextField
143 hasClearButton: false
150 hasClearButton: false
144 anchors {
151 anchors {
145− fill: parent;
152+ fill: parent
146 leftMargin: units.gu(1)
153 leftMargin: units.gu(1)
147 topMargin: units.gu(1)
154 topMargin: units.gu(1)
148 bottomMargin: units.gu(1)
155 bottomMargin: units.gu(1)
@@ -160,6 +167,9 @@ Item {
160 source: "image://theme/clear"
167 source: "image://theme/clear"
161 opacity: searchTextField.text.length > 0 && !searchActivityIndicator.running
168 opacity: searchTextField.text.length > 0 && !searchActivityIndicator.running
162 visible: opacity > 0
169 visible: opacity > 0
170+ Behavior on opacity {
171+ UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
172+ }
163 }
173 }
164
174
165 ActivityIndicator {
175 ActivityIndicator {
@@ -175,14 +185,14 @@ Item {
175 }
185 }
176
186
177 onClicked: {
187 onClicked: {
178− root.resetSearch(false)
188+ root.resetSearch(true);
179− root.openSearchHistory()
189+ root.openSearchHistory();
180 }
190 }
181 }
191 }
182
192
183 onActiveFocusChanged: {
193 onActiveFocusChanged: {
184 if (activeFocus) {
194 if (activeFocus) {
185− root.openSearchHistory()
195+ root.openSearchHistory();
186 }
196 }
187 }
197 }
188 }
198 }
@@ -202,7 +212,7 @@ Item {
202 iconName: "back"
212 iconName: "back"
203 visible: root.showBackButton
213 visible: root.showBackButton
204 onTriggered: {
214 onTriggered: {
205− root.backClicked()
215+ root.backClicked();
206 }
216 }
207 }
217 }
208
218
@@ -211,8 +221,8 @@ Item {
211 iconName: "search"
221 iconName: "search"
212 visible: root.searchEntryEnabled
222 visible: root.searchEntryEnabled
213 onTriggered: {
223 onTriggered: {
214− headerContainer.showSearch = true
224+ headerContainer.showSearch = true;
215− searchTextField.forceActiveFocus()
225+ searchTextField.forceActiveFocus();
216 }
226 }
217 }
227 }
218 ]
228 ]
@@ -220,7 +230,7 @@ Item {
220
230
221 property var contents: null
231 property var contents: null
222 Component.onCompleted: {
232 Component.onCompleted: {
223− if (root.imageSource.length > 0) {
233+ if (root.imageSource) {
224 header.contents = imageComponent.createObject();
234 header.contents = imageComponent.createObject();
225 }
235 }
226 }
236 }
@@ -236,6 +246,7 @@ Item {
236 source: root.imageSource
246 source: root.imageSource
237 fillMode: Image.PreserveAspectFit
247 fillMode: Image.PreserveAspectFit
238 horizontalAlignment: Image.AlignLeft
248 horizontalAlignment: Image.AlignLeft
249+ sourceSize.height: height
239 }
250 }
240 }
251 }
241 }
252 }
@@ -247,29 +258,10 @@ Item {
247 id: popoverComponent
258 id: popoverComponent
248 Popover {
259 Popover {
249 id: popover
260 id: popover
261+ autoClose: false
250
262
251 Component.onDestruction: {
263 Component.onDestruction: {
252− headerContainer.popover = null
264+ headerContainer.popover = null;
253− }
254−
255− // FIXME: this should go into the first item below, but enable: false
256− // prevents mouse events propagation
257− AbstractButton {
258− anchors {
259− top: parent.top
260− right: parent.right
261− }
262− height: units.gu(6)
263− width: height
264−
265− onClicked: PopupUtils.close(popover)
266−
267− Image {
268− anchors.centerIn: parent
269− width: units.gu(2)
270− height: units.gu(2)
271− source: "../Dash/graphics/icon_listview_clear.png"
272− }
273 }
265 }
274
266
275 Column {
267 Column {
@@ -289,9 +281,9 @@ Item {
289 showDivider: index < recentSearches.count - 1
281 showDivider: index < recentSearches.count - 1
290 text: query
282 text: query
291 onClicked: {
283 onClicked: {
292− searchHistory.addQuery(text)
284+ searchHistory.addQuery(text);
293− searchTextField.text = text
285+ searchTextField.text = text;
294− PopupUtils.close(popover)
286+ PopupUtils.close(popover);
295 }
287 }
296 }
288 }
297 }
289 }
qml/Components/SearchHistoryModel.qml → qml/Components/SearchHistoryModel/SearchHistoryModel.qmlrenamed+1
@@ -14,6 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17+pragma Singleton
17import QtQuick 2.0
18import QtQuick 2.0
18
19
19// TODO sanitize input, move to persistent storage
20// TODO sanitize input, move to persistent storage
qml/Components/SearchHistoryModel/qmldirnew file+1
@@ -0,0 +1 @@
1+singleton SearchHistoryModel 1.0 SearchHistoryModel.qml
qml/Dash/Dash.qml−3
@@ -26,7 +26,6 @@ Showable {
26
26
27 visible: shown
27 visible: shown
28
28
29− property ListModel searchHistory: SearchHistoryModel {}
30 property bool searchable: !dashContent.previewOpen && !scopeItem.previewOpen
29 property bool searchable: !dashContent.previewOpen && !scopeItem.previewOpen
31
30
32 property string showScopeOnLoaded: "clickscope"
31 property string showScopeOnLoaded: "clickscope"
@@ -76,7 +75,6 @@ Showable {
76 height: parent.height
75 height: parent.height
77 model: filteredScopes
76 model: filteredScopes
78 scopes: scopes
77 scopes: scopes
79− searchHistory: dash.searchHistory
80 visible: x != -width
78 visible: x != -width
81 onGotoScope: {
79 onGotoScope: {
82 dash.setCurrentScope(scopeId, true, false);
80 dash.setCurrentScope(scopeId, true, false);
@@ -110,7 +108,6 @@ Showable {
110 anchors.left: dashContent.right
108 anchors.left: dashContent.right
111 width: parent.width
109 width: parent.width
112 height: parent.height
110 height: parent.height
113− searchHistory: dash.searchHistory
114 scale: dash.contentScale
111 scale: dash.contentScale
115 clip: scale != 1.0
112 clip: scale != 1.0
116 visible: scope != null
113 visible: scope != null
qml/Dash/DashContent.qml+1−4
@@ -15,7 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18−import Ubuntu.Components 1.1
18+import Ubuntu.Components 0.1
19import Unity 0.2
19import Unity 0.2
20import Utils 0.1
20import Utils 0.1
21import "../Components"
21import "../Components"
@@ -28,8 +28,6 @@ Item {
28 readonly property alias currentIndex: dashContentList.currentIndex
28 readonly property alias currentIndex: dashContentList.currentIndex
29 property alias previewOpen: previewListView.open
29 property alias previewOpen: previewListView.open
30
30
31− property ListModel searchHistory
32−
33 signal scopeLoaded(string scopeId)
31 signal scopeLoaded(string scopeId)
34 signal gotoScope(string scopeId)
32 signal gotoScope(string scopeId)
35 signal openScope(var scope)
33 signal openScope(var scope)
@@ -147,7 +145,6 @@ Item {
147
145
148 onLoaded: {
146 onLoaded: {
149 item.objectName = scope.id
147 item.objectName = scope.id
150− item.searchHistory = dashContent.searchHistory;
151 item.previewListView = previewListView;
148 item.previewListView = previewListView;
152 item.scope = Qt.binding(function() { return scope })
149 item.scope = Qt.binding(function() { return scope })
153 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
150 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
qml/Dash/GenericScopeView.qml+1−4
@@ -15,8 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18−import Ubuntu.Components 1.1
18+import Ubuntu.Components 0.1
19−import Ubuntu.Components.Themes.Ambiance 1.1
20import Utils 0.1
19import Utils 0.1
21import Unity 0.2
20import Unity 0.2
22import Unity.Application 0.1
21import Unity.Application 0.1
@@ -33,7 +32,6 @@ FocusScope {
33 property Item previewListView: null
32 property Item previewListView: null
34 property string title
33 property string title
35 property bool hasBackAction: false
34 property bool hasBackAction: false
36− property ListModel searchHistory
37 property bool enableHeightBehaviorOnNextCreation: false
35 property bool enableHeightBehaviorOnNextCreation: false
38 property var categoryView: categoryView
36 property var categoryView: categoryView
39 property color foregroundColor: scope && scope.customizations["foreground-color"] || "grey"
37 property color foregroundColor: scope && scope.customizations["foreground-color"] || "grey"
@@ -325,7 +323,6 @@ FocusScope {
325 id: pageHeader
323 id: pageHeader
326 width: parent.width
324 width: parent.width
327 title: scopeView.title
325 title: scopeView.title
328− searchHistory: scopeView.searchHistory
329 showBackButton: scopeView.hasBackAction
326 showBackButton: scopeView.hasBackAction
330 searchEntryEnabled: true
327 searchEntryEnabled: true
331 searchInProgress: scopeView.scope.searchInProgress
328 searchInProgress: scopeView.scope.searchInProgress
qml/Dash/PreviewListView.qml+1−1
@@ -15,7 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18−import Ubuntu.Components 1.1
18+import Ubuntu.Components 0.1
19import Unity 0.2
19import Unity 0.2
20import "../Components"
20import "../Components"
21import "Previews" as Previews
21import "Previews" as Previews
qml/Dash/ScopeItem.qml−3
@@ -25,8 +25,6 @@ Item {
25 property alias scope: scopeView.scope
25 property alias scope: scopeView.scope
26 property alias previewOpen: previewListView.open
26 property alias previewOpen: previewListView.open
27
27
28− property ListModel searchHistory
29−
30 signal back
28 signal back
31 signal gotoScope(string scopeId)
29 signal gotoScope(string scopeId)
32 signal openScope(var scope)
30 signal openScope(var scope)
@@ -50,7 +48,6 @@ Item {
50 isCurrent: scope != null
48 isCurrent: scope != null
51 title: scope ? scope.name : ""
49 title: scope ? scope.name : ""
52 hasBackAction: true
50 hasBackAction: true
53− searchHistory: root.searchHistory
54 previewListView: previewListView
51 previewListView: previewListView
55
52
56 onBackClicked: root.back();
53 onBackClicked: root.back();
qml/Dash/graphics/icon_listview_clear@20.pngdeleted

Binary file not shown.

qml/ScopeTool.qml−1
@@ -73,7 +73,6 @@ Rectangle {
73 id: dashContent
73 id: dashContent
74
74
75 model: filteredScopes
75 model: filteredScopes
76− searchHistory: SearchHistoryModel { }
77 property var scope: scopes.getScope(currentIndex)
76 property var scope: scopes.getScope(currentIndex)
78
77
79 anchors {
78 anchors {
tests/qmltests/Components/tst_PageHeader.qml+1−1
@@ -201,7 +201,6 @@ Item {
201 }
201 }
202
202
203 searchEntryEnabled: true
203 searchEntryEnabled: true
204− searchHistory: SearchHistoryModel {}
205 title: "%^$%^%^&%^&%^$%GHR%"
204 title: "%^$%^%^&%^&%^$%GHR%"
206 imageSource: showImageCheckBox.checked ? titleImageSource : ""
205 imageSource: showImageCheckBox.checked ? titleImageSource : ""
207 showBackButton: showBackButtonCheckBox.checked
206 showBackButton: showBackButtonCheckBox.checked
@@ -244,6 +243,7 @@ Item {
244 anchors.verticalCenter: parent.verticalCenter
243 anchors.verticalCenter: parent.verticalCenter
245 }
244 }
246 }
245 }
246+
247 Row {
247 Row {
248 spacing: units.gu(1)
248 spacing: units.gu(1)
249 anchors {
249 anchors {
tests/qmltests/Dash/tst_Dash.qml−21
@@ -70,27 +70,6 @@ Item {
70 ]
70 ]
71 }
71 }
72
72
73− function test_set_current_scope_data() {
74− return get_scope_data()
75− }
76−
77− function test_set_current_scope(data) {
78− // wait for scopes to load
79− tryCompare(scopes, "loaded", true);
80−
81− var tabbar = findChild(dash, "tabbar");
82− verify(tabbar != undefined)
83− var dashContent = findChild(dash, "dashContent");
84− var current_index = dashContent.currentIndex;
85−
86− dash.setCurrentScope(data.tag, true /* animate */, false /* reset */);
87− compare(dashContent.currentIndex, data.shouldBeVisible ? data.visualIndex : current_index);
88−
89− var dashContentList = findChild(dash, "dashContentList");
90− var expectedTitle = dashContentList.model.get(data.shouldBeVisible ? data.visualIndex : current_index).title
91− compare(tabbar.title, expectedTitle);
92− }
93−
94 function test_show_scope_on_load_data() {
73 function test_show_scope_on_load_data() {
95 return get_scope_data()
74 return get_scope_data()
96 }
75 }
tests/qmltests/Dash/tst_DashContent.qml−2
@@ -47,8 +47,6 @@ Item {
47 model: scopesModel
47 model: scopesModel
48 }
48 }
49 scopes : scopesModel
49 scopes : scopesModel
50−
51− searchHistory: SearchHistoryModel {}
52 }
50 }
53
51
54 SignalSpy {
52 SignalSpy {