Changing all for loops, starting list settings

This commit is contained in:
Adsooi 2020-12-25 23:42:31 +01:00
parent 05e51fdd73
commit f0d795478f
7 changed files with 216 additions and 61 deletions

136
qml/ListSetting.qml Normal file
View file

@ -0,0 +1,136 @@
import QtQuick 2.12
ListView {
id: control
signal changed()
property bool dictionaryMode: false
property bool keyType: "string"
property bool valueType: "string"
property string preKeyLabel: ""
property string postKeyLabel: ": "
property var keyRegexp: /^.+$/
property var valueRegexp: /^.+$/
model: ListModel {}
delegate: Row {
height: 30
width: control.width
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
}
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 = ""
}
if(control.keyType == 'double') {
value = parseFloat(value)
if(value.toString()=="NaN")
value = ""
}
if(value != "") {
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
}
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 = ""
}
if(control.valueType == 'double') {
value = parseFloat(value)
if(value.toString()=="NaN")
value = ""
}
if(value != "") {
model.setProperty(index, 'value', value)
control.changed()
}
}
}
}
footer: Button {
id: addEntryBtn
text: '+ Add Entry'
width: control.width
height: visible ? implicitHeight : 0
onClicked: {
control.model.append({
key: "",
value: ""
})
}
}
function import(importer) {
model.clear()
if(dictionaryMode) {
for(var key in importer) model.append({
key: key,
value: importer[value]
})
} else {
for(var key in importer) model.append({
key: key,
value: importer[value]
})
}
}
function export() {
if(d
}
}

View file

@ -115,12 +115,12 @@ ApplicationWindow {
function saveDiagram(filename) { function saveDiagram(filename) {
var objs = {} var objs = {}
Object.keys(Objects.currentObjects).forEach(function(objType){ for(var objType in Objects.currentObjects){
objs[objType] = [] objs[objType] = []
Objects.currentObjects[objType].forEach(function(obj){ for(var obj of Objects.currentObjects[objType]) {
objs[objType].push(obj.export()) objs[objType].push(obj.export())
}) }
}) }
Helper.write(filename, JSON.stringify({ Helper.write(filename, JSON.stringify({
"xzoom": settings.xzoom, "xzoom": settings.xzoom,
"yzoom": settings.yzoom, "yzoom": settings.yzoom,
@ -140,7 +140,7 @@ ApplicationWindow {
function loadDiagram(filename) { function loadDiagram(filename) {
var data = JSON.parse(Helper.load(filename)) var data = JSON.parse(Helper.load(filename))
if("type" in Object.keys(data) && data["type"] == "logplotv1") { if(Object.keys(data).includes("type") && data["type"] == "logplotv1") {
settings.xzoom = data["xzoom"] settings.xzoom = data["xzoom"]
settings.yzoom = data["yzoom"] settings.yzoom = data["yzoom"]
settings.xmin = data["xmin"] settings.xmin = data["xmin"]
@ -154,13 +154,13 @@ ApplicationWindow {
root.width = data["width"] root.width = data["width"]
Objects.currentObjects = {} Objects.currentObjects = {}
Object.keys(data['objects']).forEach(function(objType){ for(var objType in data['objects']) {
Objects.currentObjects[objType] = [] Objects.currentObjects[objType] = []
data['objects'][objType].forEach(function(objData){ for(var objData of data['objects'][objType]) {
var obj = new Objects.types[objType](...objData) var obj = new Objects.types[objType](...objData)
Objects.currentObjects[objType].push(obj) Objects.currentObjects[objType].push(obj)
}) }
}) }
// Refreshing sidebar // Refreshing sidebar
if(sidebarSelector.currentIndex == 0) { if(sidebarSelector.currentIndex == 0) {
// For some reason, if we load a file while the tab is on object, // For some reason, if we load a file while the tab is on object,

View file

@ -54,13 +54,13 @@ Canvas {
reset(ctx) reset(ctx)
drawGrille(ctx) drawGrille(ctx)
drawAxises(ctx) drawAxises(ctx)
Object.keys(Objects.currentObjects).forEach(function(objType){ for(var objType in Objects.currentObjects) {
Objects.currentObjects[objType].forEach(function(obj){ for(var obj of Objects.currentObjects[objType]){
ctx.strokeStyle = obj.color ctx.strokeStyle = obj.color
ctx.fillStyle = obj.color ctx.fillStyle = obj.color
if(obj.visible) obj.draw(canvas, ctx) if(obj.visible) obj.draw(canvas, ctx)
}) }
}) }
drawLabels(ctx) drawLabels(ctx)
} }

View file

@ -55,8 +55,8 @@ ListView {
id: typeVisibilityCheckBox id: typeVisibilityCheckBox
checked: Objects.currentObjects[objType] != undefined ? Objects.currentObjects[objType].every(obj => obj.visible) : true checked: Objects.currentObjects[objType] != undefined ? Objects.currentObjects[objType].every(obj => obj.visible) : true
onClicked: { onClicked: {
Objects.currentObjects[objType].forEach(obj => obj.visible = this.checked) for(var obj of Objects.currentObjects[objType]) obj.visible = this.checked
objTypeList.editingRows.forEach(obj => obj.objVisible = this.checked) for(var obj of objTypeList.editingRows) obj.objVisible = this.checked
objectListList.changed() objectListList.changed()
} }
@ -115,7 +115,7 @@ ListView {
objEditor.objType = objType objEditor.objType = objType
objEditor.objIndex = index objEditor.objIndex = index
objEditor.editingRow = controlRow objEditor.editingRow = controlRow
objEditor.open() objEditor.show()
} }
} }
} }
@ -135,7 +135,7 @@ ListView {
objEditor.objType = objType objEditor.objType = objType
objEditor.objIndex = index objEditor.objIndex = index
objEditor.editingRow = controlRow objEditor.editingRow = controlRow
objEditor.open() objEditor.show()
} }
} }
@ -192,7 +192,7 @@ ListView {
id: objEditor id: objEditor
property string objType: 'Point' property string objType: 'Point'
property int objIndex: 0 property int objIndex: 0
property var editingRow: QtObject{} property QtObject editingRow: QtObject{}
property var obj: Objects.currentObjects[objType][objIndex] property var obj: Objects.currentObjects[objType][objIndex]
title: `Logarithmic Plotter` title: `Logarithmic Plotter`
width: 300 width: 300
@ -224,7 +224,6 @@ ListView {
onChanged: function(newValue) { onChanged: function(newValue) {
var newName = Utils.parseName(newValue) var newName = Utils.parseName(newValue)
if(newName != '' && objEditor.obj.name != newName) { if(newName != '' && objEditor.obj.name != newName) {
console.log('Renaming to', newName)
if(Objects.getObjectByName(newName) != null) { if(Objects.getObjectByName(newName) != null) {
console.log(Objects.getObjectByName(newName).name, newName) console.log(Objects.getObjectByName(newName).name, newName)
newName = Objects.getNewName(newName) newName = Objects.getNewName(newName)
@ -255,8 +254,7 @@ ListView {
// Dynamic properties // Dynamic properties
Repeater { Repeater {
property var objProps: Objects.types[objEditor.objType].properties() id: dlgCustomProperties
model: Array.from(Object.keys(objProps), prop => [prop, objProps[prop]]) // Converted to 2-dimentional array.
Item { Item {
height: 30 height: 30
@ -268,17 +266,17 @@ ListView {
height: 30 height: 30
width: parent.width width: parent.width
visible: modelData[0].startsWith('comment') visible: modelData[0].startsWith('comment')
text: modelData[1] text: visible ? modelData[1] : ''
color: sysPalette.windowText color: sysPalette.windowText
} }
TextSetting { TextSetting {
id: customPropText id: customPropText
height: 30 height: visible ? 30 : 0
width: parent.width width: parent.width
label: parent.label label: parent.label
isDouble: modelData[1] == 'number' isDouble: modelData[1] == 'number'
visible: modelData[1] in ['Expression', 'Domain', 'string', 'number'] visible: ['Expression', 'Domain', 'string', 'number'].includes(modelData[1])
defValue: visible ? { defValue: visible ? {
'Expression': () => Utils.simplifyExpression(objEditor.obj[modelData[0]].toEditableString()), 'Expression': () => Utils.simplifyExpression(objEditor.obj[modelData[0]].toEditableString()),
'Domain': () => objEditor.obj[modelData[0]].toString(), 'Domain': () => objEditor.obj[modelData[0]].toString(),
@ -316,7 +314,7 @@ ListView {
width: dlgProperties.width width: dlgProperties.width
label: parent.label label: parent.label
// True to select an object of type, false for enums. // True to select an object of type, false for enums.
property bool selectObjMode: (typeof modelData[1] == "string" && modelData[1] in Object.keys(Objects.types)) property bool selectObjMode: (typeof modelData[1] == "string" && Object.keys(Objects.types).includes(modelData[1]))
model: visible ? model: visible ?
(selectObjMode ? Objects.getObjectsName(modelData[1]).concat(['+ Create new ' + modelData[1]]) : modelData[1]) (selectObjMode ? Objects.getObjectsName(modelData[1]).concat(['+ Create new ' + modelData[1]]) : modelData[1])
: [] : []
@ -346,6 +344,12 @@ ListView {
} }
} }
} }
function show() {
var objProps = Objects.types[objEditor.objType].properties()
dlgCustomProperties.model = Object.keys(objProps).map(prop => [prop, objProps[prop]]) // Converted to 2-dimentional array.
objEditor.open()
}
} }
footer: Column { footer: Column {
@ -371,8 +375,6 @@ ListView {
height: visible ? implicitHeight : 0 height: visible ? implicitHeight : 0
icon.source: './icons/'+modelData+'.svg' // Default to dark version icon.source: './icons/'+modelData+'.svg' // Default to dark version
onClicked: { onClicked: {
Objects.createNewRegisteredObject(modelData) Objects.createNewRegisteredObject(modelData)
objectListList.update() objectListList.update()
@ -383,8 +385,8 @@ ListView {
function update() { function update() {
objectListList.changed() objectListList.changed()
objectListList.model.forEach(function(objType){ for(var objType in objectListList.model) {
objectListList.listViews[objType].model = Objects.currentObjects[objType] objectListList.listViews[objType].model = Objects.currentObjects[objType]
}) }
} }
} }

View file

@ -79,11 +79,13 @@ function executeExpression(expr){
} }
class Sequence extends Expression { class Sequence extends Expression {
constructor(name, baseValues = {}, expr) { constructor(name, baseValues = {}, valuePlus = 1, expr = "") {
// u[n+valuePlus] = expr
console.log('Expression', expr) console.log('Expression', expr)
super(expr) super(expr)
this.name = name this.name = name
this.baseValues = baseValues this.baseValues = baseValues
this.valuePlus = valuePlus
} }
isConstant() { isConstant() {
@ -93,7 +95,7 @@ class Sequence extends Expression {
execute(n = 0) { execute(n = 0) {
if(this.cached) return this.cachedValue if(this.cached) return this.cachedValue
if(n in this.baseValues) return this.baseValues[n] if(n in this.baseValues) return this.baseValues[n]
var vars = Object.assign({'n': n-1}, evalVariables) var vars = Object.assign({'n': n-this.valuePlus}, evalVariables)
vars[this.name] = this.baseValues vars[this.name] = this.baseValues
var un = this.calc.evaluate(vars) var un = this.calc.evaluate(vars)
this.baseValues[n] = un this.baseValues[n] = un
@ -101,7 +103,7 @@ class Sequence extends Expression {
} }
} }
var test = new Sequence('u', {0: 0}, '3*u[n]+3') var test = new Sequence('u', {0: 0, 1: 1}, 2, '3*u[n]+3')
console.log(test) console.log(test)
for(var i=0; i<20; i++) for(var i=0; i<20; i++)
console.log('u' + Utils.textsub(i) + ' = ' + test.execute(i)) console.log('u' + Utils.textsub(i) + ' = ' + test.execute(i))
@ -330,8 +332,8 @@ class DomainSet extends SpecialDomain {
console.log(values) console.log(values)
var newVals = {} var newVals = {}
this.executedValues = [] this.executedValues = []
for(var i = 0; i < values.length; i++) { for(var value of values) {
var expr = new Expression(values[i].toString()) var expr = new Expression(value.toString())
var ex = expr.execute() var ex = expr.execute()
newVals[ex] = expr newVals[ex] = expr
this.executedValues.push(ex) this.executedValues.push(ex)
@ -342,8 +344,8 @@ class DomainSet extends SpecialDomain {
includes(x) { includes(x) {
if(typeof x == 'string') x = executeExpression(x) if(typeof x == 'string') x = executeExpression(x)
for(var i = 0; i < this.values.length; i++) for(var value of this.values)
if(x == this.values[i].execute()) return true if(x == value.execute()) return true
return false return false
} }
@ -385,7 +387,7 @@ class DomainSet extends SpecialDomain {
return new DomainSet(values) return new DomainSet(values)
} }
var notIncludedValues = [] var notIncludedValues = []
for(var i = 0; i < this.values.length; i++) { for(var value in this.values) {
var value = this.executedValues[i] var value = this.executedValues[i]
if(domain instanceof Interval) { if(domain instanceof Interval) {
if(domain.begin.execute() == value && domain.openBegin) { if(domain.begin.execute() == value && domain.openBegin) {
@ -412,7 +414,7 @@ class DomainSet extends SpecialDomain {
return this return this
} }
var includedValues = [] var includedValues = []
for(var i = 0; i < this.values.length; i++) { for(var i in this.values) {
var value = this.executedValues[i] var value = this.executedValues[i]
if(domain instanceof Interval) { if(domain instanceof Interval) {
if(domain.begin.execute() == value && !domain.openBegin) { if(domain.begin.execute() == value && !domain.openBegin) {

View file

@ -35,6 +35,25 @@ function getNewName(allowedLetters) {
return ret return ret
} }
class List {
constructor(type, format=/^.+$/, label = '') {
// type can be string, int and double.
this.type = type
this.format = format
this.label = label
}
}
class Dictionary {
constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ') {
// type & keyType can be string, int and double.
this.type = type
this.keyType = keyType
this.format = format
this.preKeyLabel = preKeyLabel
this.postKeyLabel = postKeyLabel
}
}
class DrawableObject { class DrawableObject {
// Class to extend for every type of object that // Class to extend for every type of object that
@ -47,7 +66,9 @@ class DrawableObject {
static createable() {return true} static createable() {return true}
// Properties are set with key as property name and // Properties are set with key as property name and
// value as it's type name (e.g 'Expression', 'string', // value as it's type name (e.g 'Expression', 'string',
// 'Point'...) or an array with possibilities for enums. // 'Point'...), an Array for enumerations,
// a List instance for lists, a Dictionary instance for
// dictionary
// Used for property modifier in the sidebar. // Used for property modifier in the sidebar.
static properties() {return {}} static properties() {return {}}
@ -83,14 +104,13 @@ class DrawableObject {
} }
update() { update() {
for(var i = 0; i < this.requiredBy.length; i++) { for(var req of this.requiredBy) {
this.requiredBy[i].update() req.update()
} }
} }
delete() { delete() {
for(var i = 0; i < this.requiredBy.length; i++) { for(var toRemove of this.requiredBy) {
var toRemove = this.requiredBy[i]
toRemove.delete() toRemove.delete()
currentObjects[toRemove.type] = currentObjects[toRemove.type].filter(obj => obj.name != toRemove.name) currentObjects[toRemove.type] = currentObjects[toRemove.type].filter(obj => obj.name != toRemove.name)
} }
@ -460,8 +480,7 @@ class SommeGainsBode extends DrawableObject {
} }
execute(x = 0) { execute(x = 0) {
for(var i=0; i<this.cachedParts.length; i++) { for(var [dbfn, inDrawDom] of this.cachedParts) {
var [dbfn, inDrawDom] = this.cachedParts[i]
if(inDrawDom.includes(x)) { if(inDrawDom.includes(x)) {
return dbfn.execute(x) return dbfn.execute(x)
} }
@ -474,8 +493,7 @@ class SommeGainsBode extends DrawableObject {
} }
simplify(x = 1) { simplify(x = 1) {
for(var i=0; i<this.cachedParts.length; i++) { for(var [dbfn, inDrawDom] of this.cachedParts) {
var [dbfn, inDrawDom] = this.cachedParts[i]
if(inDrawDom.includes(x)) { if(inDrawDom.includes(x)) {
return dbfn.simplify(x) return dbfn.simplify(x)
} }
@ -512,20 +530,19 @@ class SommeGainsBode extends DrawableObject {
var gainsBeforeP = [] var gainsBeforeP = []
var gainsAfterP = [] var gainsAfterP = []
var gainTotal = 0 var gainTotal = 0
for(var i=0; i < om0xList.length; i++){ for(var om0x of om0xList){
if(om0xPass[om0xList[i]]) { // High-pass if(om0xPass[om0x]) { // High-pass
gainsBeforeP.push(om0xGains[om0xList[i]]) gainsBeforeP.push(om0xGains[om0x])
gainsAfterP.push(0) gainsAfterP.push(0)
gainTotal += om0xGains[om0xList[i]] // Gain at first gainTotal += om0xGains[om0x] // Gain at first
} else { } else {
gainsBeforeP.push(0) gainsBeforeP.push(0)
gainsAfterP.push(om0xGains[om0xList[i]]) gainsAfterP.push(om0xGains[om0x])
} }
} }
console.log(gainsBeforeP, gainsAfterP)
// Calculating parts // Calculating parts
var previousPallier = drawMin var previousPallier = drawMin
for(var pallier = 0; pallier < om0xList.length; pallier++) { for(var pallier = 0; pallier <= om0xList.length; pallier++) {
var dbfn = new MathLib.Expression(`${gainTotal}*(ln(x)-ln(${previousPallier}))/ln(10)+${baseY}`) var dbfn = new MathLib.Expression(`${gainTotal}*(ln(x)-ln(${previousPallier}))/ln(10)+${baseY}`)
var inDrawDom = MathLib.parseDomain(`]${previousPallier};${om0xList[pallier]}]`) var inDrawDom = MathLib.parseDomain(`]${previousPallier};${om0xList[pallier]}]`)
this.cachedParts.push([dbfn, inDrawDom]) this.cachedParts.push([dbfn, inDrawDom])
@ -538,8 +555,7 @@ class SommeGainsBode extends DrawableObject {
draw(canvas, ctx) { draw(canvas, ctx) {
if(this.cachedParts.length > 0) { if(this.cachedParts.length > 0) {
for(var i=0; i<this.cachedParts.length; i++) { for(var [dbfn, inDrawDom] of this.cachedParts) {
var [dbfn, inDrawDom] = this.cachedParts[i]
Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R) Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R)
if(inDrawDom.includes(this.labelX)) { if(inDrawDom.includes(this.labelX)) {
// Label // Label
@ -735,8 +751,7 @@ class SommePhasesBode extends ExecutableObject {
if(currentObjects['Phase Bode'] != undefined) { if(currentObjects['Phase Bode'] != undefined) {
console.log('Recalculating cache phase') console.log('Recalculating cache phase')
for(var i = 0; i < currentObjects['Phase Bode'].length; i++) { for(var obj of currentObjects['Phase Bode']) {
var obj = currentObjects['Phase Bode'][i]
this.om0xList.push(obj.om_0.x.execute()) this.om0xList.push(obj.om_0.x.execute())
if(phasesDict[obj.om_0.x.execute()] == undefined) { if(phasesDict[obj.om_0.x.execute()] == undefined) {
phasesDict[obj.om_0.x.execute()] = obj.phase.execute() phasesDict[obj.om_0.x.execute()] = obj.phase.execute()
@ -959,9 +974,9 @@ function getObjectsName(objType) {
return currentObjects[objType].map(obj => obj.name) return currentObjects[objType].map(obj => obj.name)
} }
function createNewRegisteredObject(objType) { function createNewRegisteredObject(objType, args=[]) {
if(Object.keys(types).indexOf(objType) == -1) return null // Object type does not exist. if(Object.keys(types).indexOf(objType) == -1) return null // Object type does not exist.
var newobj = new types[objType]() var newobj = new types[objType](...args)
if(Object.keys(currentObjects).indexOf(objType) == -1) { if(Object.keys(currentObjects).indexOf(objType) == -1) {
currentObjects[objType] = [] currentObjects[objType] = []
} }