import QtQuick import Quickshell.Networking import qs.config import qs.components // One network in the wifi menu. Rectangle { id: root required property WifiNetwork network property bool selected: false signal activated signal forgetRequested signal entered // Owe is opportunistic encryption: no passphrase to ask for. readonly property bool secured: root.network.security !== WifiSecurityType.Open && root.network.security !== WifiSecurityType.Owe readonly property string securityLabel: { switch (root.network.security) { case WifiSecurityType.Open: return "Open"; case WifiSecurityType.Owe: return "Open, encrypted"; case WifiSecurityType.Sae: case WifiSecurityType.Wpa3SuiteB192: return "WPA3"; case WifiSecurityType.Wpa2Psk: case WifiSecurityType.Wpa2Eap: return "WPA2"; case WifiSecurityType.WpaPsk: case WifiSecurityType.WpaEap: return "WPA"; case WifiSecurityType.StaticWep: case WifiSecurityType.DynamicWep: return "WEP"; default: return "Secured"; } } readonly property string status: { switch (root.network.state) { case ConnectionState.Connecting: return "Connecting…"; case ConnectionState.Disconnecting: return "Disconnecting…"; case ConnectionState.Connected: return "Connected"; default: return root.network.known ? "Saved · " + root.securityLabel : root.securityLabel; } } implicitHeight: 40 radius: Theme.radius color: root.selected ? Theme.surfaceActive : "transparent" Behavior on color { ColorAnimation { duration: Theme.animDuration easing.type: Theme.animEasing } } WifiGlyph { id: glyph anchors { left: parent.left leftMargin: Theme.padding + 2 verticalCenter: parent.verticalCenter } size: 20 // Quarters, so a network only changes bars on a real move rather than // on every scan. level: Math.min(3, Math.floor(root.network.signalStrength * 4)) color: root.network.connected ? Theme.accent : Theme.text dimColor: Theme.border } Column { anchors { left: glyph.right right: lock.left leftMargin: Theme.padding * 2 rightMargin: Theme.padding verticalCenter: parent.verticalCenter } spacing: 1 Text { width: parent.width elide: Text.ElideRight text: root.network.name color: Theme.text font.family: Theme.fontFamily font.pixelSize: Theme.fontSize } Text { width: parent.width elide: Text.ElideRight text: root.status color: root.network.connected ? Theme.accent : Theme.textDim font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeSmall } } // A padlock, drawn: same reasoning as the glyphs. Item { id: lock anchors { right: parent.right rightMargin: Theme.padding * 2 verticalCenter: parent.verticalCenter } visible: root.secured width: visible ? 9 : 0 height: 11 Rectangle { width: parent.width height: 6 y: parent.height - height radius: 1 color: Theme.textDim } Rectangle { x: 1.5 width: parent.width - 3 height: 7 radius: width / 2 color: "transparent" border.width: 1.5 border.color: Theme.textDim } } MouseArea { anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor acceptedButtons: Qt.LeftButton | Qt.RightButton onEntered: root.entered() onClicked: event => { if (event.button === Qt.RightButton) root.forgetRequested(); else root.activated(); } } }