1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 21:45:38 -05:00

widgets: add spacer, divider, tweak interface

This commit is contained in:
bbedward
2025-08-02 13:10:39 -04:00
parent 2e85494236
commit 21c40b58bc
47 changed files with 2660 additions and 2205 deletions

View File

@@ -10,9 +10,9 @@ import qs.Widgets
Column {
id: root
property string currentSinkDisplayName: AudioService.sink ? AudioService.displayName(AudioService.sink) : ""
width: parent.width
spacing: Theme.spacingM
@@ -50,21 +50,27 @@ Column {
color: Theme.primary
font.weight: Font.Medium
}
}
}
Repeater {
model: {
if (!Pipewire.ready || !Pipewire.nodes || !Pipewire.nodes.values) return []
let sinks = []
if (!Pipewire.ready || !Pipewire.nodes || !Pipewire.nodes.values)
return [];
let sinks = [];
for (let i = 0; i < Pipewire.nodes.values.length; i++) {
let node = Pipewire.nodes.values[i]
if (!node || node.isStream) continue
if ((node.type & PwNodeType.AudioSink) === PwNodeType.AudioSink) {
sinks.push(node)
}
let node = Pipewire.nodes.values[i];
if (!node || node.isStream)
continue;
if ((node.type & PwNodeType.AudioSink) === PwNodeType.AudioSink)
sinks.push(node);
}
return sinks
return sinks;
}
Rectangle {
@@ -119,7 +125,9 @@ Column {
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
visible: text !== ""
}
}
}
MouseArea {
@@ -131,8 +139,12 @@ Column {
onClicked: {
if (modelData)
Pipewire.preferredDefaultAudioSink = modelData;
}
}
}
}
}
}

View File

@@ -10,9 +10,9 @@ import qs.Widgets
Column {
id: root
property string currentSourceDisplayName: AudioService.source ? AudioService.displayName(AudioService.source) : ""
width: parent.width
spacing: Theme.spacingM
@@ -50,21 +50,27 @@ Column {
color: Theme.primary
font.weight: Font.Medium
}
}
}
Repeater {
model: {
if (!Pipewire.ready || !Pipewire.nodes || !Pipewire.nodes.values) return []
let sources = []
if (!Pipewire.ready || !Pipewire.nodes || !Pipewire.nodes.values)
return [];
let sources = [];
for (let i = 0; i < Pipewire.nodes.values.length; i++) {
let node = Pipewire.nodes.values[i]
if (!node || node.isStream) continue
if ((node.type & PwNodeType.AudioSource) === PwNodeType.AudioSource && !node.name.includes(".monitor")) {
sources.push(node)
}
let node = Pipewire.nodes.values[i];
if (!node || node.isStream)
continue;
if ((node.type & PwNodeType.AudioSource) === PwNodeType.AudioSource && !node.name.includes(".monitor"))
sources.push(node);
}
return sources
return sources;
}
Rectangle {
@@ -117,7 +123,9 @@ Column {
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
visible: text !== ""
}
}
}
MouseArea {
@@ -129,8 +137,12 @@ Column {
onClicked: {
if (modelData)
Pipewire.preferredDefaultAudioSource = modelData;
}
}
}
}
}
}

View File

@@ -9,10 +9,10 @@ import qs.Widgets
Column {
id: root
property real micLevel: Math.min(100, (AudioService.source && AudioService.source.audio && AudioService.source.audio.volume * 100) || 0)
property bool micMuted: (AudioService.source && AudioService.source.audio && AudioService.source.audio.muted) || false
width: parent.width
spacing: Theme.spacingM
@@ -40,8 +40,10 @@ Column {
onClicked: {
if (AudioService.source && AudioService.source.audio)
AudioService.source.audio.muted = !AudioService.source.audio.muted;
}
}
}
Item {
@@ -74,7 +76,9 @@ Column {
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standardDecel
}
}
}
Rectangle {
@@ -90,16 +94,9 @@ Column {
anchors.verticalCenter: parent.verticalCenter
scale: micMouseArea.containsMouse || micMouseArea.pressed ? 1.2 : 1
Behavior on scale {
NumberAnimation {
duration: Anims.durShort
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standard
}
}
Rectangle {
id: micTooltip
width: tooltipText.contentWidth + Theme.spacingS * 2
height: tooltipText.contentHeight + Theme.spacingXS * 2
radius: Theme.cornerRadiusSmall
@@ -111,24 +108,38 @@ Column {
anchors.horizontalCenter: parent.horizontalCenter
visible: (micMouseArea.containsMouse && !root.micMuted) || micMouseArea.isDragging
opacity: visible ? 1 : 0
StyledText {
id: tooltipText
text: Math.round(root.micLevel) + "%"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.centerIn: parent
}
Behavior on opacity {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
Behavior on scale {
NumberAnimation {
duration: Anims.durShort
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standard
}
}
}
}
MouseArea {
@@ -197,6 +208,7 @@ Column {
micMouseArea.isDragging = false;
}
}
}
DankIcon {
@@ -205,5 +217,7 @@ Column {
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
}
}

View File

@@ -10,7 +10,7 @@ import qs.Widgets
Column {
id: root
width: parent.width
spacing: Theme.spacingM
visible: BluetoothService.adapter && BluetoothService.adapter.enabled
@@ -34,6 +34,7 @@ Column {
Rectangle {
id: scanButton
width: Math.max(100, scanText.contentWidth + Theme.spacingL * 2)
height: 32
radius: Theme.cornerRadius
@@ -61,6 +62,7 @@ Column {
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
@@ -70,12 +72,14 @@ Column {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (BluetoothService.adapter) {
if (BluetoothService.adapter)
BluetoothService.adapter.discovering = !BluetoothService.adapter.discovering;
}
}
}
}
}
Rectangle {
@@ -88,6 +92,7 @@ Column {
Column {
id: noteColumn
anchors.fill: parent
anchors.margins: Theme.spacingM
spacing: Theme.spacingS
@@ -110,6 +115,7 @@ Column {
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
StyledText {
@@ -119,14 +125,16 @@ Column {
wrapMode: Text.WordWrap
width: parent.width
}
}
}
Repeater {
model: {
if (!BluetoothService.adapter || !BluetoothService.adapter.discovering || !Bluetooth.devices)
return [];
var filtered = Bluetooth.devices.values.filter((dev) => {
return dev && !dev.paired && !dev.pairing && !dev.blocked && (dev.signalStrength === undefined || dev.signalStrength > 0);
});
@@ -213,8 +221,10 @@ Column {
text: {
if (modelData.pairing)
return "Pairing...";
if (modelData.blocked)
return "Blocked";
return BluetoothService.getSignalStrength(modelData);
}
font.pixelSize: Theme.fontSizeSmall
@@ -242,9 +252,13 @@ Column {
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
visible: modelData.signalStrength !== undefined && modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked
}
}
}
}
}
Rectangle {
@@ -292,11 +306,12 @@ Column {
cursorShape: canConnect && !isBusy ? Qt.PointingHandCursor : (isBusy ? Qt.BusyCursor : Qt.ArrowCursor)
enabled: canConnect && !isBusy
onClicked: {
if (modelData) {
if (modelData)
BluetoothService.connectDeviceWithTrust(modelData);
}
}
}
}
MouseArea {
@@ -308,12 +323,14 @@ Column {
cursorShape: canConnect && !isBusy ? Qt.PointingHandCursor : (isBusy ? Qt.BusyCursor : Qt.ArrowCursor)
enabled: canConnect && !isBusy
onClicked: {
if (modelData) {
if (modelData)
BluetoothService.connectDeviceWithTrust(modelData);
}
}
}
}
}
Column {
@@ -322,11 +339,10 @@ Column {
visible: {
if (!BluetoothService.adapter || !BluetoothService.adapter.discovering || !Bluetooth.devices)
return false;
var availableCount = Bluetooth.devices.values.filter((dev) => {
return dev && !dev.paired && !dev.pairing && !dev.blocked && (dev.signalStrength === undefined || dev.signalStrength > 0);
}).length;
return availableCount === 0;
}
@@ -347,6 +363,7 @@ Column {
to: 360
duration: 2000
}
}
StyledText {
@@ -356,6 +373,7 @@ Column {
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
StyledText {
@@ -364,6 +382,7 @@ Column {
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
}
}
StyledText {
@@ -373,15 +392,15 @@ Column {
visible: {
if (!BluetoothService.adapter || !Bluetooth.devices)
return true;
var availableCount = Bluetooth.devices.values.filter((dev) => {
return dev && !dev.paired && !dev.pairing && !dev.blocked && (dev.signalStrength === undefined || dev.signalStrength > 0);
}).length;
return availableCount === 0 && !BluetoothService.adapter.discovering;
}
wrapMode: Text.WordWrap
width: parent.width
horizontalAlignment: Text.AlignHCenter
}
}
}

View File

@@ -10,11 +10,11 @@ import qs.Widgets
Rectangle {
id: root
property var deviceData: null
property bool menuVisible: false
property var parentItem
function show(x, y) {
const menuWidth = 160;
const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2;
@@ -27,14 +27,14 @@ Rectangle {
root.visible = true;
root.menuVisible = true;
}
function hide() {
root.menuVisible = false;
Qt.callLater(() => {
root.visible = false;
});
}
visible: false
width: 160
height: menuColumn.implicitHeight + Theme.spacingS * 2
@@ -45,7 +45,7 @@ Rectangle {
z: 1000
opacity: menuVisible ? 1 : 0
scale: menuVisible ? 1 : 0.85
Rectangle {
anchors.fill: parent
anchors.topMargin: 4
@@ -56,26 +56,26 @@ Rectangle {
color: Qt.rgba(0, 0, 0, 0.15)
z: parent.z - 1
}
Column {
id: menuColumn
anchors.fill: parent
anchors.margins: Theme.spacingS
spacing: 1
Rectangle {
width: parent.width
height: 32
radius: Theme.cornerRadiusSmall
color: connectArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: root.deviceData && root.deviceData.connected ? "link_off" : "link"
size: Theme.iconSize - 2
@@ -83,7 +83,7 @@ Rectangle {
opacity: 0.7
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: root.deviceData && root.deviceData.connected ? "Disconnect" : "Connect"
font.pixelSize: Theme.fontSizeSmall
@@ -91,60 +91,63 @@ Rectangle {
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: connectArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (root.deviceData) {
if (root.deviceData.connected) {
if (root.deviceData.connected)
root.deviceData.disconnect();
} else {
else
BluetoothService.connectDeviceWithTrust(root.deviceData);
}
}
root.hide();
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
Rectangle {
width: parent.width - Theme.spacingS * 2
height: 5
anchors.horizontalCenter: parent.horizontalCenter
color: "transparent"
Rectangle {
anchors.centerIn: parent
width: parent.width
height: 1
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
}
}
Rectangle {
width: parent.width
height: 32
radius: Theme.cornerRadiusSmall
color: forgetArea.containsMouse ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) : "transparent"
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: "delete"
size: Theme.iconSize - 2
@@ -152,7 +155,7 @@ Rectangle {
opacity: 0.7
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Forget Device"
font.pixelSize: Theme.fontSizeSmall
@@ -160,42 +163,49 @@ Rectangle {
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: forgetArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (root.deviceData) {
if (root.deviceData)
root.deviceData.forget();
}
root.hide();
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
}

View File

@@ -10,7 +10,7 @@ import qs.Widgets
Rectangle {
id: root
width: parent.width
height: 60
radius: Theme.cornerRadius
@@ -47,7 +47,9 @@ Rectangle {
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
}
}
}
MouseArea {
@@ -57,9 +59,10 @@ Rectangle {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (BluetoothService.adapter) {
if (BluetoothService.adapter)
BluetoothService.adapter.enabled = !BluetoothService.adapter.enabled;
}
}
}
}
}

View File

@@ -10,9 +10,9 @@ import qs.Widgets
Column {
id: root
property var bluetoothContextMenuWindow
width: parent.width
spacing: Theme.spacingM
visible: BluetoothService.adapter && BluetoothService.adapter.enabled
@@ -84,8 +84,11 @@ Column {
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
visible: text.length > 0
}
}
}
}
Rectangle {
@@ -126,7 +129,9 @@ Column {
ColorAnimation {
duration: Theme.shortDuration
}
}
}
MouseArea {
@@ -138,13 +143,15 @@ Column {
enabled: !BluetoothService.isDeviceBusy(modelData)
cursorShape: enabled ? Qt.PointingHandCursor : Qt.BusyCursor
onClicked: {
if (modelData.connected) {
if (modelData.connected)
modelData.disconnect();
} else {
else
BluetoothService.connectDeviceWithTrust(modelData);
}
}
}
}
}
}
}

View File

@@ -5,9 +5,9 @@ import Quickshell.Bluetooth
import Quickshell.Io
import Quickshell.Widgets
import qs.Common
import qs.Modules.ControlCenter.Bluetooth
import qs.Services
import qs.Widgets
import qs.Modules.ControlCenter.Bluetooth
Item {
id: bluetoothTab
@@ -22,18 +22,23 @@ Item {
width: parent.width
spacing: Theme.spacingL
BluetoothToggle { }
BluetoothToggle {
}
PairedDevicesList {
bluetoothContextMenuWindow: bluetoothContextMenuWindow
}
AvailableDevicesList { }
AvailableDevicesList {
}
}
}
BluetoothContextMenu {
id: bluetoothContextMenuWindow
parentItem: bluetoothTab
}
@@ -52,5 +57,7 @@ Item {
onClicked: {
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,25 +4,27 @@ import Quickshell
import Quickshell.Io
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Modules
import qs.Services
import qs.Widgets
ScrollView {
id: displayTab
clip: true
property var brightnessDebounceTimer: Timer {
interval: BrightnessService.ddcAvailable ? 500 : 50 // 500ms for slow DDC (i2c), 50ms for fast laptop backlight
repeat: false
property var brightnessDebounceTimer
brightnessDebounceTimer: Timer {
property int pendingValue: 0
interval: BrightnessService.ddcAvailable ? 500 : 50 // 500ms for slow DDC (i2c), 50ms for fast laptop backlight
repeat: false
onTriggered: {
console.log("Debounce timer fired, setting brightness to:", pendingValue);
BrightnessService.setBrightness(pendingValue);
}
}
clip: true
Column {
width: parent.width
spacing: Theme.spacingL

View File

@@ -9,13 +9,14 @@ import qs.Widgets
Rectangle {
id: ethernetCard
width: parent.width
height: 80
radius: Theme.cornerRadius
color: {
if (ethernetPreferenceArea.containsMouse && NetworkService.ethernetConnected && NetworkService.wifiEnabled && NetworkService.networkStatus !== "ethernet")
return Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8);
return Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.5);
}
border.color: NetworkService.networkStatus === "ethernet" ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
@@ -47,6 +48,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
}
}
StyledText {
@@ -56,11 +58,13 @@ Rectangle {
leftPadding: Theme.iconSize + Theme.spacingM
elide: Text.ElideRight
}
}
// Loading spinner for preference changes
DankIcon {
id: ethernetLoadingSpinner
name: "refresh"
size: Theme.iconSize - 4
color: Theme.primary
@@ -69,7 +73,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
visible: NetworkService.changingPreference && NetworkService.targetPreference === "ethernet"
z: 10
RotationAnimation {
target: ethernetLoadingSpinner
property: "rotation"
@@ -79,11 +83,13 @@ Rectangle {
duration: 1000
loops: Animation.Infinite
}
}
// Ethernet toggle switch (matching WiFi style)
DankToggle {
id: ethernetToggle
checked: NetworkService.ethernetConnected
enabled: true
anchors.right: parent.right
@@ -97,6 +103,7 @@ Rectangle {
// MouseArea for network preference (excluding toggle area)
MouseArea {
id: ethernetPreferenceArea
anchors.fill: parent
anchors.rightMargin: 60 // Exclude toggle area
hoverEnabled: true
@@ -118,5 +125,7 @@ Rectangle {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}

View File

@@ -9,25 +9,31 @@ import qs.Widgets
Rectangle {
id: wifiCard
property var refreshTimer
function getWiFiSignalIcon(signalStrength) {
switch (signalStrength) {
case "excellent": return "wifi";
case "good": return "wifi_2_bar";
case "fair": return "wifi_1_bar";
case "poor": return "signal_wifi_0_bar";
default: return "wifi";
case "excellent":
return "wifi";
case "good":
return "wifi_2_bar";
case "fair":
return "wifi_1_bar";
case "poor":
return "signal_wifi_0_bar";
default:
return "wifi";
}
}
width: parent.width
height: 80
radius: Theme.cornerRadius
color: {
if (wifiPreferenceArea.containsMouse && NetworkService.ethernetConnected && NetworkService.wifiEnabled && NetworkService.networkStatus !== "wifi")
return Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8);
return Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.5);
}
border.color: NetworkService.networkStatus === "wifi" ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
@@ -47,13 +53,12 @@ Rectangle {
DankIcon {
name: {
if (!NetworkService.wifiEnabled) {
if (!NetworkService.wifiEnabled)
return "wifi_off";
} else if (NetworkService.currentWifiSSID !== "") {
else if (NetworkService.currentWifiSSID !== "")
return getWiFiSignalIcon(NetworkService.wifiSignalStrength);
} else {
else
return "wifi";
}
}
size: Theme.iconSize
color: NetworkService.networkStatus === "wifi" ? Theme.primary : Theme.surfaceText
@@ -62,13 +67,12 @@ Rectangle {
StyledText {
text: {
if (!NetworkService.wifiEnabled) {
if (!NetworkService.wifiEnabled)
return "WiFi is off";
} else if (NetworkService.wifiEnabled && NetworkService.currentWifiSSID) {
else if (NetworkService.wifiEnabled && NetworkService.currentWifiSSID)
return NetworkService.currentWifiSSID || "Connected";
} else {
else
return "Not Connected";
}
}
font.pixelSize: Theme.fontSizeMedium
color: NetworkService.networkStatus === "wifi" ? Theme.primary : Theme.surfaceText
@@ -76,28 +80,30 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
}
}
StyledText {
text: {
if (!NetworkService.wifiEnabled) {
if (!NetworkService.wifiEnabled)
return "Turn on WiFi to see networks";
} else if (NetworkService.wifiEnabled && NetworkService.currentWifiSSID) {
else if (NetworkService.wifiEnabled && NetworkService.currentWifiSSID)
return NetworkService.wifiIP || "Connected";
} else {
else
return "Select a network below";
}
}
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
leftPadding: Theme.iconSize + Theme.spacingM
elide: Text.ElideRight
}
}
// Loading spinner for preference changes
DankIcon {
id: wifiLoadingSpinner
name: "refresh"
size: Theme.iconSize - 4
color: Theme.primary
@@ -106,7 +112,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
visible: NetworkService.changingPreference && NetworkService.targetPreference === "wifi"
z: 10
RotationAnimation {
target: wifiLoadingSpinner
property: "rotation"
@@ -116,11 +122,13 @@ Rectangle {
duration: 1000
loops: Animation.Infinite
}
}
// WiFi toggle switch
DankToggle {
id: wifiToggle
checked: NetworkService.wifiEnabled
enabled: true
toggling: NetworkService.wifiToggling
@@ -140,15 +148,16 @@ Rectangle {
NetworkService.refreshNetworkStatus();
}
NetworkService.toggleWifiRadio();
if (refreshTimer) {
if (refreshTimer)
refreshTimer.triggered = true;
}
}
}
// MouseArea for network preference (excluding toggle area)
MouseArea {
id: wifiPreferenceArea
anchors.fill: parent
anchors.rightMargin: 60 // Exclude toggle area
hoverEnabled: true
@@ -170,5 +179,7 @@ Rectangle {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}

View File

@@ -19,20 +19,16 @@ Rectangle {
function show(x, y) {
const menuWidth = 160;
wifiContextMenuWindow.visible = true;
Qt.callLater(() => {
const menuHeight = wifiMenuColumn.implicitHeight + Theme.spacingS * 2;
let finalX = x - menuWidth / 2;
let finalY = y + 4;
finalX = Math.max(Theme.spacingS, Math.min(finalX, parentItem.width - menuWidth - Theme.spacingS));
finalY = Math.max(Theme.spacingS, Math.min(finalY, parentItem.height - menuHeight - Theme.spacingS));
if (finalY + menuHeight > parentItem.height - Theme.spacingS) {
finalY = y - menuHeight - 4;
finalY = Math.max(Theme.spacingS, finalY);
}
wifiContextMenuWindow.x = finalX;
wifiContextMenuWindow.y = finalY;
wifiContextMenuWindow.menuVisible = true;
@@ -56,7 +52,6 @@ Rectangle {
z: 1000
opacity: menuVisible ? 1 : 0
scale: menuVisible ? 1 : 0.85
Component.onCompleted: {
menuVisible = false;
visible = false;
@@ -76,6 +71,7 @@ Rectangle {
Column {
id: wifiMenuColumn
anchors.fill: parent
anchors.margins: Theme.spacingS
spacing: 1
@@ -108,10 +104,12 @@ Rectangle {
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: connectWifiArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
@@ -142,7 +140,9 @@ Rectangle {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
// Separator
@@ -158,6 +158,7 @@ Rectangle {
height: 1
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
}
}
// Forget Network option (only for saved networks)
@@ -189,17 +190,19 @@ Rectangle {
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: forgetWifiArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (wifiContextMenuWindow.networkData) {
if (wifiContextMenuWindow.networkData)
NetworkService.forgetWifiNetwork(wifiContextMenuWindow.networkData.ssid);
}
wifiContextMenuWindow.hide();
}
}
@@ -209,7 +212,9 @@ Rectangle {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
// Network Info option
@@ -240,17 +245,19 @@ Rectangle {
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: infoWifiArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (wifiContextMenuWindow.networkData && networkInfoModalRef) {
if (wifiContextMenuWindow.networkData && networkInfoModalRef)
networkInfoModalRef.showNetworkInfo(wifiContextMenuWindow.networkData.ssid, wifiContextMenuWindow.networkData);
}
wifiContextMenuWindow.hide();
}
}
@@ -260,8 +267,11 @@ Rectangle {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
Behavior on opacity {
@@ -269,6 +279,7 @@ Rectangle {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
@@ -276,5 +287,7 @@ Rectangle {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
}

View File

@@ -9,21 +9,26 @@ import qs.Widgets
Column {
id: root
property var wifiContextMenuWindow
property var sortedWifiNetworks
property var wifiPasswordModalRef
function getWiFiSignalIcon(signalStrength) {
switch (signalStrength) {
case "excellent": return "wifi";
case "good": return "wifi_2_bar";
case "fair": return "wifi_1_bar";
case "poor": return "signal_wifi_0_bar";
default: return "wifi";
case "excellent":
return "wifi";
case "good":
return "wifi_2_bar";
case "fair":
return "wifi_1_bar";
case "poor":
return "signal_wifi_0_bar";
default:
return "wifi";
}
}
anchors.top: parent.top
anchors.topMargin: 100
anchors.left: parent.left
@@ -31,7 +36,7 @@ Column {
anchors.bottom: parent.bottom
visible: NetworkService.wifiEnabled
spacing: Theme.spacingS
// Available Networks Section with refresh button (spanning version)
Row {
width: parent.width
@@ -59,6 +64,7 @@ Column {
DankIcon {
id: refreshIconSpan
anchors.centerIn: parent
name: "refresh"
size: Theme.iconSize - 6
@@ -80,11 +86,14 @@ Column {
duration: 200
easing.type: Easing.OutQuad
}
}
}
MouseArea {
id: refreshAreaSpan
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
@@ -96,9 +105,11 @@ Column {
}
}
}
}
}
// Scrollable networks container
Flickable {
width: parent.width
@@ -109,12 +120,13 @@ Column {
boundsBehavior: Flickable.DragAndOvershootBounds
flickDeceleration: 8000
maximumFlickVelocity: 15000
Column {
id: spanningNetworksColumn
width: parent.width
spacing: Theme.spacingXS
Repeater {
model: NetworkService.wifiAvailable && NetworkService.wifiEnabled ? sortedWifiNetworks : []
@@ -129,11 +141,12 @@ Column {
Item {
anchors.fill: parent
anchors.margins: Theme.spacingXS
anchors.rightMargin: Theme.spacingM // Extra right margin for scrollbar
anchors.rightMargin: Theme.spacingM // Extra right margin for scrollbar
// Signal strength icon
DankIcon {
id: signalIcon2
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
name: getWiFiSignalIcon(modelData.signalStrength)
@@ -164,29 +177,37 @@ Column {
text: {
if (modelData.connected)
return "Connected";
if (NetworkService.connectionStatus === "connecting" && NetworkService.connectingSSID === modelData.ssid)
return "Connecting...";
if (NetworkService.connectionStatus === "invalid_password" && NetworkService.connectingSSID === modelData.ssid)
return "Invalid password";
if (modelData.saved)
return "Saved" + (modelData.secured ? " • Secured" : " • Open");
return modelData.secured ? "Secured" : "Open";
}
font.pixelSize: Theme.fontSizeSmall - 1
color: {
if (NetworkService.connectionStatus === "connecting" && NetworkService.connectingSSID === modelData.ssid)
return Theme.primary;
if (NetworkService.connectionStatus === "invalid_password" && NetworkService.connectingSSID === modelData.ssid)
return Theme.error;
return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7);
}
elide: Text.ElideRight
}
}
// Right side icons
Row {
id: rightIcons2
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingXS
@@ -203,6 +224,7 @@ Column {
// Context menu button
Rectangle {
id: wifiMenuButton
width: 24
height: 24
radius: 12
@@ -218,6 +240,7 @@ Column {
MouseArea {
id: wifiMenuButtonArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
@@ -226,7 +249,6 @@ Column {
let buttonCenter = wifiMenuButtonArea.width / 2;
let buttonBottom = wifiMenuButtonArea.height;
let globalPos = wifiMenuButtonArea.mapToItem(wifiContextMenuWindow.parentItem, buttonCenter, buttonBottom);
Qt.callLater(() => {
wifiContextMenuWindow.show(globalPos.x, globalPos.y);
});
@@ -237,20 +259,25 @@ Column {
ColorAnimation {
duration: Theme.shortDuration
}
}
}
}
}
MouseArea {
id: networkArea2
anchors.fill: parent
anchors.rightMargin: 32 // Exclude menu button area
anchors.rightMargin: 32 // Exclude menu button area
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (modelData.connected)
return;
return ;
if (modelData.saved) {
NetworkService.connectToWifi(modelData.ssid);
@@ -265,12 +292,17 @@ Column {
}
}
}
}
}
}
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
}
}
}