diff --git a/lookandfeel/contents/components/BatteryIcon.qml b/lookandfeel/contents/components/BatteryIcon.qml new file mode 100644 index 000000000..308eaf85c --- /dev/null +++ b/lookandfeel/contents/components/BatteryIcon.qml @@ -0,0 +1,100 @@ +/* + * Copyright 2011 Viranch Mehta + * Copyright 2013 Kai Uwe Broulik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.0 +import org.kde.plasma.core 2.0 as PlasmaCore + +Item { + property bool hasBattery + property int percent + property bool pluggedIn + + PlasmaCore.Svg { + id: svg + imagePath: "icons/battery" + } + + PlasmaCore.SvgItem { + id: batterySvg + anchors.fill: parent + svg: svg + elementId: "Battery" + } + + PlasmaCore.SvgItem { + id: fillSvg + anchors.fill: parent + svg: svg + elementId: hasBattery ? fillElement(percent) : "Unavailable" + visible: elementId != "" + } + + function fillElement(p) { + // We switched from having steps of 20 for the battery percentage to a more accurate + // step of 10. This means we break other and older themes. + // If the Fill10 element is not found, it is likely that the theme doesn't support + // that and we use the older method of obtaining the fill element. + if (!svg.hasElement("Fill10")) { + print("No Fill10 element found in your theme's battery.svg - Using legacy 20% steps for battery icon"); + if (p >= 90) { + return "Fill100"; + } else if (p >= 70) { + return "Fill80"; + } else if (p >= 50) { + return "Fill60"; + } else if (p > 20) { + return "Fill40"; + } else if (p >= 10) { + return "Fill20"; + } + return ""; + } else { + if (p >= 95) { + return "Fill100"; + } else if (p >= 85) { + return "Fill90"; + } else if (p >= 75) { + return "Fill90"; + } else if (p >= 65) { + return "Fill80"; + } else if (p >= 55) { + return "Fill60"; + } else if (p >= 45) { + return "Fill50"; + } else if (p >= 35) { + return "Fill40"; + } else if (p >= 25) { + return "Fill30"; + } else if (p >= 15) { + return "Fill20"; + } else if (p > 5) { + return "Fill10"; + } + return ""; + } + } + + PlasmaCore.SvgItem { + anchors.fill: parent + svg: svg + elementId: "AcAdapter" + visible: pluggedIn + } +} diff --git a/lookandfeel/contents/components/InfoPane.qml b/lookandfeel/contents/components/InfoPane.qml new file mode 100644 index 000000000..d6416737a --- /dev/null +++ b/lookandfeel/contents/components/InfoPane.qml @@ -0,0 +1,70 @@ +import QtQuick 2.0 +import QtQuick.Layouts 1.1 +import org.kde.plasma.components 2.0 as PlasmaComponents +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.extras 2.0 as PlasmaExtras + +ColumnLayout { + PlasmaComponents.Label { //should be a heading but we want it _loads_ bigger + text: Qt.formatTime(timeSource.data["Local"]["Time"], Locale.ShortFormat) + //we fill the width then align the text so that we can make the text shrink to fit + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + + font.weight: Font.DemiBold + fontSizeMode: Text.HorizontalFit + font.pointSize: 36 + } + + PlasmaComponents.Label { + text: Qt.formatDate(timeSource.data["Local"]["Date"], Locale.LongFormat); + Layout.alignment: Qt.AlignRight + } + + RowLayout { + Layout.alignment: Qt.AlignRight + visible: pmSource.connectedSources != "" + + BatteryIcon { + hasBattery: true + percent: pmSource.data["Battery0"]["Percent"] + pluggedIn: pmSource.data["AC Adapter"]["Plugged in"] + + height: 20 //FIXME + width: 20 + } + + PlasmaComponents.Label { + text: i18n("%1\% battery remaining", pmSource.data["Battery0"]["Percent"]) + Layout.alignment: Qt.AlignRight + wrapMode: Text.Wrap + } + } + + + PlasmaCore.DataSource { + id: pmSource + engine: "powermanagement" + connectedSources: sources + onSourceAdded: { + if (source == "Battery0") { + disconnectSource(source); + connectSource(source); + } + } + onSourceRemoved: { + if (source == "Battery0") { + disconnectSource(source); + } + } + } + + PlasmaCore.DataSource { + id: timeSource + engine: "time" + connectedSources: ["Local"] + interval: 1000 + } + + +} diff --git a/lookandfeel/contents/components/UserList.qml b/lookandfeel/contents/components/UserList.qml new file mode 100644 index 000000000..cff4e2c83 --- /dev/null +++ b/lookandfeel/contents/components/UserList.qml @@ -0,0 +1,116 @@ +import QtQuick 2.0 + +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents + +ListView { + + property int userItemWidth: 140 + property int userItemHeight: 140 + property int userFaceSize: 88 + property int padding: 4 + + delegate: userDelegate + focus: true + + orientation: ListView.Horizontal + + highlightRangeMode: ListView.StrictlyEnforceRange + + readonly property string selectedUser: currentItem.userName //FIXME read only + + Component { + id: userDelegate + + Item { + id: wrapper + + property bool isCurrent: ListView.isCurrentItem + + property string name: (model.realName === "") ? model.name : model.realName + property string userName: model.name + + width: userItemWidth + height: userItemHeight + + opacity: isCurrent ? 1.0 : 0.618 + + Rectangle {//debug + visible: debug + border.color: "blue" + border.width: 1 + anchors.fill: parent + color: "#00000000" + z:-1000 + } + + Behavior on opacity { + NumberAnimation { + duration: 250 + } + } + + Item { + id: imageWrapper + scale: isCurrent ? 1.0 : 0.8 + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + + height: frame.height + + Behavior on scale { + NumberAnimation { + duration: 100 + } + } + + //TODO there code was to show a blue border on mouseover + //which shows that something is interactable. + //we can't have that whilst using widgets/background as the base + //I'd quite like it back + + PlasmaCore.FrameSvgItem { + id: frame + width: face.width + padding * 6 + height: face.height + padding * 6 + imagePath: "widgets/background" + + anchors.horizontalCenter: parent.horizontalCenter + } + + PlasmaCore.IconItem { + id: face + anchors.centerIn: frame + width: userFaceSize + height: userFaceSize + source: model.icon ? model.icon : "user-identity" + } + } + + PlasmaComponents.Label { + id: loginText + anchors.top: imageWrapper.bottom + anchors.topMargin: -10 + anchors.left: parent.left + anchors.right: parent.right + text: name + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + maximumLineCount: 2 + wrapMode: Text.Wrap + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: { + wrapper.ListView.view.currentIndex = index; + wrapper.ListView.view.forceActiveFocus(); + } + } + } + } + +} diff --git a/lookandfeel/contents/components/UserSelect.qml b/lookandfeel/contents/components/UserSelect.qml new file mode 100644 index 000000000..155b29b7b --- /dev/null +++ b/lookandfeel/contents/components/UserSelect.qml @@ -0,0 +1,72 @@ +import QtQuick 2.1 +import QtQuick.Layouts 1.1 + +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents + +Item { + height: usersList.height + + property alias model: usersList.model + property alias selectedUser: usersList.selectedUser + + InfoPane { + id: infoPane + anchors { + verticalCenter: usersList.verticalCenter + right: usersList.left + left: parent.left + } + } + + UserList { + id: usersList + + Rectangle {//debug + visible: debug + border.color: "red" + border.width: 1 + anchors.fill: parent + color: "#00000000" + z:-1000 + } + + anchors { + top: parent.top + left: parent.horizontalCenter + right: parent.right + + leftMargin: -userItemWidth*1.5 //allow 1 item to the left of the centre (the half is to fit the item that will go in the centre) + } + clip: true + height: userItemHeight + // / currentIndex: indexForUserName(greeter.lastLoggedInUser) + cacheBuffer: 1000 + + //highlight the item in the middle. The actual list view starts -1.5 userItemWidths so this moves the highlighted item to the centre + preferredHighlightBegin: userItemWidth * 1 + preferredHighlightEnd: userItemWidth * 2 + + //if the user presses down or enter, focus password + //if user presses any normal key + //copy that character pressed to the pasword box and force focus + + //can't use forwardTo as I want to switch focus. Also it doesn't work. + Keys.onPressed: { + if (event.key == Qt.Key_Down || + event.key == Qt.Key_Enter || + event.key == Qt.Key_Return) { + passwordInput.forceActiveFocus(); + } else if (event.key & Qt.Key_Escape) { + //if special key, do nothing. Qt.Escape is 0x10000000 which happens to be a mask used for all special keys in Qt. + } else { + passwordInput.text += event.text; + passwordInput.forceActiveFocus(); + } + } + + Component.onCompleted: { + currentIndex = 0; + } + } +} diff --git a/lookandfeel/contents/components/artwork/background.png b/lookandfeel/contents/components/artwork/background.png new file mode 100644 index 000000000..af2a07523 Binary files /dev/null and b/lookandfeel/contents/components/artwork/background.png differ