summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2018-07-06 22:47:19 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-07-12 16:08:21 +0200
commit727e3f05df471548e590958168c52c474ab44e06 (patch)
treede80b6c523956795f3678aa474c67f6236aa541a
parent395f85b92f461923619fcf713f8029311630a8f2 (diff)
downloadkube-727e3f05df471548e590958168c52c474ab44e06.tar.gz
kube-727e3f05df471548e590958168c52c474ab44e06.zip
A view search overlay
-rw-r--r--framework/qml/MailListView.qml51
-rw-r--r--framework/qml/SearchPopup.qml184
-rw-r--r--framework/qml/View.qml25
-rw-r--r--framework/qmldir1
-rw-r--r--views/conversation/qml/View.qml23
5 files changed, 227 insertions, 57 deletions
diff --git a/framework/qml/MailListView.qml b/framework/qml/MailListView.qml
index 7e6f584d..998d9729 100644
--- a/framework/qml/MailListView.qml
+++ b/framework/qml/MailListView.qml
@@ -31,19 +31,10 @@ FocusScope {
31 property bool isTrash : false 31 property bool isTrash : false
32 property bool isUnread : false 32 property bool isUnread : false
33 property variant currentMail: null 33 property variant currentMail: null
34 property bool showFilter: false 34 property alias filter: mailListModel.filter
35 property string filter: null
36
37 onFilterChanged: {
38 Kube.Fabric.postMessage(Kube.Messages.searchString, {"searchString": filter})
39 }
40 35
41 onParentFolderChanged: { 36 onParentFolderChanged: {
42 currentMail = null 37 currentMail = null
43 filterField.clearSearch()
44 }
45 onShowFilterChanged: {
46 find.forceActiveFocus()
47 } 38 }
48 39
49 Kube.Listener { 40 Kube.Listener {
@@ -74,45 +65,6 @@ FocusScope {
74 65
75 spacing: 0 66 spacing: 0
76 67
77 Rectangle {
78 id: filterField
79 Layout.fillWidth: true
80 height: Kube.Units.gridUnit * 2
81 color: Kube.Colors.buttonColor
82 visible: root.showFilter
83
84 function clearSearch() {
85 root.showFilter = false
86 find.text = ""
87 root.filter = ""
88 }
89
90 RowLayout {
91 anchors {
92 verticalCenter: parent.verticalCenter
93 }
94
95 width: parent.width - Kube.Units.smallSpacing
96 spacing: 0
97
98 Kube.IconButton {
99 iconName: Kube.Icons.remove
100 activeFocusOnTab: visible
101 onClicked: filterField.clearSearch()
102 }
103
104 Kube.TextField {
105 id: find
106 Layout.fillWidth: true
107 placeholderText: qsTr("Filter...")
108 onTextChanged: root.filter = text
109 activeFocusOnTab: visible
110 focus: visible
111 Keys.onEscapePressed: filterField.clearSearch()
112 }
113 }
114 }
115
116 Kube.ListView { 68 Kube.ListView {
117 id: listView 69 id: listView
118 objectName: "listView" 70 objectName: "listView"
@@ -156,7 +108,6 @@ FocusScope {
156 model: Kube.MailListModel { 108 model: Kube.MailListModel {
157 id: mailListModel 109 id: mailListModel
158 parentFolder: root.parentFolder 110 parentFolder: root.parentFolder
159 filter: root.filter
160 } 111 }
161 112
162 delegate: Kube.ListDelegate { 113 delegate: Kube.ListDelegate {
diff --git a/framework/qml/SearchPopup.qml b/framework/qml/SearchPopup.qml
new file mode 100644
index 00000000..b1787e1b
--- /dev/null
+++ b/framework/qml/SearchPopup.qml
@@ -0,0 +1,184 @@
1/*
2 * Copyright (C) 2017 Michael Bohlender, <michael.bohlender@kdemail.net>
3 * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsys.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20
21import QtQuick 2.9
22import QtQuick.Controls 2
23import QtQuick.Layouts 1.1
24
25import org.kube.framework 1.0 as Kube
26
27Item {
28 id: root
29
30 property rect searchArea
31 property string backgroundColor: Kube.Colors.darkCharcoalGrey
32 property real backgroundOpacity: 0
33 property real searchAreaOpacity: backgroundOpacity / 4
34
35 NumberAnimation on backgroundOpacity {
36 id: fadeIn
37 from: 0
38 to: 0.8
39 duration: 100
40 }
41
42 Component.onCompleted: fadeIn.start()
43
44 NumberAnimation on backgroundOpacity {
45 id: fadeOut
46 running: false
47 to: 0
48 duration: 100
49 onRunningChanged: {
50 if (!running) {
51 root.destroy()
52 }
53 }
54 }
55
56 function close() {
57 fadeOut.start()
58 }
59
60 property string filter: ""
61
62 parent: ApplicationWindow.overlay
63 anchors.fill: parent
64 enabled: false
65
66 //left
67 Rectangle {
68 x: 0
69 y: 0
70 width: searchArea.x
71 height: parent.height
72 color: parent.backgroundColor
73 opacity: parent.backgroundOpacity
74 }
75 //bottom
76 Rectangle {
77 x: searchArea.x
78 y: searchArea.y + searchArea.height
79 width: searchArea.width
80 height: parent.height - y
81 color: parent.backgroundColor
82 opacity: parent.backgroundOpacity
83 }
84 //right
85 Rectangle {
86 x: searchArea.x + searchArea.width
87 y: 0
88 width: parent.width - x
89 height: parent.height
90 color: parent.backgroundColor
91 opacity: parent.backgroundOpacity
92 }
93 //bottom
94 Rectangle {
95 x: searchArea.x
96 y: 0
97 width: searchArea.width
98 height: searchArea.y
99 color: parent.backgroundColor
100 opacity: parent.backgroundOpacity
101 }
102 //outline
103 Rectangle {
104 x: searchArea.x
105 y: searchArea.y
106 width: searchArea.width
107 height: searchArea.height
108 color: "transparent"
109 border {
110 width: 3
111 color: Kube.Colors.highlightColor
112 }
113 Rectangle {
114 anchors.fill: parent
115 color: parent.parent.backgroundColor
116 opacity: parent.parent.searchAreaOpacity
117 }
118 }
119
120
121 Rectangle {
122 id: filterField
123 enabled: true
124 parent: ApplicationWindow.overlay
125
126 anchors {
127 horizontalCenter: parent.horizontalCenter
128 }
129 y: parent.height / 3
130 height: Kube.Units.gridUnit * 2
131 width: Kube.Units.gridUnit * 30
132 radius: Kube.Units.smallSpacing
133
134 color: Kube.Colors.darkBackgroundColor
135
136 states: [
137 State {
138 name: "searchInProgress"
139 when: find.text.length != 0
140 PropertyChanges {target: filterField; y: Kube.Units.gridUnit}
141 PropertyChanges {target: root; searchAreaOpacity: 0}
142 }
143 ]
144
145 transitions: Transition {
146 NumberAnimation { properties: "y"; easing.type: Easing.InOutQuad }
147 }
148
149 function clearSearch() {
150 find.text = ""
151 root.close()
152 }
153
154 Shortcut {
155 sequences: [StandardKey.Cancel]
156 onActivated: filterField.clearSearch()
157 }
158
159 RowLayout {
160 anchors {
161 verticalCenter: parent.verticalCenter
162 }
163
164 width: parent.width - Kube.Units.smallSpacing
165 spacing: 0
166
167 Kube.IconButton {
168 iconName: Kube.Icons.remove
169 activeFocusOnTab: visible
170 onClicked: filterField.clearSearch()
171 }
172
173 Kube.TextField {
174 id: find
175 Layout.fillWidth: true
176 placeholderText: qsTr("Filter...")
177 onTextChanged: root.filter = text
178 activeFocusOnTab: visible
179 focus: visible
180 Keys.onEscapePressed: filterField.clearSearch()
181 }
182 }
183 }
184}
diff --git a/framework/qml/View.qml b/framework/qml/View.qml
index 9daa76a8..88cc3f10 100644
--- a/framework/qml/View.qml
+++ b/framework/qml/View.qml
@@ -31,6 +31,19 @@ FocusScope {
31 property int count: contentItems.length 31 property int count: contentItems.length
32 default property alias contentItems: content.data 32 default property alias contentItems: content.data
33 33
34 property rect searchArea: null
35 property string filter: ""
36 property var searchObject: null
37 function triggerSearch() {
38 root.searchObject = searchComponent.createObject(root)
39 }
40 function clearSearch() {
41 if (root.searchObject) {
42 root.searchObject.close()
43 root.searchObject = null
44 }
45 }
46
34 property bool __aborted: false 47 property bool __aborted: false
35 48
36 //This signal will be emitted once all initial properties have been set and the view is ready to load 49 //This signal will be emitted once all initial properties have been set and the view is ready to load
@@ -104,4 +117,16 @@ FocusScope {
104 id: content 117 id: content
105 anchors.fill: parent 118 anchors.fill: parent
106 } 119 }
120
121 Component {
122 id: searchComponent
123 Kube.SearchPopup {
124 searchArea: root.searchArea
125 onFilterChanged: {
126 root.filter = filter
127 }
128 }
129
130 }
131
107} 132}
diff --git a/framework/qmldir b/framework/qmldir
index 808563c9..b4d4fc8e 100644
--- a/framework/qmldir
+++ b/framework/qmldir
@@ -11,6 +11,7 @@ EditAccount 1.0 EditAccount.qml
11LoginAccount 1.0 LoginAccount.qml 11LoginAccount 1.0 LoginAccount.qml
12Outbox 1.0 Outbox.qml 12Outbox 1.0 Outbox.qml
13HelpPopup 1.0 HelpPopup.qml 13HelpPopup 1.0 HelpPopup.qml
14SearchPopup 1.0 SearchPopup.qml
14NotificationPopup 1.0 NotificationPopup.qml 15NotificationPopup 1.0 NotificationPopup.qml
15Icon 1.0 Icon.qml 16Icon 1.0 Icon.qml
16IconButton 1.0 IconButton.qml 17IconButton 1.0 IconButton.qml
diff --git a/views/conversation/qml/View.qml b/views/conversation/qml/View.qml
index 89e6379c..2a5e3d0c 100644
--- a/views/conversation/qml/View.qml
+++ b/views/conversation/qml/View.qml
@@ -29,6 +29,18 @@ Kube.View {
29 id: root 29 id: root
30 property alias currentAccount: accountFolderview.currentAccount 30 property alias currentAccount: accountFolderview.currentAccount
31 31
32 //We have to hardcode because all the mapToItem/mapFromItem functions are garbage
33 searchArea: Qt.rect(ApplicationWindow.window.sidebarWidth + mailListView.parent.x, 0, (mailView.x + mailView.width) - mailListView.parent.x, (mailView.y + mailView.height) - mailListView.y)
34 onFilterChanged: {
35 mailListView.filter = filter
36 Kube.Fabric.postMessage(Kube.Messages.searchString, {"searchString": filter})
37 }
38
39 Kube.Listener {
40 filter: Kube.Messages.search
41 onMessageReceived: root.triggerSearch()
42 }
43
32 Shortcut { 44 Shortcut {
33 sequences: ['j'] 45 sequences: ['j']
34 onActivated: Kube.Fabric.postMessage(Kube.Messages.selectNextConversation, {}) 46 onActivated: Kube.Fabric.postMessage(Kube.Messages.selectNextConversation, {})
@@ -156,12 +168,10 @@ Kube.View {
156 Layout.minimumWidth: Kube.Units.gridUnit * 10 168 Layout.minimumWidth: Kube.Units.gridUnit * 10
157 Kube.Listener { 169 Kube.Listener {
158 filter: Kube.Messages.folderSelection 170 filter: Kube.Messages.folderSelection
159 onMessageReceived: mailListView.parentFolder = message.folder 171 onMessageReceived: {
160 } 172 root.clearSearch()
161 173 mailListView.parentFolder = message.folder
162 Kube.Listener { 174 }
163 filter: Kube.Messages.search
164 onMessageReceived: mailListView.showFilter = true
165 } 175 }
166 onCurrentMailChanged: { 176 onCurrentMailChanged: {
167 Kube.Fabric.postMessage(Kube.Messages.mailSelection, {"mail": currentMail}) 177 Kube.Fabric.postMessage(Kube.Messages.mailSelection, {"mail": currentMail})
@@ -210,5 +220,4 @@ Kube.View {
210 } 220 }
211 } 221 }
212 } 222 }
213
214} 223}