Improve even more zoom transitions

This commit is contained in:
2024-07-12 22:21:41 +02:00
parent 2b85dce86a
commit 4da0e784ca
11 changed files with 347 additions and 323 deletions

View File

@@ -4,6 +4,10 @@ import QtQuick.Layouts
import EVChargerApp import EVChargerApp
NavigationPage { NavigationPage {
function backPressed() {
return false
}
title: qsTr("Setup or add device") title: qsTr("Setup or add device")
WhiteBox { WhiteBox {

View File

@@ -3,41 +3,28 @@ import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import EVChargerApp import EVChargerApp
Loader { AnimatedStackView {
id: loader id: stackView
sourceComponent: deviceList
function backPressed() { function backPressed() {
return loader.item.backPressed() if (stackView.currentItem.backPressed())
} return true
if (depth > 1) {
DevicesModel { pop()
id: devicesModel return true
settings: theSettings
Component.onCompleted: start()
}
Component {
id: deviceList
DeviceListScreen {
//onDeviceSelected: (url, password) => loader.setSource("DeviceScreen.qml", { url, password })
onDeviceSelected: function(url, password) {
loader.sourceComponent = deviceScreen
loader.item.url = url;
loader.item.password = password;
}
} }
return false
}
initialItem: DeviceListScreen {
onDeviceSelected: (url, password) => stackView.push(deviceScreenComponent, { url, password })
} }
Component { Component {
id: deviceScreen id: deviceScreenComponent
DeviceScreen { DeviceScreen {
onClose: loader.sourceComponent = deviceList onCloseRequested: stackView.pop()
} }
} }
} }

View File

@@ -7,6 +7,10 @@ import EVChargerApp
NavigationPage { NavigationPage {
title: qsTr("App Settings") title: qsTr("App Settings")
function backPressed() {
return false
}
WhiteBox { WhiteBox {
Layout.fillWidth: true Layout.fillWidth: true

View File

@@ -6,6 +6,8 @@ import EVChargerApp
AnimatedStackView { AnimatedStackView {
id: stackView id: stackView
signal closeRequested()
function backPressed() { function backPressed() {
if (depth > 1) { if (depth > 1) {
pop() pop()
@@ -46,7 +48,7 @@ AnimatedStackView {
Layout.fillHeight: true Layout.fillHeight: true
text: qsTr("Devices") text: qsTr("Devices")
onClicked: loader.close() onClicked: closeRequested()
} }
} }
} }

View File

@@ -9,8 +9,7 @@ ColumnLayout {
required property DeviceConnection deviceConnection required property DeviceConnection deviceConnection
function backPressed() { function backPressed() {
close() return false
return true
} }
Connections { Connections {
@@ -47,6 +46,6 @@ ColumnLayout {
Button { Button {
text: qsTr("Cancel") text: qsTr("Cancel")
onClicked: close() onClicked: stackView.pop()
} }
} }

View File

@@ -3,307 +3,299 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import EVChargerApp import EVChargerApp
AnimatedStackView { BaseNavigationPage {
id: stackView id: page
title: qsTr("Device list")
signal deviceSelected(url: string, password: string) signal deviceSelected(url: string, password: string)
function backPressed() { function backPressed() {
if (depth > 1) {
pop()
return true
}
return false return false
} }
initialItem: BaseNavigationPage { CloudUrlsModel {
id: page id: cloudUrlsModel
title: qsTr("Device list") }
CloudUrlsModel {
id: cloudUrlsModel
}
headerItems: [
Button {
text: qsTr("App Settings")
icon.source: "material-icons/settings.svg"
display: AbstractButton.IconOnly
onClicked: stackView.push(appSettingsPage)
Component {
id: appSettingsPage
AppSettingsPage {
}
}
}
]
ListView {
id: listView
model: devicesModel
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
spacing: 10
contentX: -15
ScrollBar.vertical: ScrollBar {
interactive: false
}
footer: Item {
height: 75
}
section.property: "saved"
section.criteria: ViewSection.FullString
section.delegate: Component {
id: sectionHeading
Text {
width: ListView.view.width - 30
height: implicitHeight + 50
bottomPadding: 10
verticalAlignment: Text.AlignBottom
wrapMode: Text.Wrap
required property bool section
text: section ? qsTr("My devices") : qsTr("Found devices")
font.bold: true
font.pixelSize: 20
}
}
delegate: SwipeDelegate {
id: delegate
checkable: true
width: ListView.view.width - 30
required property int index
required property string name
required property string serial
required property string manufacturer
required property string deviceType
required property string friendlyName
required property string password
required property bool saved
required property string hostName
required property string ip
Component.onCompleted: {
background.color = "white"
background.radius = 5
}
swipe.enabled: saved
swipe.right: Label {
id: deleteLabel
text: qsTr("Delete")
color: "white"
verticalAlignment: Label.AlignVCenter
padding: 12
height: parent.height
anchors.right: parent.right
SwipeDelegate.onClicked: {
listView.model.removeRow(delegate.index)
swipe.close()
delegate.checked = false;
}
background: Rectangle {
color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
}
}
contentItem: ColumnLayout {
RowLayout {
Image {
height: parent.height
//Layout.fillHeight: true
source: {
if (delegate.deviceType == "go-eCharger_V5" ||
delegate.deviceType == "go-eCharger_V4" ||
delegate.deviceType == "wattpilot_V2")
{
return "icons/ChargerV4.svg"
} else if (delegate.deviceType == "go-eCharger" ||
delegate.deviceType == "wattpilot") {
return "icons/ChargerV3.svg"
} else if (delegate.deviceType == "go-eCharger_Phoenix") {
return "icons/Charger.svg"
} else if (delegate.deviceType.includes("controller")) {
return "icons/Controller.svg"
}
}
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Text {
Layout.fillWidth: true
text: delegate.friendlyName
font.bold: true
elide: Text.ElideRight
}
Text {
Layout.fillWidth: true
text: qsTr("Serial Number %0").arg(delegate.serial);
}
}
}
GridLayout {
id: grid
visible: false
columns: 2
rowSpacing: 10
columnSpacing: 10
Text {
text: qsTr("Manufacturer:")
Layout.leftMargin: 60
}
Text {
text: delegate.manufacturer
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: qsTr("Device Type:")
Layout.leftMargin: 60
}
Text {
text: delegate.deviceType
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: qsTr("Host Name:")
Layout.leftMargin: 60
}
Text {
text: delegate.hostName
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: qsTr("Ip:")
Layout.leftMargin: 60
}
Text {
text: delegate.ip
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
RowLayout {
Layout.columnSpan: 2
Button {
Layout.fillWidth: true
enabled: delegate.ip != ""
text: qsTr("Local")
onClicked: deviceSelected("ws://" + delegate.ip + "/ws", delegate.password)
}
Button {
Layout.fillWidth: true
property var cloudUrl: {
for (let i = 0; i < cloudUrlsModel.count; ++i) {
const entry = cloudUrlsModel.get(i);
if (delegate.manufacturer === entry.manufacturer &&
delegate.deviceType.includes(entry.deviceType)) {
return entry.url;
}
}
return null;
}
enabled: cloudUrl !== null
text: qsTr("Cloud")
onClicked: deviceSelected(cloudUrl + delegate.serial, delegate.password)
}
Button {
Layout.fillWidth: true
text: qsTr("Solala")
onClicked: deviceSelected("wss://solalaweb.com/" + delegate.serial, delegate.password)
visible: theSettings.showSolalaweb
}
}
}
}
states: [
State {
name: "expanded"
when: delegate.checked
PropertyChanges {
// TODO: When Qt Design Studio supports generalized grouped properties, change to:
// grid.visible: true
// qmllint disable Quick.property-changes-parsed
target: grid
visible: true
}
}
]
}
}
headerItems: [
Button { Button {
parent: page text: qsTr("App Settings")
anchors { icon.source: "material-icons/settings.svg"
right: parent.right display: AbstractButton.IconOnly
rightMargin: 10
bottom: parent.bottom
bottomMargin: 25
}
text: qsTr("Add or setup device") onClicked: stackView.push(appSettingsPage)
icon.source: "material-icons/add.svg"
font.pointSize: 12
font.bold: true
highlighted: true
Material.accent: Material.Blue
display: listView.contentY < 20 ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
onClicked: stackView.push(addDeviceScreen)
Component { Component {
id: addDeviceScreen id: appSettingsPage
AddDeviceScreen { AppSettingsPage {
} }
} }
} }
]
ListView {
id: listView
model: devicesModel
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
spacing: 10
contentX: -15
ScrollBar.vertical: ScrollBar {
interactive: false
}
footer: Item {
height: 75
}
section.property: "saved"
section.criteria: ViewSection.FullString
section.delegate: Component {
id: sectionHeading
Text {
width: ListView.view.width - 30
height: implicitHeight + 50
bottomPadding: 10
verticalAlignment: Text.AlignBottom
wrapMode: Text.Wrap
required property bool section
text: section ? qsTr("My devices") : qsTr("Found devices")
font.bold: true
font.pixelSize: 20
}
}
delegate: SwipeDelegate {
id: delegate
checkable: true
width: ListView.view.width - 30
required property int index
required property string name
required property string serial
required property string manufacturer
required property string deviceType
required property string friendlyName
required property string password
required property bool saved
required property string hostName
required property string ip
Component.onCompleted: {
background.color = "white"
background.radius = 5
}
swipe.enabled: saved
swipe.right: Label {
id: deleteLabel
text: qsTr("Delete")
color: "white"
verticalAlignment: Label.AlignVCenter
padding: 12
height: parent.height
anchors.right: parent.right
SwipeDelegate.onClicked: {
listView.model.removeRow(delegate.index)
swipe.close()
delegate.checked = false;
}
background: Rectangle {
color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
}
}
contentItem: ColumnLayout {
RowLayout {
Image {
height: parent.height
//Layout.fillHeight: true
source: {
if (delegate.deviceType == "go-eCharger_V5" ||
delegate.deviceType == "go-eCharger_V4" ||
delegate.deviceType == "wattpilot_V2")
{
return "icons/ChargerV4.svg"
} else if (delegate.deviceType == "go-eCharger" ||
delegate.deviceType == "wattpilot") {
return "icons/ChargerV3.svg"
} else if (delegate.deviceType == "go-eCharger_Phoenix") {
return "icons/Charger.svg"
} else if (delegate.deviceType.includes("controller")) {
return "icons/Controller.svg"
}
}
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Text {
Layout.fillWidth: true
text: delegate.friendlyName
font.bold: true
elide: Text.ElideRight
}
Text {
Layout.fillWidth: true
text: qsTr("Serial Number %0").arg(delegate.serial);
}
}
}
GridLayout {
id: grid
visible: false
columns: 2
rowSpacing: 10
columnSpacing: 10
Text {
text: qsTr("Manufacturer:")
Layout.leftMargin: 60
}
Text {
text: delegate.manufacturer
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: qsTr("Device Type:")
Layout.leftMargin: 60
}
Text {
text: delegate.deviceType
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: qsTr("Host Name:")
Layout.leftMargin: 60
}
Text {
text: delegate.hostName
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: qsTr("Ip:")
Layout.leftMargin: 60
}
Text {
text: delegate.ip
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
RowLayout {
Layout.columnSpan: 2
Button {
Layout.fillWidth: true
enabled: delegate.ip != ""
text: qsTr("Local")
onClicked: deviceSelected("ws://" + delegate.ip + "/ws", delegate.password)
}
Button {
Layout.fillWidth: true
property var cloudUrl: {
for (let i = 0; i < cloudUrlsModel.count; ++i) {
const entry = cloudUrlsModel.get(i);
if (delegate.manufacturer === entry.manufacturer &&
delegate.deviceType.includes(entry.deviceType)) {
return entry.url;
}
}
return null;
}
enabled: cloudUrl !== null
text: qsTr("Cloud")
onClicked: deviceSelected(cloudUrl + delegate.serial, delegate.password)
}
Button {
Layout.fillWidth: true
text: qsTr("Solala")
onClicked: deviceSelected("wss://solalaweb.com/" + delegate.serial, delegate.password)
visible: theSettings.showSolalaweb
}
}
}
}
states: [
State {
name: "expanded"
when: delegate.checked
PropertyChanges {
// TODO: When Qt Design Studio supports generalized grouped properties, change to:
// grid.visible: true
// qmllint disable Quick.property-changes-parsed
target: grid
visible: true
}
}
]
}
}
Button {
parent: page
anchors {
right: parent.right
rightMargin: 10
bottom: parent.bottom
bottomMargin: 25
}
text: qsTr("Add or setup device")
icon.source: "material-icons/add.svg"
font.pointSize: 12
font.bold: true
highlighted: true
Material.accent: Material.Blue
display: listView.contentY < 20 ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
onClicked: stackView.push(addDeviceScreen)
Component {
id: addDeviceScreen
AddDeviceScreen {
}
}
} }
} }

View File

@@ -6,7 +6,7 @@ import EVChargerApp
Loader { Loader {
id: loader id: loader
signal close signal closeRequested()
property alias url: theDeviceConnection.url property alias url: theDeviceConnection.url
property alias password: theDeviceConnection.password property alias password: theDeviceConnection.password
@@ -61,6 +61,7 @@ Loader {
MainScreen { MainScreen {
deviceConnection: theDeviceConnection deviceConnection: theDeviceConnection
onCloseRequested: loader.closeRequested()
} }
} }

View File

@@ -16,6 +16,14 @@ ApplicationWindow {
id: theSettings id: theSettings
} }
DevicesModel {
id: devicesModel
settings: theSettings
Component.onCompleted: start()
}
FontLoader { FontLoader {
id: materialIcons id: materialIcons
source: "ui-icons/MaterialIcons-Regular.ttf" source: "ui-icons/MaterialIcons-Regular.ttf"
@@ -33,6 +41,7 @@ ApplicationWindow {
AppInstance { AppInstance {
width: view.width width: view.width
height: view.height
} }
} }
} }

View File

@@ -6,6 +6,8 @@ import EVChargerApp
ColumnLayout { ColumnLayout {
id: mainScreen id: mainScreen
signal closeRequested
required property DeviceConnection deviceConnection required property DeviceConnection deviceConnection
function backPressed() { function backPressed() {
@@ -16,8 +18,7 @@ ColumnLayout {
stackLayout.currentIndex = Qt.binding(() => tabBar.currentIndex) stackLayout.currentIndex = Qt.binding(() => tabBar.currentIndex)
return true return true
} }
loader.close() return false
return true
} }
ApiKeyValueHelper { ApiKeyValueHelper {
@@ -187,6 +188,10 @@ ColumnLayout {
delegate: Loader { delegate: Loader {
source: model.source source: model.source
onLoaded: {
if (item.closeRequested)
item.closeRequested.connect(closeRequested)
}
} }
} }
} }

View File

@@ -60,10 +60,17 @@ WhiteBox {
description: qsTr("Specific energy and time") description: qsTr("Specific energy and time")
onClicked: { onClicked: {
if (selectedMode) if (selectedMode)
stackView.push("DailyTripPage.qml") stackView.push(dailyTripPageComponent)
else else
valueChanger.sendMessage({type: "setValue", key: "lmo", value: 5}) valueChanger.sendMessage({type: "setValue", key: "lmo", value: 5})
} }
Component {
id: dailyTripPageComponent
DailyTripPage {
}
}
} }
BusyIndicator { BusyIndicator {

View File

@@ -54,8 +54,15 @@ NavigationPage {
} }
text: qsTr("(%0) Wi-Fi Scan").arg(wifiScanResult.value == null ? 0 : wifiScanResult.value.length) text: qsTr("(%0) Wi-Fi Scan").arg(wifiScanResult.value == null ? 0 : wifiScanResult.value.length)
onClicked: stackView.push("WiFiScanPage.qml", {wifiScanResult} ) onClicked: stackView.push(wiFiScanPageComponent, {wifiScanResult} )
enabled: wifiScanResult.value != null enabled: wifiScanResult.value != null
Component {
id: wiFiScanPageComponent
WiFiScanPage {
}
}
} }
Button { Button {
@@ -66,8 +73,15 @@ NavigationPage {
} }
text: qsTr("(%0) Wi-Fi Errors").arg(wifiErrorLog.value == null ? 0 : wifiErrorLog.value.length) text: qsTr("(%0) Wi-Fi Errors").arg(wifiErrorLog.value == null ? 0 : wifiErrorLog.value.length)
onClicked: stackView.push("WiFiErrorsPage.qml", {wifiErrorLog} ) onClicked: stackView.push(wiFiErrorsPageComponent, {wifiErrorLog} )
enabled: wifiErrorLog.value != null enabled: wifiErrorLog.value != null
Component {
id: wiFiErrorsPageComponent
WiFiErrorsPage {
}
}
} }
Item { Item {