Fix text centering
Sort applauncher entries alphabetical Use global fontFamily and font size (Theme.qml) Tons of other small fixes
This commit is contained in:
parent
ac456fa9a3
commit
a1a9060111
27 changed files with 535 additions and 1060 deletions
|
|
@ -34,7 +34,8 @@ Item {
|
|||
text: panel.displayedWindowTitle && panel.displayedWindowTitle.length > 60
|
||||
? panel.displayedWindowTitle.substring(0, 60) + "..."
|
||||
: panel.displayedWindowTitle
|
||||
font.pixelSize: 12
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
color: Theme.textSecondary
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
|
|
|||
|
|
@ -75,7 +75,10 @@ PanelWindow {
|
|||
}
|
||||
function updateFilter() {
|
||||
var query = searchField.text ? searchField.text.toLowerCase() : "";
|
||||
var apps = root.appModel;
|
||||
// Sort apps alphabetically by name (case-insensitive)
|
||||
var apps = root.appModel.slice().sort(function(a, b) {
|
||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||
});
|
||||
var results = [];
|
||||
// Calculator mode: starts with '='
|
||||
if (query.startsWith("=")) {
|
||||
|
|
@ -98,7 +101,11 @@ PanelWindow {
|
|||
results = results.concat(apps);
|
||||
} else {
|
||||
var fuzzyResults = Fuzzysort.go(query, apps, { keys: ["name", "comment", "genericName"] });
|
||||
results = results.concat(fuzzyResults.map(function(r) { return r.obj; }));
|
||||
// Sort fuzzy results alphabetically by name as well
|
||||
var sortedFuzzy = fuzzyResults.map(function(r) { return r.obj; }).sort(function(a, b) {
|
||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||
});
|
||||
results = results.concat(sortedFuzzy);
|
||||
}
|
||||
root.filteredApps = results;
|
||||
root.selectedIndex = 0;
|
||||
|
|
@ -158,18 +165,22 @@ PanelWindow {
|
|||
height: 48
|
||||
Layout.fillWidth: true
|
||||
border.color: searchField.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
border.width: 2
|
||||
border.width: searchField.activeFocus ? 2 : 1
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: 14
|
||||
anchors.rightMargin: 14
|
||||
spacing: 10
|
||||
anchors.margins: 14
|
||||
Text {
|
||||
text: "search"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 22
|
||||
font.pixelSize: Theme.fontSizeHeader
|
||||
color: searchField.activeFocus ? Theme.accentPrimary : Theme.textSecondary
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
TextField {
|
||||
id: searchField
|
||||
|
|
@ -177,15 +188,19 @@ PanelWindow {
|
|||
color: Theme.textPrimary
|
||||
placeholderTextColor: Theme.textSecondary
|
||||
background: null
|
||||
font.pixelSize: 17
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onTextChanged: root.updateFilter()
|
||||
selectedTextColor: Theme.onAccent
|
||||
selectionColor: Theme.accentPrimary
|
||||
padding: 2
|
||||
padding: 0
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
font.bold: true
|
||||
Component.onCompleted: contentItem.cursorColor = Theme.textPrimary
|
||||
onActiveFocusChanged: contentItem.cursorColor = Theme.textPrimary
|
||||
|
|
@ -265,7 +280,7 @@ PanelWindow {
|
|||
visible: !modelData.isCalculator && !parent.iconLoaded
|
||||
text: "broken_image"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 22
|
||||
font.pixelSize: Theme.fontSizeHeader
|
||||
color: Theme.accentPrimary
|
||||
}
|
||||
}
|
||||
|
|
@ -275,7 +290,8 @@ PanelWindow {
|
|||
Text {
|
||||
text: modelData.name
|
||||
color: hovered || isSelected ? Theme.onAccent : Theme.textPrimary
|
||||
font.pixelSize: 14
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.bold: hovered || isSelected
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
|
|
@ -284,7 +300,8 @@ PanelWindow {
|
|||
Text {
|
||||
text: modelData.isCalculator ? (modelData.expr + " = " + modelData.result) : (modelData.comment || modelData.genericName || "")
|
||||
color: hovered || isSelected ? Theme.onAccent : Theme.textSecondary
|
||||
font.pixelSize: 11
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
|
@ -293,7 +310,7 @@ PanelWindow {
|
|||
Text {
|
||||
text: modelData.isCalculator ? "content_copy" : "chevron_right"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 16
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: hovered || isSelected ? Theme.onAccent : Theme.textSecondary
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,221 +0,0 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Bluetooth
|
||||
import qs.Settings
|
||||
import qs.Components
|
||||
|
||||
Item {
|
||||
id: bluetoothDisplay
|
||||
width: 22
|
||||
height: 22
|
||||
|
||||
property color hoverColor: Theme.rippleEffect
|
||||
property real hoverOpacity: 0.0
|
||||
property bool isActive: mouseArea.containsMouse || (bluetoothPopup && bluetoothPopup.visible)
|
||||
|
||||
// Show the Bluetooth popup when clicked
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if (bluetoothPopup.visible) {
|
||||
bluetoothPopup.hidePopup();
|
||||
} else {
|
||||
bluetoothPopup.showAt(this, 0, parent.height);
|
||||
}
|
||||
}
|
||||
onEntered: bluetoothDisplay.hoverOpacity = 0.18
|
||||
onExited: bluetoothDisplay.hoverOpacity = 0.0
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: -4 // Make hover area larger than icon
|
||||
color: hoverColor
|
||||
opacity: isActive ? 0.18 : hoverOpacity
|
||||
radius: height / 2
|
||||
z: 0
|
||||
visible: opacity > 0.01
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "bluetooth"
|
||||
font.family: isActive ? "Material Symbols Rounded" : "Material Symbols Outlined"
|
||||
font.pixelSize: 18
|
||||
color: bluetoothPopup.visible ? Theme.accentPrimary : Theme.textPrimary
|
||||
z: 1
|
||||
}
|
||||
|
||||
Behavior on hoverOpacity {
|
||||
NumberAnimation {
|
||||
duration: 120
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
|
||||
// The popup window for device list
|
||||
PopupWindow {
|
||||
id: bluetoothPopup
|
||||
implicitWidth: 350
|
||||
//property int deviceCount: (typeof Bluetooth.devices.count === 'number' && Bluetooth.devices.count >= 0) ? Bluetooth.devices.count : 0
|
||||
//implicitHeight: Math.max(100, Math.min(420, 56 + (deviceCount * 36) + 24))
|
||||
implicitHeight: 400
|
||||
visible: false
|
||||
color: "transparent"
|
||||
|
||||
property var anchorItem: null
|
||||
property real anchorX
|
||||
property real anchorY
|
||||
|
||||
anchor.item: anchorItem ? anchorItem : null
|
||||
anchor.rect.x: anchorX - (implicitWidth / 2) + (anchorItem ? anchorItem.width / 2 : 0)
|
||||
anchor.rect.y: anchorY + 8 // Move popup further down
|
||||
|
||||
function showAt(item, x, y) {
|
||||
if (!item) {
|
||||
console.warn("Bluetooth: anchorItem is undefined, not showing popup.")
|
||||
return
|
||||
}
|
||||
anchorItem = item
|
||||
anchorX = x
|
||||
anchorY = y
|
||||
visible = true
|
||||
forceActiveFocus()
|
||||
}
|
||||
|
||||
function hidePopup() {
|
||||
visible = false
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
Keys.onEscapePressed: bluetoothPopup.hidePopup()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: bg
|
||||
anchors.fill: parent
|
||||
color: Theme.backgroundPrimary
|
||||
radius: 12
|
||||
border.width: 1
|
||||
border.color: Theme.surfaceVariant
|
||||
z: 0
|
||||
}
|
||||
|
||||
// Header
|
||||
Rectangle {
|
||||
id: header
|
||||
width: parent.width
|
||||
height: 56
|
||||
color: "transparent"
|
||||
|
||||
Text {
|
||||
text: "Bluetooth"
|
||||
font.pixelSize: 18
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
}
|
||||
}
|
||||
|
||||
// Device list container with proper margins
|
||||
Rectangle {
|
||||
id: listContainer
|
||||
anchors.top: header.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 8
|
||||
color: "transparent"
|
||||
clip: true
|
||||
|
||||
ListView {
|
||||
id: deviceListView
|
||||
anchors.fill: parent
|
||||
spacing: 4
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
model: Bluetooth.devices
|
||||
delegate: Rectangle {
|
||||
width: parent.width
|
||||
height: 42
|
||||
color: "transparent"
|
||||
radius: 8
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 8
|
||||
color: modelData.connected ? Qt.rgba(Theme.accentPrimary.r, Theme.accentPrimary.g, Theme.accentPrimary.b, 0.18)
|
||||
: (deviceMouseArea.containsMouse ? Theme.highlight : "transparent")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 12
|
||||
anchors.rightMargin: 12
|
||||
spacing: 12
|
||||
|
||||
Text {
|
||||
text: modelData.connected ? "bluetooth" : "bluetooth_disabled"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
color: modelData.connected ? Theme.accentPrimary : Theme.textSecondary
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
text: modelData.name || "Unknown Device"
|
||||
color: modelData.connected ? Theme.accentPrimary : Theme.textPrimary
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.address
|
||||
color: modelData.connected ? Theme.accentPrimary : Theme.textSecondary
|
||||
font.pixelSize: 11
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: deviceMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if (modelData.connected) {
|
||||
modelData.disconnect()
|
||||
} else {
|
||||
modelData.connect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll indicator when needed
|
||||
Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 2
|
||||
anchors.top: listContainer.top
|
||||
anchors.bottom: listContainer.bottom
|
||||
width: 4
|
||||
radius: 2
|
||||
color: Theme.textSecondary
|
||||
opacity: deviceListView.contentHeight > deviceListView.height ? 0.3 : 0
|
||||
visible: opacity > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,9 +9,9 @@ Rectangle {
|
|||
Text {
|
||||
id: textItem
|
||||
text: Time.time
|
||||
font.family: "Roboto"
|
||||
font.family: Theme.fontFamily
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 14
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.textPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ PopupWindow {
|
|||
Layout.fillWidth: true
|
||||
color: (modelData?.enabled ?? true) ? Theme.textPrimary : Theme.textDisabled
|
||||
text: modelData?.text ?? ""
|
||||
font.pixelSize: 13
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,430 +0,0 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import qs.Settings
|
||||
|
||||
Item {
|
||||
id: wifiDisplay
|
||||
width: 22
|
||||
height: 22
|
||||
|
||||
property color hoverColor: Theme.rippleEffect
|
||||
property real hoverOpacity: 0.0
|
||||
property bool isActive: mouseArea.containsMouse || (wifiPanel && wifiPanel.visible)
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if (wifiPanel.visible) {
|
||||
wifiPanel.hidePopup();
|
||||
} else {
|
||||
wifiPanel.showAt(this, 0, parent.height);
|
||||
}
|
||||
}
|
||||
onEntered: wifiDisplay.hoverOpacity = 0.18
|
||||
onExited: wifiDisplay.hoverOpacity = 0.0
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: -4
|
||||
color: hoverColor
|
||||
opacity: isActive ? 0.18 : hoverOpacity
|
||||
radius: height / 2
|
||||
z: 0
|
||||
visible: opacity > 0.01
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "wifi"
|
||||
font.family: isActive ? "Material Symbols Rounded" : "Material Symbols Outlined"
|
||||
font.pixelSize: 18
|
||||
color: wifiPanel.visible ? Theme.accentPrimary : Theme.textPrimary
|
||||
z: 1
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
id: wifiPanel
|
||||
implicitWidth: 350
|
||||
implicitHeight: 400
|
||||
color: "transparent"
|
||||
visible: false
|
||||
property var anchorItem: null
|
||||
property real anchorX
|
||||
property real anchorY
|
||||
property var networks: [] // { ssid, signal, security, connected }
|
||||
property string connectingSsid: ""
|
||||
property string errorMsg: ""
|
||||
property string passwordPromptSsid: ""
|
||||
property string passwordInput: ""
|
||||
property bool showPasswordPrompt: false
|
||||
|
||||
WlrLayershell.keyboardFocus: visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
|
||||
function showAt(item, x, y) {
|
||||
if (!item) {
|
||||
console.warn("Wifi: anchorItem is undefined, not showing panel.");
|
||||
return;
|
||||
}
|
||||
anchorItem = item
|
||||
anchorX = x
|
||||
anchorY = y
|
||||
visible = true
|
||||
refreshNetworks()
|
||||
Qt.callLater(() => {
|
||||
wifiPanel.x = anchorX - (wifiPanel.width / 2) + (anchorItem ? anchorItem.width / 2 : 0)
|
||||
wifiPanel.y = anchorY + 8
|
||||
})
|
||||
}
|
||||
function hidePopup() {
|
||||
visible = false
|
||||
showPasswordPrompt = false
|
||||
errorMsg = ""
|
||||
}
|
||||
|
||||
// Scan for networks
|
||||
Process {
|
||||
id: scanProcess
|
||||
running: false
|
||||
command: ["nmcli", "-t", "-f", "SSID,SECURITY,SIGNAL,IN-USE", "device", "wifi", "list"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
var lines = text.split("\n");
|
||||
var nets = [];
|
||||
var seen = {};
|
||||
for (var i = 0; i < lines.length; ++i) {
|
||||
var line = lines[i].trim();
|
||||
if (!line) continue;
|
||||
var parts = line.split(":");
|
||||
var ssid = parts[0];
|
||||
var security = parts[1];
|
||||
var signal = parseInt(parts[2]);
|
||||
var inUse = parts[3] === "*";
|
||||
if (ssid && !seen[ssid]) {
|
||||
nets.push({ ssid: ssid, security: security, signal: signal, connected: inUse });
|
||||
seen[ssid] = true;
|
||||
}
|
||||
}
|
||||
wifiPanel.networks = nets;
|
||||
}
|
||||
}
|
||||
}
|
||||
function refreshNetworks() {
|
||||
scanProcess.running = true;
|
||||
}
|
||||
|
||||
// Connect to a network
|
||||
Process {
|
||||
id: connectProcess
|
||||
property string ssid: ""
|
||||
property string password: ""
|
||||
running: false
|
||||
command: password ? ["nmcli", "device", "wifi", "connect", ssid, "password", password] : ["nmcli", "device", "wifi", "connect", ssid]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
wifiPanel.connectingSsid = "";
|
||||
wifiPanel.showPasswordPrompt = false;
|
||||
wifiPanel.errorMsg = "";
|
||||
refreshNetworks();
|
||||
}
|
||||
}
|
||||
stderr: StdioCollector {
|
||||
onStreamFinished: {
|
||||
wifiPanel.connectingSsid = "";
|
||||
wifiPanel.errorMsg = text;
|
||||
wifiPanel.showPasswordPrompt = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
function connectNetwork(ssid, security) {
|
||||
if (security && security !== "--") {
|
||||
// Prompt for password
|
||||
passwordPromptSsid = ssid;
|
||||
passwordInput = "";
|
||||
showPasswordPrompt = true;
|
||||
} else {
|
||||
connectingSsid = ssid;
|
||||
connectProcess.ssid = ssid;
|
||||
connectProcess.password = "";
|
||||
connectProcess.running = true;
|
||||
}
|
||||
}
|
||||
function submitPassword() {
|
||||
connectingSsid = passwordPromptSsid;
|
||||
connectProcess.ssid = passwordPromptSsid;
|
||||
connectProcess.password = passwordInput;
|
||||
connectProcess.running = true;
|
||||
}
|
||||
// Disconnect
|
||||
Process {
|
||||
id: disconnectProcess
|
||||
property string ssid: ""
|
||||
running: false
|
||||
command: ["nmcli", "connection", "down", "id", ssid]
|
||||
onRunningChanged: {
|
||||
if (!running) {
|
||||
refreshNetworks();
|
||||
}
|
||||
}
|
||||
}
|
||||
function disconnectNetwork(ssid) {
|
||||
disconnectProcess.ssid = ssid;
|
||||
disconnectProcess.running = true;
|
||||
}
|
||||
|
||||
// UI
|
||||
Rectangle {
|
||||
id: bg
|
||||
anchors.fill: parent
|
||||
radius: 12
|
||||
border.width: 1
|
||||
border.color: Theme.surfaceVariant
|
||||
color: Theme.backgroundPrimary
|
||||
z: 0
|
||||
}
|
||||
// Header
|
||||
Rectangle {
|
||||
id: header
|
||||
width: parent.width
|
||||
height: 56
|
||||
color: "transparent"
|
||||
Text {
|
||||
text: "Wi-Fi"
|
||||
font.pixelSize: 18
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
}
|
||||
// Refresh button
|
||||
Rectangle {
|
||||
id: refreshBtn
|
||||
width: 36
|
||||
height: 36
|
||||
radius: 18
|
||||
color: Theme.surfaceVariant
|
||||
border.color: refreshMouseArea.containsMouse ? Theme.accentPrimary : Theme.outline
|
||||
border.width: 1
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 12
|
||||
MouseArea {
|
||||
id: refreshMouseArea
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: wifiPanel.refreshNetworks()
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "refresh"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
color: Theme.accentPrimary
|
||||
}
|
||||
}
|
||||
}
|
||||
// Error message
|
||||
Text {
|
||||
visible: wifiPanel.errorMsg.length > 0
|
||||
text: wifiPanel.errorMsg
|
||||
color: Theme.error
|
||||
font.pixelSize: 12
|
||||
anchors.top: header.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
anchors.topMargin: 2
|
||||
}
|
||||
// Device list container
|
||||
Rectangle {
|
||||
id: listContainer
|
||||
anchors.top: header.bottom
|
||||
anchors.topMargin: wifiPanel.showPasswordPrompt ? 68 : 0
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 8
|
||||
color: "transparent"
|
||||
clip: true
|
||||
ListView {
|
||||
id: networkListView
|
||||
anchors.fill: parent
|
||||
spacing: 4
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
model: wifiPanel.networks
|
||||
delegate: Rectangle {
|
||||
id: networkEntry
|
||||
width: parent.width
|
||||
height: modelData.ssid === wifiPanel.passwordPromptSsid && wifiPanel.showPasswordPrompt ? 110 : 42
|
||||
color: "transparent"
|
||||
radius: 8
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 8
|
||||
color: modelData.connected ? Qt.rgba(Theme.accentPrimary.r, Theme.accentPrimary.g, Theme.accentPrimary.b, 0.18)
|
||||
: ((networkMouseArea.containsMouse || (modelData.ssid === wifiPanel.passwordPromptSsid && wifiPanel.showPasswordPrompt)) ? Theme.highlight : "transparent")
|
||||
z: 0
|
||||
}
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 0
|
||||
anchors.bottomMargin: 0
|
||||
anchors.topMargin: 0
|
||||
|
||||
height: 42
|
||||
spacing: 12
|
||||
// Signal icon
|
||||
Text {
|
||||
text: signalIcon(modelData.signal)
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
color: hovered ? Theme.backgroundPrimary : (modelData.connected ? Theme.accentPrimary : Theme.textSecondary)
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
Text {
|
||||
text: modelData.ssid || "Unknown Network"
|
||||
color: hovered ? Theme.backgroundPrimary : (modelData.connected ? Theme.accentPrimary : Theme.textPrimary)
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text {
|
||||
text: modelData.security && modelData.security !== "--" ? modelData.security : "Open"
|
||||
color: hovered ? Theme.backgroundPrimary : (modelData.connected ? Theme.accentPrimary : Theme.textSecondary)
|
||||
font.pixelSize: 11
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
// Status
|
||||
Text {
|
||||
visible: modelData.connected
|
||||
text: "connected"
|
||||
color: hovered ? Theme.backgroundPrimary : Theme.accentPrimary
|
||||
font.pixelSize: 11
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
// Password prompt dropdown (only for selected network)
|
||||
Rectangle {
|
||||
visible: modelData.ssid === wifiPanel.passwordPromptSsid && wifiPanel.showPasswordPrompt
|
||||
width: parent.width
|
||||
height: 60
|
||||
radius: 8
|
||||
color: Theme.surfaceVariant
|
||||
border.color: passwordField.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
border.width: 1
|
||||
anchors.bottom: parent.bottom
|
||||
z: 2
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
spacing: 10
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
radius: 8
|
||||
color: Theme.surfaceVariant
|
||||
border.color: passwordField.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
border.width: 1
|
||||
TextInput {
|
||||
id: passwordField
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
text: wifiPanel.passwordInput
|
||||
font.pixelSize: 13
|
||||
color: Theme.textPrimary
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
clip: true
|
||||
focus: true
|
||||
selectByMouse: true
|
||||
activeFocusOnTab: true
|
||||
inputMethodHints: Qt.ImhNone
|
||||
echoMode: TextInput.Password
|
||||
onTextChanged: wifiPanel.passwordInput = text
|
||||
onAccepted: wifiPanel.submitPassword()
|
||||
MouseArea {
|
||||
id: passwordMouseArea
|
||||
anchors.fill: parent
|
||||
onClicked: passwordField.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 80
|
||||
height: 36
|
||||
radius: 18
|
||||
color: Theme.accentPrimary
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 0
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: wifiPanel.submitPassword()
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "Connect"
|
||||
color: Theme.backgroundPrimary
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: networkMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if (modelData.connected) {
|
||||
wifiPanel.disconnectNetwork(modelData.ssid)
|
||||
} else if (modelData.security && modelData.security !== "--") {
|
||||
wifiPanel.passwordPromptSsid = modelData.ssid;
|
||||
wifiPanel.passwordInput = "";
|
||||
wifiPanel.showPasswordPrompt = true;
|
||||
} else {
|
||||
wifiPanel.connectNetwork(modelData.ssid, modelData.security)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Helper for hover text color
|
||||
property bool hovered: networkMouseArea.containsMouse || (modelData.ssid === wifiPanel.passwordPromptSsid && wifiPanel.showPasswordPrompt)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Scroll indicator
|
||||
Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 2
|
||||
anchors.top: listContainer.top
|
||||
anchors.bottom: listContainer.bottom
|
||||
width: 4
|
||||
radius: 2
|
||||
color: Theme.textSecondary
|
||||
opacity: networkListView.contentHeight > networkListView.height ? 0.3 : 0
|
||||
visible: opacity > 0
|
||||
}
|
||||
}
|
||||
|
||||
// Helper for signal icon
|
||||
function signalIcon(signal) {
|
||||
if (signal >= 80) return "network_wifi_4_bar";
|
||||
if (signal >= 60) return "network_wifi_3_bar";
|
||||
if (signal >= 40) return "network_wifi_2_bar";
|
||||
if (signal >= 20) return "network_wifi_1_bar";
|
||||
return "wifi_0_bar";
|
||||
}
|
||||
}
|
||||
|
|
@ -96,6 +96,7 @@ Rectangle {
|
|||
anchors.centerIn: parent
|
||||
text: circularProgressBar.text
|
||||
font.pixelSize: textSize
|
||||
font.family: Theme.fontFamily
|
||||
font.bold: true
|
||||
color: textColor
|
||||
visible: showText
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ Item {
|
|||
id: textItem
|
||||
anchors.centerIn: parent
|
||||
text: revealPill.text
|
||||
font.pixelSize: 14
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.family: Theme.fontFamily
|
||||
font.weight: Font.Bold
|
||||
color: textColor
|
||||
visible: showPill // Hide text when pill is collapsed
|
||||
|
|
@ -78,7 +79,7 @@ Item {
|
|||
Text {
|
||||
anchors.centerIn: parent
|
||||
font.family: showPill ? "Material Symbols Rounded" : "Material Symbols Outlined"
|
||||
font.pixelSize: 14
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
text: revealPill.icon
|
||||
color: showPill ? iconTextColor : textColor
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@ IpcHandler {
|
|||
}
|
||||
}
|
||||
|
||||
// Toggle LockScreen
|
||||
function toggleLock(): void {
|
||||
if (!lockScreen) {
|
||||
console.warn("LockScreenIpcHandler: lockScreen not set!");
|
||||
return;
|
||||
}
|
||||
console.log("[IPC] LockScreen lock() called");
|
||||
console.log("[IPC] LockScreen show() called");
|
||||
lockScreen.locked = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,13 +18,15 @@ QtObject {
|
|||
}
|
||||
|
||||
function loadSettings() {
|
||||
weatherCity = settings.value("weatherCity", weatherCity)
|
||||
profileImage = settings.value("profileImage", profileImage)
|
||||
let wc = settings.value("weatherCity", "Dinslaken");
|
||||
weatherCity = (wc !== undefined && wc !== null) ? wc : "Dinslaken";
|
||||
let pi = settings.value("profileImage", "https://cdn.discordapp.com/avatars/158005126638993408/de403f05fd7f74bb17e01a9b066a30fa?size=64");
|
||||
profileImage = (pi !== undefined && pi !== null) ? pi : "https://cdn.discordapp.com/avatars/158005126638993408/de403f05fd7f74bb17e01a9b066a30fa?size=64";
|
||||
let tempUnit = settings.value("weatherTempUnit", "celsius")
|
||||
useFahrenheit = (tempUnit === "fahrenheit")
|
||||
wallpaperFolder = settings.value("wallpaperFolder", wallpaperFolder)
|
||||
currentWallpaper = settings.value("currentWallpaper", currentWallpaper)
|
||||
videoPath = settings.value("videoPath", videoPath)
|
||||
wallpaperFolder = settings.value("wallpaperFolder", "/home/lysec/nixos/assets/wallpapers")
|
||||
currentWallpaper = settings.value("currentWallpaper", "")
|
||||
videoPath = settings.value("videoPath", "/home/lysec/Videos")
|
||||
console.log("Loaded profileImage:", profileImage)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,4 +37,12 @@ QtObject {
|
|||
// Shadows & Overlays
|
||||
readonly property color shadow: "#000000B3" // Standard soft black shadow
|
||||
readonly property color overlay: "#11121ACC" // Deep bluish overlay
|
||||
|
||||
// Font Properties
|
||||
readonly property string fontFamily: "Roboto" // Family for all text
|
||||
|
||||
readonly property int fontSizeHeader: 32 // Headers and titles
|
||||
readonly property int fontSizeBody: 16 // Body text and general content
|
||||
readonly property int fontSizeSmall: 14 // Small text like clock, labels
|
||||
readonly property int fontSizeCaption: 12 // Captions and fine print
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import qs.Settings
|
|||
import qs.Helpers
|
||||
import "../Helpers/Weather.js" as WeatherHelper
|
||||
|
||||
// Password-only lockscreen for all screens
|
||||
WlSessionLock {
|
||||
id: lock
|
||||
|
||||
property string errorMessage: ""
|
||||
property bool authenticating: false
|
||||
property string password: ""
|
||||
|
|
@ -24,7 +24,7 @@ WlSessionLock {
|
|||
property string weatherInfo: ""
|
||||
property string weatherIcon: ""
|
||||
property double currentTemp: 0
|
||||
locked: false // Start unlocked, only lock when button is clicked
|
||||
locked: false
|
||||
|
||||
// On component completed, fetch weather data
|
||||
Component.onCompleted: {
|
||||
|
|
@ -120,332 +120,334 @@ WlSessionLock {
|
|||
console.log("PAM start result:", started);
|
||||
}
|
||||
|
||||
// Lock surface
|
||||
WlSessionLockSurface {
|
||||
// Blurred wallpaper background
|
||||
Image {
|
||||
id: lockBgImage
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
source: Settings.currentWallpaper !== "" ? Settings.currentWallpaper : "/home/lysec/nixos/assets/wallpapers/lantern.png"
|
||||
cache: true
|
||||
smooth: true
|
||||
sourceSize.width: 2560
|
||||
sourceSize.height: 1440
|
||||
visible: true // Show the original for FastBlur input
|
||||
}
|
||||
FastBlur {
|
||||
anchors.fill: parent
|
||||
source: lockBgImage
|
||||
radius: 48 // Adjust blur strength as needed
|
||||
transparentBorder: true
|
||||
}
|
||||
// Main content container (moved up, Rectangle removed)
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 30
|
||||
width: Math.min(parent.width * 0.8, 400)
|
||||
|
||||
|
||||
|
||||
|
||||
Component {
|
||||
id: lockComponent
|
||||
WlSessionLockSurface {
|
||||
// Blurred wallpaper background
|
||||
Image {
|
||||
id: lockBgImage
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
source: Settings.currentWallpaper !== "" ? Settings.currentWallpaper : "/home/lysec/nixos/assets/wallpapers/lantern.png"
|
||||
cache: true
|
||||
smooth: true
|
||||
sourceSize.width: 2560
|
||||
sourceSize.height: 1440
|
||||
visible: true // Show the original for FastBlur input
|
||||
}
|
||||
FastBlur {
|
||||
anchors.fill: parent
|
||||
source: lockBgImage
|
||||
radius: 48 // Adjust blur strength as needed
|
||||
transparentBorder: true
|
||||
}
|
||||
// Main content container (moved up, Rectangle removed)
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 30
|
||||
width: Math.min(parent.width * 0.8, 400)
|
||||
|
||||
// User avatar/icon
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
width: 80
|
||||
height: 80
|
||||
radius: 40
|
||||
// User avatar/icon
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
width: 80
|
||||
height: 80
|
||||
radius: 40
|
||||
color: Theme.accentPrimary
|
||||
|
||||
Image {
|
||||
id: avatarImage
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
source: Settings.profileImage
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
visible: false // Only show the masked version
|
||||
asynchronous: true
|
||||
}
|
||||
OpacityMask {
|
||||
anchors.fill: avatarImage
|
||||
source: avatarImage
|
||||
maskSource: Rectangle {
|
||||
width: avatarImage.width
|
||||
height: avatarImage.height
|
||||
radius: avatarImage.width / 2
|
||||
visible: false
|
||||
}
|
||||
visible: Settings.profileImage !== ""
|
||||
}
|
||||
// Fallback icon
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "person"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 32
|
||||
color: Theme.onAccent
|
||||
visible: Settings.profileImage === ""
|
||||
}
|
||||
// Glow effect
|
||||
layer.enabled: true
|
||||
layer.effect: Glow {
|
||||
color: Theme.accentPrimary
|
||||
|
||||
Image {
|
||||
id: avatarImage
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
source: Settings.profileImage
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
visible: false // Only show the masked version
|
||||
asynchronous: true
|
||||
}
|
||||
OpacityMask {
|
||||
anchors.fill: avatarImage
|
||||
source: avatarImage
|
||||
maskSource: Rectangle {
|
||||
width: avatarImage.width
|
||||
height: avatarImage.height
|
||||
radius: avatarImage.width / 2
|
||||
visible: false
|
||||
}
|
||||
visible: Settings.profileImage !== ""
|
||||
}
|
||||
// Fallback icon
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "person"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 32
|
||||
color: Theme.onAccent
|
||||
visible: Settings.profileImage === ""
|
||||
}
|
||||
// Glow effect
|
||||
layer.enabled: true
|
||||
layer.effect: Glow {
|
||||
color: Theme.accentPrimary
|
||||
radius: 8
|
||||
samples: 16
|
||||
}
|
||||
}
|
||||
|
||||
// Username
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: Quickshell.env("USER")
|
||||
font.pixelSize: 24
|
||||
font.weight: Font.Medium
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
|
||||
// Password input container
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 50
|
||||
radius: 25
|
||||
color: Theme.surface
|
||||
opacity: 0.3
|
||||
border.color: passwordInput.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
border.width: 2
|
||||
|
||||
TextInput {
|
||||
id: passwordInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 15
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
font.pixelSize: 16
|
||||
color: Theme.textPrimary
|
||||
echoMode: TextInput.Password
|
||||
passwordCharacter: "●"
|
||||
passwordMaskDelay: 0
|
||||
|
||||
text: lock.password
|
||||
onTextChanged: lock.password = text
|
||||
|
||||
// Placeholder text
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "Enter password..."
|
||||
color: Theme.textSecondary
|
||||
opacity: 0.6
|
||||
font.pixelSize: 16
|
||||
visible: !passwordInput.text && !passwordInput.activeFocus
|
||||
}
|
||||
|
||||
// Handle Enter key
|
||||
Keys.onPressed: function(event) {
|
||||
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||
lock.unlockAttempt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Error message
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: lock.errorMessage
|
||||
color: Theme.error
|
||||
font.pixelSize: 14
|
||||
visible: lock.errorMessage !== ""
|
||||
opacity: lock.errorMessage !== "" ? 1 : 0
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 200 }
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock button
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
width: 120
|
||||
height: 44
|
||||
radius: 22
|
||||
color: unlockButtonArea.containsMouse ? Theme.accentPrimary : "transparent"
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 2
|
||||
opacity: lock.authenticating ? 0.5 : 0.8
|
||||
enabled: !lock.authenticating
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: lock.authenticating ? "Authenticating..." : "Unlock"
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
color: unlockButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: unlockButtonArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if (!lock.authenticating) {
|
||||
lock.unlockAttempt()
|
||||
}
|
||||
}
|
||||
}
|
||||
radius: 8
|
||||
samples: 16
|
||||
}
|
||||
}
|
||||
|
||||
// Top-center info panel (clock + weather)
|
||||
ColumnLayout {
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 40
|
||||
spacing: 8
|
||||
// Clock
|
||||
Text {
|
||||
id: timeText
|
||||
text: Qt.formatDateTime(new Date(), "HH:mm")
|
||||
font.pixelSize: 48
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
Text {
|
||||
id: dateText
|
||||
text: Qt.formatDateTime(new Date(), "dddd, MMMM d")
|
||||
// Username
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: Quickshell.env("USER")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 24
|
||||
font.weight: Font.Medium
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
|
||||
// Password input container
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 50
|
||||
radius: 25
|
||||
color: Theme.surface
|
||||
opacity: 0.3
|
||||
border.color: passwordInput.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
border.width: 2
|
||||
|
||||
TextInput {
|
||||
id: passwordInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 15
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 16
|
||||
color: Theme.textSecondary
|
||||
opacity: 0.8
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
// Weather info (centered, no city)
|
||||
RowLayout {
|
||||
spacing: 6
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
visible: weatherData && weatherData.current_weather
|
||||
color: Theme.textPrimary
|
||||
echoMode: TextInput.Password
|
||||
passwordCharacter: "●"
|
||||
passwordMaskDelay: 0
|
||||
|
||||
text: lock.password
|
||||
onTextChanged: lock.password = text
|
||||
|
||||
// Placeholder text
|
||||
Text {
|
||||
text: weatherData && weatherData.current_weather ? materialSymbolForCode(weatherData.current_weather.weathercode) : "cloud"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 28
|
||||
color: Theme.accentPrimary
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Text {
|
||||
text: weatherData && weatherData.current_weather ? (Settings.useFahrenheit ? `${Math.round(weatherData.current_weather.temperature * 9/5 + 32)}°F` : `${Math.round(weatherData.current_weather.temperature)}°C`) : (Settings.useFahrenheit ? "--°F" : "--°C")
|
||||
font.pixelSize: 18
|
||||
anchors.centerIn: parent
|
||||
text: "Enter password..."
|
||||
color: Theme.textSecondary
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 16
|
||||
visible: !passwordInput.text && !passwordInput.activeFocus
|
||||
}
|
||||
|
||||
// Handle Enter key
|
||||
Keys.onPressed: function(event) {
|
||||
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||
lock.unlockAttempt()
|
||||
}
|
||||
}
|
||||
}
|
||||
// Weather error
|
||||
}
|
||||
|
||||
// Error message
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: lock.errorMessage
|
||||
color: Theme.error
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 14
|
||||
visible: lock.errorMessage !== ""
|
||||
opacity: lock.errorMessage !== "" ? 1 : 0
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 200 }
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock button
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
width: 120
|
||||
height: 44
|
||||
radius: 22
|
||||
color: unlockButtonArea.containsMouse ? Theme.accentPrimary : "transparent"
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 2
|
||||
opacity: lock.authenticating ? 0.5 : 0.8
|
||||
enabled: !lock.authenticating
|
||||
|
||||
Text {
|
||||
text: weatherError
|
||||
color: Theme.error
|
||||
visible: weatherError !== ""
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
anchors.centerIn: parent
|
||||
text: lock.authenticating ? "Authenticating..." : "Unlock"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
color: unlockButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
|
||||
}
|
||||
}
|
||||
|
||||
// Update clock every second
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
timeText.text = Qt.formatDateTime(new Date(), "HH:mm")
|
||||
dateText.text = Qt.formatDateTime(new Date(), "dddd, MMMM d")
|
||||
}
|
||||
}
|
||||
|
||||
// Update weather every 10 minutes
|
||||
Timer {
|
||||
interval: 600000 // 10 minutes
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
fetchWeatherData()
|
||||
}
|
||||
}
|
||||
|
||||
// System control buttons (bottom right)
|
||||
ColumnLayout {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 32
|
||||
spacing: 12
|
||||
// Shutdown
|
||||
Rectangle {
|
||||
width: 48; height: 48; radius: 24
|
||||
color: shutdownArea.containsMouse ? Theme.error : "transparent"
|
||||
border.color: Theme.error
|
||||
border.width: 1
|
||||
MouseArea {
|
||||
id: shutdownArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
Qt.createQmlObject('import Quickshell.Io; Process { command: ["shutdown", "-h", "now"]; running: true }', lock)
|
||||
MouseArea {
|
||||
id: unlockButtonArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if (!lock.authenticating) {
|
||||
lock.unlockAttempt()
|
||||
}
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "power_settings_new"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 24
|
||||
color: shutdownArea.containsMouse ? Theme.onAccent : Theme.error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Top-center info panel (clock + weather)
|
||||
ColumnLayout {
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 40
|
||||
spacing: 8
|
||||
// Clock
|
||||
Text {
|
||||
id: timeText
|
||||
text: Qt.formatDateTime(new Date(), "HH:mm")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 48
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
Text {
|
||||
id: dateText
|
||||
text: Qt.formatDateTime(new Date(), "dddd, MMMM d")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 16
|
||||
color: Theme.textSecondary
|
||||
opacity: 0.8
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
// Weather info (centered, no city)
|
||||
RowLayout {
|
||||
spacing: 6
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
visible: weatherData && weatherData.current_weather
|
||||
Text {
|
||||
text: weatherData && weatherData.current_weather ? materialSymbolForCode(weatherData.current_weather.weathercode) : "cloud"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 28
|
||||
color: Theme.accentPrimary
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Text {
|
||||
text: weatherData && weatherData.current_weather ? (Settings.useFahrenheit ? `${Math.round(weatherData.current_weather.temperature * 9/5 + 32)}°F` : `${Math.round(weatherData.current_weather.temperature)}°C`) : (Settings.useFahrenheit ? "--°F" : "--°C")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 18
|
||||
color: Theme.textSecondary
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
// Weather error
|
||||
Text {
|
||||
text: weatherError
|
||||
color: Theme.error
|
||||
visible: weatherError !== ""
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
||||
// Update clock every second
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
timeText.text = Qt.formatDateTime(new Date(), "HH:mm")
|
||||
dateText.text = Qt.formatDateTime(new Date(), "dddd, MMMM d")
|
||||
}
|
||||
}
|
||||
|
||||
// Update weather every 10 minutes
|
||||
Timer {
|
||||
interval: 600000 // 10 minutes
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
fetchWeatherData()
|
||||
}
|
||||
}
|
||||
|
||||
// System control buttons (bottom right)
|
||||
ColumnLayout {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 32
|
||||
spacing: 12
|
||||
// Shutdown
|
||||
Rectangle {
|
||||
width: 48; height: 48; radius: 24
|
||||
color: shutdownArea.containsMouse ? Theme.error : "transparent"
|
||||
border.color: Theme.error
|
||||
border.width: 1
|
||||
MouseArea {
|
||||
id: shutdownArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
Qt.createQmlObject('import Quickshell.Io; Process { command: ["shutdown", "-h", "now"]; running: true }', lock)
|
||||
}
|
||||
}
|
||||
// Reboot
|
||||
Rectangle {
|
||||
width: 48; height: 48; radius: 24
|
||||
color: rebootArea.containsMouse ? Theme.accentPrimary : "transparent"
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 1
|
||||
MouseArea {
|
||||
id: rebootArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
Qt.createQmlObject('import Quickshell.Io; Process { command: ["reboot"]; running: true }', lock)
|
||||
}
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "refresh"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 24
|
||||
color: rebootArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "power_settings_new"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 24
|
||||
color: shutdownArea.containsMouse ? Theme.onAccent : Theme.error
|
||||
}
|
||||
}
|
||||
// Reboot
|
||||
Rectangle {
|
||||
width: 48; height: 48; radius: 24
|
||||
color: rebootArea.containsMouse ? Theme.accentPrimary : "transparent"
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 1
|
||||
MouseArea {
|
||||
id: rebootArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
Qt.createQmlObject('import Quickshell.Io; Process { command: ["reboot"]; running: true }', lock)
|
||||
}
|
||||
}
|
||||
// Logout
|
||||
Rectangle {
|
||||
width: 48; height: 48; radius: 24
|
||||
color: logoutArea.containsMouse ? Theme.accentSecondary : "transparent"
|
||||
border.color: Theme.accentSecondary
|
||||
border.width: 1
|
||||
MouseArea {
|
||||
id: logoutArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
Qt.createQmlObject('import Quickshell.Io; Process { command: ["loginctl", "terminate-user", "' + Quickshell.env("USER") + '"]; running: true }', lock)
|
||||
}
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "exit_to_app"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 24
|
||||
color: logoutArea.containsMouse ? Theme.onAccent : Theme.accentSecondary
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "refresh"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 24
|
||||
color: rebootArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
|
||||
}
|
||||
}
|
||||
// Logout
|
||||
Rectangle {
|
||||
width: 48; height: 48; radius: 24
|
||||
color: logoutArea.containsMouse ? Theme.accentSecondary : "transparent"
|
||||
border.color: Theme.accentSecondary
|
||||
border.width: 1
|
||||
MouseArea {
|
||||
id: logoutArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
Qt.createQmlObject('import Quickshell.Io; Process { command: ["loginctl", "terminate-user", "' + Quickshell.env("USER") + '"]; running: true }', lock)
|
||||
}
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "exit_to_app"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 24
|
||||
color: logoutArea.containsMouse ? Theme.onAccent : Theme.accentSecondary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,9 @@ PanelWindow {
|
|||
text: modelData.appName
|
||||
width: parent.width
|
||||
color: "white"
|
||||
font.family: Theme.fontFamily
|
||||
font.bold: true
|
||||
font.pixelSize: 14
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +85,8 @@ PanelWindow {
|
|||
text: modelData.summary
|
||||
width: parent.width
|
||||
color: "#eeeeee"
|
||||
font.pixelSize: 13
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
wrapMode: Text.Wrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
|
@ -93,7 +95,8 @@ PanelWindow {
|
|||
text: modelData.body
|
||||
width: parent.width
|
||||
color: "#cccccc"
|
||||
font.pixelSize: 12
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
wrapMode: Text.Wrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,9 +155,10 @@ PanelWindow {
|
|||
anchors.centerIn: parent
|
||||
visible: !iconImage.visible
|
||||
text: model.appName ? model.appName.charAt(0).toUpperCase() : "?"
|
||||
font.pixelSize: 18
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
font.bold: true
|
||||
color: Theme.backgroundPrimary
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -169,15 +170,17 @@ PanelWindow {
|
|||
text: model.appName
|
||||
width: parent.width
|
||||
color: Theme.textPrimary
|
||||
font.family: Theme.fontFamily
|
||||
font.bold: true
|
||||
font.pixelSize: 14
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Text {
|
||||
text: model.summary
|
||||
width: parent.width
|
||||
color: "#eeeeee"
|
||||
font.pixelSize: 13
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
wrapMode: Text.Wrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
|
@ -185,7 +188,8 @@ PanelWindow {
|
|||
text: model.body
|
||||
width: parent.width
|
||||
color: "#cccccc"
|
||||
font.pixelSize: 12
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
wrapMode: Text.Wrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,13 +35,14 @@ Rectangle {
|
|||
Text {
|
||||
text: "settings"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 28
|
||||
font.pixelSize: Theme.fontSizeHeader
|
||||
color: Settings.Theme.accentPrimary
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Settings"
|
||||
font.pixelSize: 22
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeHeader
|
||||
font.bold: true
|
||||
color: Settings.Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -59,7 +60,7 @@ Rectangle {
|
|||
anchors.centerIn: parent
|
||||
text: "close"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 18
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: closeButtonArea.containsMouse ? Settings.Theme.onAccent : Settings.Theme.accentPrimary
|
||||
}
|
||||
|
||||
|
|
@ -92,13 +93,14 @@ Rectangle {
|
|||
Text {
|
||||
text: "wb_sunny"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: Settings.Theme.accentPrimary
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Weather Settings"
|
||||
font.pixelSize: 16
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
font.bold: true
|
||||
color: Settings.Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -112,14 +114,15 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "City"
|
||||
font.pixelSize: 13
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.bold: true
|
||||
color: Settings.Theme.textPrimary
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredHeight: 40
|
||||
radius: 8
|
||||
color: Settings.Theme.surfaceVariant
|
||||
border.color: cityInput.activeFocus ? Settings.Theme.accentPrimary : Settings.Theme.outline
|
||||
|
|
@ -127,10 +130,17 @@ Rectangle {
|
|||
|
||||
TextInput {
|
||||
id: cityInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: 12
|
||||
anchors.rightMargin: 12
|
||||
anchors.topMargin: 6
|
||||
anchors.bottomMargin: 6
|
||||
text: tempWeatherCity
|
||||
font.pixelSize: 13
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Settings.Theme.textPrimary
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
clip: true
|
||||
|
|
@ -160,7 +170,8 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "Temperature Unit"
|
||||
font.pixelSize: 13
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.bold: true
|
||||
color: Settings.Theme.textPrimary
|
||||
}
|
||||
|
|
@ -193,7 +204,8 @@ Rectangle {
|
|||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: tempUseFahrenheit ? "°F" : "°C"
|
||||
font.pixelSize: 12
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
font.bold: true
|
||||
color: Settings.Theme.textPrimary
|
||||
}
|
||||
|
|
@ -240,17 +252,18 @@ Rectangle {
|
|||
Text {
|
||||
text: "person"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: Settings.Theme.accentPrimary
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Profile Image"
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
color: Settings.Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text {
|
||||
text: "Profile Image"
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
font.bold: true
|
||||
color: Settings.Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
// Profile Image Input Row
|
||||
|
|
@ -292,7 +305,7 @@ Rectangle {
|
|||
anchors.centerIn: parent
|
||||
text: "person"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 18
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: Settings.Theme.accentPrimary
|
||||
visible: tempProfileImage === ""
|
||||
}
|
||||
|
|
@ -301,7 +314,7 @@ Rectangle {
|
|||
// Text input styled exactly like weather city
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredHeight: 40
|
||||
radius: 8
|
||||
color: Settings.Theme.surfaceVariant
|
||||
border.color: profileImageInput.activeFocus ? Settings.Theme.accentPrimary : Settings.Theme.outline
|
||||
|
|
@ -309,10 +322,17 @@ Rectangle {
|
|||
|
||||
TextInput {
|
||||
id: profileImageInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: 12
|
||||
anchors.rightMargin: 12
|
||||
anchors.topMargin: 6
|
||||
anchors.bottomMargin: 6
|
||||
text: tempProfileImage
|
||||
font.pixelSize: 13
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Settings.Theme.textPrimary
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
clip: true
|
||||
|
|
@ -354,12 +374,13 @@ Rectangle {
|
|||
Text {
|
||||
text: "image"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: Settings.Theme.accentPrimary
|
||||
}
|
||||
Text {
|
||||
text: "Wallpaper Folder"
|
||||
font.pixelSize: 16
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
font.bold: true
|
||||
color: Settings.Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -369,7 +390,7 @@ Rectangle {
|
|||
// Folder Path Input
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredHeight: 40
|
||||
radius: 8
|
||||
color: Settings.Theme.surfaceVariant
|
||||
border.color: wallpaperFolderInput.activeFocus ? Settings.Theme.accentPrimary : Settings.Theme.outline
|
||||
|
|
@ -377,10 +398,17 @@ Rectangle {
|
|||
|
||||
TextInput {
|
||||
id: wallpaperFolderInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: 12
|
||||
anchors.rightMargin: 12
|
||||
anchors.topMargin: 6
|
||||
anchors.bottomMargin: 6
|
||||
text: tempWallpaperFolder
|
||||
font.pixelSize: 13
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Settings.Theme.textPrimary
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
clip: true
|
||||
|
|
@ -415,7 +443,8 @@ Rectangle {
|
|||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "Apply Changes"
|
||||
font.pixelSize: 15
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.bold: true
|
||||
color: applyButtonArea.containsMouse ? Settings.Theme.onAccent : Settings.Theme.onAccent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ ColumnLayout {
|
|||
spacing: 8
|
||||
Text {
|
||||
id: headerText
|
||||
font.pixelSize: 16
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
|
|
@ -33,7 +34,7 @@ ColumnLayout {
|
|||
anchors.centerIn: parent
|
||||
text: expanded ? "expand_less" : "expand_more"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: Theme.accentPrimary
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,14 @@ Rectangle {
|
|||
Text {
|
||||
text: "person"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: Theme.accentPrimary
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Profile Image"
|
||||
font.pixelSize: 16
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -82,7 +83,7 @@ Rectangle {
|
|||
anchors.centerIn: parent
|
||||
text: "person"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 18
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: Theme.accentPrimary
|
||||
visible: Settings.profileImage === ""
|
||||
}
|
||||
|
|
@ -91,7 +92,7 @@ Rectangle {
|
|||
// Text input styled exactly like weather city
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredHeight: 40
|
||||
radius: 8
|
||||
color: Theme.surfaceVariant
|
||||
border.color: profileImageInput.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
|
|
@ -99,10 +100,17 @@ Rectangle {
|
|||
|
||||
TextInput {
|
||||
id: profileImageInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: 12
|
||||
anchors.rightMargin: 12
|
||||
anchors.topMargin: 6
|
||||
anchors.bottomMargin: 6
|
||||
text: Settings.profileImage
|
||||
font.pixelSize: 13
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.textPrimary
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
clip: true
|
||||
|
|
@ -131,14 +139,15 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "Video Path"
|
||||
font.pixelSize: 14
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.textPrimary
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredHeight: 40
|
||||
radius: 8
|
||||
color: Theme.surfaceVariant
|
||||
border.color: videoPathInput.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
|
|
@ -146,10 +155,17 @@ Rectangle {
|
|||
|
||||
TextInput {
|
||||
id: videoPathInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: 12
|
||||
anchors.rightMargin: 12
|
||||
anchors.topMargin: 6
|
||||
anchors.bottomMargin: 6
|
||||
text: Settings.videoPath !== undefined ? Settings.videoPath : ""
|
||||
font.pixelSize: 13
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.textPrimary
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
clip: true
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ PanelWindow {
|
|||
}
|
||||
Text {
|
||||
text: "Settings"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 26
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
@ -149,6 +150,7 @@ PanelWindow {
|
|||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "Apply Changes"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 17
|
||||
font.bold: true
|
||||
color: applyButtonArea.containsMouse ? Theme.onAccent : Theme.onAccent
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ Rectangle {
|
|||
}
|
||||
Text {
|
||||
text: "Wallpaper Folder"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
@ -41,16 +42,23 @@ Rectangle {
|
|||
// Folder Path Input
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredHeight: 40
|
||||
radius: 8
|
||||
color: Theme.surfaceVariant
|
||||
border.color: folderInput.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
border.width: 1
|
||||
TextInput {
|
||||
id: folderInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: 12
|
||||
anchors.rightMargin: 12
|
||||
anchors.topMargin: 6
|
||||
anchors.bottomMargin: 6
|
||||
text: wallpaperFolder
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 13
|
||||
color: Theme.textPrimary
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "Weather Settings"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
@ -50,6 +51,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "City"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 13
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
@ -57,7 +59,7 @@ Rectangle {
|
|||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredHeight: 40
|
||||
radius: 8
|
||||
color: Theme.surfaceVariant
|
||||
border.color: cityInput.activeFocus ? Theme.accentPrimary : Theme.outline
|
||||
|
|
@ -65,9 +67,16 @@ Rectangle {
|
|||
|
||||
TextInput {
|
||||
id: cityInput
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: 12
|
||||
anchors.rightMargin: 12
|
||||
anchors.topMargin: 6
|
||||
anchors.bottomMargin: 6
|
||||
text: weatherCity
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 13
|
||||
color: Theme.textPrimary
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
|
|
@ -98,6 +107,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "Temperature Unit"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 13
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
@ -130,7 +140,8 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: useFahrenheit ? "°F" : "°C"
|
||||
text: useFahrenheit ? "\u00b0F" : "\u00b0C"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 12
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ Item {
|
|||
}
|
||||
Text {
|
||||
text: "Bluetooth"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 26
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
@ -225,6 +226,7 @@ Item {
|
|||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: modelData.name || "Unknown Device"
|
||||
font.family: Theme.fontFamily
|
||||
color: modelData.connected ? Theme.accentPrimary : Theme.textPrimary
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
|
|
@ -232,12 +234,14 @@ Item {
|
|||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: modelData.address
|
||||
font.family: Theme.fontFamily
|
||||
color: modelData.connected ? Theme.accentPrimary : Theme.textSecondary
|
||||
font.pixelSize: 11
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Text {
|
||||
text: "Paired: " + modelData.paired + " | Trusted: " + modelData.trusted
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 10
|
||||
color: Theme.textSecondary
|
||||
visible: true
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ Rectangle {
|
|||
Text {
|
||||
text: "music_note"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 48
|
||||
font.pixelSize: Theme.fontSizeHeader
|
||||
color: Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.3)
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
|
@ -113,8 +113,8 @@ Rectangle {
|
|||
Text {
|
||||
text: getAvailablePlayers().length > 0 ? "No controllable player selected" : "No music player detected"
|
||||
color: Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.6)
|
||||
font.family: "Roboto"
|
||||
font.pixelSize: 14
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ Rectangle {
|
|||
anchors.centerIn: parent
|
||||
text: "album"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.4)
|
||||
visible: !albumArt.visible
|
||||
}
|
||||
|
|
@ -206,8 +206,8 @@ Rectangle {
|
|||
Text {
|
||||
text: currentPlayer ? (currentPlayer.trackTitle || "Unknown Track") : ""
|
||||
color: Theme.textPrimary
|
||||
font.family: "Roboto"
|
||||
font.pixelSize: 14
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.bold: true
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.Wrap
|
||||
|
|
@ -218,8 +218,8 @@ Rectangle {
|
|||
Text {
|
||||
text: currentPlayer ? (currentPlayer.trackArtist || "Unknown Artist") : ""
|
||||
color: Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.8)
|
||||
font.family: "Roboto"
|
||||
font.pixelSize: 12
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
|
@ -227,8 +227,8 @@ Rectangle {
|
|||
Text {
|
||||
text: currentPlayer ? (currentPlayer.trackAlbum || "Unknown Album") : ""
|
||||
color: Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.6)
|
||||
font.family: "Roboto"
|
||||
font.pixelSize: 10
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
|
@ -334,7 +334,7 @@ Rectangle {
|
|||
anchors.centerIn: parent
|
||||
text: "skip_previous"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 12
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
color: previousButton.enabled ? Theme.accentPrimary : Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.3)
|
||||
}
|
||||
}
|
||||
|
|
@ -368,7 +368,7 @@ Rectangle {
|
|||
anchors.centerIn: parent
|
||||
text: currentPlayer && currentPlayer.isPlaying ? "pause" : "play_arrow"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 16
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: playButton.enabled ? Theme.accentPrimary : Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.3)
|
||||
}
|
||||
}
|
||||
|
|
@ -394,7 +394,7 @@ Rectangle {
|
|||
anchors.centerIn: parent
|
||||
text: "skip_next"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 12
|
||||
font.pixelSize: Theme.fontSizeCaption
|
||||
color: nextButton.enabled ? Theme.accentPrimary : Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.3)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "Settings"
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
color: settingsButtonArea.containsMouse ? Settings.Theme.onAccent : Settings.Theme.textPrimary
|
||||
|
|
@ -98,6 +99,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: isRecording ? "End" : "Record"
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
color: isRecording || recorderButtonArea.containsMouse ? Settings.Theme.onAccent : Settings.Theme.textPrimary
|
||||
|
|
@ -143,6 +145,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "Wallpaper"
|
||||
font.family: Settings.Theme.fontFamily
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
color: wallpaperButtonArea.containsMouse ? Settings.Theme.onAccent : Settings.Theme.textPrimary
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: Quickshell.env("USER")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
@ -96,6 +97,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "System Uptime: " + uptimeText
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 12
|
||||
color: Theme.textSecondary
|
||||
}
|
||||
|
|
@ -179,6 +181,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "Lock Screen"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 14
|
||||
color: lockButtonArea.containsMouse ? Theme.onAccent : Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -217,6 +220,7 @@ Rectangle {
|
|||
|
||||
Text {
|
||||
text: "Reboot"
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 14
|
||||
color: rebootButtonArea.containsMouse ? Theme.onAccent : Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
|
|
|
|||
|
|
@ -44,12 +44,13 @@ PanelWindow {
|
|||
Text {
|
||||
text: "image"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pixelSize: 32
|
||||
font.pixelSize: Theme.fontSizeHeader
|
||||
color: Theme.accentPrimary
|
||||
}
|
||||
Text {
|
||||
text: "Wallpapers"
|
||||
font.pixelSize: 26
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeHeader
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -63,7 +64,7 @@ PanelWindow {
|
|||
anchors.centerIn: parent
|
||||
text: "close"
|
||||
font.family: closeButtonArea.containsMouse ? "Material Symbols Rounded" : "Material Symbols Outlined"
|
||||
font.pixelSize: 20
|
||||
font.pixelSize: Theme.fontSizeBody
|
||||
color: closeButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
|
||||
}
|
||||
MouseArea {
|
||||
|
|
|
|||
|
|
@ -81,12 +81,14 @@ Rectangle {
|
|||
spacing: 4
|
||||
Text {
|
||||
text: city
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
Text {
|
||||
text: weatherData && weatherData.timezone_abbreviation ? `(${weatherData.timezone_abbreviation})` : ""
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 10
|
||||
color: Theme.textSecondary
|
||||
leftPadding: 2
|
||||
|
|
@ -94,6 +96,7 @@ Rectangle {
|
|||
}
|
||||
Text {
|
||||
text: weatherData && weatherData.current_weather ? ((Settings.useFahrenheit !== undefined ? Settings.useFahrenheit : false) ? `${Math.round(weatherData.current_weather.temperature * 9/5 + 32)}°F` : `${Math.round(weatherData.current_weather.temperature)}°C`) : ((Settings.useFahrenheit !== undefined ? Settings.useFahrenheit : false) ? "--°F" : "--°C")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 24
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
|
|
@ -131,6 +134,7 @@ Rectangle {
|
|||
Text {
|
||||
// Day of the week (e.g., Mon)
|
||||
text: Qt.formatDateTime(new Date(weatherData.daily.time[index]), "ddd")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 12
|
||||
color: Theme.textSecondary
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
|
@ -148,6 +152,7 @@ Rectangle {
|
|||
Text {
|
||||
// High/low temp
|
||||
text: weatherData && weatherData.daily ? ((Settings.useFahrenheit !== undefined ? Settings.useFahrenheit : false) ? `${Math.round(weatherData.daily.temperature_2m_max[index] * 9/5 + 32)}° / ${Math.round(weatherData.daily.temperature_2m_min[index] * 9/5 + 32)}°` : `${Math.round(weatherData.daily.temperature_2m_max[index])}° / ${Math.round(weatherData.daily.temperature_2m_min[index])}°`) : ((Settings.useFahrenheit !== undefined ? Settings.useFahrenheit : false) ? "--° / --°" : "--° / --°")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 12
|
||||
color: Theme.textPrimary
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
|
@ -162,6 +167,7 @@ Rectangle {
|
|||
text: errorString
|
||||
color: Theme.error
|
||||
visible: errorString !== ""
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Item {
|
|||
}
|
||||
|
||||
function signalIcon(signal) {
|
||||
if (signal >= 80) return "network_wifi_4_bar";
|
||||
if (signal >= 80) return "network_wifi";
|
||||
if (signal >= 60) return "network_wifi_3_bar";
|
||||
if (signal >= 40) return "network_wifi_2_bar";
|
||||
if (signal >= 20) return "network_wifi_1_bar";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue