From cb76fedcbc8e419e2b945baa56ac3f986a9e79a3 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Wed, 1 Sep 2021 17:13:51 +0200 Subject: Implement event model in C++ Filtering events in JS is too slow with >20,000 events. This moves the event data model into C++. --- Event.qml | 76 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 31 deletions(-) (limited to 'Event.qml') diff --git a/Event.qml b/Event.qml index 38d3eeb..7bad6d5 100644 --- a/Event.qml +++ b/Event.qml @@ -7,61 +7,77 @@ import QtQuick.Layouts 1.6 import 'util.js' as Util // This is the delegate for event list items. -Pane { - id: control +ItemDelegate { + required property var model + required property int index + required property int time - property int time - property alias tag: tag.text - property alias fields: inputs.model + property alias fields: inputs.model // field definitions property bool editing: false - signal remove - clip: true - height: visible ? stuff.height + 2*padding : 0 // TODO fix filtering and remove this padding: 2 - // set to current value or default + background: Rectangle { + anchors.fill: parent + color: highlighted ? Util.alphize(border.color, 0.1) : + (index % 2 === 0 ? palette.base : palette.alternateBase) + border { + color: editing ? palette.highlight : palette.dark + width: highlighted ? 1 : 0 + } + radius: border.width + } + + // Set inputs to current model values. function reset() { - for (var i = 0; i < fields.count; i++) { + for (var i = 0; i < fields.length; i++) { const child = inputs.itemAt(i) if (child && child.item) - child.item.set(fields.get(i).value) + child.item.set(model.values[fields[i].name]) } } + // Store current inputs in model. function store() { - for (var i = 0; i < fields.count; i++) - fields.setProperty(i, 'value', inputs.itemAt(i).item.value) + var values = {} + for (var i = 0; i < fields.length; i++) + values[fields[i].name] = inputs.itemAt(i).item.value + model.values = values } - // Pass keys to each field input in order. - Keys.forwardTo: Array.from({ length: inputs.count }, (_, i) => inputs.itemAt(i).item) + Component.onCompleted: reset() + onEditingChanged: { + if (editing) + forceActiveFocus() + } - Behavior on height { NumberAnimation { duration: 50 } } + // Try passing key to each field input in order. + Keys.forwardTo: Array.from({ length: inputs.count }, (_, i) => inputs.itemAt(i).item) - ColumnLayout { - id: stuff + contentItem: ColumnLayout { anchors { left: parent.left; right: parent.right; margins: 5 } + // Event time, tag and summary. RowLayout { Label { - text: new Date(time).toISOString().substr(12, 9) + text: new Date(model.time).toISOString().substr(12, 9) font.pixelSize: 10 Layout.alignment: Qt.AlignBaseline } Label { - id: tag + text: model.tag font.weight: Font.DemiBold Layout.alignment: Qt.AlignBaseline } Label { text: { var str = '' - for (var i = 0; i < fields.count; i++) { - const field = fields.get(i) - if (field.value && field.type !== 'TextArea') - str += (field.type === 'Bool' ? field.name : field.value) + ' ' + for (var i = 0; i < inputs.count; i++) { + const field = inputs.model[i] + const value = inputs.itemAt(i).item.value + if (value && field.type !== 'TextArea') + str += (field.type === 'Bool' ? field.name : value) + ' ' } return str } @@ -72,10 +88,8 @@ Pane { } } - // Event‐specific inputs. + // Event‐specific input fields. GridLayout { - id: fieldset - flow: GridLayout.TopToBottom rows: inputs.count @@ -86,7 +100,7 @@ Pane { Repeater { model: inputs.model delegate: Label { - text: Util.addShortcut(model.name, model.key) + text: Util.addShortcut(modelData.name, modelData.key) Layout.alignment: Qt.AlignRight } } @@ -95,12 +109,12 @@ Pane { Repeater { id: inputs delegate: Loader { - source: 'qrc:/Fields/' + model.type + '.qml' + source: 'qrc:/Fields/' + modelData.type + '.qml' Layout.fillHeight: true Layout.fillWidth: true Binding { - target: item; property: 'definition' - value: model + target: item; property: 'model' + value: modelData } } } -- cgit v1.3