Skip to content

Commit

Permalink
Use QuantityObjectModel in all uses of QuantityRow, ListQuantityGroup
Browse files Browse the repository at this point in the history
Change QuantityRow's model type to QuantityObjectModel, so that the
model cannot be specified as an array of real values, and update the
codebase accordingly so that it always uses QuantityObject with
QuantityObjectModel instead of an array-based model in all cases where
multiple quantities are displayed.

This greatly improves the performance of QuantityRow in updating its
values, as the Repeater no longer rebuilds its delegates whenever a
single quantity changes in the model.

Also, since QuantityObjectModel is able to filter out invalid values,
it is not necessary to create and show separate models depending on
whether particular values are valid.

The updates affect the following types and their uses:
- QuantityRow
- ListQuantityGroup
- ListQuantityGroupNavigation

Also remove ListTextGroup and replace its uses with ListQuantityGroup,
as ListTextGroup was being used to show text alongside number values,
and that can now easily be done with ListQuantityGroup as a
QuantityObject value can be a string if the unit is Units_None.

Part of #1338
  • Loading branch information
blammit committed Feb 14, 2025
1 parent 3ccc9e7 commit 777b93f
Show file tree
Hide file tree
Showing 54 changed files with 662 additions and 619 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,6 @@ set (VENUS_QML_MODULE_SOURCES
components/listitems/core/ListTemperature.qml
components/listitems/core/ListText.qml
components/listitems/core/ListTextField.qml
components/listitems/core/ListTextGroup.qml
components/listitems/core/ListTimeSelector.qml
components/listitems/core/PrimaryListLabel.qml
components/listitems/core/SecondaryListLabel.qml
Expand Down
29 changes: 14 additions & 15 deletions components/InverterAcOutSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ Column {

property string bindPrefix
readonly property bool isInverterCharger: isInverterChargerItem.value === 1
readonly property AcPhase acPhase: acPhaseNumber.value === 2 ? inverterData.phase3
: acPhaseNumber.value === 1 ? inverterData.phase2
: inverterData.phase1

width: parent ? parent.width : 0

Expand All @@ -28,28 +31,24 @@ Column {
ListQuantityGroup {
text: CommonWords.ac_out
preferredVisible: !root.isInverterCharger
textModel: [
{ value: inverterData.phase1.voltage, unit: VenusOS.Units_Volt_AC },
{ value: inverterData.phase1.current, unit: VenusOS.Units_Amp },
{ value: inverterData.phase1.power, unit: VenusOS.Units_Watt },
]
model: QuantityObjectModel {
QuantityObject { object: inverterData.phase1; key: "voltage"; unit: VenusOS.Units_Volt_AC }
QuantityObject { object: inverterData.phase1; key: "current"; unit: VenusOS.Units_Amp }
QuantityObject { object: inverterData.phase1; key: "power"; unit: VenusOS.Units_Watt }
}
}

ListQuantityGroup {
readonly property AcPhase acPhase: acPhaseNumber.value === 2 ? inverterData.phase3
: acPhaseNumber.value === 1 ? inverterData.phase2
: inverterData.phase1

//: %1 = phase number (1-3)
//% "AC Out L%1"
text: qsTrId("inverter_ac-out_num").arg(acPhaseNumber.isValid ? acPhaseNumber.value + 1 : 1)
preferredVisible: root.isInverterCharger
textModel: [
{ value: acPhase.voltage, unit: VenusOS.Units_Volt_AC },
{ value: acPhase.current, unit: VenusOS.Units_Amp },
{ value: acPhase.power, unit: VenusOS.Units_Watt },
{ value: acPhase.frequency, unit: VenusOS.Units_Hertz },
]
model: QuantityObjectModel {
QuantityObject { object: root.acPhase; key: "voltage"; unit: VenusOS.Units_Volt_AC }
QuantityObject { object: root.acPhase; key: "current"; unit: VenusOS.Units_Amp }
QuantityObject { object: root.acPhase; key: "power"; unit: VenusOS.Units_Watt }
QuantityObject { object: root.acPhase; key: "frequency"; unit: VenusOS.Units_Hertz }
}

VeQuickItem {
id: acPhaseNumber
Expand Down
24 changes: 14 additions & 10 deletions components/PageGensetModel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -157,28 +157,32 @@ VisibleItemModel {

model: root.nrOfPhases
delegate: ListQuantityGroup {
id: phaseDelegate

required property int index
readonly property string bindPrefix: `${root.bindPrefix}/Ac/L${index + 1}`

text: phaseRepeater.count === 1
//% "AC"
? qsTrId("ac-in-genset_ac")
: CommonWords.ac_phase_x.arg(model.index + 1)

textModel: [
{ value: phaseVoltage.value, unit: VenusOS.Units_Volt_AC },
{ value: phaseCurrent.value, unit: VenusOS.Units_Amp },
{ value: phasePower.value, unit: VenusOS.Units_Watt },
]
: CommonWords.ac_phase_x.arg(index + 1)
model: QuantityObjectModel {
QuantityObject { object: phaseVoltage; unit: VenusOS.Units_Volt_AC }
QuantityObject { object: phaseCurrent; unit: VenusOS.Units_Amp }
QuantityObject { object: phasePower; unit: VenusOS.Units_Watt }
}

VeQuickItem {
id: phaseVoltage
uid: root.bindPrefix + "/Ac/L" + (model.index + 1) + "/Voltage"
uid: phaseDelegate.bindPrefix + "/Voltage"
}
VeQuickItem {
id: phaseCurrent
uid: root.bindPrefix + "/Ac/L" + (model.index + 1) + "/Current"
uid: phaseDelegate.bindPrefix + "/Current"
}
VeQuickItem {
id: phasePower
uid: root.bindPrefix + "/Ac/L" + (model.index + 1) + "/Power"
uid: phaseDelegate.bindPrefix + "/Power"
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion components/QuantityLabel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ Item {

property alias value: quantityInfo.value
property alias unit: quantityInfo.unitType
readonly property alias quantityInfo: quantityInfo
property alias font: unitLabel.font
property alias valueColor: valueLabel.color
property alias unitColor: unitLabel.color
readonly property alias valueText: valueLabel.text
property alias valueText: valueLabel.text
readonly property alias unitText: unitLabel.text
property int alignment: Qt.AlignHCenter
property alias precision: quantityInfo.precision
property alias formatHints: quantityInfo.formatHints
property alias leftPadding: digitRow.leftPadding
property alias rightPadding: digitRow.rightPadding

implicitWidth: digitRow.width
implicitHeight: digitRow.height
Expand Down
75 changes: 28 additions & 47 deletions components/QuantityRow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,74 +9,55 @@ import Victron.VenusOS
Row {
id: root

property alias model: quantityRepeater.model
property QuantityObjectModel model
property alias quantityMetrics: quantityMetrics
property bool showFirstSeparator

// In table mode, items are spaced out without separators between them.
// (TODO if not tableMode, then invalid items should be hidden, instead of showing them as "--".)
property bool tableMode

readonly property bool _showSeparators: !tableMode
readonly property int _textAlignment: tableMode ? Qt.AlignLeft : Qt.AlignHCenter

height: Theme.geometry_listItem_height

FontMetrics {
id: fontMetrics
font.pixelSize: Theme.font_size_body2
}

Repeater {
id: quantityRepeater

delegate: Row {
model: root.model
delegate: QuantityLabel {
id: quantityDelegate

// Visibility is determined by optional 'visible' property.
readonly property bool showValue: modelData.visible !== false
readonly property var dataValue: modelData.value
readonly property bool isStringValue: typeof(dataValue) === 'string'
required property int index
required property QuantityObject quantityObject
readonly property real horizontalPadding: quantityObject.textValue.length ? Theme.geometry_listItem_content_spacing : 0

width: quantityObject.textValue.length ? implicitWidth : quantityMetrics.columnWidth(unit)
height: root.height
leftPadding: verticalSeparator.width + horizontalPadding
rightPadding: horizontalPadding
alignment: root._textAlignment
font.pixelSize: Theme.font_size_body2
value: quantityObject.numberValue
unit: quantityObject.unit
precision: quantityObject.precision
valueText: quantityObject.textValue || quantityInfo.number
valueColor: Theme.color_quantityTable_quantityValue
unitColor: Theme.color_quantityTable_quantityUnit

Item {
Rectangle {
id: verticalSeparator
anchors.verticalCenter: parent.verticalCenter
width: Theme.geometry_listItem_separator_width + (Theme.geometry_listItem_content_spacing / 2)
height: textLabel.height
width: visible ? Theme.geometry_listItem_separator_width : 0
height: fontMetrics.height
visible: root._showSeparators
&& quantityDelegate.showValue
&& (model.index !== 0 || root.showFirstSeparator)

Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
width: Theme.geometry_listItem_separator_width
height: textLabel.height
color: Theme.color_listItem_separator
}
}

QuantityLabel {
id: quantityLabel
visible: quantityDelegate.showValue && !textLabel.visible
width: quantityMetrics.columnWidth(unit)
height: root.height
alignment: root._textAlignment
font.pixelSize: Theme.font_size_body2
unit: modelData.unit || VenusOS.Units_None
precision: modelData.precision || VenusOS.Units_Precision_Default
value: isNaN(quantityDelegate.dataValue) ? NaN : quantityDelegate.dataValue
valueColor: Theme.color_quantityTable_quantityValue
unitColor: Theme.color_quantityTable_quantityUnit
}

// Show a plain label instead of a QuantityLabel if modelData.value is a string instead of
// a number.
Label {
id: textLabel
anchors.verticalCenter: parent.verticalCenter
visible: quantityDelegate.showValue && quantityDelegate.isStringValue
leftPadding: Theme.geometry_listItem_content_spacing
rightPadding: Theme.geometry_listItem_content_spacing
text: visible ? quantityDelegate.dataValue : ""
horizontalAlignment: root._textAlignment
font.pixelSize: Theme.font_size_body2
color: Theme.color_quantityTable_quantityValue
&& (quantityDelegate.index > 0 || root.showFirstSeparator)
color: Theme.color_listItem_separator
}
}
}
Expand Down
1 change: 1 addition & 0 deletions components/QuantityTable.qml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import QtQuick
import Victron.VenusOS

// TODO change this to use QuantityObjectModel for the model
Column {
id: root

Expand Down
12 changes: 7 additions & 5 deletions components/listitems/ListDcInputQuantityGroup.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ ListQuantityGroup {
//% "Input"
text: qsTrId("dc_input")
preferredVisible: inVoltage.isValid || inPower.isValid
textModel: [
{ value: inVoltage.value, unit: VenusOS.Units_Volt_DC, visible: inVoltage.isValid },
{ value: inCurrent.value, unit: VenusOS.Units_Amp, visible: inCurrent.isValid },
{ value: inPower.value, unit: VenusOS.Units_Watt, visible: inPower.isValid },
]
model: QuantityObjectModel {
filterType: QuantityObjectModel.HasValue

QuantityObject { object: inVoltage; unit: VenusOS.Units_Volt_DC }
QuantityObject { object: inCurrent; unit: VenusOS.Units_Amp }
QuantityObject { object: inPower; unit: VenusOS.Units_Watt }
}

VeQuickItem {
id: inVoltage
Expand Down
12 changes: 7 additions & 5 deletions components/listitems/ListDcOutputQuantityGroup.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ ListQuantityGroup {
//: DC output measurement values
//% "Output"
text: qsTrId("dc_output")
textModel: [
{ value: dcVoltage.value, unit: VenusOS.Units_Volt_DC },
{ value: dcCurrent.value, unit: VenusOS.Units_Amp, visible: dcCurrent.isValid },
{ value: dcPower.value, unit: VenusOS.Units_Watt, visible: dcPower.isValid },
]
model: QuantityObjectModel {
filterType: QuantityObjectModel.HasValue

QuantityObject { object: dcVoltage; unit: VenusOS.Units_Volt_DC; defaultValue: "--" }
QuantityObject { object: dcCurrent; unit: VenusOS.Units_Amp }
QuantityObject { object: dcPower; unit: VenusOS.Units_Watt }
}

VeQuickItem {
id: dcVoltage
Expand Down
3 changes: 1 addition & 2 deletions components/listitems/core/ListQuantityGroup.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import Victron.VenusOS
ListItem {
id: root

property alias textModel: quantityRow.model
property alias model: quantityRow.model

content.spacing: 0
content.children: [
QuantityRow {
id: quantityRow
Expand Down
42 changes: 0 additions & 42 deletions components/listitems/core/ListTextGroup.qml

This file was deleted.

10 changes: 5 additions & 5 deletions components/widgets/DcInputWidget.qml
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ OverviewWidget {
model: root.inputs
delegate: ListQuantityGroupNavigation {
text: model.device.name
quantityModel: [
{ value: model.device.voltage, unit: VenusOS.Units_Volt_DC },
{ value: model.device.current, unit: VenusOS.Units_Amp },
{ value: model.device.power, unit: VenusOS.Units_Watt },
]
tableMode: true
quantityModel: QuantityObjectModel {
QuantityObject { object: model.device; key: "voltage"; unit: VenusOS.Units_Volt_DC }
QuantityObject { object: model.device; key: "current"; unit: VenusOS.Units_Amp }
QuantityObject { object: model.device; key: "power"; unit: VenusOS.Units_Watt }
}

onClicked: {
Global.pageManager.pushPage(root.detailUrl, {
Expand Down
12 changes: 6 additions & 6 deletions components/widgets/DcLoadsWidget.qml
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ OverviewWidget {
GradientListView {
model: Global.allDevicesModel.combinedDcLoadDevices

delegate: ListTextGroup {
delegate: ListQuantityGroup {
id: deviceDelegate

required property var device

text: device.name
textModel: [
Units.getCombinedDisplayText(VenusOS.Units_Volt_DC, dcDevice.voltage),
Units.getCombinedDisplayText(VenusOS.Units_Amp, dcDevice.current),
Units.getCombinedDisplayText(VenusOS.Units_Watt, dcDevice.power),
]
model: QuantityObjectModel {
QuantityObject { object: dcDevice; key: "voltage"; unit: VenusOS.Units_Volt_DC }
QuantityObject { object: dcDevice; key: "current"; unit: VenusOS.Units_Amp }
QuantityObject { object: dcDevice; key: "power"; unit: VenusOS.Units_Watt }
}

DcDevice {
id: dcDevice
Expand Down
1 change: 1 addition & 0 deletions data/mock/PvInvertersImpl.qml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ QtObject {
_productId.setValue(45058) // dummy value so that ProductId is not invalid, so PageAcIn.qml will show some content
_allowedRoles.setValue(Global.acInputs.roles.map((roleInfo) => { return roleInfo.role }))
_role.setValue("pvinverter")
Global.mockDataSimulator.setMockValue(serviceUid + "/Connected", 1)
}
}
}
Expand Down
Loading

0 comments on commit 777b93f

Please sign in to comment.