List properties! Starting Sequences
This commit is contained in:
parent
f0d795478f
commit
5af98c67b0
3 changed files with 168 additions and 98 deletions
|
@ -1,111 +1,130 @@
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQml.Models 2.12
|
||||||
|
|
||||||
ListView {
|
Column {
|
||||||
id: control
|
id: control
|
||||||
|
|
||||||
signal changed()
|
signal changed()
|
||||||
|
|
||||||
|
property string label: ''
|
||||||
property bool dictionaryMode: false
|
property bool dictionaryMode: false
|
||||||
property bool keyType: "string"
|
property string keyType: "string"
|
||||||
property bool valueType: "string"
|
property string valueType: "string"
|
||||||
property string preKeyLabel: ""
|
property string preKeyLabel: ""
|
||||||
property string postKeyLabel: ": "
|
property string postKeyLabel: ": "
|
||||||
property var keyRegexp: /^.+$/
|
property var keyRegexp: /^.+$/
|
||||||
property var valueRegexp: /^.+$/
|
property var valueRegexp: /^.+$/
|
||||||
|
property bool forbidAdding: false
|
||||||
|
|
||||||
|
|
||||||
model: ListModel {}
|
property alias model: repeater.model
|
||||||
|
|
||||||
delegate: Row {
|
Text {
|
||||||
|
id: labelItem
|
||||||
height: 30
|
height: 30
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
color: sysPalette.windowText
|
||||||
|
text: control.label +": "
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
width: control.width
|
width: control.width
|
||||||
|
model: ListModel {}
|
||||||
|
|
||||||
Text {
|
Row {
|
||||||
id: preKeyText
|
id: defRow
|
||||||
height: parent.height
|
height: addEntryBtn.height
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
width: parent.width
|
||||||
color: sysPalette.windowText
|
|
||||||
text: control.preKeyLabel
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
Text {
|
||||||
id: keyInput
|
id: preKeyText
|
||||||
visible: control.dictionaryMode
|
height: parent.height
|
||||||
height: parent.height
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
width: visible ? 50 : 0
|
color: sysPalette.windowText
|
||||||
validator: RegularExpressionValidator {
|
text: control.preKeyLabel
|
||||||
regularExpression: control.keyRegexp
|
|
||||||
}
|
}
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
horizontalAlignment: TextInput.AlignHCenter
|
TextField {
|
||||||
color: sysPalette.windowText
|
id: keyInput
|
||||||
text: visible ? model.get(index).key : false
|
visible: control.dictionaryMode
|
||||||
selectByMouse: true
|
height: parent.height
|
||||||
onEditingFinished: {
|
width: visible ? 50 : 0
|
||||||
var value = text
|
validator: RegExpValidator {
|
||||||
if(control.keyType == 'int') {
|
regExp: control.keyRegexp
|
||||||
value = parseFloat(value)
|
|
||||||
if(value.toString()=="NaN")
|
|
||||||
value = ""
|
|
||||||
}
|
}
|
||||||
if(control.keyType == 'double') {
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
value = parseFloat(value)
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
if(value.toString()=="NaN")
|
color: sysPalette.windowText
|
||||||
value = ""
|
text: visible ? control.model.get(index).key : false
|
||||||
}
|
selectByMouse: true
|
||||||
if(value != "") {
|
onEditingFinished: {
|
||||||
model.setProperty(index, 'key', value)
|
var value = text
|
||||||
control.changed()
|
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 {
|
Text {
|
||||||
id: postKeyText
|
id: postKeyText
|
||||||
visible: control.dictionaryMode
|
visible: control.dictionaryMode
|
||||||
height: parent.height
|
height: parent.height
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
color: sysPalette.windowText
|
color: sysPalette.windowText
|
||||||
text: control.postKeyLabel
|
text: control.postKeyLabel
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: valueInput
|
|
||||||
height: parent.height
|
|
||||||
width: parent.width - preKeyText.width - keyInput.width - postKeyText.width
|
|
||||||
validator: RegularExpressionValidator {
|
|
||||||
regularExpression: control.valueRegexp
|
|
||||||
}
|
}
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
horizontalAlignment: TextInput.AlignHCenter
|
TextField {
|
||||||
color: sysPalette.windowText
|
id: valueInput
|
||||||
text: visible ? model.get(index).key : false
|
height: parent.height
|
||||||
selectByMouse: true
|
width: parent.width - x
|
||||||
onEditingFinished: {
|
validator: RegExpValidator {
|
||||||
var value = text
|
regExp: control.valueRegexp
|
||||||
if(control.valueType == 'int') {
|
|
||||||
value = parseFloat(value)
|
|
||||||
if(value.toString()=="NaN")
|
|
||||||
value = ""
|
|
||||||
}
|
}
|
||||||
if(control.valueType == 'double') {
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
value = parseFloat(value)
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
if(value.toString()=="NaN")
|
color: sysPalette.windowText
|
||||||
value = ""
|
text: visible ? control.model.get(index).key : false
|
||||||
}
|
selectByMouse: true
|
||||||
if(value != "") {
|
onEditingFinished: {
|
||||||
model.setProperty(index, 'value', value)
|
var value = text
|
||||||
control.changed()
|
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
|
id: addEntryBtn
|
||||||
|
visible: !control.forbidAdding
|
||||||
text: '+ Add Entry'
|
text: '+ Add Entry'
|
||||||
width: control.width
|
width: control.width
|
||||||
height: visible ? implicitHeight : 0
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
control.model.append({
|
control.model.append({
|
||||||
|
@ -115,22 +134,25 @@ ListView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function import(importer) {
|
function importModel(importer) {
|
||||||
model.clear()
|
model.clear()
|
||||||
if(dictionaryMode) {
|
for(var key in importer)
|
||||||
for(var key in importer) model.append({
|
model.append({
|
||||||
key: key,
|
key: key,
|
||||||
value: importer[value]
|
value: importer[key]
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
for(var key in importer) model.append({
|
|
||||||
key: key,
|
|
||||||
value: importer[value]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function export() {
|
function exportModel() {
|
||||||
if(d
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,7 @@ ListView {
|
||||||
id: dlgCustomProperties
|
id: dlgCustomProperties
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
height: 30
|
height: customPropListDict.visible ? customPropListDict.height : 30
|
||||||
width: dlgProperties.width
|
width: dlgProperties.width
|
||||||
property string label: Utils.camelCase2readable(modelData[0])
|
property string label: Utils.camelCase2readable(modelData[0])
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ ListView {
|
||||||
height: 30
|
height: 30
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: modelData[0].startsWith('comment')
|
visible: modelData[0].startsWith('comment')
|
||||||
text: visible ? modelData[1] : ''
|
text: visible ? modelData[1].replace('{name}', objEditor.obj.name) : ''
|
||||||
color: sysPalette.windowText
|
color: sysPalette.windowText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +341,32 @@ ListView {
|
||||||
objectListList.update()
|
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() {
|
function update() {
|
||||||
objectListList.changed()
|
objectListList.changed()
|
||||||
for(var objType in objectListList.model) {
|
for(var objType in objectListList.listViews) {
|
||||||
objectListList.listViews[objType].model = Objects.currentObjects[objType]
|
objectListList.listViews[objType].model = Objects.currentObjects[objType]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,22 +36,27 @@ function getNewName(allowedLetters) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class List {
|
class List {
|
||||||
constructor(type, format=/^.+$/, label = '') {
|
constructor(type, format = /^.+$/, label = '', forbidAdding = false) {
|
||||||
// type can be string, int and double.
|
// type can be string, int and double.
|
||||||
this.type = type
|
this.type = 'List'
|
||||||
|
this.valueType = type
|
||||||
this.format = format
|
this.format = format
|
||||||
this.label = label
|
this.label = label
|
||||||
|
this.forbidAdding = forbidAdding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Dictionary {
|
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.
|
// type & keyType can be string, int and double.
|
||||||
this.type = type
|
this.type = 'Dict'
|
||||||
|
this.valueType = type
|
||||||
this.keyType = keyType
|
this.keyType = keyType
|
||||||
this.format = format
|
this.format = format
|
||||||
|
this.keyFormat = keyFormat
|
||||||
this.preKeyLabel = preKeyLabel
|
this.preKeyLabel = preKeyLabel
|
||||||
this.postKeyLabel = postKeyLabel
|
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 = {
|
const types = {
|
||||||
'Point': Point,
|
'Point': Point,
|
||||||
|
@ -947,7 +968,8 @@ const types = {
|
||||||
'Somme gains Bode': SommeGainsBode,
|
'Somme gains Bode': SommeGainsBode,
|
||||||
'Phase Bode': PhaseBode,
|
'Phase Bode': PhaseBode,
|
||||||
'Somme phases Bode': SommePhasesBode,
|
'Somme phases Bode': SommePhasesBode,
|
||||||
'X Cursor': CursorX
|
'X Cursor': CursorX,
|
||||||
|
'Sequence': Sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentObjects = {}
|
var currentObjects = {}
|
||||||
|
|
Loading…
Reference in a new issue