18 import Ubuntu.Components 0.1
19 import Ubuntu.Components.Popups 0.1
20 import Ubuntu.Components.ListItems 0.1 as ListItem
25 property bool searchEntryEnabled:
false
26 property alias searchQuery: searchField.text
27 property ListModel searchHistory
29 property alias childItem: itemContainer.children
30 property alias showBackButton: backButton.visible
35 implicitHeight: units.gu(8.5)
37 function triggerSearch() {
38 if (searchEntryEnabled) searchField.forceActiveFocus()
41 function resetSearch() {
42 if (!searchHistory)
return;
44 searchHistory.addQuery(searchField.text);
46 searchField.text =
"";
50 searchField.focus =
false;
55 onShownChanged:
if (shown) resetSearch()
68 contentHeight: headerContainer.height
71 contentY: searchField.activeFocus || searchField.text !=
"" ? searchContainer.y : headerContainer.y
73 Behavior on contentY { NumberAnimation { duration: 200; easing.type: Easing.OutQuad } }
77 objectName: root.objectName +
"_backButton"
83 leftMargin: visible ? units.gu(2) : 0
85 width: visible ? image.width + units.gu(2) : 0
86 onClicked: root.backClicked();
89 anchors.centerIn: parent
90 source:
"graphics/headerback.png"
99 left: backButton.right
102 height: childrenRect.height
107 width: searchContainer.narrowMode ? header.width : header.width - searchContainer.width
108 height: header.height
113 objectName:
"searchContainer"
115 visible: searchEntryEnabled
116 property bool popoverShouldOpen:
false
117 property bool popoverShouldClose:
false
119 property bool narrowMode: parent.width < units.gu(80)
121 property bool active: searchField.text !=
"" || searchField.activeFocus
122 property var popover: null
124 anchors.right: headerContainer.right
125 height: header.height
128 if (active && narrowMode)
"narrowActive"
129 else if (!active && narrowMode)
"narrowInactive"
130 else if (active && !narrowMode)
"active"
131 else if (!active && !narrowMode)
"inactive"
134 if (state ==
"active" || state ==
"narrowActive") {
135 popoverShouldOpen =
true;
136 popoverShouldClose =
false;
138 popoverShouldOpen =
false;
139 popoverShouldClose =
true;
143 function openPopover() {
144 if (searchHistory.count > 0) {
145 searchContainer.popover = PopupUtils.open(popoverComponent, pointerPositioner,
147 "contentWidth": searchField.width,
148 "edgeMargins": units.gu(1)
152 popoverShouldOpen =
false;
153 popoverShouldClose =
false;
156 function closePopover() {
157 if (searchContainer.popover) {
158 PopupUtils.close(searchContainer.popover);
159 searchContainer.popover = null;
161 popoverShouldOpen =
false;
162 popoverShouldClose =
false;
165 onActiveFocusChanged:
if (!activeFocus) { searchHistory.addQuery(searchField.text) }
171 anchors.margins: units.gu(1)
173 inputMethodHints: Qt.ImhNoPredictiveText
174 hasClearButton:
false
176 primaryItem: AbstractButton {
177 enabled: searchField.text !=
"" && !searchIndicator.running
179 if (searchField.text !=
"") {
180 searchHistory.addQuery(searchField.text)
181 searchField.text =
""
184 height: parent.height
189 objectName:
"searchIndicator"
192 verticalCenter: parent.verticalCenter
194 leftMargin: units.gu(0.5)
202 objectName:
"primaryImage"
204 verticalCenter: parent.verticalCenter
206 leftMargin: units.gu(0.5)
214 id: pointerPositioner
215 anchors.left: parent.right
216 anchors.leftMargin: units.gu(0.5)
217 anchors.top: parent.bottom
222 if (text !=
"") searchContainer.closePopover()
223 else if (text ==
"" && activeFocus) searchContainer.openPopover()
226 onActiveFocusChanged: {
227 if (!activeFocus) searchContainer.closePopover()
233 when: scope && scope.searchInProgress
234 PropertyChanges { target: searchIndicator; running:
true; opacity: 1 }
235 PropertyChanges { target: primaryImage; opacity: 0 }
239 when: !scope || !scope.searchInProgress
240 PropertyChanges { target: searchIndicator; opacity: 0 }
241 PropertyChanges { target: primaryImage; opacity: 1 }
249 SequentialAnimation {
250 NumberAnimation { target: primaryImage;
property:
"opacity"; duration: UbuntuAnimation.FastDuration; easing.type: Easing.Linear }
251 NumberAnimation { target: searchIndicator;
property:
"opacity"; duration: UbuntuAnimation.FastDuration; easing.type: Easing.Linear }
260 AnchorChanges { target: itemContainer; anchors.top: headerContainer.top }
261 AnchorChanges { target: searchContainer; anchors.left: undefined; anchors.top: itemContainer.top }
265 PropertyChanges { target: searchField; highlighted:
true }
266 AnchorChanges { target: itemContainer; anchors.top: searchContainer.bottom }
267 AnchorChanges { target: searchContainer; anchors.left: headerContainer.left; anchors.top: headerContainer.top }
272 PropertyChanges { target: searchContainer; width: units.gu(40) }
273 PropertyChanges { target: primaryImage; source: searchField.text ?
"../Dash/graphics/icon_clear.png" :
"../Dash/graphics/icon_search_active.png" }
274 PropertyChanges { target: searchField; highlighted:
true }
279 PropertyChanges { target: searchContainer; width: units.gu(25) }
280 PropertyChanges { target: primaryImage; source:
"../Dash/graphics/icon_search_inactive.png" }
281 PropertyChanges { target: searchField; highlighted:
false }
286 PropertyChanges { target: header; contentY: 0 }
287 PropertyChanges { target: primaryImage; source: searchField.text ?
"../Dash/graphics/icon_clear.png" :
"../Dash/graphics/icon_search_active.png" }
290 name:
"narrowInactive"
292 PropertyChanges { target: header; contentY: header.height }
293 PropertyChanges { target: primaryImage; source: searchField.text ?
"../Dash/graphics/icon_clear.png" :
"../Dash/graphics/icon_search_active.png" }
300 SequentialAnimation {
302 NumberAnimation { targets: [searchContainer, searchField];
property:
"width"; duration: 200; easing.type: Easing.InOutQuad }
303 PropertyAction { target: primaryImage;
property:
"source" }
304 AnchorAnimation { targets: [searchContainer, itemContainer]; duration: 200; easing.type: Easing.InOutQuad }
306 ScriptAction { script:
if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
311 ScriptAction { script:
if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
312 NumberAnimation { targets: [searchContainer, searchField] ;
property:
"width"; duration: 200; easing.type: Easing.InOutQuad }
313 AnchorAnimation { targets: [searchContainer, itemContainer]; duration: 200; easing.type: Easing.InOutQuad }
317 SequentialAnimation {
319 NumberAnimation { targets: [searchContainer, searchField] ;
property:
"width"; duration: 200; easing.type: Easing.OutQuad }
320 AnchorAnimation { targets: [searchContainer, itemContainer]; duration: 200; easing.type: Easing.InOutQuad }
322 ScriptAction { script:
if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
327 ScriptAction { script:
if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
328 NumberAnimation { targets: [searchContainer, searchField] ;
property:
"width"; duration: 200; easing.type: Easing.OutQuad }
329 AnchorAnimation { targets: [searchContainer, itemContainer]; duration: 200; easing.type: Easing.InOutQuad }
348 onClicked: searchContainer.closePopover()
351 anchors.centerIn: parent
354 source:
"../Dash/graphics/icon_listview_clear.png"
365 ListItem.Standard { enabled:
false; text: i18n.tr(
"Recent searches") }
371 delegate: ListItem.Standard {
372 showDivider: index < recentSearches.count - 1
375 searchHistory.addQuery(text)
376 searchField.text = text
385 enabled: searchField.activeFocus
393 height: searchContainer.popover ? parent.height + searchContainer.popover.contentHeight + units.gu(2) : parent.height
395 onPressed: searchField.focus =
false
407 bottom: parent.bottom
410 source:
"graphics/PageHeaderBaseDivider.sci"