Changeset View
Changeset View
Standalone View
Standalone View
applets/kickoff/package/contents/ui/Header.qml
Show All 13 Lines | |||||
14 | * You should have received a copy of the GNU General Public License along | 14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | 15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | */ | 17 | */ | ||
18 | 18 | | |||
19 | import QtQuick 2.0 | 19 | import QtQuick 2.0 | ||
20 | import org.kde.plasma.core 2.0 as PlasmaCore | 20 | import org.kde.plasma.core 2.0 as PlasmaCore | ||
21 | import org.kde.plasma.components 2.0 as PlasmaComponents | 21 | import org.kde.plasma.components 2.0 as PlasmaComponents | ||
22 | import org.kde.plasma.components 3.0 as PlasmaComponents3 | ||||
22 | import org.kde.plasma.extras 2.0 as PlasmaExtras | 23 | import org.kde.plasma.extras 2.0 as PlasmaExtras | ||
23 | import org.kde.kcoreaddons 1.0 as KCoreAddons | 24 | import org.kde.kcoreaddons 1.0 as KCoreAddons | ||
24 | import org.kde.kquickcontrolsaddons 2.0 | 25 | import org.kde.kquickcontrolsaddons 2.0 | ||
25 | 26 | | |||
26 | Item { | 27 | Item { | ||
27 | id: header | 28 | id: header | ||
28 | 29 | | |||
29 | implicitHeight: units.gridUnit * 5 | 30 | implicitHeight: units.gridUnit * 5 | ||
30 | 31 | | |||
31 | property alias query: queryField.text | 32 | property alias query: queryField.text | ||
32 | property Item input: queryField | 33 | property Item input: queryField | ||
33 | 34 | | |||
34 | KCoreAddons.KUser { | 35 | KCoreAddons.KUser { | ||
35 | id: kuser | 36 | id: kuser | ||
36 | } | 37 | } | ||
37 | 38 | | |||
38 | state: (query !== "") ? "query" : "hint" | 39 | state: "name" | ||
39 | 40 | | |||
40 | Timer { | 41 | Timer { | ||
41 | id: labelTimer | 42 | id: labelTimer | ||
42 | interval: 8000 | 43 | interval: 8000 | ||
44 | running: true | ||||
43 | repeat: true | 45 | repeat: true | ||
44 | running: (header.state === "hint" || header.state === "info") && plasmoid.expanded && (header.query === "") | | |||
45 | onTriggered: { | 46 | onTriggered: { | ||
46 | if (header.state == "info") { | 47 | if (header.state == "name") { | ||
47 | header.state = "hint"; | | |||
48 | } else if (header.state == "hint") { | | |||
49 | header.state = "info"; | 48 | header.state = "info"; | ||
49 | } else { | ||||
50 | header.state = "name"; | ||||
51 | } | ||||
52 | } | ||||
53 | } | ||||
54 | | ||||
55 | states: [ | ||||
56 | State { | ||||
57 | name: "name" | ||||
58 | PropertyChanges { | ||||
59 | target: nameLabel | ||||
60 | opacity: 1 | ||||
61 | y: 0 | ||||
62 | } | ||||
63 | PropertyChanges { | ||||
64 | target: infoLabel | ||||
65 | opacity: 0 | ||||
66 | y: -1 | ||||
davidedmundson: What's this about? Negative offsets are weird, and we also have a 300ms animation to move 1px? | |||||
I was copying this from the original, but yeah, it did seem weird to me too. Removed. ngraham: I was copying this from the original, but yeah, it did seem weird to me too. Removed. | |||||
50 | } | 67 | } | ||
68 | }, | ||||
69 | State { | ||||
70 | name: "info" | ||||
71 | PropertyChanges { | ||||
72 | target: nameLabel | ||||
73 | y: -1 | ||||
74 | opacity: 0 | ||||
75 | } | ||||
76 | PropertyChanges { | ||||
77 | target: infoLabel | ||||
78 | y: 0 | ||||
79 | opacity: 0.4 | ||||
51 | } | 80 | } | ||
52 | } | 81 | } | ||
82 | ] // states | ||||
83 | | ||||
53 | 84 | | |||
54 | Image { | 85 | Image { | ||
55 | id: faceIcon | 86 | id: faceIcon | ||
56 | source: kuser.faceIconUrl | 87 | source: kuser.faceIconUrl | ||
57 | cache: false | 88 | cache: false | ||
58 | visible: source !== "" | 89 | visible: source !== "" | ||
59 | 90 | | |||
60 | width: units.gridUnit * 3 | 91 | width: units.gridUnit * 3 | ||
Show All 37 Lines | |||||
98 | 129 | | |||
99 | PlasmaExtras.Heading { | 130 | PlasmaExtras.Heading { | ||
100 | id: nameLabel | 131 | id: nameLabel | ||
101 | 132 | | |||
102 | level: 2 | 133 | level: 2 | ||
103 | text: kuser.fullName | 134 | text: kuser.fullName | ||
104 | elide: Text.ElideRight | 135 | elide: Text.ElideRight | ||
105 | horizontalAlignment: Text.AlignLeft | 136 | horizontalAlignment: Text.AlignLeft | ||
106 | verticalAlignment: Text.AlignTop | 137 | verticalAlignment: Text.AlignBottom | ||
107 | height: paintedHeight | 138 | | ||
139 | Behavior on opacity { NumberAnimation { duration: units.longDuration; easing.type: Easing.InOutQuad; } } | ||||
140 | Behavior on y { NumberAnimation { duration: units.longDuration; easing.type: Easing.InOutQuad; } } | ||||
108 | 141 | | |||
109 | anchors { | 142 | anchors { | ||
110 | left: faceIcon.right | 143 | left: faceIcon.right | ||
111 | top: faceIcon.top | 144 | bottom: queryField.top | ||
davidedmundson: and here | |||||
112 | right: parent.right | | |||
113 | leftMargin: units.gridUnit | 145 | leftMargin: units.gridUnit | ||
114 | rightMargin: units.gridUnit | | |||
115 | } | 146 | } | ||
116 | } | 147 | } | ||
117 | 148 | | |||
118 | Item { | 149 | PlasmaExtras.Heading { | ||
119 | id: searchWidget | | |||
120 | | ||||
121 | property int animationDuration: units.longDuration | | |||
122 | property real normalOpacity: .6 | | |||
123 | property int yOffset: height / 2 | | |||
124 | | ||||
125 | height: infoLabel.height | | |||
126 | anchors { | | |||
127 | left: nameLabel.left | | |||
128 | top: nameLabel.bottom | | |||
129 | right: nameLabel.right | | |||
130 | } | | |||
131 | | ||||
132 | PlasmaComponents.Label { | | |||
133 | id: infoLabel | 150 | id: infoLabel | ||
134 | anchors { | 151 | | ||
135 | left: parent.left | 152 | level: 5 | ||
136 | right: parent.right | 153 | font.letterSpacing: -0.4 | ||
We can't do this. You're assuming lots of things about the user's font that you can't do. davidedmundson: We can't do this. You're assuming lots of things about the user's font that you can't do. | |||||
Oops, this was left over from an earlier idea that I abandoned. Removed. ngraham: Oops, this was left over from an earlier idea that I abandoned. Removed. | |||||
137 | } | 154 | opacity: 0 | ||
138 | horizontalAlignment: Text.AlignLeft | | |||
139 | verticalAlignment: Text.AlignBottom | | |||
140 | text: kuser.os != "" ? i18n("%2@%3 (%1)", kuser.os, kuser.loginName, kuser.host) : i18n("%1@%2", kuser.loginName, kuser.host) | 155 | text: kuser.os != "" ? i18n("%2@%3 (%1)", kuser.os, kuser.loginName, kuser.host) : i18n("%1@%2", kuser.loginName, kuser.host) | ||
141 | elide: Text.ElideRight | 156 | elide: Text.ElideRight | ||
157 | horizontalAlignment: Text.AlignLeft | ||||
158 | verticalAlignment: Text.AlignBottom | ||||
142 | 159 | | |||
143 | Behavior on opacity { NumberAnimation { duration: searchWidget.animationDuration; easing.type: Easing.InOutQuad; } } | 160 | Behavior on opacity { NumberAnimation { duration: units.longDuration; easing.type: Easing.InOutQuad; } } | ||
144 | Behavior on y { NumberAnimation { duration: searchWidget.animationDuration; easing.type: Easing.InOutQuad; } } | 161 | Behavior on y { NumberAnimation { duration: units.longDuration; easing.type: Easing.InOutQuad; } } | ||
145 | } | | |||
146 | 162 | | |||
147 | PlasmaComponents.Label { | | |||
148 | id: hintLabel | | |||
149 | anchors { | 163 | anchors { | ||
150 | left: parent.left | 164 | left: faceIcon.right | ||
This will no longer elide as the right is not constrained. If you have a long username this will just overflow out the box. When dealing with text items, it's easier to think in terms of bounding box rather than where the text itself. Include the rightMargin back too. davidedmundson: This will no longer elide as the right is not constrained.
If you have a long username this… | |||||
151 | right: parent.right | 165 | bottom: queryField.top | ||
166 | leftMargin: units.gridUnit | ||||
152 | } | 167 | } | ||
153 | verticalAlignment: Text.AlignBottom | | |||
154 | text: i18nc("Type is a verb here, not a noun", "Type to search...") | | |||
155 | Behavior on opacity { NumberAnimation { duration: searchWidget.animationDuration; easing.type: Easing.InOutQuad; } } | | |||
156 | Behavior on y { NumberAnimation { duration: searchWidget.animationDuration; easing.type: Easing.InOutQuad; } } | | |||
157 | } | 168 | } | ||
158 | 169 | | |||
159 | 170 | // Show the info instead of the user's name when hovering over it | |||
160 | MouseArea { | 171 | MouseArea { | ||
161 | anchors.fill: parent | 172 | anchors.fill: nameLabel | ||
162 | cursorShape: header.state === "hint" ? Qt.PointingHandCursor : Qt.ArrowCursor | 173 | hoverEnabled: true | ||
163 | acceptedButtons: Qt.LeftButton | 174 | onEntered: { | ||
164 | enabled: header.state === "hint" | 175 | labelTimer.stop() | ||
165 | onClicked: { | 176 | header.state = "info" | ||
166 | root.previousState = "Normal" | 177 | } | ||
167 | root.state = "Search" | 178 | onExited: { | ||
168 | header.state = "query" | 179 | labelTimer.start() | ||
169 | queryField.forceActiveFocus() | 180 | header.state = "name" | ||
181 | } | ||||
170 | } | 182 | } | ||
171 | 183 | | |||
172 | PlasmaComponents.TextField { | 184 | // Use the PC3 TextField because the PC2 version has placeholder text color issues | ||
185 | // (https://bugs.kde.org/show_bug.cgi?id=396813) | ||||
186 | // FIXME: use the PC2 version once 396813 is fixed so we can avoid the PC3 import | ||||
187 | PlasmaComponents3.TextField { | ||||
173 | id: queryField | 188 | id: queryField | ||
174 | anchors.fill: parent | 189 | | ||
175 | clearButtonShown: true | 190 | placeholderText: i18n("Search...") | ||
176 | visible: opacity > 0 | | |||
177 | placeholderText: i18nc("Type is a verb here, not a noun", "Type to search...") | | |||
178 | Behavior on opacity { NumberAnimation { duration: searchWidget.animationDuration / 4 } } | | |||
179 | 191 | | |||
180 | onTextChanged: { | 192 | onTextChanged: { | ||
181 | if (root.state != "Search") { | 193 | if (root.state != "Search") { | ||
182 | root.previousState = root.state; | 194 | root.previousState = root.state; | ||
183 | root.state = "Search"; | 195 | root.state = "Search"; | ||
184 | } | 196 | } | ||
185 | if (text == "") { | 197 | if (text == "") { | ||
186 | root.state = root.previousState; | 198 | root.state = root.previousState; | ||
187 | header.state = "info"; | | |||
188 | } else { | | |||
189 | header.state = "query"; | | |||
190 | } | | |||
191 | } | | |||
192 | } | | |||
193 | } | 199 | } | ||
194 | } | 200 | } | ||
195 | 201 | | |||
196 | states: [ | 202 | anchors { | ||
197 | State { | 203 | left: faceIcon.right | ||
198 | name: "info" | 204 | bottom: faceIcon.bottom | ||
199 | PropertyChanges { | 205 | right: parent.right | ||
200 | target: infoLabel | 206 | leftMargin: units.gridUnit | ||
201 | opacity: searchWidget.normalOpacity | 207 | rightMargin: units.gridUnit | ||
202 | y: 0 | | |||
203 | } | | |||
204 | PropertyChanges { | | |||
205 | target: hintLabel | | |||
206 | opacity: 0 | | |||
207 | y: searchWidget.yOffset | | |||
208 | } | 208 | } | ||
209 | PropertyChanges { | 209 | | ||
210 | target: queryField | 210 | // Implement our own clear button because the PC3 version doesn't have one | ||
211 | opacity: 0 | 211 | // (https://bugs.kde.org/show_bug.cgi?id=396828) | ||
davidedmundson: No working round Plasma code in Plasma. | |||||
212 | // FIXME: Replace this Row and everything in it with "clearButtonShown: true" | ||||
213 | // once we can use the PC2 version again after 396813 is fixed | ||||
214 | Row { | ||||
215 | anchors { | ||||
216 | right: queryField.right | ||||
217 | rightMargin: 6 | ||||
218 | verticalCenter: queryField.verticalCenter | ||||
212 | } | 219 | } | ||
213 | }, | 220 | PlasmaCore.IconItem { | ||
214 | State { | 221 | //ltr confusingly refers to the direction of the arrow in the icon, not the text direction which it should be used in | ||
215 | name: "hint" | 222 | source: LayoutMirroring.enabled ? "edit-clear-locationbar-ltr" : "edit-clear-locationbar-rtl" | ||
216 | PropertyChanges { | 223 | height: Math.max(queryField.height * 0.8, units.iconSizes.small) | ||
217 | target: infoLabel | 224 | width: height | ||
218 | y: -searchWidget.yOffset | 225 | opacity: (queryField.length > 0 && queryField.enabled) ? 1 : 0 | ||
219 | opacity: 0 | 226 | visible: opacity > 0 | ||
227 | Behavior on opacity { | ||||
228 | NumberAnimation { | ||||
229 | duration: units.longDuration | ||||
230 | easing.type: Easing.InOutQuad | ||||
220 | } | 231 | } | ||
221 | PropertyChanges { | | |||
222 | target: hintLabel | | |||
223 | y: 0 | | |||
224 | opacity: searchWidget.normalOpacity | | |||
225 | } | 232 | } | ||
226 | PropertyChanges { | 233 | MouseArea { | ||
227 | target: queryField | 234 | anchors.fill: parent | ||
228 | opacity: 0 | 235 | onClicked: { | ||
236 | queryField.text = "" | ||||
237 | queryField.forceActiveFocus() | ||||
229 | } | 238 | } | ||
230 | }, | | |||
231 | State { | | |||
232 | name: "query" | | |||
233 | PropertyChanges { | | |||
234 | target: infoLabel | | |||
235 | opacity: 0 | | |||
236 | } | 239 | } | ||
237 | PropertyChanges { | | |||
238 | target: hintLabel | | |||
239 | opacity: 0 | | |||
240 | } | 240 | } | ||
241 | PropertyChanges { | | |||
242 | target: queryField | | |||
243 | opacity: 1 | | |||
244 | } | 241 | } | ||
245 | } | 242 | } | ||
246 | ] // states | | |||
247 | } | 243 | } |
What's this about? Negative offsets are weird, and we also have a 300ms animation to move 1px?