1
0
Fork 0
mirror of https://github.com/HenkKalkwater/sddm-nx synced 2024-12-22 07:55:16 +00:00

Initial commit

This commit is contained in:
Chris Josten 2020-05-15 01:12:55 +02:00
commit 636e786f88
18 changed files with 663 additions and 0 deletions

89
Main.qml Normal file
View file

@ -0,0 +1,89 @@
import QtQuick 2.0
import QtGamepad 1.0
import SddmComponents 2.0
import "components"
import "."
Rectangle {
id: root
color: "black"
property LoginPane _userSelector
property string _user
property string _password
Repeater {
model: screenModel
Image {
x: geometry.x
y: geometry.y
width: geometry.width
height: geometry.height
source: Style.background
Loader {
Component.onCompleted: console.log("%1, %2, %3 %4".arg(geometry.x).arg(geometry.y).arg(geometry.width).arg(geometry.height))
anchors.fill: parent
source: screenModel.primary == index ? "./components/LoginPane.qml" : ""
onLoaded: {
if (screenModel.primary == index) {
_userSelector = item
_userSelector.userSelected.connect(root.userSelected)
_userSelector.closed.connect(root.userClosed)
_userSelector.hostname = sddm.hostname
console.log("Opening userSelect")
//startupAnim.start()
}
}
onStatusChanged: {
if (status == Loader.Error) {
console.log("Something went wrong!")
}
}
}
}
}
Dialog {
id: errorDialog
anchors.fill: parent
message: qsTr("Invalid password")
onClosed: _userSelector.open()
}
SequentialAnimation {
id: startupAnim
running: true
ColorAnimation {
target: root
property: "color"
from: "black"
to: "white"
easing.type: Easing.InOutQuad
duration: 250
}
PauseAnimation {
duration: 300
}
ScriptAction {
script: _userSelector.open()
}
}
Connections {
target: sddm
onLoginFailed: {
errorDialog.show()
}
}
function userSelected(name, password) {
_user = name
_password = password
_userSelector.close()
}
function userClosed() {
//errorDialog.show()
sddm.login(_user, _password, _userSelector.sessionIndex)
}
}

27
Style.qml Normal file
View file

@ -0,0 +1,27 @@
pragma Singleton
import QtQuick 2.0
QtObject {
property color backgroundColor: "#FF444444"
property color backgroundColor2: "#FF888888"
property color foregroundColor: "white"
property color overlayColor: "#cc000000"
property color highlightColor: "#FFAAAAFF"
property color highlightColor2: "blue"
property real highlightGap: 1
property int highlightBorderSize: 8
property real smallPadding: 16
property real mediumPadding: 32
property real horizontalPadding: 32
property real horizontalContentPadding: 64
property int iconSize: 32
property int fontTitleSize: 32
property int fontNormalSize: 24
property string background: config.background ? config.background : Qt.resolvedUrl("bg.png")
}

BIN
bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

BIN
bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 KiB

30
components/Cursor.qml Normal file
View file

@ -0,0 +1,30 @@
import QtQuick 2.6
import ".."
Rectangle {
id: highlightItem
property Item target
anchors.centerIn: parent
implicitWidth: target.width + Style.highlightGap
implicitHeight: target.height + Style.highlightGap
color: "#00000000"
radius: 3
border.width: Style.highlightBorderSize - 2 * Style.highlightGap
border.color: Style.highlightColor
SequentialAnimation on border.color {
loops: Animation.Infinite
ColorAnimation {
from: Style.highlightColor
to: Style.highlightColor2
easing.type: Easing.InQuad
duration: 3000
}
ColorAnimation {
from: Style.highlightColor2
to: Style.highlightColor
easing.type: Easing.OutQuad
duration: 3000
}
}
}

91
components/Dialog.qml Normal file
View file

@ -0,0 +1,91 @@
import QtQuick 2.6
import QtQuick.Controls 2.6
import ".."
FocusScope {
id: dialogRoot
visible: false
enabled: visible
property alias message: messageText.text
signal closed()
opacity: visible ? 1 : 0
Behavior on opacity { NumberAnimation {} }
Rectangle {
anchors.fill: parent
color: Style.overlayColor
}
Rectangle {
anchors.centerIn: parent
width: 600
height: column.height
color: Style.backgroundColor
Column {
id: column
width: parent.width
Text {
id: messageText
width: parent.width
padding: Style.horizontalPadding
font.pixelSize: Style.fontNormalSize
color: Style.foregroundColor
}
Button {
id: button
flat: true
focus: true
width: parent.width
leftPadding: Style.horizontalPadding
rightPadding: leftPadding
topPadding: Style.smallPadding
bottomPadding: topPadding
font.pixelSize: Style.fontNormalSize
palette.buttonText: Style.highlightColor
palette.brightText: Style.highlightColor
palette.windowText: Style.highlightColor
palette.button: Style.backgroundColor2
palette.mid: Style.backgroundColor2
onClicked: {
hide()
}
indicator: Cursor {
target: button.background
visible: button.visualFocus
}
text: qsTr("Close")
}
}
}
SequentialAnimation {
id: hideAnimation
NumberAnimation {
target: dialogRoot
property: "opacity"
to: 0
}
ScriptAction {
script: {
dialogRoot.visible = false;
dialogRoot.closed()
}
}
}
function show () {
console.log("ErrorDialog open")
visible = true;
dialogRoot.focus = true;
}
function hide () {
hideAnimation.start()
}
}

10
components/Divider.qml Normal file
View file

@ -0,0 +1,10 @@
import QtQuick 2.0
import ".."
Rectangle {
anchors.left: parent.left
anchors.leftMargin: Style.horizontalPadding
anchors.right: parent.right
anchors.rightMargin: Style.horizontalPadding
height: 3
}

230
components/LoginPane.qml Normal file
View file

@ -0,0 +1,230 @@
import QtQuick 2.6
import QtQuick.Controls 2.6
import QtGraphicalEffects 1.6
import QtQuick.Layouts 1.6
import ".."
import "."
Item {
// This rectangle spans the screen
id: loginPaneRoot
// Emitted when an user is selected
signal userSelected(string user, string password)
signal closed()
property string hostname
property int sessionIndex
property bool _open: false
property string _user
// Gives a blur effect to the background
Item {
id: background
opacity: 0
anchors.fill: parent
Image {
id: effectSource
source: Style.background //refers to the root in Main.qml
anchors.fill: parent
visible: false
}
GaussianBlur {
id: blur
anchors.fill: effectSource
source: effectSource
radius: 16
samples: 16
}
}
// The actual pane
Rectangle {
id: userSelector
anchors.bottom: parent.bottom
anchors.bottomMargin: -height
width: parent.width
height: content.height
color: Style.backgroundColor
Column {
id: content
width: parent.width
Title {
text: "Who is using %1?".arg(hostname)
anchors.left: parent.left
anchors.leftMargin: Style.horizontalContentPadding
}
Divider {}
Item { height: Style.mediumPadding; width: 1; }
FocusScope {
width: parent.width
height: 220
Row {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
spacing: Style.highlightBorderSize + Style.highlightGap * 2
/*ListModel {
id: userModel
ListElement { realName: "test1"; icon: "file:///home/chris/.face.icon";}
ListElement { realName: "test2"; icon: "file:///home/chris/.face.icon";}
ListElement { realName: "test3"; icon: "file:///home/chris/.face.icon";}
}*/
Repeater {
model: userModel
UserDelegate {
focus: true
text: model.realName
icon.source: model.icon
onClicked: {
_user = model.realName
showPasswordOverlay()
}
}
}
}
}
Item { height: Style.mediumPadding; width: 1; }
Divider {}
//Item { height: Style.mediumPadding; width: 1; }
RowLayout {
height: Style.iconSize + Style.mediumPadding
anchors.left: parent.left
anchors.leftMargin: Style.horizontalContentPadding
anchors.right: parent.right
anchors.rightMargin: anchors.leftMargin
TintedImage {
Layout.preferredWidth: Style.iconSize
Layout.preferredHeight: Style.iconSize
color: Style.foregroundColor
source: "../icons/keyboard.svg"
}
ComboBox {
Layout.fillHeight: true
//height: parent.height
Layout.preferredWidth: 400
model: keyboard.layouts
flat: true
font.pixelSize: Style.fontNormalSize
palette.buttonText: Style.foregroundColor
palette.button: Style.backgroundColor
palette.mid: Style.backgroundColor2
palette.dark: Style.foregroundColor
palette.light: Style.backgroundColor
palette.window: Style.backgroundColor
textRole: "longName"
currentIndex: keyboard.currentLayout
onCurrentIndexChanged: keyboard.currentLayout = currentIndex
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
ComboBox {
id: sessionIndex
Layout.fillHeight: true
//height: parent.height
Layout.preferredWidth: 400
model: sessionModel
flat: true
font.pixelSize: Style.fontNormalSize
palette.buttonText: Style.foregroundColor
palette.button: Style.backgroundColor
palette.mid: Style.backgroundColor2
palette.dark: Style.foregroundColor
palette.light: Style.backgroundColor
palette.window: Style.backgroundColor
textRole: "name"
currentIndex: sessionModel.lastIndex
onCurrentIndexChanged: loginPaneRoot.sessionIndex = currentIndex
}
}
//Item { height: Style.mediumPadding; width: 1; }
}
ParallelAnimation {
id: userSelectorShow
NumberAnimation {
target: background
property: "opacity"
from: 0
to: 1
duration: 100
}
NumberAnimation {
target: userSelector
property: "anchors.bottomMargin"
from: -userSelector.height
to: 0
duration: 150
easing.type: Easing.OutQuad
}
}
SequentialAnimation {
id: userSelectorHide
ParallelAnimation {
NumberAnimation {
target: userSelector
property: "anchors.bottomMargin"
from: 0
to: -userSelector.height
duration: 150
easing.type: Easing.InQuad
}
NumberAnimation {
target: background
property: "opacity"
from: 1
to: 0
duration: 100
}
}
ScriptAction {
script: closed()
}
}
}
PasswordOverlay {
id: passwordOverlay
enabled: false
anchors.fill: parent
opacity: enabled ? 1 : 0
Behavior on opacity { NumberAnimation {} }
username: _user
onPasswordEntered: {
hidePasswordOverlay()
userSelected(_user, password)
}
onCancelled: hidePasswordOverlay()
}
function showPasswordOverlay() {
userSelector.enabled = false;
passwordOverlay.enabled = true;
passwordOverlay.focus = true;
}
function hidePasswordOverlay() {
userSelector.enabled = true;
passwordOverlay.enabled = false;
}
function open() {
if (!_open) userSelectorShow.start()
}
function close() {
console.log("Closing pane")
/*if (_open)*/ userSelectorHide.start()
}
}

View file

@ -0,0 +1,63 @@
import QtQuick 2.6
import QtQuick.Controls 2.6
import ".."
FocusScope {
id: overlay
property string username
signal passwordEntered(string password)
signal cancelled()
Connections {
target: Qt.inputMethod
onVisibleChanged: {
if (!Qt.inputMethod.visible) cancelled()
}
}
Rectangle {
anchors.fill: parent
color: Style.overlayColor
TextField {
focus: true
//anchors.top: parent.top
property real _vkeyboardOffset: Qt.inputMethod.visible
? root.height - Qt.inputMethod.keyboardRectangle.top : 0
y: (parent.height - _vkeyboardOffset) / 2 - height / 2
Behavior on y { NumberAnimation { duration: 100 }}
anchors.left: parent.left
anchors.right: parent.right
//anchors.topMargin: Style.horizontalPadding
anchors.leftMargin: Style.horizontalContentPadding
anchors.rightMargin: Style.horizontalContentPadding
padding: Style.mediumPadding
color: Style.foregroundColor
echoMode: TextInput.Password
placeholderText: "Enter the password for %1".arg(username)
//color: Style.foregroundColor
font.pixelSize: Style.fontTitleSize
background: Rectangle {
color: "#00000000"
border.width: Style.highlightBorderSize
border.color: Style.backgroundColor2
}
Keys.onEscapePressed: cancelled()
onAccepted: {
passwordEntered(text)
text = ""
}
}
}
}

View file

@ -0,0 +1,23 @@
import QtQuick 2.6
import QtGraphicalEffects 1.6
Item {
property alias source: image.source
property alias color: colorOverlay.color
// I thought this should be standard
implicitWidth: image.implicitWidth
implicitHeight: image.implicitHeight
Image {
id: image
visible: false
anchors.fill: parent
smooth: true
}
ColorOverlay {
id: colorOverlay
anchors.fill: parent
source: image
}
}

9
components/Title.qml Normal file
View file

@ -0,0 +1,9 @@
import QtQuick 2.6
import ".."
Text {
color: Style.foregroundColor
font.pixelSize: Style.fontTitleSize
topPadding: Style.smallPadding
bottomPadding: Style.smallPadding
}

View file

@ -0,0 +1,71 @@
import QtQuick 2.6
import QtQuick.Controls 2.6
import QtGraphicalEffects 1.0
import ".."
AbstractButton {
id: userDelegateRoot
//property alias icon: userPic.source
//property alias name: userName.text
focusPolicy: Qt.StrongFocus
readonly property real _innerWidth: 180
readonly property real _innerHeight: 220
//cursorShape: Qt.PointingHandCursor
indicator: Cursor {
target: backgroundItem
visible: userDelegateRoot.visualFocus
}
background: Item {
id: backgroundItem
anchors.centerIn: parent
width: contentItem.width + 2 * Style.highlightBorderSize
height: contentItem.height + 2 * Style.highlightBorderSize
Rectangle {
id: backgroundItemInner
anchors.centerIn: parent
color: userDelegateRoot.down ? Style.backgroundColor : Style.backgroundColor2
implicitWidth: parent.width - 2 * Style.highlightBorderSize
implicitHeight: parent.height - 2 * Style.highlightBorderSize
visible: false
}
DropShadow {
anchors.fill: backgroundItemInner
horizontalOffset: 3
verticalOffset: 3
radius: 8.0
samples: 17
color: "#80000000"
source: backgroundItemInner
}
}
contentItem: Item {
id: contentItem
implicitWidth: _innerWidth
implicitHeight: _innerHeight
Image {
id: userPic
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
width: parent.width
height: width
source: userDelegateRoot.icon.source
}
Text {
id: userName
anchors.top: userPic.bottom
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: userDelegateRoot.text
font.pixelSize: Style.fontNormalSize
color: Style.foregroundColor
}
}
}

1
icons/keyboard.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"/><path d="M0 0h24v24H0zm0 0h24v24H0z" fill="none"/></svg>

After

Width:  |  Height:  |  Size: 391 B

1
icons/mouse.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M13 1.07V9h7c0-4.08-3.05-7.44-7-7.93zM4 15c0 4.42 3.58 8 8 8s8-3.58 8-8v-4H4v4zm7-13.93C7.05 1.56 4 4.92 4 9h7V1.07z"/></svg>

After

Width:  |  Height:  |  Size: 254 B

14
metadata.desktop Normal file
View file

@ -0,0 +1,14 @@
[SddmGreeterTheme]
Name=NX Theme
Namep[nl]=NX-Thema
Description=A theme inspired by the Nintendo Switch
Description[nl]=Een theme geinspireerd door de Nintendo Switch
Preview=screenshot.png
MainScript=Main.qml
Author=Chris Josten
License=lgpl-v3
Type=sddm-theme
ConfigFile=theme.conf
Theme-Id=nx-sddm
Theme-API=2.0

1
qmldir Normal file
View file

@ -0,0 +1 @@
singleton Style 1.0 Style.qml

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

3
theme.conf Normal file
View file

@ -0,0 +1,3 @@
[General]
background=