Adding private fields for Modules

This commit is contained in:
Ad5001 2024-10-10 05:25:34 +02:00
parent b02ed87a29
commit 934dd3ea1b
Signed by: Ad5001
GPG key ID: EF45F9C6AFE20160
6 changed files with 144 additions and 130 deletions

View file

@ -25,23 +25,20 @@ import Objects from "./objects.mjs"
import History from "./history.mjs" import History from "./history.mjs"
class CanvasAPI extends Module { class CanvasAPI extends Module {
/** @type {CanvasInterface} */
#canvas = null
/** @type {CanvasRenderingContext2D} */
#ctx = null
/** @type {{show(string, string, string)}} */
#drawingErrorDialog = null
constructor() { constructor() {
super("Canvas", { super("Canvas", {
canvas: CanvasInterface, canvas: CanvasInterface,
drawingErrorDialog: DialogInterface drawingErrorDialog: DialogInterface
}) })
/** @type {CanvasInterface} */
this._canvas = null
/** @type {CanvasRenderingContext2D} */
this._ctx = null
/**
* @type {{show(string, string, string)}}
* @private
*/
this._drawingErrorDialog = null
/** /**
* *
* @type {Object.<string, {expression: Expression, value: number, maxDraw: number}>} * @type {Object.<string, {expression: Expression, value: number, maxDraw: number}>}
@ -67,18 +64,18 @@ class CanvasAPI extends Module {
*/ */
initialize({ canvas, drawingErrorDialog }) { initialize({ canvas, drawingErrorDialog }) {
super.initialize({ canvas, drawingErrorDialog }) super.initialize({ canvas, drawingErrorDialog })
this._canvas = canvas this.#canvas = canvas
this._drawingErrorDialog = drawingErrorDialog this.#drawingErrorDialog = drawingErrorDialog
} }
get width() { get width() {
if(!this.initialized) throw new Error("Attempting width before initialize!") if(!this.initialized) throw new Error("Attempting width before initialize!")
return this._canvas.width return this.#canvas.width
} }
get height() { get height() {
if(!this.initialized) throw new Error("Attempting height before initialize!") if(!this.initialized) throw new Error("Attempting height before initialize!")
return this._canvas.height return this.#canvas.height
} }
/** /**
@ -87,7 +84,7 @@ class CanvasAPI extends Module {
*/ */
get xmin() { get xmin() {
if(!this.initialized) throw new Error("Attempting xmin before initialize!") if(!this.initialized) throw new Error("Attempting xmin before initialize!")
return this._canvas.xmin return this.#canvas.xmin
} }
/** /**
@ -96,7 +93,7 @@ class CanvasAPI extends Module {
*/ */
get xzoom() { get xzoom() {
if(!this.initialized) throw new Error("Attempting xzoom before initialize!") if(!this.initialized) throw new Error("Attempting xzoom before initialize!")
return this._canvas.xzoom return this.#canvas.xzoom
} }
/** /**
@ -105,7 +102,7 @@ class CanvasAPI extends Module {
*/ */
get ymax() { get ymax() {
if(!this.initialized) throw new Error("Attempting ymax before initialize!") if(!this.initialized) throw new Error("Attempting ymax before initialize!")
return this._canvas.ymax return this.#canvas.ymax
} }
/** /**
@ -114,7 +111,7 @@ class CanvasAPI extends Module {
*/ */
get yzoom() { get yzoom() {
if(!this.initialized) throw new Error("Attempting yzoom before initialize!") if(!this.initialized) throw new Error("Attempting yzoom before initialize!")
return this._canvas.yzoom return this.#canvas.yzoom
} }
/** /**
@ -123,7 +120,7 @@ class CanvasAPI extends Module {
*/ */
get xlabel() { get xlabel() {
if(!this.initialized) throw new Error("Attempting xlabel before initialize!") if(!this.initialized) throw new Error("Attempting xlabel before initialize!")
return this._canvas.xlabel return this.#canvas.xlabel
} }
/** /**
@ -132,7 +129,7 @@ class CanvasAPI extends Module {
*/ */
get ylabel() { get ylabel() {
if(!this.initialized) throw new Error("Attempting ylabel before initialize!") if(!this.initialized) throw new Error("Attempting ylabel before initialize!")
return this._canvas.ylabel return this.#canvas.ylabel
} }
/** /**
@ -141,7 +138,7 @@ class CanvasAPI extends Module {
*/ */
get linewidth() { get linewidth() {
if(!this.initialized) throw new Error("Attempting linewidth before initialize!") if(!this.initialized) throw new Error("Attempting linewidth before initialize!")
return this._canvas.linewidth return this.#canvas.linewidth
} }
/** /**
@ -150,7 +147,7 @@ class CanvasAPI extends Module {
*/ */
get textsize() { get textsize() {
if(!this.initialized) throw new Error("Attempting textsize before initialize!") if(!this.initialized) throw new Error("Attempting textsize before initialize!")
return this._canvas.textsize return this.#canvas.textsize
} }
/** /**
@ -159,7 +156,7 @@ class CanvasAPI extends Module {
*/ */
get logscalex() { get logscalex() {
if(!this.initialized) throw new Error("Attempting logscalex before initialize!") if(!this.initialized) throw new Error("Attempting logscalex before initialize!")
return this._canvas.logscalex return this.#canvas.logscalex
} }
/** /**
@ -168,7 +165,7 @@ class CanvasAPI extends Module {
*/ */
get showxgrad() { get showxgrad() {
if(!this.initialized) throw new Error("Attempting showxgrad before initialize!") if(!this.initialized) throw new Error("Attempting showxgrad before initialize!")
return this._canvas.showxgrad return this.#canvas.showxgrad
} }
/** /**
@ -177,7 +174,7 @@ class CanvasAPI extends Module {
*/ */
get showygrad() { get showygrad() {
if(!this.initialized) throw new Error("Attempting showygrad before initialize!") if(!this.initialized) throw new Error("Attempting showygrad before initialize!")
return this._canvas.showygrad return this.#canvas.showygrad
} }
/** /**
@ -201,7 +198,7 @@ class CanvasAPI extends Module {
requestPaint() { requestPaint() {
if(!this.initialized) throw new Error("Attempting requestPaint before initialize!") if(!this.initialized) throw new Error("Attempting requestPaint before initialize!")
this._canvas.requestPaint() this.#canvas.requestPaint()
} }
/** /**
@ -209,17 +206,17 @@ class CanvasAPI extends Module {
*/ */
redraw() { redraw() {
if(!this.initialized) throw new Error("Attempting redraw before initialize!") if(!this.initialized) throw new Error("Attempting redraw before initialize!")
this._ctx = this._canvas.getContext("2d") this.#ctx = this.#canvas.getContext("2d")
this._computeAxes() this._computeAxes()
this._reset() this._reset()
this._drawGrid() this._drawGrid()
this._drawAxes() this._drawAxes()
this._drawLabels() this._drawLabels()
this._ctx.lineWidth = this.linewidth this.#ctx.lineWidth = this.linewidth
for(let objType in Objects.currentObjects) { for(let objType in Objects.currentObjects) {
for(let obj of Objects.currentObjects[objType]) { for(let obj of Objects.currentObjects[objType]) {
this._ctx.strokeStyle = obj.color this.#ctx.strokeStyle = obj.color
this._ctx.fillStyle = obj.color this.#ctx.fillStyle = obj.color
if(obj.visible) if(obj.visible)
try { try {
obj.draw(this) obj.draw(this)
@ -227,12 +224,12 @@ class CanvasAPI extends Module {
// Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file)
console.error(e) console.error(e)
console.log(e.stack) console.log(e.stack)
this._drawingErrorDialog.show(objType, obj.name, e.message) this.#drawingErrorDialog.show(objType, obj.name, e.message)
History.undo() History.undo()
} }
} }
} }
this._ctx.lineWidth = 1 this.#ctx.lineWidth = 1
} }
/** /**
@ -240,9 +237,9 @@ class CanvasAPI extends Module {
* @private * @private
*/ */
_computeAxes() { _computeAxes() {
let exprY = new Expression(`x*(${this._canvas.yaxisstep})`) let exprY = new Expression(`x*(${this.#canvas.yaxisstep})`)
let y1 = exprY.execute(1) let y1 = exprY.execute(1)
let exprX = new Expression(`x*(${this._canvas.xaxisstep})`) let exprX = new Expression(`x*(${this.#canvas.xaxisstep})`)
let x1 = exprX.execute(1) let x1 = exprX.execute(1)
this.axesSteps = { this.axesSteps = {
x: { x: {
@ -264,10 +261,10 @@ class CanvasAPI extends Module {
*/ */
_reset() { _reset() {
// Reset // Reset
this._ctx.fillStyle = "#FFFFFF" this.#ctx.fillStyle = "#FFFFFF"
this._ctx.strokeStyle = "#000000" this.#ctx.strokeStyle = "#000000"
this._ctx.font = `${this.textsize}px sans-serif` this.#ctx.font = `${this.textsize}px sans-serif`
this._ctx.fillRect(0, 0, this.width, this.height) this.#ctx.fillRect(0, 0, this.width, this.height)
} }
/** /**
@ -275,7 +272,7 @@ class CanvasAPI extends Module {
* @private * @private
*/ */
_drawGrid() { _drawGrid() {
this._ctx.strokeStyle = "#C0C0C0" this.#ctx.strokeStyle = "#C0C0C0"
if(this.logscalex) { if(this.logscalex) {
for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow++) { for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow++) {
for(let xmulti = 1; xmulti < 10; xmulti++) { for(let xmulti = 1; xmulti < 10; xmulti++) {
@ -299,7 +296,7 @@ class CanvasAPI extends Module {
* @private * @private
*/ */
_drawAxes() { _drawAxes() {
this._ctx.strokeStyle = "#000000" this.#ctx.strokeStyle = "#000000"
let axisypos = this.logscalex ? 1 : 0 let axisypos = this.logscalex ? 1 : 0
this.drawXLine(axisypos) this.drawXLine(axisypos)
this.drawYLine(0) this.drawYLine(0)
@ -320,19 +317,19 @@ class CanvasAPI extends Module {
let axisypx = this.x2px(this.logscalex ? 1 : 0) // X coordinate of Y axis let axisypx = this.x2px(this.logscalex ? 1 : 0) // X coordinate of Y axis
let axisxpx = this.y2px(0) // Y coordinate of X axis let axisxpx = this.y2px(0) // Y coordinate of X axis
// Labels // Labels
this._ctx.fillStyle = "#000000" this.#ctx.fillStyle = "#000000"
this._ctx.font = `${this.textsize}px sans-serif` this.#ctx.font = `${this.textsize}px sans-serif`
this._ctx.fillText(this.ylabel, axisypx + 10, 24) this.#ctx.fillText(this.ylabel, axisypx + 10, 24)
let textWidth = this._ctx.measureText(this.xlabel).width let textWidth = this.#ctx.measureText(this.xlabel).width
this._ctx.fillText(this.xlabel, this.width - 14 - textWidth, axisxpx - 5) this.#ctx.fillText(this.xlabel, this.width - 14 - textWidth, axisxpx - 5)
// Axis graduation labels // Axis graduation labels
this._ctx.font = `${this.textsize - 4}px sans-serif` this.#ctx.font = `${this.textsize - 4}px sans-serif`
let txtMinus = this._ctx.measureText("-").width let txtMinus = this.#ctx.measureText("-").width
if(this.showxgrad) { if(this.showxgrad) {
if(this.logscalex) { if(this.logscalex) {
for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow += 1) { for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow += 1) {
textWidth = this._ctx.measureText("10" + textsup(xpow)).width textWidth = this.#ctx.measureText("10" + textsup(xpow)).width
if(xpow !== 0) if(xpow !== 0)
this.drawVisibleText("10" + textsup(xpow), this.x2px(Math.pow(10, xpow)) - textWidth / 2, axisxpx + 16 + (6 * (xpow === 1))) this.drawVisibleText("10" + textsup(xpow), this.x2px(Math.pow(10, xpow)) - textWidth / 2, axisxpx + 16 + (6 * (xpow === 1)))
} }
@ -350,13 +347,13 @@ class CanvasAPI extends Module {
for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) { for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) {
let drawY = y * this.axesSteps.y.value let drawY = y * this.axesSteps.y.value
let txtY = this.axesSteps.y.expression.simplify(y).toString().replace(/^\((.+)\)$/, "$1") let txtY = this.axesSteps.y.expression.simplify(y).toString().replace(/^\((.+)\)$/, "$1")
textWidth = this._ctx.measureText(txtY).width textWidth = this.#ctx.measureText(txtY).width
this.drawVisibleText(txtY, axisypx - 6 - textWidth, this.y2px(drawY) + 4 + (10 * (y === 0))) this.drawVisibleText(txtY, axisypx - 6 - textWidth, this.y2px(drawY) + 4 + (10 * (y === 0)))
if(y !== 0) if(y !== 0)
this.drawVisibleText("-" + txtY, axisypx - 6 - textWidth - txtMinus, this.y2px(-drawY) + 4) this.drawVisibleText("-" + txtY, axisypx - 6 - textWidth - txtMinus, this.y2px(-drawY) + 4)
} }
} }
this._ctx.fillStyle = "#FFFFFF" this.#ctx.fillStyle = "#FFFFFF"
} }
// //
@ -394,7 +391,7 @@ class CanvasAPI extends Module {
drawVisibleText(text, x, y) { drawVisibleText(text, x, y) {
if(x > 0 && x < this.width && y > 0 && y < this.height) { if(x > 0 && x < this.width && y > 0 && y < this.height) {
text.toString().split("\n").forEach((txt, i) => { text.toString().split("\n").forEach((txt, i) => {
this._ctx.fillText(txt, x, y + (this.textsize * i)) this.#ctx.fillText(txt, x, y + (this.textsize * i))
}) })
} }
} }
@ -409,8 +406,8 @@ class CanvasAPI extends Module {
* @param {number} height * @param {number} height
*/ */
drawVisibleImage(image, x, y, width, height) { drawVisibleImage(image, x, y, width, height) {
this._canvas.markDirty(Qt.rect(x, y, width, height)) this.#canvas.markDirty(Qt.rect(x, y, width, height))
this._ctx.drawImage(image, x, y, width, height) this.#ctx.drawImage(image, x, y, width, height)
} }
/** /**
@ -424,7 +421,7 @@ class CanvasAPI extends Module {
let defaultHeight = this.textsize * 1.2 // Approximate but good enough! let defaultHeight = this.textsize * 1.2 // Approximate but good enough!
for(let txt of text.split("\n")) { for(let txt of text.split("\n")) {
theight += defaultHeight theight += defaultHeight
if(this._ctx.measureText(txt).width > twidth) twidth = this._ctx.measureText(txt).width if(this.#ctx.measureText(txt).width > twidth) twidth = this.#ctx.measureText(txt).width
} }
return { "width": twidth, "height": theight } return { "width": twidth, "height": theight }
} }
@ -494,10 +491,10 @@ class CanvasAPI extends Module {
* @param {number} y2 * @param {number} y2
*/ */
drawLine(x1, y1, x2, y2) { drawLine(x1, y1, x2, y2) {
this._ctx.beginPath() this.#ctx.beginPath()
this._ctx.moveTo(x1, y1) this.#ctx.moveTo(x1, y1)
this._ctx.lineTo(x2, y2) this.#ctx.lineTo(x2, y2)
this._ctx.stroke() this.#ctx.stroke()
} }
/** /**
@ -509,9 +506,9 @@ class CanvasAPI extends Module {
* @param {number} dashPxSize * @param {number} dashPxSize
*/ */
drawDashedLine(x1, y1, x2, y2, dashPxSize = 6) { drawDashedLine(x1, y1, x2, y2, dashPxSize = 6) {
this._ctx.setLineDash([dashPxSize / 2, dashPxSize]) this.#ctx.setLineDash([dashPxSize / 2, dashPxSize])
this.drawLine(x1, y1, x2, y2) this.drawLine(x1, y1, x2, y2)
this._ctx.setLineDash([]) this.#ctx.setLineDash([])
} }
/** /**
@ -522,10 +519,10 @@ class CanvasAPI extends Module {
*/ */
renderLatexImage(ltxText, color, callback) { renderLatexImage(ltxText, color, callback) {
const onRendered = (imgData) => { const onRendered = (imgData) => {
if(!this._canvas.isImageLoaded(imgData.source) && !this._canvas.isImageLoading(imgData.source)) { if(!this.#canvas.isImageLoaded(imgData.source) && !this.#canvas.isImageLoading(imgData.source)) {
// Wait until the image is loaded to callback. // Wait until the image is loaded to callback.
this._canvas.loadImage(imgData.source) this.#canvas.loadImage(imgData.source)
this._canvas.imageLoaders[imgData.source] = [callback, imgData] this.#canvas.imageLoaders[imgData.source] = [callback, imgData]
} else { } else {
// Callback directly // Callback directly
callback(imgData) callback(imgData)
@ -543,11 +540,11 @@ class CanvasAPI extends Module {
// //
get font() { get font() {
return this._ctx.font return this.#ctx.font
} }
set font(value) { set font(value) {
return this._ctx.font = value return this.#ctx.font = value
} }
/** /**
@ -560,9 +557,9 @@ class CanvasAPI extends Module {
* @param {boolean} counterclockwise * @param {boolean} counterclockwise
*/ */
arc(x, y, radius, startAngle, endAngle, counterclockwise = false) { arc(x, y, radius, startAngle, endAngle, counterclockwise = false) {
this._ctx.beginPath() this.#ctx.beginPath()
this._ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise) this.#ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise)
this._ctx.stroke() this.#ctx.stroke()
} }
/** /**
@ -572,9 +569,9 @@ class CanvasAPI extends Module {
* @param {number} radius * @param {number} radius
*/ */
disc(x, y, radius) { disc(x, y, radius) {
this._ctx.beginPath() this.#ctx.beginPath()
this._ctx.arc(x, y, radius, 0, 2 * Math.PI) this.#ctx.arc(x, y, radius, 0, 2 * Math.PI)
this._ctx.fill() this.#ctx.fill()
} }
/** /**
@ -585,7 +582,7 @@ class CanvasAPI extends Module {
* @param {number} h * @param {number} h
*/ */
fillRect(x, y, w, h) { fillRect(x, y, w, h) {
this._ctx.fillRect(x, y, w, h) this.#ctx.fillRect(x, y, w, h)
} }
} }

View file

@ -25,6 +25,10 @@ globalThis.Modules = globalThis.Modules || {}
* Base class for global APIs in runtime. * Base class for global APIs in runtime.
*/ */
export class Module { export class Module {
/** @type {string} */
#name
/** @type {Object.<string, (Interface|string|number|boolean)>} */
#initializationParameters
/** /**
* *
@ -33,8 +37,8 @@ export class Module {
*/ */
constructor(name, initializationParameters = {}) { constructor(name, initializationParameters = {}) {
console.log(`Loading module ${name}...`) console.log(`Loading module ${name}...`)
this.__name = name this.#name = name
this.__initializationParameters = initializationParameters this.#initializationParameters = initializationParameters
this.initialized = false this.initialized = false
} }
@ -45,15 +49,15 @@ export class Module {
*/ */
initialize(options) { initialize(options) {
if(this.initialized) if(this.initialized)
throw new Error(`Cannot reinitialize module ${this.__name}.`) throw new Error(`Cannot reinitialize module ${this.#name}.`)
console.log(`Initializing ${this.__name}...`) console.log(`Initializing ${this.#name}...`)
for(const [name, value] of Object.entries(this.__initializationParameters)) { for(const [name, value] of Object.entries(this.#initializationParameters)) {
if(!options.hasOwnProperty(name)) if(!options.hasOwnProperty(name))
throw new Error(`Option '${name}' of initialize of module ${this.__name} does not exist.`) throw new Error(`Option '${name}' of initialize of module ${this.#name} does not exist.`)
if(typeof value === "function" && value.prototype instanceof Interface) if(typeof value === "function" && value.prototype instanceof Interface)
Interface.check_implementation(value, options[name]) Interface.check_implementation(value, options[name])
else if(typeof value !== typeof options[name]) else if(typeof value !== typeof options[name])
throw new Error(`Option '${name}' of initialize of module ${this.__name} is not a '${value}' (${typeof options[name]}).`) throw new Error(`Option '${name}' of initialize of module ${this.#name} is not a '${value}' (${typeof options[name]}).`)
} }
this.initialized = true this.initialized = true
} }

View file

@ -35,15 +35,17 @@ const evalVariables = {
} }
class ExprParserAPI extends Module { class ExprParserAPI extends Module {
#parser = new Parser()
constructor() { constructor() {
super("ExprParser") super("ExprParser")
this.currentVars = {} this.currentVars = {}
this._parser = new Parser() this.#parser = new Parser()
this._parser.consts = Object.assign({}, this._parser.consts, evalVariables) this.#parser.consts = Object.assign({}, this.#parser.consts, evalVariables)
this._parser.functions.integral = this.integral.bind(this) this.#parser.functions.integral = this.integral.bind(this)
this._parser.functions.derivative = this.derivative.bind(this) this.#parser.functions.derivative = this.derivative.bind(this)
} }
/** /**
@ -68,7 +70,7 @@ class ExprParserAPI extends Module {
[f, variable] = args [f, variable] = args
if(typeof f !== "string" || typeof variable !== "string") if(typeof f !== "string" || typeof variable !== "string")
throw EvalError(qsTranslate("usage", "Usage:\n%1").arg(usage2)) throw EvalError(qsTranslate("usage", "Usage:\n%1").arg(usage2))
f = this._parser.parse(f).toJSFunction(variable, this.currentVars) f = this.#parser.parse(f).toJSFunction(variable, this.currentVars)
} else } else
throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2))
return f return f
@ -79,7 +81,7 @@ class ExprParserAPI extends Module {
* @returns {ExprEvalExpression} * @returns {ExprEvalExpression}
*/ */
parse(expression) { parse(expression) {
return this._parser.parse(expression) return this.#parser.parse(expression)
} }
integral(a, b, ...args) { integral(a, b, ...args) {

View file

@ -24,6 +24,12 @@ import { DialogInterface, RootInterface, SettingsInterface } from "./interface.m
class IOAPI extends Module { class IOAPI extends Module {
/** @type {RootInterface} */
#rootElement
/** @type {SettingsInterface} */
#settings
/** @type {{show: function(string)}} */
#alert
constructor() { constructor() {
super("IO", { super("IO", {
@ -46,9 +52,9 @@ class IOAPI extends Module {
*/ */
initialize({ root, settings, alert }) { initialize({ root, settings, alert }) {
super.initialize({ root, settings, alert }) super.initialize({ root, settings, alert })
this.rootElement = root this.#rootElement = root
this.settings = settings this.#settings = settings
this.alert = alert this.#alert = alert
} }
/** /**
@ -69,27 +75,27 @@ class IOAPI extends Module {
} }
} }
let settings = { let settings = {
"xzoom": this.settings.xzoom, "xzoom": this.#settings.xzoom,
"yzoom": this.settings.yzoom, "yzoom": this.#settings.yzoom,
"xmin": this.settings.xmin, "xmin": this.#settings.xmin,
"ymax": this.settings.ymax, "ymax": this.#settings.ymax,
"xaxisstep": this.settings.xaxisstep, "xaxisstep": this.#settings.xaxisstep,
"yaxisstep": this.settings.yaxisstep, "yaxisstep": this.#settings.yaxisstep,
"xaxislabel": this.settings.xlabel, "xaxislabel": this.#settings.xlabel,
"yaxislabel": this.settings.ylabel, "yaxislabel": this.#settings.ylabel,
"logscalex": this.settings.logscalex, "logscalex": this.#settings.logscalex,
"linewidth": this.settings.linewidth, "linewidth": this.#settings.linewidth,
"showxgrad": this.settings.showxgrad, "showxgrad": this.#settings.showxgrad,
"showygrad": this.settings.showygrad, "showygrad": this.#settings.showygrad,
"textsize": this.settings.textsize, "textsize": this.#settings.textsize,
"history": History.serialize(), "history": History.serialize(),
"width": this.rootElement.width, "width": this.#rootElement.width,
"height": this.rootElement.height, "height": this.#rootElement.height,
"objects": objs, "objects": objs,
"type": "logplotv1" "type": "logplotv1"
} }
Helper.write(filename, JSON.stringify(settings)) Helper.write(filename, JSON.stringify(settings))
this.alert.show(qsTranslate("io", "Saved plot to '%1'.").arg(filename.split("/").pop())) this.#alert.show(qsTranslate("io", "Saved plot to '%1'.").arg(filename.split("/").pop()))
History.history.saved = true History.history.saved = true
} }
@ -101,32 +107,32 @@ class IOAPI extends Module {
if(!this.initialized) throw new Error("Attempting loadDiagram before initialize!") if(!this.initialized) throw new Error("Attempting loadDiagram before initialize!")
if(!History.initialized) throw new Error("Attempting loadDiagram before history is initialized!") if(!History.initialized) throw new Error("Attempting loadDiagram before history is initialized!")
let basename = filename.split("/").pop() let basename = filename.split("/").pop()
this.alert.show(qsTranslate("io", "Loading file '%1'.").arg(basename)) this.#alert.show(qsTranslate("io", "Loading file '%1'.").arg(basename))
let data = JSON.parse(Helper.load(filename)) let data = JSON.parse(Helper.load(filename))
let error = "" let error = ""
if(data.hasOwnProperty("type") && data["type"] === "logplotv1") { if(data.hasOwnProperty("type") && data["type"] === "logplotv1") {
History.clear() History.clear()
// Importing settings // Importing settings
this.settings.saveFilename = filename this.#settings.saveFilename = filename
this.settings.xzoom = parseFloat(data["xzoom"]) || 100 this.#settings.xzoom = parseFloat(data["xzoom"]) || 100
this.settings.yzoom = parseFloat(data["yzoom"]) || 10 this.#settings.yzoom = parseFloat(data["yzoom"]) || 10
this.settings.xmin = parseFloat(data["xmin"]) || 5 / 10 this.#settings.xmin = parseFloat(data["xmin"]) || 5 / 10
this.settings.ymax = parseFloat(data["ymax"]) || 24 this.#settings.ymax = parseFloat(data["ymax"]) || 24
this.settings.xaxisstep = data["xaxisstep"] || "4" this.#settings.xaxisstep = data["xaxisstep"] || "4"
this.settings.yaxisstep = data["yaxisstep"] || "4" this.#settings.yaxisstep = data["yaxisstep"] || "4"
this.settings.xlabel = data["xaxislabel"] || "" this.#settings.xlabel = data["xaxislabel"] || ""
this.settings.ylabel = data["yaxislabel"] || "" this.#settings.ylabel = data["yaxislabel"] || ""
this.settings.logscalex = data["logscalex"] === true this.#settings.logscalex = data["logscalex"] === true
if("showxgrad" in data) if("showxgrad" in data)
this.settings.showxgrad = data["showxgrad"] this.#settings.showxgrad = data["showxgrad"]
if("showygrad" in data) if("showygrad" in data)
this.settings.textsize = data["showygrad"] this.#settings.textsize = data["showygrad"]
if("linewidth" in data) if("linewidth" in data)
this.settings.linewidth = data["linewidth"] this.#settings.linewidth = data["linewidth"]
if("textsize" in data) if("textsize" in data)
this.settings.textsize = data["textsize"] this.#settings.textsize = data["textsize"]
this.rootElement.height = parseFloat(data["height"]) || 500 this.#rootElement.height = parseFloat(data["height"]) || 500
this.rootElement.width = parseFloat(data["width"]) || 1000 this.#rootElement.width = parseFloat(data["width"]) || 1000
// Importing objects // Importing objects
Objects.currentObjects = {} Objects.currentObjects = {}
@ -158,18 +164,18 @@ class IOAPI extends Module {
History.unserialize(...data["history"]) History.unserialize(...data["history"])
// Refreshing sidebar // Refreshing sidebar
this.rootElement.updateObjectsLists() this.#rootElement.updateObjectsLists()
} else { } else {
error = qsTranslate("io", "Invalid file provided.") error = qsTranslate("io", "Invalid file provided.")
} }
if(error !== "") { if(error !== "") {
console.log(error) console.log(error)
this.alert.show(qsTranslate("io", "Could not load file: ") + error) this.#alert.show(qsTranslate("io", "Could not load file: ") + error)
// TODO: Error handling // TODO: Error handling
return return
} }
Canvas.redraw() Canvas.redraw()
this.alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename)) this.#alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename))
History.history.saved = true History.history.saved = true
} }

View file

@ -60,6 +60,9 @@ class LatexRenderResult {
} }
class LatexAPI extends Module { class LatexAPI extends Module {
/** @type {LatexInterface} */
#latex = null
constructor() { constructor() {
super("Latex", { super("Latex", {
latex: LatexInterface, latex: LatexInterface,
@ -77,8 +80,7 @@ class LatexAPI extends Module {
*/ */
initialize({ latex, helper }) { initialize({ latex, helper }) {
super.initialize({ latex, helper }) super.initialize({ latex, helper })
this.latex = latex this.#latex = latex
this.helper = helper
this.enabled = helper.getSettingBool("enable_latex") this.enabled = helper.getSettingBool("enable_latex")
} }
@ -93,7 +95,7 @@ class LatexAPI extends Module {
*/ */
findPrerendered(markup, fontSize, color) { findPrerendered(markup, fontSize, color) {
if(!this.initialized) throw new Error("Attempting findPrerendered before initialize!") if(!this.initialized) throw new Error("Attempting findPrerendered before initialize!")
const data = this.latex.findPrerendered(markup, fontSize, color) const data = this.#latex.findPrerendered(markup, fontSize, color)
let ret = null let ret = null
if(data !== "") if(data !== "")
ret = new LatexRenderResult(...data.split(",")) ret = new LatexRenderResult(...data.split(","))
@ -110,7 +112,7 @@ class LatexAPI extends Module {
*/ */
async requestAsyncRender(markup, fontSize, color) { async requestAsyncRender(markup, fontSize, color) {
if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!") if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!")
let args = this.latex.render(markup, fontSize, color).split(",") let args = this.#latex.render(markup, fontSize, color).split(",")
return new LatexRenderResult(...args) return new LatexRenderResult(...args)
} }

View file

@ -20,6 +20,9 @@ import General from "../preferences/general.mjs"
import Editor from "../preferences/expression.mjs" import Editor from "../preferences/expression.mjs"
import DefaultGraph from "../preferences/default.mjs" import DefaultGraph from "../preferences/default.mjs"
/**
* Module for application wide settings.
*/
class PreferencesAPI extends Module { class PreferencesAPI extends Module {
constructor() { constructor() {
super("Preferences") super("Preferences")