2
* Copyright (C) 2013 Canonical, Ltd.
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; version 3.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18
import Ubuntu.Components 0.1
19
import Ubuntu.Components.Popups 0.1
20
import Ubuntu.Components.ListItems 0.1 as ListItem
25
The text that is shown inside the Page Header
26
\qmlproperty string text
28
property alias text: label.text
30
property bool searchEntryEnabled: false
31
property alias searchQuery: searchField.text
32
property ListModel searchHistory: SearchHistoryModel {}
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);
45
searchField.text = "";
46
searchField.focus = false;
51
onShownChanged: if (shown) resetSearch()
64
contentHeight: headerContainer.height
67
contentY: searchField.activeFocus || searchField.text != "" ? searchContainer.y : headerContainer.y
69
Behavior on contentY { NumberAnimation { duration: 200; easing.type: Easing.OutQuad } }
71
// FIXME this could potentially be simplified to avoid all the containers
76
height: childrenRect.height
88
leftMargin: units.gu(2)
90
verticalCenter: parent.verticalCenter
96
font.weight: Font.Light
98
elide: Text.ElideRight
106
objectName: "searchContainer"
108
visible: searchEntryEnabled
110
property bool narrowMode: parent.width < label.contentWidth + units.gu(50)
112
property bool active: searchField.text != "" || searchField.activeFocus
113
property var popover: null
115
anchors.right: textContainer.right
116
height: header.height
119
if (active && narrowMode) "narrowActive"
120
else if (!active && narrowMode) "narrowInactive"
121
else if (active && !narrowMode) "active"
122
else if (!active && !narrowMode) "inactive"
124
function openPopover() {
125
if (searchHistory.count > 0) {
126
searchContainer.popover = PopupUtils.open(popoverComponent, searchField,
128
"pointerTarget": pointerPositioner,
129
"contentWidth": searchField.width,
130
"edgeMargins": units.gu(1)
136
function closePopover() {
137
if (searchContainer.popover) PopupUtils.close(searchContainer.popover)
140
onActiveFocusChanged: if (!activeFocus) { searchHistory.addQuery(searchField.text) }
146
anchors.margins: units.gu(1)
148
hasClearButton: false
150
primaryItem: Button {
151
enabled: searchField.text != ""
152
ItemStyle.class: "transparent-button"
154
if (searchField.text != "") {
155
searchHistory.addQuery(searchField.text)
156
searchField.text = ""
159
height: parent.height
165
verticalCenter: parent.verticalCenter
167
leftMargin: units.gu(0.5)
174
id: pointerPositioner
175
anchors.left: parent.right
176
anchors.leftMargin: units.gu(0.5)
177
anchors.top: parent.bottom
182
if (text != "") searchContainer.closePopover()
183
else if (text == "" && activeFocus) searchContainer.openPopover()
186
onActiveFocusChanged: {
187
if (!activeFocus) searchContainer.closePopover()
194
AnchorChanges { target: textContainer; anchors.top: headerContainer.top }
195
AnchorChanges { target: searchContainer; anchors.left: undefined; anchors.top: textContainer.top }
199
PropertyChanges { target: searchField; highlighted: true }
200
AnchorChanges { target: textContainer; anchors.top: searchContainer.bottom }
201
AnchorChanges { target: searchContainer; anchors.left: headerContainer.left; anchors.top: headerContainer.top }
206
PropertyChanges { target: searchContainer; width: units.gu(40) }
207
PropertyChanges { target: primaryImage; source: searchField.text ? "../Dash/graphics/icon_clear.png" : "../Dash/graphics/icon_search_active.png" }
208
PropertyChanges { target: searchField; highlighted: true }
213
PropertyChanges { target: searchContainer; width: units.gu(25) }
214
PropertyChanges { target: primaryImage; source: "../Dash/graphics/icon_search_inactive.png" }
215
PropertyChanges { target: searchField; highlighted: false }
220
PropertyChanges { target: header; contentY: 0 }
221
PropertyChanges { target: primaryImage; source: searchField.text ? "../Dash/graphics/icon_clear.png" : "../Dash/graphics/icon_search_active.png" }
224
name: "narrowInactive"
226
PropertyChanges { target: header; contentY: header.height }
227
PropertyChanges { target: primaryImage; source: searchField.text ? "../Dash/graphics/icon_clear.png" : "../Dash/graphics/icon_search_active.png" }
234
SequentialAnimation {
236
NumberAnimation { targets: [searchContainer, searchField]; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
237
PropertyAction { target: primaryImage; property: "source" }
238
AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
240
ScriptAction { script: searchContainer.openPopover() }
245
ScriptAction { script: searchContainer.closePopover() }
246
NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
247
AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
251
SequentialAnimation {
253
NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
254
AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
256
ScriptAction { script: searchContainer.openPopover() }
261
ScriptAction { script: searchContainer.closePopover() }
262
NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
263
AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
272
// FIXME: this should go into the first item below, but enable: false
273
// prevents mouse events propagation
275
ItemStyle.class: "transparent-button"
283
onClicked: searchContainer.closePopover()
286
anchors.centerIn: parent
289
source: "../Dash/graphics/icon_listview_clear.png"
300
ListItem.Standard { enabled: false; text: i18n.tr("Recent searches") }
306
delegate: ListItem.Standard {
307
showDivider: index < recentSearches.count - 1
310
searchHistory.addQuery(text)
311
searchField.text = text
320
enabled: searchField.activeFocus
328
height: searchContainer.popover ? parent.height + searchContainer.popover.contentHeight + units.gu(2) : parent.height
330
onPressed: searchField.focus = false
342
bottom: parent.bottom
345
source: "graphics/PageHeaderBaseDivider.sci"