526 lines
18 KiB
QML
Raw Normal View History

2022-03-04 23:58:22 +01:00
import QtQuick.Controls 1.1
import QtQuick.Controls 2.12 as QQC2
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.extras 2.0 as PlasmaExtras
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
import QtQuick 2.8
import SddmComponents 2.0
import QtMultimedia 5.7
import "components"
Rectangle {
// Main Container
id: container
LayoutMirroring.enabled: Qt.locale().textDirection == Qt.RightToLeft
LayoutMirroring.childrenInherit: true
// Inherited from SDDMComponents
TextConstants {
id: textConstants
}
// Set SDDM actions
Connections {
target: sddm
onLoginSucceeded: {
}
onLoginFailed: {
error_message.color = "#dc322f"
error_message.text = textConstants.loginFailed
}
}
// Set Font
FontLoader {
id: textFont; name: config.displayFont
}
// Background Fill
Rectangle {
anchors.fill: parent
color: "black"
}
// Set Background Image
Image {
id: image1
anchors.fill: parent
//source: config.background
fillMode: Image.PreserveAspectCrop
}
// Set Background Video1
MediaPlayer {
id: mediaplayer1
autoPlay: true; muted: true
playlist: Playlist {
id: playlist1
playbackMode: Playlist.Random
onLoaded: { mediaplayer1.play() }
}
}
VideoOutput {
id: video1
fillMode: VideoOutput.PreserveAspectCrop
anchors.fill: parent; source: mediaplayer1
MouseArea {
id: mouseArea1
anchors.fill: parent;
//onPressed: {playlist1.shuffle(); playlist1.next();}
onPressed: {}
2022-03-04 23:58:22 +01:00
}
Keys.onPressed: {}
2022-03-04 23:58:22 +01:00
}
WallpaperFader {
id: fader1
visible: true
anchors.fill: parent
state: "off"
source: video1
}
// Set Background Video2
MediaPlayer {
id: mediaplayer2
autoPlay: true; muted: true
playlist: Playlist {
id: playlist2; playbackMode: Playlist.Random
//onLoaded: { mediaplayer2.play() }
}
}
VideoOutput {
id: video2
fillMode: VideoOutput.PreserveAspectCrop
anchors.fill: parent; source: mediaplayer2
opacity: 0
MouseArea {
id: mouseArea2
enabled: false
anchors.fill: parent;
onPressed: {}
2022-03-04 23:58:22 +01:00
}
Behavior on opacity {}
Keys.onPressed: {}
2022-03-04 23:58:22 +01:00
}
WallpaperFader {
id: fader2
visible: true
anchors.fill: parent
state: "off"
source: video2
}
property MediaPlayer currentPlayer: mediaplayer1
// Timer event to handle fade between videos
Timer {
interval: 1000;
running: true; repeat: true
onTriggered: {
if (currentPlayer.duration != -1 && currentPlayer.position > currentPlayer.duration - 10000) { // pre load the 2nd player
if (video2.opacity == 0) { // toogle opacity
mediaplayer2.play()
} else
mediaplayer1.play()
}
if (currentPlayer.duration != -1 && currentPlayer.position > currentPlayer.duration - 3000) { // initiate transition
if (video2.opacity == 0) { // toogle opacity
mouseArea1.enabled = false
currentPlayer = mediaplayer2
video2.opacity = 1
triggerTimer.start()
mouseArea2.enabled = true
} else {
mouseArea2.enabled = false
currentPlayer = mediaplayer1
video2.opacity = 0
triggerTimer.start()
mouseArea1.enabled = true
}
}
}
}
Timer { // this timer waits for fade to stop and stops the video
id: triggerTimer
interval: 4000; running: false; repeat: false
onTriggered: {
if (video2.opacity == 1)
mediaplayer1.stop()
else
mediaplayer2.stop()
}
}
// Clock and Login Area
Rectangle {
id: rectangle
anchors.fill: parent
color: "transparent"
MouseArea {
id: loginScreenRoot
anchors.fill: parent
property bool uiVisible: true
property bool blockUI: mainStack.depth > 1 || userListComponent.mainPasswordBox.text.length > 0 || inputPanel.keyboardActive || config.type !== "image"
hoverEnabled: true
drag.filterChildren: true
onPressed: uiVisible = true;
onPositionChanged: uiVisible = true;
onUiVisibleChanged: {
if (blockUI) {
fadeoutTimer.running = false;
} else if (uiVisible) {
fadeoutTimer.restart();
}
}
onBlockUIChanged: {
if (blockUI) {
fadeoutTimer.running = false;
uiVisible = true;
} else {
fadeoutTimer.restart();
}
}
Keys.onPressed: {
uiVisible = true;
event.accepted = false;
}
//takes one full minute for the ui to disappear
Timer {
id: fadeoutTimer
running: true
interval: 60000
onTriggered: {
if (!loginScreenRoot.blockUI) {
loginScreenRoot.uiVisible = false;
}
}
}
QQC2.StackView {
id: mainStack
anchors.fill: parent
// If true (depends on the style and environment variables), hover events are always accepted
// and propagation stopped. This means the parent MouseArea won't get them and the UI won't be shown.
// Disable capturing those events while the UI is hidden to avoid that, while still passing events otherwise.
// One issue is that while the UI is visible, mouse activity won't keep resetting the timer, but when it
// finally expires, the next event should immediately set uiVisible = true again.
hoverEnabled: loginScreenRoot.uiVisible ? undefined : false
focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it
Timer {
//SDDM has a bug in 0.13 where even though we set the focus on the right item within the window, the window doesn't have focus
//it is fixed in 6d5b36b28907b16280ff78995fef764bb0c573db which will be 0.14
//we need to call "window->activate()" *After* it's been shown. We can't control that in QML so we use a shoddy timer
//it's been this way for all Plasma 5.x without a huge problem
running: true
repeat: false
interval: 200
onTriggered: mainStack.forceActiveFocus()
}
initialItem: Login {
id: userListComponent
userListModel: userModel
loginScreenUiVisible: loginScreenRoot.uiVisible
userListCurrentIndex: userModel.lastIndex >= 0 ? userModel.lastIndex : 0
lastUserName: userModel.lastUser
showUserList: {
if ( !userListModel.hasOwnProperty("count")
|| !userListModel.hasOwnProperty("disableAvatarsThreshold"))
return (userList.y + mainStack.y) > 0
if ( userListModel.count === 0 ) return false
if ( userListModel.hasOwnProperty("containsAllUsers") && !userListModel.containsAllUsers ) return false
return userListModel.count <= userListModel.disableAvatarsThreshold && (userList.y + mainStack.y) > 0
}
onLoginRequest: {
sddm.login(username, password, sessionButton.currentIndex)
}
2022-03-04 23:58:22 +01:00
}
Behavior on opacity {
OpacityAnimator {
duration: PlasmaCore.Units.longDuration
}
}
readonly property real zoomFactor: 3
popEnter: Transition {
ScaleAnimator {
from: mainStack.zoomFactor
to: 1
duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
easing.type: Easing.OutCubic
}
OpacityAnimator {
from: 0
to: 1
duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
easing.type: Easing.OutCubic
}
}
popExit: Transition {
ScaleAnimator {
from: 1
to: 0
duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
easing.type: Easing.OutCubic
}
OpacityAnimator {
from: 1
to: 0
duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
easing.type: Easing.OutCubic
}
}
pushEnter: Transition {
ScaleAnimator {
from: 0
to: 1
duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
easing.type: Easing.OutCubic
}
OpacityAnimator {
from: 0
to: 1
duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
easing.type: Easing.OutCubic
}
}
pushExit: Transition {
ScaleAnimator {
from: 1
to: mainStack.zoomFactor
duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
easing.type: Easing.OutCubic
}
OpacityAnimator {
from: 1
to: 0
duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
easing.type: Easing.OutCubic
}
}
}
Loader {
id: inputPanel
state: "hidden"
property bool keyboardActive: item ? item.active : false
onKeyboardActiveChanged: {
if (keyboardActive) {
state = "visible"
// Otherwise the password field loses focus and virtual keyboard
// keystrokes get eaten
userListComponent.mainPasswordBox.forceActiveFocus();
} else {
state = "hidden";
}
}
source: Qt.platform.pluginName.includes("wayland") ? "components/VirtualKeyboard_wayland.qml" : "components/VirtualKeyboard.qml"
anchors {
left: parent.left
right: parent.right
}
function showHide() {
state = state == "hidden" ? "visible" : "hidden";
}
states: [
State {
name: "visible"
PropertyChanges {
target: mainStack
y: Math.min(0, root.height - inputPanel.height - userListComponent.visibleBoundary)
}
},
State {
name: "hidden"
PropertyChanges {
target: mainStack
y: 0
}
}
]
transitions: [
Transition {
from: "hidden"
to: "visible"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
target: mainStack
property: "y"
duration: PlasmaCore.Units.longDuration
easing.type: Easing.InOutQuad
}
}
}
},
Transition {
from: "visible"
to: "hidden"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
target: mainStack
property: "y"
duration: PlasmaCore.Units.longDuration
easing.type: Easing.InOutQuad
}
}
}
}
]
}
Component {
id: userPromptComponent
Login {
showUsernamePrompt: true
loginScreenUiVisible: loginScreenRoot.uiVisible
fontSize: parseInt(config.fontSize) + 2
// using a model rather than a QObject list to avoid QTBUG-75900
userListModel: ListModel {
ListElement {
name: ""
iconSource: ""
}
Component.onCompleted: {
// as we can't bind inside ListElement
setProperty(0, "name", i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Type in Username and Password"));
}
}
}
}
Image {
id: logo
visible: config.showlogo == "shown"
source: config.logo
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: footer.top
anchors.bottomMargin: PlasmaCore.Units.largeSpacing
asynchronous: true
sourceSize.height: height
opacity: loginScreenRoot.uiVisible ? 0 : 1
fillMode: Image.PreserveAspectFit
height: Math.round(PlasmaCore.Units.gridUnit * 3.5)
Behavior on opacity {
// OpacityAnimator when starting from 0 is buggy (it shows one frame with opacity 1)"
NumberAnimation {
duration: PlasmaCore.Units.longDuration
easing.type: Easing.InOutQuad
}
}
}
//Footer
RowLayout {
id: footer
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
margins: PlasmaCore.Units.smallSpacing
}
Behavior on opacity {
OpacityAnimator {
duration: PlasmaCore.Units.longDuration
}
}
PlasmaComponents3.ToolButton {
text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Button to show/hide virtual keyboard", "Virtual Keyboard")
font.pointSize: config.fontSize
icon.name: inputPanel.keyboardActive ? "input-keyboard-virtual-on" : "input-keyboard-virtual-off"
onClicked: inputPanel.showHide()
visible: inputPanel.status == Loader.Ready
}
KeyboardButton {
font.pointSize: config.fontSize
}
SessionButton {
id: sessionButton
font.pointSize: config.fontSize
}
Item {
Layout.fillWidth: true
}
Battery {
fontSize: config.fontSize
}
}
}
Clock {
id: clock
y: parent.height * config.relativePositionY - clock.height / 2
x: parent.width * config.relativePositionX - clock.width / 2
}
}
Component.onCompleted: {
// Set Focus
/* if (username_input_box.text == "") */
/* username_input_box.focus = true */
/* else */
/* password_input_box.focus = true */
video1.focus = true
// load and randomize playlist
var time = parseInt(new Date().toLocaleTimeString(Qt.locale(),'h'))
if ( time >= 5 && time <= 17 ) {
playlist1.load(Qt.resolvedUrl(config.background_vid_day), 'm3u')
playlist2.load(Qt.resolvedUrl(config.background_vid_day), 'm3u')
image1.source = config.background_img_day
} else {
playlist1.load(Qt.resolvedUrl(config.background_vid_night), 'm3u')
playlist2.load(Qt.resolvedUrl(config.background_vid_night), 'm3u')
image1.source = config.background_img_night
}
for (var k = 0; k < Math.ceil(Math.random() * 10) ; k++) {
playlist1.shuffle()
playlist2.shuffle()
}
}
}