diff --git a/qml/ListSetting.qml b/qml/ListSetting.qml index d6beb0c..9d478af 100644 --- a/qml/ListSetting.qml +++ b/qml/ListSetting.qml @@ -1,111 +1,130 @@ import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQml.Models 2.12 -ListView { +Column { id: control signal changed() + property string label: '' property bool dictionaryMode: false - property bool keyType: "string" - property bool valueType: "string" + property string keyType: "string" + property string valueType: "string" property string preKeyLabel: "" property string postKeyLabel: ": " property var keyRegexp: /^.+$/ property var valueRegexp: /^.+$/ + property bool forbidAdding: false - model: ListModel {} + property alias model: repeater.model - delegate: Row { + Text { + id: labelItem height: 30 + verticalAlignment: TextInput.AlignVCenter + color: sysPalette.windowText + text: control.label +": " + } + + Repeater { + id: repeater width: control.width + model: ListModel {} - Text { - id: preKeyText - height: parent.height - verticalAlignment: TextInput.AlignVCenter - color: sysPalette.windowText - text: control.preKeyLabel - } - - TextField { - id: keyInput - visible: control.dictionaryMode - height: parent.height - width: visible ? 50 : 0 - validator: RegularExpressionValidator { - regularExpression: control.keyRegexp + Row { + id: defRow + height: addEntryBtn.height + width: parent.width + + Text { + id: preKeyText + height: parent.height + verticalAlignment: TextInput.AlignVCenter + color: sysPalette.windowText + text: control.preKeyLabel } - verticalAlignment: TextInput.AlignVCenter - horizontalAlignment: TextInput.AlignHCenter - color: sysPalette.windowText - text: visible ? model.get(index).key : false - selectByMouse: true - onEditingFinished: { - var value = text - if(control.keyType == 'int') { - value = parseFloat(value) - if(value.toString()=="NaN") - value = "" + + TextField { + id: keyInput + visible: control.dictionaryMode + height: parent.height + width: visible ? 50 : 0 + validator: RegExpValidator { + regExp: control.keyRegexp } - if(control.keyType == 'double') { - value = parseFloat(value) - if(value.toString()=="NaN") - value = "" - } - if(value != "") { - model.setProperty(index, 'key', value) - control.changed() + verticalAlignment: TextInput.AlignVCenter + horizontalAlignment: TextInput.AlignHCenter + color: sysPalette.windowText + text: visible ? control.model.get(index).key : false + selectByMouse: true + onEditingFinished: { + var value = text + if(control.keyType == 'int') { + value = parseInt(value) + if(value.toString()=="NaN") + value = "" + } + if(control.keyType == 'double') { + value = parseFloat(value) + if(value.toString()=="NaN") + value = "" + } + if(value != "" && valueInput.acceptableInput) { + control.model.setProperty(index, 'key', value) + control.changed() + } } } - } - - Text { - id: postKeyText - visible: control.dictionaryMode - height: parent.height - verticalAlignment: TextInput.AlignVCenter - color: sysPalette.windowText - text: control.postKeyLabel - } - - TextField { - id: valueInput - height: parent.height - width: parent.width - preKeyText.width - keyInput.width - postKeyText.width - validator: RegularExpressionValidator { - regularExpression: control.valueRegexp + + Text { + id: postKeyText + visible: control.dictionaryMode + height: parent.height + verticalAlignment: TextInput.AlignVCenter + color: sysPalette.windowText + text: control.postKeyLabel } - verticalAlignment: TextInput.AlignVCenter - horizontalAlignment: TextInput.AlignHCenter - color: sysPalette.windowText - text: visible ? model.get(index).key : false - selectByMouse: true - onEditingFinished: { - var value = text - if(control.valueType == 'int') { - value = parseFloat(value) - if(value.toString()=="NaN") - value = "" + + TextField { + id: valueInput + height: parent.height + width: parent.width - x + validator: RegExpValidator { + regExp: control.valueRegexp } - if(control.valueType == 'double') { - value = parseFloat(value) - if(value.toString()=="NaN") - value = "" - } - if(value != "") { - model.setProperty(index, 'value', value) - control.changed() + verticalAlignment: TextInput.AlignVCenter + horizontalAlignment: TextInput.AlignHCenter + color: sysPalette.windowText + text: visible ? control.model.get(index).key : false + selectByMouse: true + onEditingFinished: { + var value = text + if(control.valueType == 'int') { + value = parseInt(value) + if(value.toString()=="NaN") + value = "" + } + if(control.valueType == 'double') { + value = parseFloat(value) + if(value.toString()=="NaN") + value = "" + } + if(value != "" && keyInput.acceptableInput) { + control.model.setProperty(index, 'value', value) + control.changed() + } } } } } - footer: Button { + Button { id: addEntryBtn + visible: !control.forbidAdding text: '+ Add Entry' width: control.width - height: visible ? implicitHeight : 0 onClicked: { control.model.append({ @@ -115,22 +134,25 @@ ListView { } } - function import(importer) { + function importModel(importer) { model.clear() - if(dictionaryMode) { - for(var key in importer) model.append({ + for(var key in importer) + model.append({ key: key, - value: importer[value] + value: importer[key] }) - } else { - for(var key in importer) model.append({ - key: key, - value: importer[value] - }) - } } - function export() { - if(d + function exportModel() { + if(dictionaryMode) { + var ret = {} + for(var i = 0; i < model.count; i++) + ret[model.get(i).key] = model.get(i).value + return ret + } else { + var ret = [] + for(var i = 0; i < model.count; i++) + ret.push(model.get(i).value) + } } } diff --git a/qml/ObjectLists.qml b/qml/ObjectLists.qml index dd89e4a..54e6a01 100644 --- a/qml/ObjectLists.qml +++ b/qml/ObjectLists.qml @@ -257,7 +257,7 @@ ListView { id: dlgCustomProperties Item { - height: 30 + height: customPropListDict.visible ? customPropListDict.height : 30 width: dlgProperties.width property string label: Utils.camelCase2readable(modelData[0]) @@ -266,7 +266,7 @@ ListView { height: 30 width: parent.width visible: modelData[0].startsWith('comment') - text: visible ? modelData[1] : '' + text: visible ? modelData[1].replace('{name}', objEditor.obj.name) : '' color: sysPalette.windowText } @@ -341,6 +341,32 @@ ListView { objectListList.update() } } + + ListSetting { + id: customPropListDict + width: parent.width + + visible: typeof modelData[1] == 'object' && 'type' in modelData[1] && (modelData[1].type == 'List' || modelData[1].type == 'Dict') + label: parent.label + dictionaryMode: visible ? modelData[1].type == 'Dict' : false + keyType: dictionaryMode ? modelData[1].keyType : 'string' + valueType: visible ? modelData[1].type : 'string' + preKeyLabel: (dictionaryMode ? modelData[1].preKeyLabel : modelData[1].label).replace('{name}', objEditor.obj.name) + postKeyLabel: (dictionaryMode ? modelData[1].postKeyLabel : '').replace('{name}', objEditor.obj.name) + keyRegexp: dictionaryMode ? modelData[1].keyFormat : /^.+$/ + valueRegexp: visible ? modelData[1].format : /^.+$/ + forbidAdding: visible ? modelData[1].forbidAdding : false + + onChanged: { + Objects.currentObjects[objEditor.objType][objEditor.objIndex][modelData[0]] = exportModel() + } + + Component.onCompleted: { + console.log('Visible', visible, modelData[0], modelData[1]) + console.log('Type', ('type' in modelData[1]), modelData[1].type) + if(visible) importModel(objEditor.obj[modelData[0]]) + } + } } } } @@ -385,7 +411,7 @@ ListView { function update() { objectListList.changed() - for(var objType in objectListList.model) { + for(var objType in objectListList.listViews) { objectListList.listViews[objType].model = Objects.currentObjects[objType] } } diff --git a/qml/js/objects.js b/qml/js/objects.js index 34ee9ae..23680ba 100644 --- a/qml/js/objects.js +++ b/qml/js/objects.js @@ -36,22 +36,27 @@ function getNewName(allowedLetters) { } class List { - constructor(type, format=/^.+$/, label = '') { + constructor(type, format = /^.+$/, label = '', forbidAdding = false) { // type can be string, int and double. - this.type = type + this.type = 'List' + this.valueType = type this.format = format this.label = label + this.forbidAdding = forbidAdding } } class Dictionary { - constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ') { + constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ', forbidAdding = false) { // type & keyType can be string, int and double. - this.type = type + this.type = 'Dict' + this.valueType = type this.keyType = keyType this.format = format + this.keyFormat = keyFormat this.preKeyLabel = preKeyLabel this.postKeyLabel = postKeyLabel + this.forbidAdding = forbidAdding } } @@ -938,7 +943,23 @@ class CursorX extends DrawableObject { } } - +class Sequence extends ExecutableObject { + static type(){return 'Sequence'} + static typeMultiple(){return 'Sequences'} + static properties() {return { + 'defaultExpression': new Dictionary('string', 'int', /^.+$/, /^(\d+)$/, '{name}[n+', '] = ', true), + 'comment1': 'NOTE: Use {name}[n] to refer to uā‚™, u[n+1] for uā‚™ā‚Šā‚...', + 'markedValues': new Dictionary('string', 'int', /^.+$/, /^(\d+)$/, '{name}[', '] = '), + }} + + constructor(name = null, visible = true, color = null, labelContent = 'name + value', + defaultExp = {1: "u[n]"}, markedValues = {0: 0}) { + if(name == null) name = getNewName('uvwPSUVWabcde') + super(name, visible, color, labelContent) + this.defaultExpression = defaultExp + this.markedValues = markedValues + } +} const types = { 'Point': Point, @@ -947,7 +968,8 @@ const types = { 'Somme gains Bode': SommeGainsBode, 'Phase Bode': PhaseBode, 'Somme phases Bode': SommePhasesBode, - 'X Cursor': CursorX + 'X Cursor': CursorX, + 'Sequence': Sequence } var currentObjects = {}