diff --git a/common/src/events.mjs b/common/src/events.mjs index f1ec970..bed4dea 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -38,7 +38,7 @@ export class BaseEvent { export class BaseEventEmitter { static emits = [] - /** @type {Record} */ + /** @type {Record>} */ #listeners = {} constructor() { @@ -54,7 +54,7 @@ export class BaseEventEmitter { * @param {function(BaseEvent)} eventListener - The function to be called back when the event is emitted. */ addEventListener(eventType, eventListener) { - if(!this.emits.includes(eventType)) { + if(!this.constructor.emits.includes(eventType)) { const className = this.constructor.name const eventTypes = this.constructor.emits.join(", ") throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) @@ -71,7 +71,7 @@ export class BaseEventEmitter { * @returns {boolean} True if the listener was removed, false if it was not found. */ removeEventListener(eventType, eventListener) { - if(!this.emits.includes(eventType)) { + if(!this.constructor.emits.includes(eventType)) { const className = this.constructor.name const eventTypes = this.constructor.emits.join(", ") throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) @@ -88,8 +88,11 @@ export class BaseEventEmitter { emit(e) { if(!(e instanceof BaseEvent)) throw new Error("Cannot emit non event object.") - if(!this.emits.includes(e.name)) - throw new Error(`Cannot emit event '${e.name}' from class ${this.constructor.name}. ${this.constructor.name} can only emits: ${this.constructor.emits.join(", ")}.`) + if(!this.constructor.emits.includes(e.name)) { + const className = this.constructor.name + const eventTypes = this.constructor.emits.join(", ") + throw new Error(`Cannot emit event '${e.name}' from class ${className}. ${className} can only emit: ${eventTypes}`) + } for(const listener of this.#listeners[e.name]) listener(e) } diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index 2aa14ad..5d42f5e 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -23,6 +23,7 @@ import { Expression } from "../math/index.mjs" import Latex from "./latex.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" +import Settings from "./settings.mjs" class CanvasAPI extends Module { /** @type {CanvasInterface} */ @@ -84,7 +85,7 @@ class CanvasAPI extends Module { */ get xmin() { if(!this.initialized) throw new Error("Attempting xmin before initialize!") - return this.#canvas.xmin + return Settings.xmin } /** @@ -93,7 +94,7 @@ class CanvasAPI extends Module { */ get xzoom() { if(!this.initialized) throw new Error("Attempting xzoom before initialize!") - return this.#canvas.xzoom + return Settings.xzoom } /** @@ -102,7 +103,7 @@ class CanvasAPI extends Module { */ get ymax() { if(!this.initialized) throw new Error("Attempting ymax before initialize!") - return this.#canvas.ymax + return Settings.ymax } /** @@ -111,7 +112,7 @@ class CanvasAPI extends Module { */ get yzoom() { if(!this.initialized) throw new Error("Attempting yzoom before initialize!") - return this.#canvas.yzoom + return Settings.yzoom } /** @@ -120,7 +121,7 @@ class CanvasAPI extends Module { */ get xlabel() { if(!this.initialized) throw new Error("Attempting xlabel before initialize!") - return this.#canvas.xlabel + return Settings.xlabel } /** @@ -129,7 +130,7 @@ class CanvasAPI extends Module { */ get ylabel() { if(!this.initialized) throw new Error("Attempting ylabel before initialize!") - return this.#canvas.ylabel + return Settings.ylabel } /** @@ -138,7 +139,7 @@ class CanvasAPI extends Module { */ get linewidth() { if(!this.initialized) throw new Error("Attempting linewidth before initialize!") - return this.#canvas.linewidth + return Settings.linewidth } /** @@ -147,7 +148,7 @@ class CanvasAPI extends Module { */ get textsize() { if(!this.initialized) throw new Error("Attempting textsize before initialize!") - return this.#canvas.textsize + return Settings.textsize } /** @@ -156,7 +157,7 @@ class CanvasAPI extends Module { */ get logscalex() { if(!this.initialized) throw new Error("Attempting logscalex before initialize!") - return this.#canvas.logscalex + return Settings.logscalex } /** @@ -165,7 +166,7 @@ class CanvasAPI extends Module { */ get showxgrad() { if(!this.initialized) throw new Error("Attempting showxgrad before initialize!") - return this.#canvas.showxgrad + return Settings.showxgrad } /** @@ -174,7 +175,7 @@ class CanvasAPI extends Module { */ get showygrad() { if(!this.initialized) throw new Error("Attempting showygrad before initialize!") - return this.#canvas.showygrad + return Settings.showygrad } /** @@ -237,9 +238,9 @@ class CanvasAPI extends Module { * @private */ _computeAxes() { - let exprY = new Expression(`x*(${this.#canvas.yaxisstep})`) + let exprY = new Expression(`x*(${Settings.yaxisstep})`) let y1 = exprY.execute(1) - let exprX = new Expression(`x*(${this.#canvas.xaxisstep})`) + let exprX = new Expression(`x*(${Settings.xaxisstep})`) let x1 = exprX.execute(1) this.axesSteps = { x: { diff --git a/common/src/module/index.mjs b/common/src/module/index.mjs index fe2e8d9..2530a00 100644 --- a/common/src/module/index.mjs +++ b/common/src/module/index.mjs @@ -17,6 +17,7 @@ */ import Objects from "./objects.mjs" +import Settings from "./settings.mjs" import ExprParser from "./expreval.mjs" import Latex from "./latex.mjs" import History from "./history.mjs" @@ -26,6 +27,7 @@ import Preferences from "./preferences.mjs" export default { Objects, + Settings, ExprParser, Latex, History, diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index f6e5a13..606ec4d 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -78,7 +78,7 @@ export class SettingsInterface extends Interface { showygrad = BOOLEAN } -export class CanvasInterface extends SettingsInterface { +export class CanvasInterface extends Interface { imageLoaders = OBJECT /** @type {function(string): CanvasRenderingContext2D} */ getContext = FUNCTION diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index e32f2cf..183ae01 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -20,22 +20,20 @@ import { Module } from "./common.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" import Canvas from "./canvas.mjs" +import Settings from "./settings.mjs" import { DialogInterface, RootInterface, SettingsInterface } from "./interface.mjs" class IOAPI extends Module { /** @type {RootInterface} */ #rootElement - /** @type {SettingsInterface} */ - #settings /** @type {{show: function(string)}} */ #alert constructor() { super("IO", { alert: DialogInterface, - root: RootInterface, - settings: SettingsInterface + root: RootInterface }) /** * Path of the currently opened file. Empty if no file is opened. @@ -47,13 +45,11 @@ class IOAPI extends Module { /** * Initializes module with QML elements. * @param {RootInterface} root - * @param {SettingsInterface} settings * @param {{show: function(string)}} alert */ - initialize({ root, settings, alert }) { - super.initialize({ root, settings, alert }) + initialize({ root, alert }) { + super.initialize({ root, alert }) this.#rootElement = root - this.#settings = settings this.#alert = alert } @@ -75,19 +71,19 @@ class IOAPI extends Module { } } let settings = { - "xzoom": this.#settings.xzoom, - "yzoom": this.#settings.yzoom, - "xmin": this.#settings.xmin, - "ymax": this.#settings.ymax, - "xaxisstep": this.#settings.xaxisstep, - "yaxisstep": this.#settings.yaxisstep, - "xaxislabel": this.#settings.xlabel, - "yaxislabel": this.#settings.ylabel, - "logscalex": this.#settings.logscalex, - "linewidth": this.#settings.linewidth, - "showxgrad": this.#settings.showxgrad, - "showygrad": this.#settings.showygrad, - "textsize": this.#settings.textsize, + "xzoom": Settings.xzoom, + "yzoom": Settings.yzoom, + "xmin": Settings.xmin, + "ymax": Settings.ymax, + "xaxisstep": Settings.xaxisstep, + "yaxisstep": Settings.yaxisstep, + "xaxislabel": Settings.xlabel, + "yaxislabel": Settings.ylabel, + "logscalex": Settings.logscalex, + "linewidth": Settings.linewidth, + "showxgrad": Settings.showxgrad, + "showygrad": Settings.showygrad, + "textsize": Settings.textsize, "history": History.serialize(), "width": this.#rootElement.width, "height": this.#rootElement.height, @@ -113,24 +109,24 @@ class IOAPI extends Module { if(data.hasOwnProperty("type") && data["type"] === "logplotv1") { History.clear() // Importing settings - this.#settings.saveFilename = filename - this.#settings.xzoom = parseFloat(data["xzoom"]) || 100 - this.#settings.yzoom = parseFloat(data["yzoom"]) || 10 - this.#settings.xmin = parseFloat(data["xmin"]) || 5 / 10 - this.#settings.ymax = parseFloat(data["ymax"]) || 24 - this.#settings.xaxisstep = data["xaxisstep"] || "4" - this.#settings.yaxisstep = data["yaxisstep"] || "4" - this.#settings.xlabel = data["xaxislabel"] || "" - this.#settings.ylabel = data["yaxislabel"] || "" - this.#settings.logscalex = data["logscalex"] === true + Settings.set("saveFilename", filename, false) + Settings.set("xzoom", parseFloat(data["xzoom"]) || 100, false) + Settings.set("yzoom", parseFloat(data["yzoom"]) || 10, false) + Settings.set("xmin", parseFloat(data["xmin"]) || 5 / 10, false) + Settings.set("ymax", parseFloat(data["ymax"]) || 24, false) + Settings.set("xaxisstep", data["xaxisstep"] || "4", false) + Settings.set("yaxisstep", data["yaxisstep"] || "4", false) + Settings.set("xlabel", data["xaxislabel"] || "", false) + Settings.set("ylabel", data["yaxislabel"] || "", false) + Settings.set("logscalex", data["logscalex"] === true, false) if("showxgrad" in data) - this.#settings.showxgrad = data["showxgrad"] + Settings.set("showxgrad", data["showxgrad"], false) if("showygrad" in data) - this.#settings.textsize = data["showygrad"] + Settings.set("showygrad", data["showygrad"], false) if("linewidth" in data) - this.#settings.linewidth = data["linewidth"] + Settings.set("linewidth", data["linewidth"], false) if("textsize" in data) - this.#settings.textsize = data["textsize"] + Settings.set("textsize", data["textsize"], false) this.#rootElement.height = parseFloat(data["height"]) || 500 this.#rootElement.width = parseFloat(data["width"]) || 1000 diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index 4487dde..4d79ce2 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -18,6 +18,7 @@ import { Module } from "./common.mjs" import { BaseEvent } from "../events.mjs" +import { HelperInterface } from "./interface.mjs" /** @@ -48,19 +49,20 @@ class SettingsAPI extends Module { static emits = ["changed"] #properties = new Map([ - ['xzoom', 100], - ['yzoom', 10], - ['xmin', .5], - ['ymax', 25], - ['xaxisstep', "4"], - ['yaxisstep', "4"], - ['xlabel', ""], - ['ylabel', ""], - ['linewidth', 1], - ['textsize', 18], - ['logscalex', true], - ['showxgrad', true], - ['showygrad', true], + ["saveFilename", ""], + ["xzoom", 100], + ["yzoom", 10], + ["xmin", .5], + ["ymax", 25], + ["xaxisstep", "4"], + ["yaxisstep", "4"], + ["xlabel", ""], + ["ylabel", ""], + ["linewidth", 1], + ["textsize", 18], + ["logscalex", true], + ["showxgrad", true], + ["showygrad", true] ]) constructor() { @@ -74,14 +76,14 @@ class SettingsAPI extends Module { // Initialize default values. for(const key of this.#properties.keys()) { switch(typeof this.#properties.get(key)) { - case 'boolean': - this.set(key, helper.getSettingBool(key), false) + case "boolean": + this.set(key, helper.getSettingBool("default_graph."+key), false) break - case 'number': - this.set(key, helper.getSettingInt(key), false) + case "number": + this.set(key, helper.getSettingInt("default_graph."+key), false) break - case 'string': - this.set(key, helper.getSetting(key), false) + case "string": + this.set(key, helper.getSetting("default_graph."+key), false) break } } @@ -89,16 +91,20 @@ class SettingsAPI extends Module { /** * Sets a setting to a given value - * - * @param {boolean} byUser - Set to true if the user is at the origin of this change. + * + * @param {string} property + * @param {string|number|boolean} value + * @param {boolean} byUser - Set to true if the user is at the origin of this change. */ set(property, value, byUser) { - if(!this.#properties.has(property)) + if(!this.#properties.has(property)) { throw new Error(`Property ${property} is not a setting.`) + } const oldValue = this.#properties.get(property) + console.debug("Setting", property, "from", oldValue, "to", value, `(${typeof value}, ${byUser})`) const propType = typeof oldValue if(propType !== typeof value) - throw new Error(`Value of ${property} must be a ${propType}.`) + throw new Error(`Value of ${property} must be a ${propType} (${typeof value} provided).`) this.#properties.set(property, value) this.emit(new ChangedEvent(property, oldValue, value, byUser === true)) } @@ -107,67 +113,70 @@ class SettingsAPI extends Module { * Zoom on the x axis of the diagram. * @returns {number} */ - get xzoom() { return this.#properties.get("xzoom"); } + get xzoom() { return this.#properties.get("xzoom") } /** * Zoom on the y axis of the diagram. * @returns {number} */ - get yzoom() { return this.#properties.get("yzoom"); } + get yzoom() { return this.#properties.get("yzoom") } /** * Minimum x of the diagram. * @returns {number} */ - get xmin() { return this.#properties.get("xmin"); } + get xmin() { return this.#properties.get("xmin") } /** * Maximum y of the diagram. * @returns {number} */ - get ymax() { return this.#properties.get("ymax"); } + get ymax() { return this.#properties.get("ymax") } /** * Step of the x axis graduation (expression). * @note Only available in non-logarithmic mode. * @returns {string} */ - get xaxisstep() { return this.#properties.get("xaxisstep"); } + get xaxisstep() { return this.#properties.get("xaxisstep") } /** * Step of the y axis graduation (expression). * @returns {string} */ - get yaxisstep() { return this.#properties.get("yaxisstep"); } + get yaxisstep() { return this.#properties.get("yaxisstep") } /** * Label used on the x axis. * @returns {string} */ - get xlabel() { return this.#properties.get("xlabel"); } + get xlabel() { return this.#properties.get("xlabel") } /** * Label used on the y axis. * @returns {string} */ - get ylabel() { return this.#properties.get("ylabel"); } + get ylabel() { return this.#properties.get("ylabel") } /** * Width of lines that will be drawn into the canvas. * @returns {number} */ - get linewidth() { return this.#properties.get("linewidth"); } + get linewidth() { return this.#properties.get("linewidth") } /** * Font size of the text that will be drawn into the canvas. * @returns {number} */ - get textsize() { return this.#properties.get("textsize"); } + get textsize() { return this.#properties.get("textsize") } /** * true if the canvas should be in logarithmic mode, false otherwise. * @returns {boolean} */ - get logscalex() { return this.#properties.get("logscalex"); } + get logscalex() { return this.#properties.get("logscalex") } /** * true if the x graduation should be shown, false otherwise. * @returns {boolean} */ - get showxgrad() { return this.#properties.get("showxgrad"); } + get showxgrad() { return this.#properties.get("showxgrad") } /** * true if the y graduation should be shown, false otherwise. * @returns {boolean} */ - get showygrad() { return this.#properties.get("showygrad"); } - + get showygrad() { return this.#properties.get("showygrad") } } + +Modules.Settings = Modules.Settings || new SettingsAPI() +export default Modules.Settings + diff --git a/common/src/utils.mjs b/common/src/utils.mjs index 4f6b0c5..094147d 100644 --- a/common/src/utils.mjs +++ b/common/src/utils.mjs @@ -35,6 +35,19 @@ String.prototype.removeEnclosure = function() { return this.substring(1, this.length - 1) } +/** + * Rounds to a certain number of decimal places. + * From https://stackoverflow.com/a/48764436 + * + * @param {number} decimalPlaces + * @return {number} + */ +Number.prototype.toDecimalPrecision = function(decimalPlaces = 0) { + const p = Math.pow(10, decimalPlaces); + const n = (this * p) * (1 + Number.EPSILON); + return Math.round(n) / p; +} + const powerpos = { "-": "⁻", "+": "⁺", diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 38d05be..07b6002 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -30,104 +30,15 @@ import Qt.labs.platform as Native */ Canvas { id: canvas - anchors.top: separator.bottom + anchors.top: parent.top anchors.left: parent.left height: parent.height - 90 width: parent.width - - /*! - \qmlproperty double LogGraphCanvas::xmin - Minimum x of the diagram, provided from settings. - \sa Settings - */ - property double xmin: 0 - /*! - \qmlproperty double LogGraphCanvas::ymax - Maximum y of the diagram, provided from settings. - \sa Settings - */ - property double ymax: 0 - /*! - \qmlproperty double LogGraphCanvas::xzoom - Zoom on the x axis of the diagram, provided from settings. - \sa Settings - */ - property double xzoom: 10 - /*! - \qmlproperty double LogGraphCanvas::yzoom - Zoom on the y axis of the diagram, provided from settings. - \sa Settings - */ - property double yzoom: 10 - /*! - \qmlproperty string LogGraphCanvas::xaxisstep - Step of the x axis graduation, provided from settings. - \note: Only available in non-logarithmic mode. - \sa Settings - */ - property string xaxisstep: "4" - /*! - \qmlproperty string LogGraphCanvas::yaxisstep - Step of the y axis graduation, provided from settings. - \sa Settings - */ - property string yaxisstep: "4" - /*! - \qmlproperty string LogGraphCanvas::xlabel - Label used on the x axis, provided from settings. - \sa Settings - */ - property string xlabel: "" - /*! - \qmlproperty string LogGraphCanvas::ylabel - Label used on the y axis, provided from settings. - \sa Settings - */ - property string ylabel: "" - /*! - \qmlproperty double LogGraphCanvas::linewidth - Width of lines that will be drawn into the canvas, provided from settings. - \sa Settings - */ - property double linewidth: 1 - /*! - \qmlproperty double LogGraphCanvas::textsize - Font size of the text that will be drawn into the canvas, provided from settings. - \sa Settings - */ - property double textsize: 14 - /*! - \qmlproperty bool LogGraphCanvas::logscalex - true if the canvas should be in logarithmic mode, false otherwise. - Provided from settings. - \sa Settings - */ - property bool logscalex: false - /*! - \qmlproperty bool LogGraphCanvas::showxgrad - true if the x graduation should be shown, false otherwise. - Provided from settings. - \sa Settings - */ - property bool showxgrad: false - /*! - \qmlproperty bool LogGraphCanvas::showygrad - true if the y graduation should be shown, false otherwise. - Provided from settings. - \sa Settings - */ - property bool showygrad: false - /*! \qmlproperty var LogGraphCanvas::imageLoaders Dictionary of format {image: [callback.image data]} containing data for defered image loading. */ property var imageLoaders: {} - /*! - \qmlproperty var LogGraphCanvas::ctx - Cache for the 2D context so that it may be used asynchronously. - */ - property var ctx Component.onCompleted: { imageLoaders = {} @@ -155,7 +66,7 @@ Canvas { Object.keys(imageLoaders).forEach((key) => { if(isImageLoaded(key)) { // Calling callback - imageLoaders[key][0](canvas, ctx, imageLoaders[key][1]) + imageLoaders[key][0](imageLoaders[key][1]) delete imageLoaders[key] } }) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 8545153..d6b2c3f 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -145,20 +145,6 @@ ApplicationWindow { width: sidebar.inPortrait ? parent.width : parent.width - sidebar.width//*sidebar.position x: sidebar.width//*sidebar.position - xmin: settings.xmin - ymax: settings.ymax - xzoom: settings.xzoom - yzoom: settings.yzoom - xlabel: settings.xlabel - ylabel: settings.ylabel - yaxisstep: settings.yaxisstep - xaxisstep: settings.xaxisstep - logscalex: settings.logscalex - linewidth: settings.linewidth - textsize: settings.textsize - showxgrad: settings.showxgrad - showygrad: settings.showygrad - property bool firstDrawDone: false onPainted: if(!firstDrawDone) { diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index afa3e09..a0c030a 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -175,17 +175,17 @@ Item { Icon { id: iconLabel anchors.top: parent.top - anchors.topMargin: icon == "" ? 0 : 3 - source: control.visible && icon != "" ? "../icons/" + control.icon : "" + anchors.topMargin: parent.icon == "" ? 0 : 3 + source: control.visible && parent.icon != "" ? "../icons/" + control.icon : "" width: height - height: icon == "" || !visible ? 0 : 24 + height: parent.icon == "" || !visible ? 0 : 24 color: sysPalette.windowText } Label { id: labelItem anchors.left: iconLabel.right - anchors.leftMargin: icon == "" ? 0 : 5 + anchors.leftMargin: parent.icon == "" ? 0 : 5 anchors.top: parent.top height: parent.height width: Math.max(85, implicitWidth) @@ -231,8 +231,8 @@ Item { onEditingFinished: { if(insertButton.focus || insertPopup.focus) return let value = text - if(value != "" && value.toString() != defValue) { - let expr = parse(value) + if(value != "" && value.toString() != parent.defValue) { + let expr = parent.parse(value) if(expr != null) { control.changed(expr) defValue = expr.toEditableString() @@ -280,10 +280,10 @@ Item { acPopupContent.itemSelected = 0 - if(event.text in openAndCloseMatches && autoClosing) { + if(event.text in parent.openAndCloseMatches && autoClosing) { let start = selectionStart insert(selectionStart, event.text) - insert(selectionEnd, openAndCloseMatches[event.text]) + insert(selectionEnd, parent.openAndCloseMatches[event.text]) cursorPosition = start+1 event.accepted = true } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index e8514d4..7a7072b 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -17,8 +17,6 @@ */ import QtQuick -import QtQuick.Controls -import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! \qmltype ViewPositionChangeOverlay @@ -81,7 +79,7 @@ Item { property int prevY /*! \qmlproperty double ViewPositionChangeOverlay::baseZoomMultiplier - How much should the zoom be mutliplied/scrolled by for one scroll step (120° on the mouse wheel). + How much should the zoom be multiplied/scrolled by for one scroll step (120° on the mouse wheel). */ property double baseZoomMultiplier: 0.1 @@ -91,15 +89,15 @@ Item { cursorShape: pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor property int positionChangeTimer: 0 - function updatePosition(deltaX, deltaY) { + function updatePosition(deltaX, deltaY, isEnd) { const unauthorized = [NaN, Infinity, -Infinity] - const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(settingsInstance.xmin)-deltaX)) - const ymax = settingsInstance.ymax + deltaY/canvas.yzoom + const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(Modules.Settings.xmin)-deltaX)) + const ymax = Modules.Settings.ymax + deltaY/Modules.Settings.yzoom if(!unauthorized.includes(xmin)) - settingsInstance.xmin = xmin + Modules.Settings.set("xmin", xmin, isEnd) if(!unauthorized.includes(ymax)) - settingsInstance.ymax = ymax.toFixed(4) - settingsInstance.changed() + Modules.Settings.set("ymax", ymax.toDecimalPrecision(6), isEnd) + Modules.Canvas.requestPaint() parent.positionChanged(deltaX, deltaY) } @@ -113,9 +111,9 @@ Item { onPositionChanged: function(mouse) { positionChangeTimer++ if(positionChangeTimer == 3) { - let deltaX = mouse.x - prevX - let deltaY = mouse.y - prevY - updatePosition(deltaX, deltaY) + let deltaX = mouse.x - parent.prevX + let deltaY = mouse.y - parent.prevY + updatePosition(deltaX, deltaY, false) prevX = mouse.x prevY = mouse.y positionChangeTimer = 0 @@ -123,35 +121,35 @@ Item { } onReleased: function(mouse) { - let deltaX = mouse.x - prevX - let deltaY = mouse.y - prevY - updatePosition(deltaX, deltaY) + let deltaX = mouse.x - parent.prevX + let deltaY = mouse.y - parent.prevY + updatePosition(deltaX, deltaY, true) parent.endPositionChange(deltaX, deltaY) } onWheel: function(wheel) { // Scrolling let scrollSteps = Math.round(wheel.angleDelta.y / 120) - let zoomMultiplier = Math.pow(1+baseZoomMultiplier, Math.abs(scrollSteps)) + let zoomMultiplier = Math.pow(1+parent.baseZoomMultiplier, Math.abs(scrollSteps)) // Avoid floating-point rounding errors by removing the zoom *after* - let xZoomDelta = (settingsInstance.xzoom*zoomMultiplier - settingsInstance.xzoom) - let yZoomDelta = (settingsInstance.yzoom*zoomMultiplier - settingsInstance.yzoom) + let xZoomDelta = (Modules.Settings.xzoom*zoomMultiplier - Modules.Settings.xzoom) + let yZoomDelta = (Modules.Settings.yzoom*zoomMultiplier - Modules.Settings.yzoom) if(scrollSteps < 0) { // Negative scroll xZoomDelta *= -1 yZoomDelta *= -1 } - let newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(0) - let newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(0) + let newXZoom = (Modules.Settings.xzoom+xZoomDelta).toDecimalPrecision(0) + let newYZoom = (Modules.Settings.yzoom+yZoomDelta).toDecimalPrecision(0) // Check if we need to have more precision if(newXZoom < 10) - newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(4) + newXZoom = (Modules.Settings.xzoom+xZoomDelta).toDecimalPrecision(4) if(newYZoom < 10) - newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(4) + newYZoom = (Modules.Settings.yzoom+yZoomDelta).toDecimalPrecision(4) if(newXZoom > 0.5) - settingsInstance.xzoom = newXZoom + Modules.Settings.set("xzoom", newXZoom) if(newYZoom > 0.5) - settingsInstance.yzoom = newYZoom - settingsInstance.changed() + Modules.Settings.set("yzoom", newYZoom) + Modules.Canvas.requestPaint() } } }