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
28 property var scope: null
29 property alias childItem: itemContainer.children
30 property alias bottomItem: bottomContainer.children
31 property alias showBackButton: backButton.visible
35 height: header.height + units.gu(2) + bottomContainer.height
36 implicitHeight: header.height + units.gu(2) + bottomContainer.height
38 function triggerSearch() {
39 if (searchEntryEnabled) searchField.forceActiveFocus()
42 function resetSearch() {
43 if (!searchHistory)
return;
45 searchHistory.addQuery(searchField.text);
47 searchField.text =
"";
51 searchField.focus =
false;
56 onShownChanged:
if (shown) resetSearch()
69 contentHeight: headerContainer.height
72 contentY: searchField.activeFocus || searchField.text !=
"" ? searchContainer.y : headerContainer.y
74 Behavior on contentY { NumberAnimation { duration: 200; easing.type: Easing.OutQuad } }
78 objectName: root.objectName +
"_backButton"
84 leftMargin: visible ? units.gu(2) : 0
86 width: visible ? image.width + units.gu(2) : 0
87 onClicked: root.backClicked();
90 anchors.centerIn: parent
91 source:
"graphics/headerback.png"
100 left: backButton.right
103 height: childrenRect.height
108 width: searchContainer.narrowMode ? header.width : header.width - searchContainer.width
109 height: header.height
114 objectName:
"searchContainer"
116 visible: searchEntryEnabled
117 property bool popoverShouldOpen:
false
118 property bool popoverShouldClose:
false
120 property bool narrowMode: parent.width < units.gu(80)
122 property bool active: searchField.text !=
"" || searchField.activeFocus
123 property var popover: null
125 anchors.right: headerContainer.right
126 height: header.height
129 if (active && narrowMode)
"narrowActive"
130 else if (!active && narrowMode)
"narrowInactive"
131 else if (active && !narrowMode)
"active"
132 else if (!active && !narrowMode)
"inactive"
135 if (state ==
"active" || state ==
"narrowActive") {
136 popoverShouldOpen =
true;
137 popoverShouldClose =
false;
139 popoverShouldOpen =
false;
140 popoverShouldClose =
true;
144 function openPopover() {
145 if (searchHistory.count > 0) {
146 searchContainer.popover = PopupUtils.open(popoverComponent, pointerPositioner,
148 "contentWidth": searchField.width,
149 "edgeMargins": units.gu(1)
153 popoverShouldOpen =
false;
154 popoverShouldClose =
false;
157 function closePopover() {
158 if (searchContainer.popover) {
159 PopupUtils.close(searchContainer.popover);
160 searchContainer.popover = null;
162 popoverShouldOpen =
false;
163 popoverShouldClose =
false;
166 onActiveFocusChanged:
if (!activeFocus) { searchHistory.addQuery(searchField.text) }
172 anchors.margins: units.gu(1)
174 inputMethodHints: Qt.ImhNoPredictiveText
175 hasClearButton:
false
177 primaryItem: AbstractButton {
178 enabled: searchField.text !=
"" && !searchIndicator.running
180 if (searchField.text !=
"") {
181 searchHistory.addQuery(searchField.text)
182 searchField.text =
""
185 height: parent.height
190 objectName:
"searchIndicator"
193 verticalCenter: parent.verticalCenter
195 leftMargin: units.gu(0.5)
203 objectName:
"primaryImage"
205 verticalCenter: parent.verticalCenter
207 leftMargin: units.gu(0.5)
215 id: pointerPositioner
216 anchors.left: parent.right
217 anchors.leftMargin: units.gu(0.5)
218 anchors.top: parent.bottom
223 if (text !=
"") searchContainer.closePopover()
224 else if (text ==
"" && activeFocus) searchContainer.openPopover()
227 onActiveFocusChanged: {
228 if (!activeFocus) searchContainer.closePopover()
234 when: scope && scope.searchInProgress
235 PropertyChanges { target: searchIndicator; running:
true; opacity: 1 }
236 PropertyChanges { target: primaryImage; opacity: 0 }
240 when: !scope || !scope.searchInProgress
241 PropertyChanges { target: searchIndicator; opacity: 0 }
242 PropertyChanges { target: primaryImage; opacity: 1 }
250 SequentialAnimation {
251 NumberAnimation { target: primaryImage;
property:
"opacity"; duration: UbuntuAnimation.FastDuration; easing.type: Easing.Linear }
252 NumberAnimation { target: searchIndicator;
property:
"opacity"; duration: UbuntuAnimation.FastDuration; easing.type: Easing.Linear }
261 AnchorChanges { target: itemContainer; anchors.top: headerContainer.top }
262 AnchorChanges { target: searchContainer; anchors.left: undefined; anchors.top: itemContainer.top }
266 PropertyChanges { target: searchField; highlighted:
true }
267 AnchorChanges { target: itemContainer; anchors.top: searchContainer.bottom }
268 AnchorChanges { target: searchContainer; anchors.left: headerContainer.left; anchors.top: headerContainer.top }
273 PropertyChanges { target: searchContainer; width: units.gu(40) }
274 PropertyChanges { target: primaryImage; source: searchField.text ?
"../Dash/graphics/icon_clear.png" :
"../Dash/graphics/icon_search_active.png" }
275 PropertyChanges { target: searchField; highlighted:
true }
280 PropertyChanges { target: searchContainer; width: units.gu(25) }
281 PropertyChanges { target: primaryImage; source:
"../Dash/graphics/icon_search_inactive.png" }
282 PropertyChanges { target: searchField; highlighted:
false }
287 PropertyChanges { target: header; contentY: 0 }
288 PropertyChanges { target: primaryImage; source: searchField.text ?
"../Dash/graphics/icon_clear.png" :
"../Dash/graphics/icon_search_active.png" }
291 name:
"narrowInactive"
293 PropertyChanges { target: header; contentY: header.height }
294 PropertyChanges { target: primaryImage; source: searchField.text ?
"../Dash/graphics/icon_clear.png" :
"../Dash/graphics/icon_search_active.png" }
301 SequentialAnimation {
303 NumberAnimation { targets: [searchContainer, searchField];
property:
"width"; duration: 200; easing.type: Easing.InOutQuad }
304 PropertyAction { target: primaryImage;
property:
"source" }
305 AnchorAnimation { targets: [searchContainer, itemContainer]; duration: 200; easing.type: Easing.InOutQuad }
307 ScriptAction { script:
if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
312 ScriptAction { script:
if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
313 NumberAnimation { targets: [searchContainer, searchField] ;
property:
"width"; duration: 200; easing.type: Easing.InOutQuad }
314 AnchorAnimation { targets: [searchContainer, itemContainer]; duration: 200; easing.type: Easing.InOutQuad }
318 SequentialAnimation {
320 NumberAnimation { targets: [searchContainer, searchField] ;
property:
"width"; duration: 200; easing.type: Easing.OutQuad }
321 AnchorAnimation { targets: [searchContainer, itemContainer]; duration: 200; easing.type: Easing.InOutQuad }
323 ScriptAction { script:
if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
328 ScriptAction { script:
if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
329 NumberAnimation { targets: [searchContainer, searchField] ;
property:
"width"; duration: 200; easing.type: Easing.OutQuad }
330 AnchorAnimation { targets: [searchContainer, itemContainer]; duration: 200; easing.type: Easing.InOutQuad }
349 onClicked: searchContainer.closePopover()
352 anchors.centerIn: parent
355 source:
"../Dash/graphics/icon_listview_clear.png"
366 ListItem.Standard { enabled:
false; text: i18n.tr(
"Recent searches") }
372 delegate: ListItem.Standard {
373 showDivider: index < recentSearches.count - 1
376 searchHistory.addQuery(text)
377 searchField.text = text
386 enabled: searchField.activeFocus
394 height: searchContainer.popover ? parent.height + searchContainer.popover.contentHeight + units.gu(2) : parent.height
396 onPressed: searchField.focus =
false
408 bottom: bottomContainer.top
411 source:
"graphics/PageHeaderBaseDivider.sci"
420 bottom: parent.bottom
422 height: childrenRect.height