refactor: move item list -> new component
This commit is contained in:
parent
b874dfc983
commit
ab87ba51da
2 changed files with 230 additions and 203 deletions
123
modules/nexus/common/ItemList.qml
Normal file
123
modules/nexus/common/ItemList.qml
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Caelestia.Config
|
||||||
|
import qs.components
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool showList
|
||||||
|
property string placeholderIcon
|
||||||
|
property string placeholderText
|
||||||
|
property int extraHeight
|
||||||
|
|
||||||
|
property alias model: list.model
|
||||||
|
property alias delegate: list.delegate
|
||||||
|
readonly property alias list: list
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: (showList && list.count > 0 ? list.contentHeight : placeholder.implicitHeight + Tokens.padding.extraLarge * 2) + extraHeight
|
||||||
|
radius: Tokens.rounding.extraSmall
|
||||||
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: placeholder
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
active: opacity > 0
|
||||||
|
asynchronous: true
|
||||||
|
opacity: root.showList && list.count > 0 ? 0 : 1
|
||||||
|
|
||||||
|
sourceComponent: ColumnLayout {
|
||||||
|
spacing: Tokens.spacing.extraSmall
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: root.placeholderIcon
|
||||||
|
color: Colours.palette.m3outline
|
||||||
|
font: Tokens.font.icon.large
|
||||||
|
animate: true
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: root.placeholderText
|
||||||
|
color: Colours.palette.m3outline
|
||||||
|
font: Tokens.font.body.large
|
||||||
|
animate: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: list
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
interactive: false
|
||||||
|
opacity: root.showList ? 1 : 0
|
||||||
|
|
||||||
|
add: Transition {
|
||||||
|
Anim {
|
||||||
|
property: "opacity"
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove: Transition {
|
||||||
|
Anim {
|
||||||
|
property: "opacity"
|
||||||
|
to: 0
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
move: Transition {
|
||||||
|
Anim {
|
||||||
|
property: "opacity"
|
||||||
|
to: 1
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
Anim {
|
||||||
|
property: "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
displaced: Transition {
|
||||||
|
Anim {
|
||||||
|
property: "opacity"
|
||||||
|
to: 1
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
Anim {
|
||||||
|
property: "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -59,226 +59,130 @@ PageBase {
|
||||||
verticalPadding: Tokens.padding.large
|
verticalPadding: Tokens.padding.large
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
ItemList {
|
||||||
Layout.fillWidth: true
|
id: networkList
|
||||||
implicitHeight: (Nmcli.wifiEnabled && networkList.count > 0 ? networkList.contentHeight : noNetworksPlaceholder.implicitHeight + Tokens.padding.extraLarge * 2) + (Nmcli.scanning ? Tokens.rounding.extraSmall : 0) // Inline so it isn't affected by anim
|
|
||||||
radius: Tokens.rounding.extraSmall
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
showList: Nmcli.wifiEnabled
|
||||||
Anim {}
|
placeholderIcon: Nmcli.wifiEnabled ? "wifi_find" : "signal_wifi_off"
|
||||||
|
placeholderText: Nmcli.wifiEnabled ? qsTr("No networks found") : qsTr("Wi-Fi disabled")
|
||||||
|
extraHeight: Nmcli.scanning ? Tokens.rounding.extraSmall : 0 // Inline so it isn't affected by anim
|
||||||
|
list.anchors.top: scanningIndicator.bottom
|
||||||
|
|
||||||
|
model: ScriptModel {
|
||||||
|
values: [...Nmcli.networks].sort((a, b) => {
|
||||||
|
if (a.active)
|
||||||
|
return -1;
|
||||||
|
if (b.active)
|
||||||
|
return 1;
|
||||||
|
return b.strength - a.strength;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
delegate: StateLayer {
|
||||||
id: noNetworksPlaceholder
|
id: network
|
||||||
|
|
||||||
anchors.centerIn: parent
|
required property Nmcli.AccessPoint modelData
|
||||||
active: opacity > 0
|
property bool currentSelected
|
||||||
asynchronous: true
|
property real textOpacity: disabled ? 0.5 : 1
|
||||||
opacity: Nmcli.wifiEnabled && networkList.count > 0 ? 0 : 1
|
|
||||||
|
|
||||||
sourceComponent: ColumnLayout {
|
disabled: currentSelected || Nmcli.connectingSsid() === modelData.ssid
|
||||||
spacing: Tokens.spacing.extraSmall
|
|
||||||
|
anchors.left: networkList.list.contentItem.left
|
||||||
|
anchors.right: networkList.list.contentItem.right
|
||||||
|
implicitHeight: networkLayout.implicitHeight + networkLayout.anchors.margins * 2
|
||||||
|
radius: Tokens.rounding.extraSmall
|
||||||
|
anchors.fill: undefined
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (!modelData.active) {
|
||||||
|
NetworkConnection.handleConnect(modelData);
|
||||||
|
currentSelected = true;
|
||||||
|
root.networkSelected(modelData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on textOpacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onActiveChanged(): void {
|
||||||
|
if (network.modelData.active)
|
||||||
|
network.currentSelected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
target: network.modelData
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onNetworkSelected(ap: Nmcli.AccessPoint): void {
|
||||||
|
if (ap !== network.modelData)
|
||||||
|
network.currentSelected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
target: root
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: networkLayout
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Tokens.padding.medium
|
||||||
|
anchors.leftMargin: Tokens.padding.largeIncreased
|
||||||
|
anchors.rightMargin: Tokens.padding.largeIncreased
|
||||||
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
text: Icons.getNetworkIcon(network.modelData.strength)
|
||||||
text: Nmcli.wifiEnabled ? "wifi_find" : "signal_wifi_off"
|
color: network.modelData.active ? Colours.palette.m3primary : Colours.tPalette.m3onSurfaceVariant
|
||||||
color: Colours.palette.m3outline
|
font: Tokens.font.icon.medium
|
||||||
font: Tokens.font.icon.large
|
opacity: network.textOpacity
|
||||||
animate: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
ColumnLayout {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.fillWidth: true
|
||||||
text: Nmcli.wifiEnabled ? qsTr("No networks found") : qsTr("Wi-Fi disabled")
|
spacing: 0
|
||||||
color: Colours.palette.m3outline
|
opacity: network.textOpacity
|
||||||
font: Tokens.font.body.large
|
|
||||||
animate: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
StyledText {
|
||||||
Anim {
|
|
||||||
type: Anim.DefaultEffects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: networkList
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: scanningIndicator.bottom
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
interactive: false
|
|
||||||
|
|
||||||
model: ScriptModel {
|
|
||||||
values: [...Nmcli.networks].sort((a, b) => {
|
|
||||||
if (a.active)
|
|
||||||
return -1;
|
|
||||||
if (b.active)
|
|
||||||
return 1;
|
|
||||||
return b.strength - a.strength;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
add: Transition {
|
|
||||||
Anim {
|
|
||||||
property: "opacity"
|
|
||||||
from: 0
|
|
||||||
to: 1
|
|
||||||
type: Anim.DefaultEffects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remove: Transition {
|
|
||||||
Anim {
|
|
||||||
property: "opacity"
|
|
||||||
to: 0
|
|
||||||
type: Anim.DefaultEffects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
move: Transition {
|
|
||||||
Anim {
|
|
||||||
property: "opacity"
|
|
||||||
to: 1
|
|
||||||
type: Anim.DefaultEffects
|
|
||||||
}
|
|
||||||
Anim {
|
|
||||||
property: "y"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
displaced: Transition {
|
|
||||||
Anim {
|
|
||||||
property: "opacity"
|
|
||||||
to: 1
|
|
||||||
type: Anim.DefaultEffects
|
|
||||||
}
|
|
||||||
Anim {
|
|
||||||
property: "y"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: StateLayer {
|
|
||||||
id: network
|
|
||||||
|
|
||||||
required property Nmcli.AccessPoint modelData
|
|
||||||
property bool currentSelected
|
|
||||||
property real textOpacity: disabled ? 0.5 : 1
|
|
||||||
|
|
||||||
disabled: currentSelected || Nmcli.connectingSsid() === modelData.ssid
|
|
||||||
|
|
||||||
anchors.left: networkList.contentItem.left
|
|
||||||
anchors.right: networkList.contentItem.right
|
|
||||||
implicitHeight: networkLayout.implicitHeight + networkLayout.anchors.margins * 2
|
|
||||||
radius: Tokens.rounding.extraSmall
|
|
||||||
anchors.fill: undefined
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
if (!modelData.active) {
|
|
||||||
NetworkConnection.handleConnect(modelData);
|
|
||||||
currentSelected = true;
|
|
||||||
root.networkSelected(modelData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on textOpacity {
|
|
||||||
Anim {
|
|
||||||
type: Anim.DefaultEffects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onActiveChanged(): void {
|
|
||||||
if (network.modelData.active)
|
|
||||||
network.currentSelected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
target: network.modelData
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onNetworkSelected(ap: Nmcli.AccessPoint): void {
|
|
||||||
if (ap !== network.modelData)
|
|
||||||
network.currentSelected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
target: root
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: networkLayout
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Tokens.padding.medium
|
|
||||||
anchors.leftMargin: Tokens.padding.largeIncreased
|
|
||||||
anchors.rightMargin: Tokens.padding.largeIncreased
|
|
||||||
spacing: Tokens.spacing.medium
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
text: Icons.getNetworkIcon(network.modelData.strength)
|
|
||||||
color: network.modelData.active ? Colours.palette.m3primary : Colours.tPalette.m3onSurfaceVariant
|
|
||||||
font: Tokens.font.icon.medium
|
|
||||||
opacity: network.textOpacity
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: 0
|
text: network.modelData.ssid
|
||||||
opacity: network.textOpacity
|
font: Tokens.font.body.small
|
||||||
|
elide: Text.ElideRight
|
||||||
StyledText {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: network.modelData.ssid
|
|
||||||
font: Tokens.font.body.small
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Security: %1").arg(network.modelData.security)
|
|
||||||
color: Colours.tPalette.m3outline
|
|
||||||
font: Tokens.font.label.small
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimLoader {
|
StyledText {
|
||||||
sourceComp: Nmcli.connectingSsid() === network.modelData.ssid ? loadingComp : iconComp
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Security: %1").arg(network.modelData.security)
|
||||||
Component {
|
color: Colours.tPalette.m3outline
|
||||||
id: iconComp
|
font: Tokens.font.label.small
|
||||||
|
elide: Text.ElideRight
|
||||||
MaterialIcon {
|
|
||||||
text: network.modelData.active ? "settings" : "lock"
|
|
||||||
color: network.modelData.active ? Colours.palette.m3primary : Colours.tPalette.m3onSurfaceVariant
|
|
||||||
font: Tokens.font.icon.medium
|
|
||||||
opacity: network.textOpacity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: loadingComp
|
|
||||||
|
|
||||||
LoadingIndicator {
|
|
||||||
implicitSize: Math.round(Tokens.font.icon.medium.pointSize * 1.3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
opacity: Nmcli.wifiEnabled ? 1 : 0
|
AnimLoader {
|
||||||
|
sourceComp: Nmcli.connectingSsid() === network.modelData.ssid ? loadingComp : iconComp
|
||||||
|
|
||||||
Behavior on opacity {
|
Component {
|
||||||
Anim {
|
id: iconComp
|
||||||
type: Anim.DefaultEffects
|
|
||||||
|
MaterialIcon {
|
||||||
|
text: network.modelData.active ? "settings" : "lock"
|
||||||
|
color: network.modelData.active ? Colours.palette.m3primary : Colours.tPalette.m3onSurfaceVariant
|
||||||
|
font: Tokens.font.icon.medium
|
||||||
|
opacity: network.textOpacity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: loadingComp
|
||||||
|
|
||||||
|
LoadingIndicator {
|
||||||
|
implicitSize: Math.round(Tokens.font.icon.medium.pointSize * 1.3)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue