diff --git a/sddm-theme/ActionButton.qml b/sddm-theme/ActionButton.qml new file mode 100644 --- /dev/null +++ b/sddm-theme/ActionButton.qml @@ -0,0 +1,71 @@ +/* + * Copyright 2016 David Edmundson + * + * 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.2 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents + +Item { + id: root + property alias text: label.text + property alias iconSource: icon.source + signal clicked + + activeFocusOnTab: true + + implicitWidth: units.gridUnit * 4 + implicitHeight: units.gridUnit * 3 + units.smallSpacing + label.implicitHeight + + PlasmaCore.IconItem { + id: icon + anchors { + top: parent.top + left: parent.left + right: parent.right + } + active: mouseArea.containsMouse || root.activeFocus + } + PlasmaComponents.Label { + id: label + anchors { + top: icon.bottom + topMargin: units.smallSpacing + left: parent.left + right: parent.right + } + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignTop + wrapMode: Text.Wrap + } + + MouseArea { + id: mouseArea + hoverEnabled: true + onClicked: root.clicked() + anchors.fill: parent + } + + Keys.onEnterPressed: clicked() + Keys.onReturnPressed: clicked() + Keys.onSpacePressed: clicked() + + Accessible.onPressAction: clicked() + Accessible.role: Accessible.Button + Accessible.name: label.text +} diff --git a/sddm-theme/Background.qml b/sddm-theme/Background.qml --- a/sddm-theme/Background.qml +++ b/sddm-theme/Background.qml @@ -27,26 +27,13 @@ FocusScope { - id: container - property alias source: image.source property alias fillMode: image.fillMode property alias status: image.status - LinearGradient { - x: geometry.x; y: geometry.y; width: geometry.width; height:geometry.height - gradient: Gradient { - GradientStop { - position: 0.0 - color: "#1fb4f9" - } - GradientStop { - position: 1.0 - color: "#197cf1" - } - } - cached: true - visible: image.status == Image.Null || image.status == Image.Error + Rectangle { + anchors.fill: parent + color: "#1d99f3" } Image { @@ -57,9 +44,4 @@ focus: true smooth: true } - - MouseArea { - anchors.fill: parent - onClicked: container.focus = true - } } diff --git a/sddm-theme/BatteryIcon.qml b/sddm-theme/BatteryIcon.qml deleted file mode 100644 --- a/sddm-theme/BatteryIcon.qml +++ /dev/null @@ -1,134 +0,0 @@ -/* - * 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 - property string batteryType - - PlasmaCore.Svg { - id: svg - imagePath: "icons/battery" - colorGroup: PlasmaCore.ColorScope.colorGroup - onRepaintNeeded: { // needed to detect the hint item go away when theme changes - batterySvg.visible = Qt.binding(function() { return !otherBatteriesSvg.visible && (!svg.hasElement("hint-dont-superimpose-fill") || !hasBattery); }) - } - } - - PlasmaCore.SvgItem { - id: batterySvg - anchors.centerIn: parent - width: units.roundToIconSize(Math.min(parent.width, parent.height)) - height: width - svg: svg - elementId: "Battery" - visible: !otherBatteriesSvg.visible && (!svg.hasElement("hint-dont-superimpose-fill") || !hasBattery) - } - - PlasmaCore.SvgItem { - id: fillSvg - anchors.fill: batterySvg - svg: svg - elementId: hasBattery ? fillElement(percent) : "Unavailable" - visible: !otherBatteriesSvg.visible - } - - 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"; - } else { - return "Fill0"; - } - } else { - if (p >= 95) { - return "Fill100"; - } else if (p >= 85) { - return "Fill90"; - } else if (p >= 75) { - return "Fill80"; - } else if (p >= 65) { - return "Fill70"; - } 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"; - } else { - return "Fill0"; - } - } - } - - PlasmaCore.SvgItem { - anchors.fill: batterySvg - svg: svg - elementId: "AcAdapter" - visible: pluggedIn && !otherBatteriesSvg.visible - } - - PlasmaCore.IconItem { - id: otherBatteriesSvg - anchors.fill: batterySvg - source: elementForType(batteryType) - visible: source !== "" - } - - function elementForType(t) { - switch(t) { - case "Mouse": - return "input-mouse-battery"; - case "Keyboard": - return "input-keyboard-battery"; - case "Pda": - return "phone-battery"; - case "Phone": - return "phone-battery"; - case "Ups": - return "battery-ups"; - default: - return ""; - } - } -} diff --git a/sddm-theme/Clock.qml b/sddm-theme/Clock.qml new file mode 100644 --- /dev/null +++ b/sddm-theme/Clock.qml @@ -0,0 +1,43 @@ +/* + * Copyright 2016 David Edmundson + * + * 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 QtQuick.Layouts 1.1 + +import org.kde.plasma.core 2.0 +import org.kde.plasma.components 2.0 + +ColumnLayout { + Label { + text: Qt.formatTime(timeSource.data["Local"]["DateTime"]) + font.pointSize: 32 //Mockup says this, I'm not sure what to do? + Layout.alignment: Qt.AlignHCenter + } + Label { + text: Qt.formatDate(timeSource.data["Local"]["DateTime"], Qt.DefaultLocaleLongDate) + font.pointSize: 18 + Layout.alignment: Qt.AlignHCenter + } + DataSource { + id: timeSource + engine: "time" + connectedSources: ["Local"] + interval: 1000 + } +} diff --git a/sddm-theme/KeyboardButton.qml b/sddm-theme/KeyboardButton.qml --- a/sddm-theme/KeyboardButton.qml +++ b/sddm-theme/KeyboardButton.qml @@ -10,10 +10,10 @@ property int currentIndex: -1 - text: instantiator.objectAt(currentIndex).shortName + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Keyboard Layout: %1", instantiator.objectAt(currentIndex).shortName) implicitWidth: minimumWidth - Component.onCompleted: currentIndex = Qt.binding(function() {return keyboard.currentLayout}); + Component.onCompleted: currentIndex = Qt.binding(function() {return keyboard.currentLayout}); menu: QQC.Menu { id: keyboardMenu diff --git a/sddm-theme/Login.qml b/sddm-theme/Login.qml --- a/sddm-theme/Login.qml +++ b/sddm-theme/Login.qml @@ -1,3 +1,22 @@ +/* + * Copyright 2016 David Edmundson + * + * 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.2 import QtQuick.Layouts 1.1 @@ -9,140 +28,132 @@ Item { id: root - property bool searching: false - property bool loggingIn: false - property string notificationMessage - property int sessionIndex + /* + * Whether a text box for the user to type a username should be visible + */ + property bool showUsernamePrompt: false + /* + * Any message to be displayed to the user, visible above the text fields + */ + property alias notificationMessage: notificationsLabel.text + + /* + * A list of Items (typically ActionButtons) to be shown in a Row beneath the prompts + */ + property alias actionItems: actionItemsLayout.children + + /* + * A model with a list of users to show in the view + * The following roles should exist: + * - name + * - iconSource + */ + property alias userListModel: userList.model + + /* + * Self explanatory + */ + property alias userListCurrentIndex: userList.currentIndex + + + /* + * Login has been requested with the following username and password + * If username field is visible, it will be taken from that, otherwise from the "name" property of the currentIndex + */ + signal loginRequest(string username, string password) - onSearchingChanged: { - if (searching) { - mainStack.push(usernameInput); - } else { - mainStack.pop(); - } - mainStack.currentItem.forceActiveFocus(); + function startLogin() { + var username = showUsernamePrompt ? userNameInput.text : userList.selectedUser + var password = passwordBox.text + loginRequest(username, password); } - Component { - id: userView - //even though stackview is a scope in itself we need a spacer item to align the user list - //so that components are always the same height. - //if the stackview changes height the animation looks weird + UserList { + id: userList + anchors { + bottom: parent.verticalCenter + left: parent.left + right: parent.right + } + onUserSelected: passwordBox.forceActiveFocus() + } - //FocusScope rather than Item to focus proxy onto the user list - FocusScope { - function incrementCurrentIndex() { - userList.incrementCurrentIndex(); - } + ColumnLayout { + id: prompts + anchors.top: parent.verticalCenter + anchors.topMargin: units.gridUnit * 0.5 + anchors.horizontalCenter: parent.horizontalCenter - function decrementCurrentIndex() { - userList.decrementCurrentIndex() - } + height: Math.max(implicitHeight, units.gridUnit * 10) + width: Math.max(implicitWidth, units.gridUnit * 16) - property alias userName: userList.selectedUser + PlasmaComponents.Label { + id: notificationsLabel - UserList { - id: userList - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - model: userModel - focus: true - onUserSelected: nextItemInFocusChain().forceActiveFocus() - } - } - } + Layout.fillWidth: true - Component { - id: usernameInput - FocusScope { - property alias userName: userNameInput.text - - PlasmaComponents.TextField { - id: userNameInput - focus: true - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Username"); - } + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + font.italic: true } - } - function startLogin() { - root.loggingIn = true - root.notificationMessage = "" - sddm.login(mainStack.currentItem.userName, passwordBox.text, sessionButton.currentIndex) - } + PlasmaComponents.TextField { + id: userNameInput + Layout.fillWidth: true - Connections { - target: sddm - onLoginFailed: { - root.loggingIn = false - root.notificationMessage = i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login Failed") + visible: showUsernamePrompt + focus: showUsernamePrompt //if there's a username prompt it gets focus first, otherwise password does + placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Username"); } - } + PlasmaComponents.TextField { + id: passwordBox + Layout.fillWidth: true - //main bit: - StackView { - id: mainStack - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: passwordBox.top - anchors.bottomMargin: units.smallSpacing + placeholderText: "Password" + focus: !showUsernamePrompt + echoMode: TextInput.Password - initialItem: userView - } - - PlasmaComponents.TextField { - id: passwordBox - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: units.largeSpacing * 5 - placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Password") - focus: true - echoMode: TextInput.Password - - enabled: !loggingIn + onAccepted: startLogin() - onAccepted: startLogin() + Keys.onEscapePressed: { + mainStack.currentItem.forceActiveFocus(); + } - Keys.onEscapePressed: { - mainStack.currentItem.forceActiveFocus(); + //if empty and left or right is pressed change selection in user switch + //this cannot be in keys.onLeftPressed as then it doesn't reach the password box + Keys.onPressed: { + if (event.key == Qt.Key_Left && !text) { + userList.decrementCurrentIndex(); + event.accepted = true + } + if (event.key == Qt.Key_Right && !text) { + userList.incrementCurrentIndex(); + event.accepted = true + } + } } + PlasmaComponents.Button { + id: loginButton + Layout.fillWidth: true - //if empty and left or right is pressed change selection in user switch - //this cannot be in keys.onLeftPressed as then it doesn't reach the password box - Keys.onPressed: { - if (event.key == Qt.Key_Left && !text && mainStack.currentItem.decrementCurrentIndex) { - mainStack.currentItem.decrementCurrentIndex(); - event.accepted = true - } - if (event.key == Qt.Key_Right && !text && mainStack.currentItem.incrementCurrentIndex) { - mainStack.currentItem.incrementCurrentIndex(); - event.accepted = true - } + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login") + onClicked: startLogin(); + } + Item { + Layout.fillHeight: true } } - PlasmaComponents.Button { - id: loginButton - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: passwordBox.bottom - anchors.topMargin: units.smallSpacing - - text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login") - enabled: !loggingIn + Row { //deliberately not rowlayout as I'm not trying to resize child items + id: actionItemsLayout + spacing: units.smallSpacing - onClicked: startLogin(); - } - - PlasmaComponents.Label { - id: notificationsLabel - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: loginButton.bottom - anchors.topMargin: units.smallSpacing - text: root.notificationMessage + //align centre, but cap to the width of the screen + anchors { + top: prompts.bottom + topMargin: units.gridUnit * 0.25 + horizontalCenter: parent.horizontalCenter + } } } diff --git a/sddm-theme/Main.qml b/sddm-theme/Main.qml --- a/sddm-theme/Main.qml +++ b/sddm-theme/Main.qml @@ -1,5 +1,5 @@ /* - * Copyright 2014 David Edmundson + * Copyright 2016 David Edmundson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -29,9 +29,12 @@ PlasmaCore.ColorScope { id: root colorGroup: PlasmaCore.Theme.ComplementaryColorGroup + width: 1600 height: 900 + property string notificationMessage + LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft LayoutMirroring.childrenInherit: true @@ -45,100 +48,149 @@ } } - Login { - id: login - sessionIndex: sessionButton.currentIndex - - anchors.top: parent.top - anchors.topMargin: footer.height - anchors.bottom: footer.top - anchors.left: parent.left - anchors.right: parent.right - focus: true + Clock { + anchors.bottom: parent.verticalCenter + anchors.bottomMargin: units.gridUnit * 13 + anchors.horizontalCenter: parent.horizontalCenter } - //Footer - RowLayout { - id: footer - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: units.smallSpacing - SessionButton { - id: sessionButton - Component.onCompleted: { - currentIndex = sessionModel.lastIndex + StackView { + id: mainStack + anchors { + top: parent.top + bottom: footer.top + left: parent.left + right: parent.right + topMargin: footer.height // effectively centre align within the view + } + focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it + initialItem: Login { + userListModel: userModel + userListCurrentIndex: userModel.lastIndex >= 0 ? userModel.lastIndex : 0 + + notificationMessage: root.notificationMessage + + actionItems: [ + ActionButton { + iconSource: "system-suspend" + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Suspend") + onClicked: sddm.suspend() + enabled: sddm.canSuspend + }, + ActionButton { + iconSource: "system-reboot" + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Restart") + onClicked: sddm.reboot() + enabled: sddm.canReboot + }, + ActionButton { + iconSource: "system-shutdown" + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Shutdown") + onClicked: sddm.powerOff() + enabled: sddm.canPowerOff + }, + ActionButton { + iconSource: "system-search" + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Different User") + onClicked: mainStack.push(userPrompt) + enabled: true + } + ] + + onLoginRequest: { + root.notificationMessage = "" + sddm.login(username, password, sessionButton.currentIndex) } } - PlasmaComponents.ToolButton { - implicitWidth: minimumWidth - property alias searching : login.searching - iconSource: searching ? "edit-select" : "search" - text: searching ? i18nd("plasma_lookandfeel_org.kde.lookandfeel","Select User") : i18nd("plasma_lookandfeel_org.kde.lookandfeel","Search for User") - - onClicked: { - searching = !searching + Behavior on opacity { + OpacityAnimator { + duration: units.longDuration } } - Item { - Layout.fillWidth: true - } - PlasmaComponents.ToolButton { - iconSource: "system-suspend" - text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Suspend") - implicitWidth: minimumWidth - onClicked: sddm.suspend() - visible: sddm.canSuspend + } + + Component { + id: userPrompt + Login { + showUsernamePrompt: true + notificationMessage: root.notificationMessage + + userListModel: QtObject { + property string name: i18nd("plasma_lookandfeel_org", "Login as different user") + property string iconSource: "" + } + + onLoginRequest: { + root.notificationMessage = "" + sddm.login(username, password, sessionButton.currentIndex) + } + + actionItems: [ + ActionButton { + iconSource: "system-suspend" //FIXME waiting on VDG to tell me icon name + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Back") + onClicked: mainStack.pop() + } + ] } + } - PlasmaComponents.ToolButton { - iconSource: "system-reboot" - text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Restart") - implicitWidth: minimumWidth - onClicked: sddm.reboot() - visible: sddm.canReboot + //Footer + RowLayout { + id: footer + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + margins: units.smallSpacing } - PlasmaComponents.ToolButton { - iconSource: "system-shutdown" - text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Shutdown") - implicitWidth: minimumWidth - onClicked: sddm.powerOff() - visible: sddm.canPowerOff + Behavior on opacity { + OpacityAnimator { + duration: units.longDuration + } } - BatteryIcon { - implicitWidth: units.iconSizes.medium - implicitHeight: units.iconSizes.medium + KeyboardButton { + } - visible: pmSource.data["Battery"]["Has Cumulative"] + SessionButton { + id: sessionButton + } - hasBattery: true - percent: pmSource.data["Battery"]["Percent"] - pluggedIn: pmSource.data["AC Adapter"] ? pmSource.data["AC Adapter"]["Plugged in"] : false + Item { + Layout.fillWidth: true + } + } - PlasmaCore.DataSource { - id: pmSource - engine: "powermanagement" - connectedSources: ["Battery", "AC Adapter"] - } + Connections { + target: sddm + onLoginFailed: { + notificationMessage = i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login Failed") } - KeyboardButton { + onLoginSucceeded: { + //note SDDM will kill the greeter at some random point after this + //there is no certainty any transition will finish, it depends on the time it + //takes to complete the init + mainStack.opacity = 0 + footer.opacity = 0 } + } - PlasmaComponents.Label { - text: Qt.formatTime(timeSource.data["Local"]["DateTime"]) - //Do I need the FontMetrics magic to set implicitWidth? - PlasmaCore.DataSource { - id: timeSource - engine: "time" - connectedSources: ["Local"] - interval: 1000 - } + onNotificationMessageChanged: { + if (notificationMessage) { + notificationResetTimer.start(); } } + + Timer { + id: notificationResetTimer + interval: 3000 + onTriggered: notificationMessage = "" + } + } diff --git a/sddm-theme/README.txt b/sddm-theme/README.txt deleted file mode 100644 --- a/sddm-theme/README.txt +++ /dev/null @@ -1,10 +0,0 @@ -This is a display manager theme for SDDM - -It installs into ${INSTALL_PREFIX}/sddm/themes -A copy of components is installed into the same path - -components is deliberately imported as "components" for this reason - -For testing, I recommend symlinking ../lookandfeel/contents/components/ into components -When testing, don't wonder about the white space left of the login promt. This is a simulation of 2 screens, -and the login promt should only appear on primary (right) screen (there is no config dummydata, so the background isn't paintet). diff --git a/sddm-theme/SessionButton.qml b/sddm-theme/SessionButton.qml --- a/sddm-theme/SessionButton.qml +++ b/sddm-theme/SessionButton.qml @@ -1,3 +1,22 @@ +/* + * Copyright 2016 David Edmundson + * + * 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.2 import org.kde.plasma.core 2.0 as PlasmaCore @@ -12,7 +31,12 @@ implicitWidth: minimumWidth iconSource: "" - text: instantiator.objectAt(currentIndex).text + + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Desktop Session: %1", instantiator.objectAt(currentIndex).text || "") + + Component.onCompleted: { + currentIndex = sessionModel.lastIndex + } menu: QQC.Menu { id: menu diff --git a/sddm-theme/UserDelegate.qml b/sddm-theme/UserDelegate.qml --- a/sddm-theme/UserDelegate.qml +++ b/sddm-theme/UserDelegate.qml @@ -31,16 +31,14 @@ property string name property string userName property string iconSource - - implicitWidth: units.gridUnit * 8 //6 wide + 1 either side spacing - implicitHeight: units.gridUnit * 7 + usernameDelegate.implicitHeight - signal clicked() + property real faceSize: Math.min(width, height - usernameDelegate.height - units.smallSpacing) + Item { id: imageSource - implicitWidth: units.gridUnit * 6 - implicitHeight: implicitWidth + width: faceSize + height: faceSize //we sometimes have a path to an image sometimes an icon //IconItem tries to load a full path as an icon which is rubbish @@ -57,15 +55,16 @@ source: visible ? "user-identity" : undefined visible: (face.status == Image.Error || face.status == Image.Null) anchors.fill: parent + anchors.margins: units.gridUnit * 0.5 // because mockup says so... } } ShaderEffect { anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter - implicitWidth: imageSource.width - implicitHeight: imageSource.height + width: imageSource.width + height: imageSource.height supportsAtlasTextures: true @@ -75,24 +74,24 @@ live: false } - property var colorBorder: theme.buttonFocusColor + property var colorBorder: PlasmaCore.ColorScope.textColor //draw a circle with an antialised border //innerRadius = size of the inner circle with contents //outerRadius = size of the border //blend = area to blend between two colours //all sizes are normalised so 0.5 == half the width of the texture - //if copying into another project don't forget to * qt_Opacity. It's just unused here - //and connect themeChanged to update() + //if copying into another project don't forget to connect themeChanged to update() + //but in SDDM that's a bit pointless fragmentShader: " varying highp vec2 qt_TexCoord0; uniform highp float qt_Opacity; uniform lowp sampler2D source; uniform vec4 colorBorder; float blend = 0.01; - float innerRadius = 0.48; + float innerRadius = 0.47; float outerRadius = innerRadius + 0.02; vec4 colorEmpty = vec4(0.0, 0.0, 0.0, 0.0); @@ -111,7 +110,9 @@ else if (dist < outerRadius + blend) gl_FragColor = mix(colorBorder, colorEmpty, ((dist - outerRadius) / blend)); else - gl_FragColor = colorEmpty; + gl_FragColor = colorEmpty ; + + gl_FragColor = gl_FragColor * qt_Opacity; } " } @@ -125,10 +126,11 @@ left: parent.left right: parent.right } + height: implicitHeight // work around stupid bug in Plasma Components that sets the height text: wrapper.name elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter - //make an indication that this has active focus, this only happens when reached with text navigation + //make an indication that this has active focus, this only happens when reached with keyboard navigation font.underline: wrapper.activeFocus } diff --git a/sddm-theme/UserList.qml b/sddm-theme/UserList.qml --- a/sddm-theme/UserList.qml +++ b/sddm-theme/UserList.qml @@ -47,6 +47,9 @@ userName: model.name iconSource: model.icon || "" + width: userItemWidth + height: userItemHeight + onClicked: { ListView.view.currentIndex = index; ListView.view.userSelected(); diff --git a/sddm-theme/dummydata/sddm.qml b/sddm-theme/dummydata/sddm.qml --- a/sddm-theme/dummydata/sddm.qml +++ b/sddm-theme/dummydata/sddm.qml @@ -23,15 +23,22 @@ function login(user, password, sessionIndex) { - console.log("SDDM - logging in as ", user, password) - //pretend login failed + console.log("SDDM - logging in as ", user, password, sessionIndex) + + //modify as appropriate for testing + var success = false + + if (success) { + loginSucceeded(); + } else { + tryLogin.start(); + } - tryLogin.start(); } Timer { id: tryLogin - interval: 3000 + interval: 1000 onTriggered: loginFailed(); }