diff options
| author | gabeszm <vgabor92@protonmail.com> | 2026-09-13 10:48:36 +0200 |
|---|---|---|
| committer | gabeszm <vgabor92@protonmail.com> | 2026-09-13 10:48:36 +0200 |
| commit | b132f616fc27a62ad9612ec42a19b027e72a52b7 (patch) | |
| tree | bf4d29f6c4246d560fb3cd97aba059f638191ed5 /raveos-sddm-theme/sddm-rave-theme/Components/Input.qml | |
| parent | a65fb557cfce85e27448139e9c0317c36b7d06cb (diff) | |
| download | RaveOS-PKGBUILD-b132f616fc27a62ad9612ec42a19b027e72a52b7.tar.gz RaveOS-PKGBUILD-b132f616fc27a62ad9612ec42a19b027e72a52b7.zip | |
fix responsive ui
Diffstat (limited to 'raveos-sddm-theme/sddm-rave-theme/Components/Input.qml')
| -rw-r--r-- | raveos-sddm-theme/sddm-rave-theme/Components/Input.qml | 923 |
1 files changed, 615 insertions, 308 deletions
diff --git a/raveos-sddm-theme/sddm-rave-theme/Components/Input.qml b/raveos-sddm-theme/sddm-rave-theme/Components/Input.qml index 47e6598..daf3ba0 100644 --- a/raveos-sddm-theme/sddm-rave-theme/Components/Input.qml +++ b/raveos-sddm-theme/sddm-rave-theme/Components/Input.qml @@ -4,14 +4,16 @@ // Distributed under the GPLv3+ License https://www.gnu.org/licenses/gpl-3.0.html import QtQuick 2.15 -import QtQuick.Layouts 1.15 +import QtQuick.Layouts 6.5 import QtQuick.Controls 2.15 -import QtQuick.Effects +import QtQuick.Effects 6.5 Column { id: inputContainer + width: parent.width Layout.fillWidth: true + clip: true property ComboBox exposeSession: sessionSelect.exposeSession property bool failed @@ -21,7 +23,7 @@ Column { // change also in selectSession height: root.font.pointSize * 2 - width: parent.width / 2 + width: parent.width anchors.horizontalCenter: parent.horizontalCenter Label { @@ -65,43 +67,176 @@ Column { } } - // Profilkép + felhasználóváltó + // Profilkép Item { id: avatarField - height: root.font.pointSize * 12 - width: parent.width / 2 + height: Math.min(root.font.pointSize * 6.5, parent.width * 0.35) + width: parent.width anchors.horizontalCenter: parent.horizontalCenter - property string userIconPath: { - var icon = userModel.data(userModel.index(selectUser.currentIndex, 0), Qt.UserRole + 4) - return (icon && icon !== "") ? icon : "" + property int currentAttempt: 0 + property var candidateIcons: [] + + function resolveIconCandidates(idx, name) { + var list = [] + var count = (typeof userModel !== "undefined" && userModel) ? userModel.count : 0 + + var uIndex = -1 + if (name && name !== "" && count > 0) { + for (var i = 0; i < count; i++) { + var qIdx = userModel.index(i, 0) + var uName = userModel.data(qIdx, Qt.UserRole + 1) + if (uName === name) { + uIndex = i + break + } + } + } + if (uIndex === -1) { + uIndex = (idx >= 0 && idx < count) ? idx : (userModel && userModel.lastIndex >= 0 ? userModel.lastIndex : 0) + } + + var directIcon = "" + var home = "" + var uName = name || "" + + if (count > 0 && uIndex >= 0 && uIndex < count) { + var qIdx = userModel.index(uIndex, 0) + directIcon = userModel.data(qIdx, Qt.UserRole + 4) || "" + home = userModel.data(qIdx, Qt.UserRole + 3) || "" + if (!uName || uName === "") { + uName = userModel.data(qIdx, Qt.UserRole + 1) || "" + } + } + + function addCandidate(p) { + if (!p || p === "") return + var s = p.toString().trim() + if (s === "") return + // Ignore generic silhouette icon installed in SDDM faces directory + if (s === "/usr/share/sddm/faces/.face.icon" || s === "file:///usr/share/sddm/faces/.face.icon") return + var url = (s.startsWith("file://") || s.startsWith("image://") || s.startsWith("qrc://") || s.startsWith("http")) ? s : ("file://" + s) + if (list.indexOf(url) === -1) { + list.push(url) + } + } + + // 1. Direct icon reported by SDDM (AccountsService or explicit face config) + if (directIcon !== "") { + addCandidate(directIcon) + } + + // 2. AccountsService system icons (standard across Linux - world-readable 644) + if (uName !== "") { + addCandidate("/var/lib/AccountsService/icons/" + uName) + addCandidate("/var/lib/AccountsService/icons/" + uName + ".png") + addCandidate("/var/lib/AccountsService/icons/" + uName + ".jpg") + addCandidate("/var/lib/AccountsService/icons/" + uName + ".jpeg") + addCandidate("/var/lib/AccountsService/icons/" + uName + ".svg") + } + + // 3. User's home directory faces + if (home !== "") { + addCandidate(home + "/.face") + addCandidate(home + "/.face.icon") + addCandidate(home + "/.face.png") + addCandidate(home + "/.face.jpg") + addCandidate(home + "/.face.jpeg") + addCandidate(home + "/.icon") + addCandidate(home + "/.avatar") + } + if (uName !== "") { + addCandidate("/home/" + uName + "/.face") + addCandidate("/home/" + uName + "/.face.icon") + addCandidate("/home/" + uName + "/.face.png") + addCandidate("/home/" + uName + "/.face.jpg") + addCandidate("/home/" + uName + "/.face.jpeg") + addCandidate("/home/" + uName + "/.icon") + addCandidate("/home/" + uName + "/.avatar") + } + + // 4. System SDDM faces directory + if (uName !== "") { + addCandidate("/usr/share/sddm/faces/" + uName + ".face.icon") + addCandidate("/usr/share/sddm/faces/" + uName + ".png") + addCandidate("/usr/share/sddm/faces/" + uName + ".jpg") + addCandidate("/usr/share/sddm/faces/" + uName) + addCandidate("/var/lib/sddm/faces/" + uName + ".face.icon") + addCandidate("/var/lib/sddm/faces/" + uName + ".png") + addCandidate("/var/lib/sddm/faces/" + uName + ".jpg") + addCandidate("/var/lib/sddm/faces/" + uName) + } + + // 5. Configured theme avatar + if (config.UserAvatar && config.UserAvatar !== "") { + addCandidate(config.UserAvatar) + } + if (config.DefaultAvatar && config.DefaultAvatar !== "") { + addCandidate(config.DefaultAvatar) + } + + return list + } + + function tryNextCandidate() { + if (currentAttempt < candidateIcons.length) { + var nextUrl = candidateIcons[currentAttempt] + currentAttempt++ + avatarPhoto.source = nextUrl + } else { + avatarPhoto.source = "" + } + } + + function updateAvatarSource() { + var targetUser = usernameField.selectedUsername + if (!targetUser && typeof userModel !== "undefined" && userModel && userModel.count > 0) { + targetUser = usernameField.getInitialUsername() + } + candidateIcons = resolveIconCandidates(usernameField.selectedUserIndex, targetUser) + currentAttempt = 0 + avatarPhoto.source = "" + if (candidateIcons.length > 0) { + tryNextCandidate() + } + } + + Component.onCompleted: updateAvatarSource() + + Connections { + target: usernameField + function onSelectedUsernameChanged() { avatarField.updateAvatarSource() } + function onSelectedUserIndexChanged() { avatarField.updateAvatarSource() } } - Column { + Connections { + target: (typeof userModel !== "undefined") ? userModel : null + function onRowsInserted() { avatarField.updateAvatarSource() } + function onModelReset() { avatarField.updateAvatarSource() } + function onDataChanged() { avatarField.updateAvatarSource() } + } + + // Avatar kör + Item { anchors.centerIn: parent - spacing: root.font.pointSize * 0.8 + width: root.font.pointSize * 5.2 + height: root.font.pointSize * 5.2 + + // Avatar drop shadow + Rectangle { + anchors.fill: parent + anchors.topMargin: root.font.pointSize * 0.15 + radius: width / 2 + color: Qt.rgba(0, 0, 0, 0.30) + } - // Avatar kör Rectangle { id: avatarCircle - anchors.horizontalCenter: parent.horizontalCenter - width: root.font.pointSize * 7 - height: root.font.pointSize * 7 + anchors.fill: parent radius: width / 2 clip: true - color: Qt.rgba(0.10, 0.10, 0.15, 0.65) - - // The source image (invisible) - Image { - id: avatarPhoto - anchors.fill: parent - source: avatarField.userIconPath !== "" ? avatarField.userIconPath : "" - fillMode: Image.PreserveAspectCrop - smooth: true - mipmap: true - visible: false - } + color: Qt.rgba(1, 1, 1, 0.15) // The mask source Item { @@ -116,15 +251,23 @@ Column { } } - // Apply MultiEffect to mask the avatarPhoto - MultiEffect { + Image { + id: avatarPhoto anchors.fill: parent - source: avatarPhoto - visible: avatarPhoto.status === Image.Ready && avatarField.userIconPath !== "" - maskEnabled: true - maskSource: avatarMask - maskThresholdMin: 0.5 - maskSpreadAtMin: 1.0 + fillMode: Image.PreserveAspectCrop + smooth: true + mipmap: true + visible: status === Image.Ready + layer.enabled: true + layer.effect: MultiEffect { + maskEnabled: true + maskSource: avatarMask + } + onStatusChanged: { + if (status === Image.Error) { + avatarField.tryNextCandidate() + } + } } Image { @@ -135,8 +278,8 @@ Column { source: Qt.resolvedUrl("../Assets/User.svg") fillMode: Image.PreserveAspectFit smooth: true - visible: avatarField.userIconPath === "" || avatarPhoto.status !== Image.Ready - opacity: 0.75 + visible: avatarPhoto.status !== Image.Ready + opacity: 0.85 } // Draw the border on top of everything! @@ -144,271 +287,391 @@ Column { anchors.fill: parent radius: parent.width / 2 color: "transparent" - border.color: Qt.rgba(1, 1, 1, 0.30) - border.width: 2 - } - } - - // Felhasználóváltó gomb (csak ha több user van) - UserSwitcher { - id: userSwitcher - anchors.horizontalCenter: parent.horizontalCenter - selectedIndex: selectUser.currentIndex - - onUserSwitched: function(idx, name) { - selectUser.currentIndex = idx - username.text = name + border.color: Qt.rgba(1, 1, 1, 0.40) + border.width: root.font.pointSize * 0.12 } } } } - Item { id: usernameField - height: root.font.pointSize * 4.5 - width: parent.width / 2 + height: root.font.pointSize * 3.8 + width: parent.width anchors.horizontalCenter: parent.horizontalCenter - Button { - id: staticUserIcon - - width: parent.height - height: parent.height - anchors.left: parent.left - z: 2 - visible: userModel.count <= 1 - enabled: false - - icon.height: parent.height * 0.25 - icon.width: parent.height * 0.25 - icon.color: config.UserIconColor - icon.source: Qt.resolvedUrl("../Assets/User.svg") + property int selectedUserIndex: (typeof userModel !== "undefined" && userModel && userModel.lastIndex >= 0) ? userModel.lastIndex : 0 + property string selectedUsername: getInitialUsername() - background: Rectangle { - color: "transparent" - border.color: "transparent" - } + function getInitialUsername() { + if (typeof userModel === "undefined" || !userModel || userModel.count === 0) return "" + var idx = (userModel.lastIndex >= 0 && userModel.lastIndex < userModel.count) ? userModel.lastIndex : 0 + var name = userModel.data(userModel.index(idx, 0), Qt.UserRole + 1) + return (name !== undefined && name !== null) ? name.toString() : "" } - ComboBox { - id: selectUser - - width: parent.height - height: parent.height - anchors.left: parent.left - z: 2 - visible: userModel.count > 1 + function selectUserAt(idx) { + if (typeof userModel === "undefined" || !userModel || idx < 0 || idx >= userModel.count) return + selectedUserIndex = idx + selectedUsername = userModel.data(userModel.index(idx, 0), Qt.UserRole + 1) || "" + avatarField.updateAvatarSource() + userDropdownPopup.close() + password.forceActiveFocus() + } - model: userModel - currentIndex: model.lastIndex - textRole: "name" - hoverEnabled: true - onActivated: { - username.text = currentText; + Connections { + target: (typeof userModel !== "undefined") ? userModel : null + function onRowsInserted() { + if (usernameField.selectedUsername === "" || usernameField.selectedUserIndex >= userModel.count) { + usernameField.selectedUserIndex = (userModel.lastIndex >= 0 && userModel.lastIndex < userModel.count) ? userModel.lastIndex : 0 + usernameField.selectedUsername = usernameField.getInitialUsername() + } + avatarField.updateAvatarSource() } - - property var popkey: config.RightToLeftLayout == "true" ? Qt.Key_Right : Qt.Key_Left - Keys.onPressed: function (event) { - if (event.key == Qt.Key_Down && !popup.opened) - username.forceActiveFocus(); - if ((event.key == Qt.Key_Up || event.key == popkey) && !popup.opened) - popup.open(); + function onModelReset() { + usernameField.selectedUserIndex = (userModel.lastIndex >= 0 && userModel.lastIndex < userModel.count) ? userModel.lastIndex : 0 + usernameField.selectedUsername = usernameField.getInitialUsername() + avatarField.updateAvatarSource() } - KeyNavigation.down: username - KeyNavigation.right: username + function onDataChanged() { + usernameField.selectedUsername = usernameField.getInitialUsername() + avatarField.updateAvatarSource() + } + } - delegate: ItemDelegate { - // minus padding - width: popupHandler.width - 20 - anchors.horizontalCenter: popupHandler.horizontalCenter + // Container button / click area + Item { + id: userSelectorButton + anchors.centerIn: parent + height: root.font.pointSize * 2.8 + width: parent.width + activeFocusOnTab: true - contentItem: Text { - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter + Keys.onReturnPressed: userDropdownPopup.visible ? userDropdownPopup.close() : userDropdownPopup.open() + Keys.onEnterPressed: userDropdownPopup.visible ? userDropdownPopup.close() : userDropdownPopup.open() + Keys.onSpacePressed: userDropdownPopup.visible ? userDropdownPopup.close() : userDropdownPopup.open() + Keys.onDownPressed: { + if (!userDropdownPopup.visible) { + password.forceActiveFocus() + } + } + KeyNavigation.down: password - text: model.name - font.pointSize: root.font.pointSize * 0.8 - font.capitalization: Font.AllLowercase - font.family: root.font.family - color: config.DropdownTextColor + // Background with drop shadow and frosted glass + Item { + anchors.fill: parent + Rectangle { + anchors.fill: parent + anchors.topMargin: root.font.pointSize * 0.12 + radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : root.font.pointSize * 0.8 + color: Qt.rgba(0, 0, 0, 0.20) } - background: Rectangle { - color: selectUser.highlightedIndex === index ? Qt.rgba(1, 1, 1, 0.15) : "transparent" - radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) / 4 : 5 + Rectangle { + anchors.fill: parent + color: userSelectorMouseArea.pressed ? Qt.rgba(1, 1, 1, 0.25) : (userSelectorMouseArea.containsMouse || userSelectorButton.activeFocus ? Qt.rgba(1, 1, 1, 0.20) : Qt.rgba(1, 1, 1, 0.14)) + border.color: userSelectorButton.activeFocus ? Qt.rgba(255, 255, 255, 0.75) : (userSelectorMouseArea.containsMouse ? Qt.rgba(255, 255, 255, 0.45) : Qt.rgba(255, 255, 255, 0.25)) + border.width: userSelectorButton.activeFocus ? root.font.pointSize * 0.12 : root.font.pointSize * 0.08 + radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : root.font.pointSize * 0.8 + Behavior on color { ColorAnimation { duration: 150 } } + Behavior on border.color { ColorAnimation { duration: 150 } } } } - indicator: Button { - id: usernameIcon - - width: selectUser.height * 1 + // Left Icon (User icon) + Button { + id: userFieldLeftIcon + width: parent.height height: parent.height anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: selectUser.height * 0 - - icon.height: parent.height * 0.25 - icon.width: parent.height * 0.25 enabled: false - icon.color: config.UserIconColor + icon.source: Qt.resolvedUrl("../Assets/User.svg") + icon.width: parent.height * 0.38 + icon.height: parent.height * 0.38 + icon.color: "#ffffff" - background: Rectangle { - color: "transparent" - border.color: "transparent" - } + background: Rectangle { color: "transparent" } } - background: Rectangle { - color: "transparent" - border.color: "transparent" - } + // Username display in the middle (Non-editable, clean text) + Text { + id: username + anchors.centerIn: parent + width: parent.width - userFieldLeftIcon.width * 2.2 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight - popup: Popup { - id: popupHandler + text: usernameField.selectedUsername + color: config.LoginFieldTextColor + font.bold: true + font.pointSize: root.font.pointSize * 0.95 + font.family: root.font.family + style: Text.Raised + styleColor: Qt.rgba(0, 0, 0, 0.40) + } - implicitHeight: contentItem.implicitHeight - width: usernameField.width - y: parent.height - username.height / 3 - x: config.RightToLeftLayout == "true" ? -loginButton.width + selectUser.width : 0 - rightMargin: config.RightToLeftLayout == "true" ? root.padding + usernameField.width / 2 : undefined - padding: 10 + // Dropdown Arrow Button on Right + Item { + id: userDropdownBtn + width: parent.height + height: parent.height + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter - contentItem: ListView { - implicitHeight: contentHeight + 20 + Canvas { + id: chevronCanvas + width: root.font.pointSize * 0.85 + height: root.font.pointSize * 0.50 + anchors.centerIn: parent + rotation: userDropdownPopup.visible ? 180 : 0 + Behavior on rotation { NumberAnimation { duration: 200; easing.type: Easing.OutCubic } } - clip: true - model: selectUser.popup.visible ? selectUser.delegateModel : null - currentIndex: selectUser.highlightedIndex - ScrollIndicator.vertical: ScrollIndicator {} - } + onPaint: { + var ctx = getContext("2d"); + ctx.reset(); + ctx.clearRect(0, 0, width, height); + ctx.strokeStyle = userSelectorMouseArea.containsMouse ? "#ffffff" : "rgba(255, 255, 255, 0.85)"; + ctx.lineWidth = Math.max(1.5, root.font.pointSize * 0.12); + ctx.lineCap = "round"; + ctx.lineJoin = "round"; - background: Rectangle { - radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) / 2 : 10 - color: Qt.rgba(1, 1, 1, 0.08) - border.color: Qt.rgba(1, 1, 1, 0.18) - border.width: 1 - layer.enabled: true - } + ctx.beginPath(); + ctx.moveTo(1.5, 1.5); + ctx.lineTo(width / 2, height - 1.5); + ctx.lineTo(width - 1.5, 1.5); + ctx.stroke(); + } - enter: Transition { - NumberAnimation { - property: "opacity" - from: 0 - to: 1 + Connections { + target: userSelectorMouseArea + function onContainsMouseChanged() { chevronCanvas.requestPaint(); } } } } - states: [ - State { - name: "pressed" - when: selectUser.down - PropertyChanges { - target: usernameIcon - icon.color: Qt.lighter(config.HoverUserIconColor, 1.1) - } - }, - State { - name: "hovered" - when: selectUser.hovered - PropertyChanges { - target: usernameIcon - icon.color: Qt.lighter(config.HoverUserIconColor, 1.2) - } - }, - State { - name: "focused" - when: selectUser.activeFocus - PropertyChanges { - target: usernameIcon - icon.color: config.HoverUserIconColor - } - } - ] - transitions: [ - Transition { - PropertyAnimation { - properties: "color, border.color, icon.color" - duration: 150 + // Whole field click area + MouseArea { + id: userSelectorMouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + if (userDropdownPopup.visible) { + userDropdownPopup.close(); + } else { + userDropdownPopup.open(); } } - ] + } } - TextField { - id: username + // Dropdown Popup + Popup { + id: userDropdownPopup - anchors.centerIn: parent - height: root.font.pointSize * 3 width: parent.width - horizontalAlignment: TextInput.AlignHCenter - z: 1 + y: parent.height + root.font.pointSize * 0.4 + x: 0 + padding: root.font.pointSize * 0.5 + dim: false + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + z: 100 - text: config.ForceLastUser == "true" ? selectUser.currentText : null - color: config.LoginFieldTextColor - font.bold: true - font.capitalization: config.AllowUppercaseLettersInUsernames == "false" ? Font.AllLowercase : Font.MixedCase - placeholderText: config.TranslatePlaceholderUsername || textConstants.userName - placeholderTextColor: config.PlaceholderTextColor - selectByMouse: true - renderType: Text.QtRendering + background: Item { + // Drop shadow underlay + Rectangle { + anchors.fill: parent + anchors.topMargin: root.font.pointSize * 0.15 + radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : root.font.pointSize * 0.8 + color: Qt.rgba(0, 0, 0, 0.40) + } - onFocusChanged: { - if (focus) - selectAll(); - } + // Frosted Glass body (minimally translucent) + Rectangle { + anchors.fill: parent + radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : root.font.pointSize * 0.8 + border.color: Qt.rgba(1, 1, 1, 0.40) + border.width: 1 + clip: true - background: Rectangle { - color: username.activeFocus ? Qt.rgba(0, 0, 0, 0.35) : Qt.rgba(0, 0, 0, 0.2) - border.color: username.activeFocus ? Qt.rgba(255, 255, 255, 0.3) : Qt.rgba(255, 255, 255, 0.12) - border.width: username.activeFocus ? 1.5 : 1 - radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : 10 - Behavior on color { - ColorAnimation { - duration: 150 - } - } - Behavior on border.color { - ColorAnimation { - duration: 150 + gradient: Gradient { + GradientStop { position: 0.0; color: Qt.rgba(0.18, 0.20, 0.28, 0.92) } + GradientStop { position: 0.5; color: Qt.rgba(0.14, 0.16, 0.24, 0.94) } + GradientStop { position: 1.0; color: Qt.rgba(0.11, 0.13, 0.20, 0.96) } } } } - onAccepted: config.AllowUppercaseLettersInUsernames == "false" ? sddm.login(username.text.toLowerCase(), password.text, sessionSelect.selectedSession) : sddm.login(username.text, password.text, sessionSelect.selectedSession) - KeyNavigation.down: passwordIcon + contentItem: ListView { + id: userDropdownList + implicitHeight: Math.min(contentHeight, root.font.pointSize * 16) + clip: true + model: userModel + spacing: root.font.pointSize * 0.25 + boundsBehavior: Flickable.StopAtBounds - states: [ - State { - name: "focused" - when: username.activeFocus - PropertyChanges { - target: username - color: Qt.lighter(config.LoginFieldTextColor, 1.15) + delegate: Item { + id: userDelegateItem + width: userDropdownList.width + height: root.font.pointSize * 3.4 + + property var itemCandidates: avatarField.resolveIconCandidates(index, model.name) + property int itemAttempt: 0 + property bool isSelected: index === usernameField.selectedUserIndex + + function tryNextItemCandidate() { + if (itemAttempt < itemCandidates.length) { + var nextUrl = itemCandidates[itemAttempt] + itemAttempt++ + dPhoto.source = nextUrl + } else { + dPhoto.source = "" + } + } + + Component.onCompleted: { + itemAttempt = 0 + dPhoto.source = "" + if (itemCandidates.length > 0) { + tryNextItemCandidate() + } + } + + Rectangle { + anchors.fill: parent + radius: root.font.pointSize * 0.6 + color: userDelegateMouse.pressed + ? Qt.rgba(1, 1, 1, 0.24) + : userDelegateMouse.containsMouse + ? Qt.rgba(1, 1, 1, 0.16) + : (userDelegateItem.isSelected ? Qt.rgba(1, 1, 1, 0.10) : "transparent") + border.color: userDelegateItem.isSelected ? Qt.rgba(1, 1, 1, 0.45) : (userDelegateMouse.containsMouse ? Qt.rgba(1, 1, 1, 0.25) : "transparent") + border.width: 1 + Behavior on color { ColorAnimation { duration: 100 } } + Behavior on border.color { ColorAnimation { duration: 100 } } + } + + Row { + anchors.fill: parent + anchors.leftMargin: root.font.pointSize * 0.8 + anchors.rightMargin: root.font.pointSize * 0.8 + spacing: root.font.pointSize * 0.8 + + // Mini avatar in dropdown row + Item { + width: root.font.pointSize * 2.4 + height: root.font.pointSize * 2.4 + anchors.verticalCenter: parent.verticalCenter + + Rectangle { + anchors.fill: parent + radius: width / 2 + clip: true + color: Qt.rgba(1, 1, 1, 0.15) + border.color: Qt.rgba(1, 1, 1, 0.35) + border.width: 1 + + Item { + id: dMask + anchors.fill: parent + visible: false + layer.enabled: true + Rectangle { + anchors.fill: parent + radius: parent.width / 2 + color: "black" + } + } + + Image { + id: dPhoto + anchors.fill: parent + fillMode: Image.PreserveAspectCrop + smooth: true + visible: status === Image.Ready + layer.enabled: true + layer.effect: MultiEffect { + maskEnabled: true + maskSource: dMask + } + onStatusChanged: { + if (status === Image.Error) { + userDelegateItem.tryNextItemCandidate() + } + } + } + + Button { + anchors.centerIn: parent + width: parent.width * 0.65 + height: parent.height * 0.65 + enabled: false + icon.source: Qt.resolvedUrl("../Assets/User.svg") + icon.width: parent.width * 0.65 + icon.height: parent.height * 0.65 + icon.color: "#ffffff" + visible: dPhoto.status !== Image.Ready + background: Rectangle { color: "transparent" } + } + } + } + + // Username & realName + Column { + anchors.verticalCenter: parent.verticalCenter + spacing: 2 + + Text { + text: model.name || "" + color: "#ffffff" + font.bold: true + font.pointSize: root.font.pointSize * 0.85 + font.family: root.font.family + style: Text.Raised + styleColor: Qt.rgba(0, 0, 0, 0.40) + } + + Text { + text: (model.realName && model.realName !== model.name) ? model.realName : "" + color: Qt.rgba(1, 1, 1, 0.65) + font.pointSize: root.font.pointSize * 0.70 + font.family: root.font.family + visible: text !== "" + } + } + } + + MouseArea { + id: userDelegateMouse + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + usernameField.selectUserAt(index) + } } } - ] + } } } Item { id: passwordField - height: root.font.pointSize * 4.5 - width: parent.width / 2 + height: root.font.pointSize * 3.8 + width: parent.width anchors.horizontalCenter: parent.horizontalCenter Button { id: passwordIcon height: parent.height - width: selectUser.height * 1 + width: parent.height anchors.left: parent.left - anchors.leftMargin: selectUser.height * 0 anchors.verticalCenter: parent.verticalCenter z: 2 @@ -478,7 +741,7 @@ Column { TextField { id: password - height: root.font.pointSize * 3 + height: root.font.pointSize * 2.8 width: parent.width anchors.centerIn: parent horizontalAlignment: TextInput.AlignHCenter @@ -494,19 +757,29 @@ Column { renderType: Text.QtRendering selectByMouse: true - background: Rectangle { - color: password.activeFocus ? Qt.rgba(0, 0, 0, 0.35) : Qt.rgba(0, 0, 0, 0.2) - border.color: password.activeFocus ? Qt.rgba(255, 255, 255, 0.3) : Qt.rgba(255, 255, 255, 0.12) - border.width: password.activeFocus ? 1.5 : 1 - radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : 10 - Behavior on color { - ColorAnimation { - duration: 150 - } + background: Item { + Rectangle { + anchors.fill: parent + anchors.topMargin: root.font.pointSize * 0.12 + radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : root.font.pointSize * 0.8 + color: Qt.rgba(0, 0, 0, 0.20) } - Behavior on border.color { - ColorAnimation { - duration: 150 + + Rectangle { + anchors.fill: parent + color: password.activeFocus ? Qt.rgba(1, 1, 1, 0.25) : Qt.rgba(1, 1, 1, 0.14) + border.color: password.activeFocus ? Qt.rgba(255, 255, 255, 0.65) : Qt.rgba(255, 255, 255, 0.25) + border.width: password.activeFocus ? root.font.pointSize * 0.12 : root.font.pointSize * 0.08 + radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : root.font.pointSize * 0.8 + Behavior on color { + ColorAnimation { + duration: 150 + } + } + Behavior on border.color { + ColorAnimation { + duration: 150 + } } } } @@ -537,10 +810,8 @@ Column { Item { id: login - // important - // try 4 or 9 ... - height: root.font.pointSize * 9 - width: parent.width / 2 + height: root.font.pointSize * 4.2 + width: parent.width anchors.horizontalCenter: parent.horizontalCenter visible: config.HideLoginButton == "true" ? false : true @@ -548,7 +819,7 @@ Column { Item { id: loginButton - height: root.font.pointSize * 3 + height: root.font.pointSize * 2.8 width: parent.width anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter @@ -568,12 +839,20 @@ Column { KeyNavigation.down: rebootBtn + // Drop shadow + Rectangle { + anchors.fill: parent + anchors.topMargin: root.font.pointSize * 0.12 + radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : root.font.pointSize * 0.8 + color: Qt.rgba(0, 0, 0, 0.25) + } + Rectangle { id: buttonBackground anchors.fill: parent - radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : 10 - border.width: loginButton.activeFocus ? 1.5 : 1 + radius: config.RoundCorners !== "" ? parseInt(config.RoundCorners) : root.font.pointSize * 0.8 + border.width: loginButton.activeFocus ? root.font.pointSize * 0.12 : root.font.pointSize * 0.08 border.color: loginButton.down ? Qt.rgba(21/255, 128/255, 61/255, 0.95) : (loginButton.hovered ? Qt.rgba(34/255, 197/255, 94/255, 0.85) : Qt.rgba(74/255, 222/255, 128/255, 0.65)) @@ -600,6 +879,8 @@ Column { font.pointSize: root.font.pointSize font.family: root.font.family color: "#ffffff" + style: Text.Raised + styleColor: Qt.rgba(0, 0, 0, 0.45) text: config.TranslateLogin || textConstants.login opacity: 1.0 @@ -622,58 +903,71 @@ Column { Item { id: powerButtonsRow - height: root.font.pointSize * 10 - width: parent.width / 2 + height: root.font.pointSize * 5.5 + width: parent.width anchors.horizontalCenter: parent.horizontalCenter Row { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter - spacing: root.font.pointSize * 3 + spacing: root.font.pointSize * 1.5 // Reboot gomb Column { - spacing: root.font.pointSize * 0.6 + spacing: root.font.pointSize * 0.45 - RoundButton { - id: rebootBtn + Item { + width: root.font.pointSize * 4.2 + height: root.font.pointSize * 4.2 - width: root.font.pointSize * 6 - height: root.font.pointSize * 6 + // Button shadow + Rectangle { + anchors.fill: parent + anchors.topMargin: root.font.pointSize * 0.12 + radius: width / 2 + color: Qt.rgba(0, 0, 0, 0.30) + } - activeFocusOnTab: true - Keys.onReturnPressed: sddm.reboot() - Keys.onEnterPressed: sddm.reboot() - KeyNavigation.right: shutdownBtn - hoverEnabled: true + RoundButton { + id: rebootBtn + anchors.fill: parent - icon.source: Qt.resolvedUrl("../Assets/Reboot.svg") - icon.width: root.font.pointSize * 3 - icon.height: root.font.pointSize * 3 - icon.color: "#ffffff" + activeFocusOnTab: true + Keys.onReturnPressed: sddm.reboot() + Keys.onEnterPressed: sddm.reboot() + KeyNavigation.right: shutdownBtn + hoverEnabled: true - opacity: rebootBtn.hovered || rebootBtn.activeFocus ? 1.0 : 0.75 - Behavior on opacity { NumberAnimation { duration: 150 } } + icon.source: Qt.resolvedUrl("../Assets/Reboot.svg") + icon.width: root.font.pointSize * 2.1 + icon.height: root.font.pointSize * 2.1 + icon.color: "#ffffff" - scale: rebootBtn.pressed ? 0.88 : 1.0 - Behavior on scale { NumberAnimation { duration: 100 } } + opacity: rebootBtn.hovered || rebootBtn.activeFocus ? 1.0 : 0.75 + Behavior on opacity { NumberAnimation { duration: 150 } } - background: Rectangle { - anchors.fill: parent - radius: width / 2 - color: rebootBtn.pressed ? Qt.rgba(1, 0.45, 0.0, 0.35) : (rebootBtn.hovered ? Qt.rgba(1, 0.55, 0.0, 0.22) : "transparent") - border.color: "transparent" - border.width: 0 - Behavior on color { ColorAnimation { duration: 150 } } - } + scale: rebootBtn.pressed ? 0.88 : 1.0 + Behavior on scale { NumberAnimation { duration: 100 } } - onClicked: sddm.reboot() + background: Rectangle { + anchors.fill: parent + radius: width / 2 + color: rebootBtn.pressed ? Qt.rgba(1, 0.45, 0.0, 0.35) : (rebootBtn.hovered ? Qt.rgba(1, 0.55, 0.0, 0.22) : "transparent") + border.color: "transparent" + border.width: 0 + Behavior on color { ColorAnimation { duration: 150 } } + } + + onClicked: sddm.reboot() + } } Text { anchors.horizontalCenter: parent.children[0].horizontalCenter text: config.TranslateReboot || textConstants.reboot color: "#ffffff" + style: Text.Raised + styleColor: Qt.rgba(0, 0, 0, 0.50) font.pointSize: root.font.pointSize * 0.8 font.family: root.font.family horizontalAlignment: Text.AlignHCenter @@ -684,47 +978,60 @@ Column { // Shutdown gomb Column { - spacing: root.font.pointSize * 0.6 + spacing: root.font.pointSize * 0.45 - RoundButton { - id: shutdownBtn + Item { + width: root.font.pointSize * 4.2 + height: root.font.pointSize * 4.2 - width: root.font.pointSize * 6 - height: root.font.pointSize * 6 + // Button shadow + Rectangle { + anchors.fill: parent + anchors.topMargin: root.font.pointSize * 0.12 + radius: width / 2 + color: Qt.rgba(0, 0, 0, 0.30) + } - activeFocusOnTab: true - Keys.onReturnPressed: sddm.powerOff() - Keys.onEnterPressed: sddm.powerOff() - KeyNavigation.left: rebootBtn - hoverEnabled: true + RoundButton { + id: shutdownBtn + anchors.fill: parent - icon.source: Qt.resolvedUrl("../Assets/Shutdown.svg") - icon.width: root.font.pointSize * 3 - icon.height: root.font.pointSize * 3 - icon.color: "#ffffff" + activeFocusOnTab: true + Keys.onReturnPressed: sddm.powerOff() + Keys.onEnterPressed: sddm.powerOff() + KeyNavigation.left: rebootBtn + hoverEnabled: true - opacity: shutdownBtn.hovered || shutdownBtn.activeFocus ? 1.0 : 0.75 - Behavior on opacity { NumberAnimation { duration: 150 } } + icon.source: Qt.resolvedUrl("../Assets/Shutdown.svg") + icon.width: root.font.pointSize * 2.1 + icon.height: root.font.pointSize * 2.1 + icon.color: "#ffffff" - scale: shutdownBtn.pressed ? 0.88 : 1.0 - Behavior on scale { NumberAnimation { duration: 100 } } + opacity: shutdownBtn.hovered || shutdownBtn.activeFocus ? 1.0 : 0.75 + Behavior on opacity { NumberAnimation { duration: 150 } } - background: Rectangle { - anchors.fill: parent - radius: width / 2 - color: shutdownBtn.pressed ? Qt.rgba(0.8, 0.1, 0.1, 0.40) : (shutdownBtn.hovered ? Qt.rgba(0.8, 0.1, 0.1, 0.25) : "transparent") - border.color: "transparent" - border.width: 0 - Behavior on color { ColorAnimation { duration: 150 } } - } + scale: shutdownBtn.pressed ? 0.88 : 1.0 + Behavior on scale { NumberAnimation { duration: 100 } } + + background: Rectangle { + anchors.fill: parent + radius: width / 2 + color: shutdownBtn.pressed ? Qt.rgba(0.8, 0.1, 0.1, 0.40) : (shutdownBtn.hovered ? Qt.rgba(0.8, 0.1, 0.1, 0.25) : "transparent") + border.color: "transparent" + border.width: 0 + Behavior on color { ColorAnimation { duration: 150 } } + } - onClicked: sddm.powerOff() + onClicked: sddm.powerOff() + } } Text { anchors.horizontalCenter: parent.children[0].horizontalCenter text: config.TranslateShutdown || textConstants.shutdown color: "#ffffff" + style: Text.Raised + styleColor: Qt.rgba(0, 0, 0, 0.50) font.pointSize: root.font.pointSize * 0.8 font.family: root.font.family horizontalAlignment: Text.AlignHCenter |