Bring in network panel to the same aesthetic

This commit is contained in:
David Heinemeier Hansson
2026-05-21 21:08:32 +02:00
parent df48130677
commit b28aaf4edb
+95 -63
View File
@@ -533,7 +533,7 @@ Panel {
bar: root.bar bar: root.bar
open: root.opened open: root.opened
focusTarget: keyCatcher focusTarget: keyCatcher
contentWidth: panel.fittedContentWidth(Style.space(340)) contentWidth: panel.fittedContentWidth(Style.space(380))
contentHeight: panel.fittedContentHeight(column.implicitHeight) contentHeight: panel.fittedContentHeight(column.implicitHeight)
// Catches all unhandled keys for keyboard navigation. AfterItem priority // Catches all unhandled keys for keyboard navigation. AfterItem priority
@@ -598,30 +598,26 @@ Panel {
anchors.top: parent.top anchors.top: parent.top
spacing: Style.space(12) spacing: Style.space(12)
// Header — interface name + type, refresh on the right. // ---------- Hero: network icon · SSID + state · actions ----------
Item { Item {
width: parent.width width: parent.width
height: Math.max(headerInfo.implicitHeight, headerActions.implicitHeight) implicitHeight: Math.max(heroIcon.implicitHeight, heroLabels.implicitHeight, headerActions.implicitHeight)
Item { Text {
id: headerInfo id: heroIcon
text: root.icon
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.display
opacity: root.networkManagerAvailable ? 1.0 : 0.5
anchors.left: parent.left anchors.left: parent.left
anchors.right: headerActions.left
anchors.rightMargin: Style.spacing.controlPaddingX
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
implicitHeight: Math.max(wifiToggleBtn.implicitHeight, wifiMainText.implicitHeight)
PanelActionButton { MouseArea {
id: wifiToggleBtn id: heroIconMouse
anchors.left: parent.left anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter hoverEnabled: true
iconText: root.icon cursorShape: Qt.PointingHandCursor
fontSize: Style.font.iconLarge
size: Style.space(28)
tooltipText: "Toggle Wi-Fi"
foreground: root.bar.foreground
hoverColor: root.bar.foreground // Override the dimming behavior
fontFamily: root.bar.fontFamily
enabled: root.networkManagerAvailable enabled: root.networkManagerAvailable
onClicked: { onClicked: {
Networking.wifiEnabled = !Networking.wifiEnabled Networking.wifiEnabled = !Networking.wifiEnabled
@@ -629,36 +625,61 @@ Panel {
} }
} }
Row { PanelToolTip {
anchors.left: wifiToggleBtn.right visible: heroIconMouse.containsMouse
anchors.leftMargin: Style.spacing.controlPaddingX text: "Toggle Wi-Fi"
anchors.right: parent.right fontFamily: root.bar.fontFamily
anchors.verticalCenter: parent.verticalCenter }
}
Text { Column {
id: wifiMainText id: heroLabels
text: { anchors.left: heroIcon.right
if (root.info.type === "wifi") return root.info.ssid || "Wi-Fi" anchors.leftMargin: Style.space(14)
if (root.info.type === "ethernet") return "Ethernet" anchors.right: headerActions.left
return root.info.iface || (root.kind === "disconnected" ? "Disconnected" : "No connection") anchors.rightMargin: Style.space(10)
anchors.verticalCenter: parent.verticalCenter
spacing: Style.space(2)
Text {
id: heroSsid
width: parent.width
text: {
if (root.info.type === "wifi") return root.info.ssid || "Wi-Fi"
if (root.info.type === "ethernet") return "Ethernet"
return root.info.iface || (root.kind === "disconnected" ? "Disconnected" : "No connection")
}
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.title
font.bold: true
elide: Text.ElideRight
}
Text {
id: heroMeta
width: parent.width
text: {
var parts = []
if (root.info.type === "wifi") {
if (root.canDisconnect) parts.push("Connected")
else if (root.kind === "disconnected") parts.push("Not connected")
if (root.info.freq) parts.push(root.formatFreq(root.info.freq))
} else if (root.info.type === "ethernet") {
parts.push("Connected")
if (root.info.speed) parts.push(root.formatSpeed(root.info.speed))
} else if (root.kind === "disconnected") {
parts.push("Not connected")
} }
color: root.bar.foreground return parts.join(" · ").toUpperCase()
font.family: root.bar.fontFamily
font.pixelSize: Style.font.subtitle
font.bold: true
elide: Text.ElideRight
width: Math.min(implicitWidth, parent.width - (wifiFreqText.visible ? wifiFreqText.implicitWidth : 0))
}
Text {
id: wifiFreqText
visible: root.info.type === "wifi" && !!root.info.freq
text: " • " + root.formatFreq(root.info.freq)
color: Qt.darker(root.bar.foreground, 1.4)
font.family: root.bar.fontFamily
font.pixelSize: Style.font.subtitle
font.bold: true
} }
visible: text !== ""
color: Qt.darker(root.bar.foreground, 1.4)
font.family: root.bar.fontFamily
font.pixelSize: Style.font.caption
font.bold: true
font.letterSpacing: 1.2
elide: Text.ElideRight
} }
} }
@@ -666,14 +687,16 @@ Panel {
id: headerActions id: headerActions
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Style.spacing.controlGap spacing: Style.space(4)
PanelActionButton { PanelActionButton {
id: disconnectBtn id: disconnectBtn
visible: root.canDisconnect visible: root.canDisconnect
enabled: !root.busy enabled: !root.busy
hasCursor: root.cursorActive && root.focusSection === "header" && root.headerIndex === 0 hasCursor: root.cursorActive && root.focusSection === "header" && root.headerIndex === 0
iconText: "󰅙" iconText: "󰖪"
fontSize: Style.font.heading
size: Style.space(30)
tooltipText: "Disconnect" tooltipText: "Disconnect"
foreground: root.bar.foreground foreground: root.bar.foreground
hoverColor: root.bar.urgent hoverColor: root.bar.urgent
@@ -688,17 +711,15 @@ Panel {
onClicked: root.disconnect(root.connectedWifiNetwork) onClicked: root.disconnect(root.connectedWifiNetwork)
} }
Button { PanelActionButton {
id: refreshBtn id: refreshBtn
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
iconText: "󰑐" iconText: "󰑐"
iconSpinning: root.scanning fontSize: Style.font.heading
size: Style.space(30)
tooltipText: "Refresh" tooltipText: "Refresh"
foreground: root.bar.foreground foreground: root.bar.foreground
horizontalPadding: Style.spacing.controlGap fontFamily: root.bar.fontFamily
verticalPadding: Style.spacing.labelGap
iconSize: Style.font.icon
active: root.scanning
hasCursor: root.cursorActive && root.focusSection === "header" && root.headerIndex === (root.canDisconnect ? 1 : 0) hasCursor: root.cursorActive && root.focusSection === "header" && root.headerIndex === (root.canDisconnect ? 1 : 0)
onHovered: function(h) { onHovered: function(h) {
if (!h) return if (!h) return
@@ -711,14 +732,15 @@ Panel {
} }
} }
// Connection details: IP, gateway, link speed, etc. // Connection details: IP, gateway, link speed, etc. Two equal-width
// columns spanning the panel — matches the Power panel's stats grid.
Row { Row {
visible: !!root.info.iface visible: !!root.info.iface
anchors.horizontalCenter: parent.horizontalCenter width: parent.width
spacing: Style.space(24) spacing: Style.space(20)
Column { Column {
width: Style.space(140) width: (parent.width - parent.spacing) / 2
spacing: Style.spacing.labelGap spacing: Style.spacing.labelGap
InfoPair { InfoPair {
visible: !!root.info.ip visible: !!root.info.ip
@@ -737,7 +759,7 @@ Panel {
} }
Column { Column {
width: Style.space(140) width: (parent.width - parent.spacing) / 2
spacing: Style.spacing.labelGap spacing: Style.spacing.labelGap
// Ethernet details // Ethernet details
@@ -768,22 +790,27 @@ Panel {
Column { Column {
width: parent.width width: parent.width
spacing: Style.space(8) spacing: Style.space(10)
PanelSectionHeader { PanelSectionHeader {
text: "DNS provider" text: "DNS PROVIDER"
foreground: root.bar.foreground foreground: root.bar.foreground
fontFamily: root.bar.fontFamily fontFamily: root.bar.fontFamily
} }
Row { Row {
id: dnsRow
width: parent.width width: parent.width
spacing: Style.space(6) spacing: Style.space(6)
readonly property int count: 4
readonly property real cellWidth: (width - spacing * (count - 1)) / count
DnsProviderPill { DnsProviderPill {
provider: "DHCP" provider: "DHCP"
index: 0 index: 0
tooltipText: "Use DNS from DHCP" tooltipText: "Use DNS from DHCP"
width: dnsRow.cellWidth
onClicked: root.setDns(provider) onClicked: root.setDns(provider)
} }
@@ -791,6 +818,7 @@ Panel {
provider: "Cloudflare" provider: "Cloudflare"
index: 1 index: 1
tooltipText: "Set DNS to Cloudflare" tooltipText: "Set DNS to Cloudflare"
width: dnsRow.cellWidth
onClicked: root.setDns(provider) onClicked: root.setDns(provider)
} }
@@ -798,6 +826,7 @@ Panel {
provider: "Google" provider: "Google"
index: 2 index: 2
tooltipText: "Set DNS to Google" tooltipText: "Set DNS to Google"
width: dnsRow.cellWidth
onClicked: root.setDns(provider) onClicked: root.setDns(provider)
} }
@@ -805,6 +834,7 @@ Panel {
provider: "Custom" provider: "Custom"
index: 3 index: 3
tooltipText: "Set custom DNS servers" tooltipText: "Set custom DNS servers"
width: dnsRow.cellWidth
onClicked: root.setDns(provider) onClicked: root.setDns(provider)
} }
} }
@@ -818,7 +848,7 @@ Panel {
PanelSectionHeader { PanelSectionHeader {
visible: root.wifiStationAvailable visible: root.wifiStationAvailable
text: root.scanning ? "Scanning Wi-Fi…" : "Wi-Fi networks" text: root.scanning ? "SCANNING WI-FI…" : "WI-FI NETWORKS"
foreground: root.bar.foreground foreground: root.bar.foreground
fontFamily: root.bar.fontFamily fontFamily: root.bar.fontFamily
} }
@@ -873,10 +903,12 @@ Panel {
required property int index required property int index
text: provider text: provider
fontSize: Style.font.bodySmall
foreground: root.bar.foreground foreground: root.bar.foreground
fontFamily: root.bar.fontFamily fontFamily: root.bar.fontFamily
horizontalPadding: Style.spacing.controlPaddingX horizontalPadding: Style.spacing.controlPaddingX
verticalPadding: Style.spacing.controlPaddingY verticalPadding: Style.spacing.controlPaddingY + Style.space(2)
bordered: true
// Map the panel's domain semantics onto Button's structural props: // Map the panel's domain semantics onto Button's structural props:
// `current DNS` is the pill's `active` fill; the keyboard cursor lights // `current DNS` is the pill's `active` fill; the keyboard cursor lights