First working Version
This commit is contained in:
commit
a08e6d68d7
18 changed files with 2166 additions and 0 deletions
63
components/AccessibilityMenu.qml
Normal file
63
components/AccessibilityMenu.qml
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import "common"
|
||||
|
||||
ComboBox {
|
||||
id: container
|
||||
property int fontSize: root.font.pointSize
|
||||
property int screenPadding: parent.Layout.margins
|
||||
background: null
|
||||
|
||||
property bool vkbd_installed: false
|
||||
function keyboardStatusChanged(state: bool) {
|
||||
vkbd_installed = state
|
||||
}
|
||||
|
||||
indicator: Button {
|
||||
anchors.fill: parent
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
renderType: Text.QtRendering
|
||||
text: ""
|
||||
font.family: iconFont
|
||||
color: container.focus ? root.palette.accent : root.palette.text
|
||||
font.pointSize: fontSize * 1.5
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
container.popup.open()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function actionPressed(id: int) {
|
||||
if (id == 0) root.activateVirtualKeyboard = !root.activateVirtualKeyboard;
|
||||
}
|
||||
|
||||
model: [
|
||||
{'value': root.activateVirtualKeyboard, 'icon': "", 'label': config.virtualKeyboard || "Virtual keyboard", 'enabled': vkbd_installed},
|
||||
]
|
||||
delegate: Toggle {
|
||||
required property var modelData;
|
||||
enabled: modelData['enabled']
|
||||
checked: modelData['value']
|
||||
icon: modelData['icon']
|
||||
text: modelData['label']
|
||||
|
||||
Component.onCompleted: toggled.connect(container.actionPressed);
|
||||
}
|
||||
|
||||
popup: PopupPanel {
|
||||
x: root.LayoutMirroring.enabled ? -parent.width : (2 * parent.width - width + parent.parent.spacing)
|
||||
interactive: false
|
||||
|
||||
model: container.delegateModel
|
||||
}
|
||||
|
||||
}
|
||||
81
components/Clock.qml
Normal file
81
components/Clock.qml
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Column {
|
||||
property int fontSize: root.font.pointSize * config.realValue("fontSizeMultiplier")
|
||||
property date value: new Date()
|
||||
|
||||
spacing: -fontSize / 2
|
||||
|
||||
readonly property var position_str: config.dateTimePosition.toLowerCase().split(/[.,\/#!$%\^&\*;:{}=\-_`~()\s]/)
|
||||
readonly property bool is_left: position_str[position_str.length-1] == "left"
|
||||
readonly property bool is_right: position_str[position_str.length-1] == "right"
|
||||
readonly property bool is_top: position_str[0] == "top"
|
||||
readonly property bool is_bottom: position_str[0] == "bottomLogin fehlgeschlagen"
|
||||
readonly property bool is_center_center: !(is_left || is_right) && !(is_top || is_bottom)
|
||||
|
||||
anchors {
|
||||
left: is_left ? parent.left : undefined
|
||||
horizontalCenter: !(is_left || is_right) ? parent.horizontalCenter : undefined
|
||||
right: is_right ? parent.right : undefined
|
||||
|
||||
top: is_top ? parent.top: undefined
|
||||
verticalCenter: !(is_top || is_bottom) ? parent.verticalCenter : undefined
|
||||
bottom: is_bottom ? parent.bottom: undefined
|
||||
}
|
||||
|
||||
Label {
|
||||
id: time_label
|
||||
visible: true
|
||||
|
||||
anchors {
|
||||
left: is_left ? parent.left : undefined
|
||||
horizontalCenter: !(is_left || is_right) ? parent.horizontalCenter : undefined
|
||||
right: is_right ? parent.right : undefined
|
||||
}
|
||||
|
||||
renderType: Text.QtRendering
|
||||
color: config.clockStyle == "outline" ? "transparent" : root.palette.text
|
||||
style: config.clockStyle == "outline" ? Text.Outline : Text.Normal
|
||||
styleColor: root.palette.text
|
||||
font.pointSize: fontSize * 3
|
||||
|
||||
function update() {
|
||||
text = Qt.formatTime(value, config.clockFormat)
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: date_label
|
||||
|
||||
anchors {
|
||||
left: is_left ? parent.left : undefined
|
||||
horizontalCenter: !(is_left || is_right) ? parent.horizontalCenter : undefined
|
||||
right: is_right ? parent.right : undefined
|
||||
}
|
||||
|
||||
renderType: Text.QtRendering
|
||||
color: root.palette.text
|
||||
font.pointSize: Math.min(1.4 * (time_label.width / text.length), fontSize * 2)
|
||||
|
||||
function update() {
|
||||
text = value.toLocaleDateString(Qt.locale(config.locale), config.dateFormat)
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
repeat: true
|
||||
running: true
|
||||
onTriggered: {
|
||||
value = new Date()
|
||||
time_label.update()
|
||||
date_label.update()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
time_label.update()
|
||||
date_label.update()
|
||||
}
|
||||
}
|
||||
90
components/LayoutSelection.qml
Normal file
90
components/LayoutSelection.qml
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import "common"
|
||||
|
||||
ComboBox {
|
||||
id: container
|
||||
property int fontSize: root.font.pointSize
|
||||
background: null
|
||||
|
||||
indicator: Button {
|
||||
anchors.fill: parent
|
||||
Text {
|
||||
id: button
|
||||
anchors.centerIn: parent
|
||||
|
||||
renderType: Text.QtRendering
|
||||
text: keyboard.layouts[keyboard.currentLayout].shortName
|
||||
font.family: iconFont
|
||||
color: container.focus ? root.palette.accent : root.palette.text
|
||||
font.pointSize: fontSize * 1.5
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
container.popup.open()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
model: keyboard.layouts
|
||||
onActivated: keyboard.currentLayout = highlightedIndex
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: keyboard_layout
|
||||
highlighted: keyboard.currentLayout == index
|
||||
|
||||
implicitHeight: fontSize * 3
|
||||
implicitWidth: label.width
|
||||
Layout.fillWidth: true
|
||||
|
||||
Text {
|
||||
id: label
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
anchors.verticalCenter: keyboard_layout.verticalCenter
|
||||
|
||||
renderType: Text.QtRendering
|
||||
text: modelData.longName
|
||||
font.family: root.font.family
|
||||
font.pointSize: fontSize
|
||||
color: root.palette.buttonText
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "selected"
|
||||
when: keyboard_layout.highlighted
|
||||
PropertyChanges {
|
||||
target: keyboard_layout.background
|
||||
color: root.palette.accent
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "highlighted"
|
||||
when: index === container.highlightedIndex
|
||||
PropertyChanges {
|
||||
target: keyboard_layout.background
|
||||
color: "#777777"
|
||||
opacity: 0.4
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
popup: PopupPanel {
|
||||
x: (parent.width - width) * 0.5
|
||||
|
||||
model: container.delegateModel
|
||||
}
|
||||
}
|
||||
221
components/LoginForm.qml
Normal file
221
components/LoginForm.qml
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import "common"
|
||||
|
||||
Column {
|
||||
id: container
|
||||
property int fontSize: root.font.pointSize
|
||||
property int p: config.ScreenPadding
|
||||
|
||||
signal loginRequest()
|
||||
function login(sessionID: int) {
|
||||
if (sessionID < 0 || sessionID >= sessionModel.count) { // turns out SDDM doesn't check session index is in bounds before sending it to the daemon
|
||||
console.error(`Could not find session "${session.currentText}" with ID ${sessionID}`);
|
||||
notificationMessageOverride = `Invalid session "${session.currentText}"`;
|
||||
loginFailed();
|
||||
}
|
||||
sddm.login(username.text, password.text, sessionID);
|
||||
}
|
||||
|
||||
function loginFailed() {
|
||||
notification.opacity = 1;
|
||||
password.text = ""
|
||||
if (notification_timeout.running) notification_timeout.stop();
|
||||
notification_timeout.start();
|
||||
password.forceActiveFocus();
|
||||
}
|
||||
|
||||
width: parent.width
|
||||
|
||||
// temporary override of notification message to display custom error messages
|
||||
property string notificationMessageOverride: ""
|
||||
|
||||
TextField {
|
||||
id: username
|
||||
width: parent.width * 0.5
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
|
||||
|
||||
text: ""
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
radius: 8
|
||||
border.color: parent.focus ? root.palette.accent : root.palette.text
|
||||
border.width: 2
|
||||
}
|
||||
|
||||
placeholderText: config.username || text_const.userName
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
selectByMouse: true
|
||||
|
||||
renderType: Text.QtRendering
|
||||
font.pointSize: fontSize * 1.2
|
||||
//font.bold: true
|
||||
font.capitalization: config.boolValue("capitaliseUsername") ? Font.Capitalize : Font.MixedCase
|
||||
color: root.palette.text
|
||||
|
||||
onAccepted: password.forceActiveFocus()
|
||||
KeyNavigation.down: password
|
||||
KeyNavigation.tab: password
|
||||
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.horizontalCenter: username.horizontalCenter
|
||||
width: username.width
|
||||
|
||||
TextField {
|
||||
id: password
|
||||
Layout.fillWidth: true
|
||||
|
||||
onVisibleChanged: { if (visible && username.text.length > 0) forceActiveFocus(); }
|
||||
|
||||
placeholderText: config.password || text_const.password
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
selectByMouse: true
|
||||
echoMode: reveal_passwd.checked ? TextInput.Normal : (config.passwordEchoStyle == "off" ? TextInput.NoEcho : TextInput.Password)
|
||||
|
||||
renderType: Text.QtRendering
|
||||
font.pointSize: fontSize
|
||||
color: root.palette.text
|
||||
passwordCharacter: "•"
|
||||
|
||||
onAccepted: {focus = false; loginRequest()}
|
||||
KeyNavigation.right: login_button
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
radius: 8
|
||||
border.color: parent.focus ? root.palette.accent : root.palette.text
|
||||
border.width: 2
|
||||
}
|
||||
|
||||
Label {
|
||||
anchors.left: parent.left
|
||||
height: parent.height
|
||||
width: height
|
||||
|
||||
opacity: keyboard.capsLock
|
||||
|
||||
Text {
|
||||
horizontalAlignment: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
renderType: Text.QtRendering
|
||||
text: ""
|
||||
font.family: iconFont
|
||||
color: root.palette.text
|
||||
font.pointSize: fontSize * 1.3
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 75 * root.animationsEnabled }
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: reveal_passwd
|
||||
|
||||
anchors.right: parent.right
|
||||
height: parent.height
|
||||
width: height
|
||||
|
||||
indicator: Text {
|
||||
height: parent.height
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
renderType: Text.QtRendering
|
||||
text: parent.checked ? "": ""
|
||||
font.family: iconFont
|
||||
color: root.palette.text
|
||||
opacity: parent.hovered ? 1 : 0.66
|
||||
font.pointSize: fontSize * 1.2
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 75 * root.animationsEnabled }
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: password.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: login_button
|
||||
visible: username.text.length > 0 && (config.boolValue("allowEmptyPassword") || (password.text.length > 0))
|
||||
implicitHeight: password.height
|
||||
Layout.fillWidth: false
|
||||
Layout.preferredWidth: implicitHeight
|
||||
|
||||
Text {
|
||||
id: icon
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
renderType: Text.QtRendering
|
||||
font.pointSize: fontSize * 1.4
|
||||
font.family: iconFont
|
||||
color: login_button.focus ? root.palette.accent : root.palette.text
|
||||
text: LayoutMirroring.enabled ? "" : ""
|
||||
}
|
||||
|
||||
onClicked: loginRequest()
|
||||
KeyNavigation.left: password
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
radius: 8
|
||||
border.color: parent.focus? root.palette.accent : root.palette.text
|
||||
border.width: 1
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "selected"
|
||||
when: login_button.pressed
|
||||
PropertyChanges {
|
||||
target: login_button.background
|
||||
color: root.palette.accent
|
||||
border.color: root.palette.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
color: root.palette.text
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Text {
|
||||
id: notification
|
||||
text: notificationMessageOverride || config.loginFailed || text_const.loginFailed
|
||||
opacity: 0
|
||||
|
||||
renderType: Text.QtRendering
|
||||
color: root.palette.accent
|
||||
font.pointSize: fontSize * 0.825
|
||||
height: fontSize * 3
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 100 * root.animationsEnabled }
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: notification_timeout
|
||||
running: false
|
||||
interval: 2500
|
||||
onTriggered: { notification.opacity = 0; notificationMessageOverride = "" }
|
||||
}
|
||||
}
|
||||
}
|
||||
121
components/PowerMenu.qml
Normal file
121
components/PowerMenu.qml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import "common"
|
||||
|
||||
ComboBox {
|
||||
id: container
|
||||
property int fontSize: root.font.pointSize
|
||||
background: null
|
||||
|
||||
indicator: Button {
|
||||
anchors.fill: parent
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
renderType: Text.QtRendering
|
||||
text: ""
|
||||
font.family: iconFont
|
||||
color: container.focus ? root.palette.accent : root.palette.text
|
||||
font.pointSize: fontSize * 1.5
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
container.popup.open()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function actionPressed() {
|
||||
if (currentIndex == 0) sddm.suspend();
|
||||
else if (currentIndex == 1) sddm.hibernate();
|
||||
else if (currentIndex == 2) sddm.reboot();
|
||||
else if (currentIndex == 3) sddm.powerOff();
|
||||
}
|
||||
|
||||
property bool forcePowerOptions: false
|
||||
|
||||
model: [
|
||||
{'icon': "", 'label': config.suspend || text_const.suspend , 'enabled': sddm.canSuspend },
|
||||
{'icon': "", 'label': config.hibernate || text_const.hibernate, 'enabled': sddm.canHibernate},
|
||||
{'icon': "", 'label': config.reboot || text_const.reboot , 'enabled': sddm.canReboot },
|
||||
{'icon': "", 'label': config.poweroff || text_const.shutdown , 'enabled': sddm.canPowerOff },
|
||||
]
|
||||
onActivated: {
|
||||
currentIndex = highlightedIndex;
|
||||
actionPressed();
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: power_option
|
||||
visible: forcePowerOptions || modelData['enabled']
|
||||
|
||||
implicitHeight: fontSize * 3
|
||||
implicitWidth: content_item.width
|
||||
Layout.fillWidth: true
|
||||
|
||||
Row {
|
||||
id: content_item
|
||||
spacing: fontSize
|
||||
anchors.verticalCenter: power_option.verticalCenter
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
Text {
|
||||
visible: config.boolValue("iconsInMenus")
|
||||
renderType: Text.QtRendering
|
||||
text: modelData['icon']
|
||||
font.family: iconFont
|
||||
font.pointSize: fontSize
|
||||
color: root.palette.buttonText
|
||||
}
|
||||
Text {
|
||||
id: label
|
||||
renderType: Text.QtRendering
|
||||
text: modelData['label']
|
||||
font.family: root.font.family
|
||||
font.pointSize: fontSize
|
||||
color: root.palette.buttonText
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
currentIndex = index;
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "selected"
|
||||
when: power_option.activeFocus
|
||||
PropertyChanges {
|
||||
target: power_option.background
|
||||
color: root.palette.accent
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "highlighted"
|
||||
when: container.highlightedIndex === index
|
||||
PropertyChanges {
|
||||
target: power_option.background
|
||||
color: "#777777"
|
||||
opacity: 0.4
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
popup: PopupPanel {
|
||||
x: (parent.width - width) * !(root.LayoutMirroring.enabled)
|
||||
interactive: false
|
||||
|
||||
model: container.delegateModel
|
||||
}
|
||||
|
||||
}
|
||||
103
components/SessionSelection.qml
Normal file
103
components/SessionSelection.qml
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import "common"
|
||||
|
||||
ComboBox {
|
||||
id: container
|
||||
property int fontSize: root.font.pointSize
|
||||
background: null
|
||||
|
||||
indicator: Button {
|
||||
anchors.fill: parent
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
renderType: Text.QtRendering
|
||||
text: ""
|
||||
font.family: iconFont
|
||||
color: container.focus ? root.palette.accent : root.palette.text
|
||||
font.pointSize: fontSize * 1.5
|
||||
|
||||
Text {
|
||||
visible: config.boolValue("displaySession")
|
||||
anchors {
|
||||
leftMargin: fontSize
|
||||
left: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
renderType: Text.QtRendering
|
||||
text: container.currentText
|
||||
font.family: root.font.family
|
||||
color: root.palette.text
|
||||
font.pointSize: fontSize
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
container.popup.open()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
model: sessionModel
|
||||
currentIndex: model.lastIndex
|
||||
textRole: "name"
|
||||
onActivated: currentIndex = highlightedIndex
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: session_item
|
||||
highlighted: container.currentIndex === index
|
||||
|
||||
implicitHeight: fontSize * 3
|
||||
implicitWidth: label.width
|
||||
Layout.fillWidth: true
|
||||
|
||||
Text {
|
||||
id: label
|
||||
padding: 10
|
||||
anchors.verticalCenter: session_item.verticalCenter
|
||||
|
||||
renderType: Text.QtRendering
|
||||
text: name
|
||||
font.family: root.font.family
|
||||
font.pointSize: fontSize
|
||||
color: root.palette.buttonText
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "selected"
|
||||
when: session_item.highlighted
|
||||
PropertyChanges {
|
||||
target: session_item.background
|
||||
color: root.palette.accent
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "highlighted"
|
||||
when: container.highlightedIndex === index
|
||||
PropertyChanges {
|
||||
target: session_item.background
|
||||
color: "#777777"
|
||||
opacity: 0.4
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
popup: PopupPanel {
|
||||
x: (parent.width - width) * root.LayoutMirroring.enabled
|
||||
|
||||
model: container.delegateModel
|
||||
}
|
||||
}
|
||||
86
components/UserList.qml
Normal file
86
components/UserList.qml
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import "common"
|
||||
|
||||
ComboBox {
|
||||
id: container
|
||||
property int fontSize: root.font.pointSize
|
||||
property int optionHeight: fontSize * 3
|
||||
background: null
|
||||
|
||||
signal userSelected()
|
||||
|
||||
indicator: Button {
|
||||
anchors.fill: parent
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
renderType: Text.QtRendering
|
||||
text: ""
|
||||
font.family: iconFont
|
||||
color: container.focus ? root.palette.accent : root.palette.text
|
||||
font.pointSize: fontSize * 1.4
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
container.popup.open()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
model: userModel
|
||||
currentIndex: model.lastIndex
|
||||
textRole: "name"
|
||||
onActivated: userSelected()
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: user_item
|
||||
implicitHeight: optionHeight
|
||||
implicitWidth: container.popup.width
|
||||
|
||||
highlighted: container.currentIndex === index
|
||||
|
||||
Text {
|
||||
id: label
|
||||
width: parent.width
|
||||
padding: 10
|
||||
anchors.verticalCenter: user_item.verticalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
renderType: Text.QtRendering
|
||||
text: model.realName != "" ? model.realName : model.name
|
||||
font.family: root.font.family
|
||||
font.pointSize: fontSize
|
||||
color: root.palette.buttonText
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "highlighted"
|
||||
when: index === container.highlightedIndex
|
||||
PropertyChanges {
|
||||
target: user_item.background
|
||||
color: "#777777"
|
||||
opacity: 0.4
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
popup: PopupPanel {
|
||||
width: container.parent.width
|
||||
y: -height
|
||||
|
||||
model: container.delegateModel
|
||||
}
|
||||
|
||||
}
|
||||
26
components/VirtualKeyboard.qml
Normal file
26
components/VirtualKeyboard.qml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.VirtualKeyboard 2.15
|
||||
import QtQuick.VirtualKeyboard.Settings 2.15
|
||||
|
||||
Item {
|
||||
id: keyboard_container
|
||||
height: input_panel.active ? input_panel.height : 0
|
||||
|
||||
InputPanel {
|
||||
id: input_panel
|
||||
active: root.activateVirtualKeyboard && (Qt.inputMethod.visible || config.boolValue("forceKeyboardVisible"))
|
||||
visible: active
|
||||
|
||||
z: 1
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
Binding {
|
||||
target: VirtualKeyboardSettings
|
||||
property: "wordCandidateList.autoHideDelay"
|
||||
value: 1000
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
54
components/common/PopupPanel.qml
Normal file
54
components/common/PopupPanel.qml
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Popup {
|
||||
id: menu
|
||||
y: -(height + root.font.pointSize / 2)
|
||||
|
||||
property var model
|
||||
property var delegate
|
||||
property alias interactive: flickable.interactive
|
||||
property real delegateHeight: fontSize * 3
|
||||
|
||||
// maximum number of options to show at once, scroll/flick to see the rest
|
||||
// adding .5 works as a visual hint there's more options by displaying half of the next button
|
||||
property real max_size: 5.5
|
||||
|
||||
padding: 0
|
||||
topPadding: background.radius
|
||||
bottomPadding: background.radius
|
||||
|
||||
background: Rectangle {
|
||||
color: root.palette.button
|
||||
radius: 8
|
||||
}
|
||||
|
||||
contentItem: Flickable {
|
||||
id: flickable
|
||||
clip: true
|
||||
implicitWidth: contentWidth
|
||||
implicitHeight: interactive ? Math.min(contentHeight, menu.max_size * (menu.delegateHeight + delegate_container.spacing)) : contentHeight
|
||||
contentWidth: delegate_container.width
|
||||
contentHeight: delegate_container.height
|
||||
|
||||
flickableDirection: Flickable.VerticalFlick
|
||||
ScrollBar.vertical: ScrollBar { }
|
||||
|
||||
ColumnLayout {
|
||||
id: delegate_container
|
||||
spacing: 4
|
||||
Repeater {
|
||||
model: menu.model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enter: Transition {
|
||||
NumberAnimation { property: "height"; from: 0.0; to: implicitHeight; duration: 50 * root.animationsEnabled }
|
||||
}
|
||||
exit: Transition {
|
||||
NumberAnimation { property: "height"; from: implicitHeight; to: 0.0; duration: 50 * root.animationsEnabled }
|
||||
}
|
||||
|
||||
}
|
||||
109
components/common/Toggle.qml
Normal file
109
components/common/Toggle.qml
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
RowLayout {
|
||||
id: item
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: fontSize * 3
|
||||
|
||||
spacing: fontSize
|
||||
Layout.leftMargin: 10
|
||||
Layout.rightMargin: 10
|
||||
|
||||
required property int index;
|
||||
property alias text: label.text
|
||||
property alias icon: icon.text
|
||||
property alias enabled: toggle.enabled
|
||||
property alias checked: toggle.checked
|
||||
signal toggled(int id)
|
||||
|
||||
Text {
|
||||
id: icon
|
||||
visible: config.boolValue("iconsInMenus")
|
||||
renderType: Text.QtRendering
|
||||
font.pointSize: fontSize
|
||||
font.family: config.iconFont
|
||||
color: root.palette.buttonText
|
||||
}
|
||||
|
||||
Text {
|
||||
id: label
|
||||
renderType: Text.QtRendering
|
||||
font.family: root.font.family
|
||||
font.pointSize: fontSize
|
||||
color: root.palette.buttonText
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: toggle
|
||||
|
||||
Layout.preferredHeight: indicator.implicitHeight + 10
|
||||
Layout.preferredWidth: indicator.implicitWidth + 10
|
||||
Layout.fillWidth: false
|
||||
|
||||
onClicked: item.toggled(index)
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
radius: 8
|
||||
}
|
||||
|
||||
indicator: Rectangle {
|
||||
anchors.centerIn: parent
|
||||
implicitHeight: fontSize * 1.5
|
||||
implicitWidth: fontSize * 3
|
||||
radius: implicitHeight / 2
|
||||
color: parent.checked ? root.palette.accent : Qt.darker(root.palette.button, 1.3)
|
||||
border.color: parent.checked ? root.palette.accent : "#cccccc"
|
||||
|
||||
Text {
|
||||
visible: true
|
||||
height: parent.height
|
||||
width: height
|
||||
x: checked ? 0 : parent.width - width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
renderType: Text.QtRendering
|
||||
text: checked ? "" : ""
|
||||
font.family: root.iconFont
|
||||
font.pointSize: fontSize * 0.7
|
||||
color: root.palette.buttonText
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: knob
|
||||
x: checked ? parent.width - width : 0
|
||||
height: parent.implicitHeight
|
||||
width: height
|
||||
radius: height / 2
|
||||
color: toggle.down ? "#cccccc" : root.palette.buttonText
|
||||
border.color: checked ? root.palette.accent : "#999999"
|
||||
}
|
||||
}
|
||||
states: [
|
||||
State {
|
||||
when: !enabled
|
||||
PropertyChanges {
|
||||
target: toggle.indicator
|
||||
color: "#555555"
|
||||
border.color: "#333333"
|
||||
opacity: 0.3
|
||||
}
|
||||
PropertyChanges {
|
||||
target: toggle
|
||||
checked: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: knob
|
||||
color: "#cccccc"
|
||||
border.color: Qt.lighter(toggle.indicator.color, 1.5)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue