Switching a lot of stuff to new Settings module

+ Fixing a bug that did not load the showygrad setting properly.
This commit is contained in:
Ad5001 2024-10-10 19:15:46 +02:00
parent f4920aadb6
commit d1ac70a946
Signed by: Ad5001
GPG key ID: EF45F9C6AFE20160
11 changed files with 148 additions and 229 deletions

View file

@ -38,7 +38,7 @@ export class BaseEvent {
export class BaseEventEmitter { export class BaseEventEmitter {
static emits = [] static emits = []
/** @type {Record<string, function[]>} */ /** @type {Record<string, Set<function>>} */
#listeners = {} #listeners = {}
constructor() { constructor() {
@ -54,7 +54,7 @@ export class BaseEventEmitter {
* @param {function(BaseEvent)} eventListener - The function to be called back when the event is emitted. * @param {function(BaseEvent)} eventListener - The function to be called back when the event is emitted.
*/ */
addEventListener(eventType, eventListener) { addEventListener(eventType, eventListener) {
if(!this.emits.includes(eventType)) { if(!this.constructor.emits.includes(eventType)) {
const className = this.constructor.name const className = this.constructor.name
const eventTypes = this.constructor.emits.join(", ") const eventTypes = this.constructor.emits.join(", ")
throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) 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. * @returns {boolean} True if the listener was removed, false if it was not found.
*/ */
removeEventListener(eventType, eventListener) { removeEventListener(eventType, eventListener) {
if(!this.emits.includes(eventType)) { if(!this.constructor.emits.includes(eventType)) {
const className = this.constructor.name const className = this.constructor.name
const eventTypes = this.constructor.emits.join(", ") const eventTypes = this.constructor.emits.join(", ")
throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) 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) { emit(e) {
if(!(e instanceof BaseEvent)) if(!(e instanceof BaseEvent))
throw new Error("Cannot emit non event object.") throw new Error("Cannot emit non event object.")
if(!this.emits.includes(e.name)) if(!this.constructor.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(", ")}.`) 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]) for(const listener of this.#listeners[e.name])
listener(e) listener(e)
} }

View file

@ -23,6 +23,7 @@ import { Expression } from "../math/index.mjs"
import Latex from "./latex.mjs" import Latex from "./latex.mjs"
import Objects from "./objects.mjs" import Objects from "./objects.mjs"
import History from "./history.mjs" import History from "./history.mjs"
import Settings from "./settings.mjs"
class CanvasAPI extends Module { class CanvasAPI extends Module {
/** @type {CanvasInterface} */ /** @type {CanvasInterface} */
@ -84,7 +85,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 Settings.xmin
} }
/** /**
@ -93,7 +94,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 Settings.xzoom
} }
/** /**
@ -102,7 +103,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 Settings.ymax
} }
/** /**
@ -111,7 +112,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 Settings.yzoom
} }
/** /**
@ -120,7 +121,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 Settings.xlabel
} }
/** /**
@ -129,7 +130,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 Settings.ylabel
} }
/** /**
@ -138,7 +139,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 Settings.linewidth
} }
/** /**
@ -147,7 +148,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 Settings.textsize
} }
/** /**
@ -156,7 +157,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 Settings.logscalex
} }
/** /**
@ -165,7 +166,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 Settings.showxgrad
} }
/** /**
@ -174,7 +175,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 Settings.showygrad
} }
/** /**
@ -237,9 +238,9 @@ class CanvasAPI extends Module {
* @private * @private
*/ */
_computeAxes() { _computeAxes() {
let exprY = new Expression(`x*(${this.#canvas.yaxisstep})`) let exprY = new Expression(`x*(${Settings.yaxisstep})`)
let y1 = exprY.execute(1) 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) let x1 = exprX.execute(1)
this.axesSteps = { this.axesSteps = {
x: { x: {

View file

@ -17,6 +17,7 @@
*/ */
import Objects from "./objects.mjs" import Objects from "./objects.mjs"
import Settings from "./settings.mjs"
import ExprParser from "./expreval.mjs" import ExprParser from "./expreval.mjs"
import Latex from "./latex.mjs" import Latex from "./latex.mjs"
import History from "./history.mjs" import History from "./history.mjs"
@ -26,6 +27,7 @@ import Preferences from "./preferences.mjs"
export default { export default {
Objects, Objects,
Settings,
ExprParser, ExprParser,
Latex, Latex,
History, History,

View file

@ -78,7 +78,7 @@ export class SettingsInterface extends Interface {
showygrad = BOOLEAN showygrad = BOOLEAN
} }
export class CanvasInterface extends SettingsInterface { export class CanvasInterface extends Interface {
imageLoaders = OBJECT imageLoaders = OBJECT
/** @type {function(string): CanvasRenderingContext2D} */ /** @type {function(string): CanvasRenderingContext2D} */
getContext = FUNCTION getContext = FUNCTION

View file

@ -20,22 +20,20 @@ import { Module } from "./common.mjs"
import Objects from "./objects.mjs" import Objects from "./objects.mjs"
import History from "./history.mjs" import History from "./history.mjs"
import Canvas from "./canvas.mjs" import Canvas from "./canvas.mjs"
import Settings from "./settings.mjs"
import { DialogInterface, RootInterface, SettingsInterface } from "./interface.mjs" import { DialogInterface, RootInterface, SettingsInterface } from "./interface.mjs"
class IOAPI extends Module { class IOAPI extends Module {
/** @type {RootInterface} */ /** @type {RootInterface} */
#rootElement #rootElement
/** @type {SettingsInterface} */
#settings
/** @type {{show: function(string)}} */ /** @type {{show: function(string)}} */
#alert #alert
constructor() { constructor() {
super("IO", { super("IO", {
alert: DialogInterface, alert: DialogInterface,
root: RootInterface, root: RootInterface
settings: SettingsInterface
}) })
/** /**
* Path of the currently opened file. Empty if no file is opened. * 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. * Initializes module with QML elements.
* @param {RootInterface} root * @param {RootInterface} root
* @param {SettingsInterface} settings
* @param {{show: function(string)}} alert * @param {{show: function(string)}} alert
*/ */
initialize({ root, settings, alert }) { initialize({ root, alert }) {
super.initialize({ root, settings, alert }) super.initialize({ root, alert })
this.#rootElement = root this.#rootElement = root
this.#settings = settings
this.#alert = alert this.#alert = alert
} }
@ -75,19 +71,19 @@ class IOAPI extends Module {
} }
} }
let settings = { let settings = {
"xzoom": this.#settings.xzoom, "xzoom": Settings.xzoom,
"yzoom": this.#settings.yzoom, "yzoom": Settings.yzoom,
"xmin": this.#settings.xmin, "xmin": Settings.xmin,
"ymax": this.#settings.ymax, "ymax": Settings.ymax,
"xaxisstep": this.#settings.xaxisstep, "xaxisstep": Settings.xaxisstep,
"yaxisstep": this.#settings.yaxisstep, "yaxisstep": Settings.yaxisstep,
"xaxislabel": this.#settings.xlabel, "xaxislabel": Settings.xlabel,
"yaxislabel": this.#settings.ylabel, "yaxislabel": Settings.ylabel,
"logscalex": this.#settings.logscalex, "logscalex": Settings.logscalex,
"linewidth": this.#settings.linewidth, "linewidth": Settings.linewidth,
"showxgrad": this.#settings.showxgrad, "showxgrad": Settings.showxgrad,
"showygrad": this.#settings.showygrad, "showygrad": Settings.showygrad,
"textsize": this.#settings.textsize, "textsize": Settings.textsize,
"history": History.serialize(), "history": History.serialize(),
"width": this.#rootElement.width, "width": this.#rootElement.width,
"height": this.#rootElement.height, "height": this.#rootElement.height,
@ -113,24 +109,24 @@ class IOAPI extends Module {
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 Settings.set("saveFilename", filename, false)
this.#settings.xzoom = parseFloat(data["xzoom"]) || 100 Settings.set("xzoom", parseFloat(data["xzoom"]) || 100, false)
this.#settings.yzoom = parseFloat(data["yzoom"]) || 10 Settings.set("yzoom", parseFloat(data["yzoom"]) || 10, false)
this.#settings.xmin = parseFloat(data["xmin"]) || 5 / 10 Settings.set("xmin", parseFloat(data["xmin"]) || 5 / 10, false)
this.#settings.ymax = parseFloat(data["ymax"]) || 24 Settings.set("ymax", parseFloat(data["ymax"]) || 24, false)
this.#settings.xaxisstep = data["xaxisstep"] || "4" Settings.set("xaxisstep", data["xaxisstep"] || "4", false)
this.#settings.yaxisstep = data["yaxisstep"] || "4" Settings.set("yaxisstep", data["yaxisstep"] || "4", false)
this.#settings.xlabel = data["xaxislabel"] || "" Settings.set("xlabel", data["xaxislabel"] || "", false)
this.#settings.ylabel = data["yaxislabel"] || "" Settings.set("ylabel", data["yaxislabel"] || "", false)
this.#settings.logscalex = data["logscalex"] === true Settings.set("logscalex", data["logscalex"] === true, false)
if("showxgrad" in data) if("showxgrad" in data)
this.#settings.showxgrad = data["showxgrad"] Settings.set("showxgrad", data["showxgrad"], false)
if("showygrad" in data) if("showygrad" in data)
this.#settings.textsize = data["showygrad"] Settings.set("showygrad", data["showygrad"], false)
if("linewidth" in data) if("linewidth" in data)
this.#settings.linewidth = data["linewidth"] Settings.set("linewidth", data["linewidth"], false)
if("textsize" in data) if("textsize" in data)
this.#settings.textsize = data["textsize"] Settings.set("textsize", data["textsize"], false)
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

View file

@ -18,6 +18,7 @@
import { Module } from "./common.mjs" import { Module } from "./common.mjs"
import { BaseEvent } from "../events.mjs" import { BaseEvent } from "../events.mjs"
import { HelperInterface } from "./interface.mjs"
/** /**
@ -48,19 +49,20 @@ class SettingsAPI extends Module {
static emits = ["changed"] static emits = ["changed"]
#properties = new Map([ #properties = new Map([
['xzoom', 100], ["saveFilename", ""],
['yzoom', 10], ["xzoom", 100],
['xmin', .5], ["yzoom", 10],
['ymax', 25], ["xmin", .5],
['xaxisstep', "4"], ["ymax", 25],
['yaxisstep', "4"], ["xaxisstep", "4"],
['xlabel', ""], ["yaxisstep", "4"],
['ylabel', ""], ["xlabel", ""],
['linewidth', 1], ["ylabel", ""],
['textsize', 18], ["linewidth", 1],
['logscalex', true], ["textsize", 18],
['showxgrad', true], ["logscalex", true],
['showygrad', true], ["showxgrad", true],
["showygrad", true]
]) ])
constructor() { constructor() {
@ -74,14 +76,14 @@ class SettingsAPI extends Module {
// Initialize default values. // Initialize default values.
for(const key of this.#properties.keys()) { for(const key of this.#properties.keys()) {
switch(typeof this.#properties.get(key)) { switch(typeof this.#properties.get(key)) {
case 'boolean': case "boolean":
this.set(key, helper.getSettingBool(key), false) this.set(key, helper.getSettingBool("default_graph."+key), false)
break break
case 'number': case "number":
this.set(key, helper.getSettingInt(key), false) this.set(key, helper.getSettingInt("default_graph."+key), false)
break break
case 'string': case "string":
this.set(key, helper.getSetting(key), false) this.set(key, helper.getSetting("default_graph."+key), false)
break break
} }
} }
@ -89,16 +91,20 @@ class SettingsAPI extends Module {
/** /**
* Sets a setting to a given value * 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) { set(property, value, byUser) {
if(!this.#properties.has(property)) if(!this.#properties.has(property)) {
throw new Error(`Property ${property} is not a setting.`) throw new Error(`Property ${property} is not a setting.`)
}
const oldValue = this.#properties.get(property) const oldValue = this.#properties.get(property)
console.debug("Setting", property, "from", oldValue, "to", value, `(${typeof value}, ${byUser})`)
const propType = typeof oldValue const propType = typeof oldValue
if(propType !== typeof value) 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.#properties.set(property, value)
this.emit(new ChangedEvent(property, oldValue, value, byUser === true)) 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. * Zoom on the x axis of the diagram.
* @returns {number} * @returns {number}
*/ */
get xzoom() { return this.#properties.get("xzoom"); } get xzoom() { return this.#properties.get("xzoom") }
/** /**
* Zoom on the y axis of the diagram. * Zoom on the y axis of the diagram.
* @returns {number} * @returns {number}
*/ */
get yzoom() { return this.#properties.get("yzoom"); } get yzoom() { return this.#properties.get("yzoom") }
/** /**
* Minimum x of the diagram. * Minimum x of the diagram.
* @returns {number} * @returns {number}
*/ */
get xmin() { return this.#properties.get("xmin"); } get xmin() { return this.#properties.get("xmin") }
/** /**
* Maximum y of the diagram. * Maximum y of the diagram.
* @returns {number} * @returns {number}
*/ */
get ymax() { return this.#properties.get("ymax"); } get ymax() { return this.#properties.get("ymax") }
/** /**
* Step of the x axis graduation (expression). * Step of the x axis graduation (expression).
* @note Only available in non-logarithmic mode. * @note Only available in non-logarithmic mode.
* @returns {string} * @returns {string}
*/ */
get xaxisstep() { return this.#properties.get("xaxisstep"); } get xaxisstep() { return this.#properties.get("xaxisstep") }
/** /**
* Step of the y axis graduation (expression). * Step of the y axis graduation (expression).
* @returns {string} * @returns {string}
*/ */
get yaxisstep() { return this.#properties.get("yaxisstep"); } get yaxisstep() { return this.#properties.get("yaxisstep") }
/** /**
* Label used on the x axis. * Label used on the x axis.
* @returns {string} * @returns {string}
*/ */
get xlabel() { return this.#properties.get("xlabel"); } get xlabel() { return this.#properties.get("xlabel") }
/** /**
* Label used on the y axis. * Label used on the y axis.
* @returns {string} * @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. * Width of lines that will be drawn into the canvas.
* @returns {number} * @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. * Font size of the text that will be drawn into the canvas.
* @returns {number} * @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. * true if the canvas should be in logarithmic mode, false otherwise.
* @returns {boolean} * @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. * true if the x graduation should be shown, false otherwise.
* @returns {boolean} * @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. * true if the y graduation should be shown, false otherwise.
* @returns {boolean} * @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

View file

@ -35,6 +35,19 @@ String.prototype.removeEnclosure = function() {
return this.substring(1, this.length - 1) 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 = { const powerpos = {
"-": "⁻", "-": "⁻",
"+": "⁺", "+": "⁺",

View file

@ -30,104 +30,15 @@ import Qt.labs.platform as Native
*/ */
Canvas { Canvas {
id: canvas id: canvas
anchors.top: separator.bottom anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
height: parent.height - 90 height: parent.height - 90
width: parent.width 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 \qmlproperty var LogGraphCanvas::imageLoaders
Dictionary of format {image: [callback.image data]} containing data for defered image loading. Dictionary of format {image: [callback.image data]} containing data for defered image loading.
*/ */
property var imageLoaders: {} property var imageLoaders: {}
/*!
\qmlproperty var LogGraphCanvas::ctx
Cache for the 2D context so that it may be used asynchronously.
*/
property var ctx
Component.onCompleted: { Component.onCompleted: {
imageLoaders = {} imageLoaders = {}
@ -155,7 +66,7 @@ Canvas {
Object.keys(imageLoaders).forEach((key) => { Object.keys(imageLoaders).forEach((key) => {
if(isImageLoaded(key)) { if(isImageLoaded(key)) {
// Calling callback // Calling callback
imageLoaders[key][0](canvas, ctx, imageLoaders[key][1]) imageLoaders[key][0](imageLoaders[key][1])
delete imageLoaders[key] delete imageLoaders[key]
} }
}) })

View file

@ -145,20 +145,6 @@ ApplicationWindow {
width: sidebar.inPortrait ? parent.width : parent.width - sidebar.width//*sidebar.position width: sidebar.inPortrait ? parent.width : parent.width - sidebar.width//*sidebar.position
x: 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 property bool firstDrawDone: false
onPainted: if(!firstDrawDone) { onPainted: if(!firstDrawDone) {

View file

@ -175,17 +175,17 @@ Item {
Icon { Icon {
id: iconLabel id: iconLabel
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: icon == "" ? 0 : 3 anchors.topMargin: parent.icon == "" ? 0 : 3
source: control.visible && icon != "" ? "../icons/" + control.icon : "" source: control.visible && parent.icon != "" ? "../icons/" + control.icon : ""
width: height width: height
height: icon == "" || !visible ? 0 : 24 height: parent.icon == "" || !visible ? 0 : 24
color: sysPalette.windowText color: sysPalette.windowText
} }
Label { Label {
id: labelItem id: labelItem
anchors.left: iconLabel.right anchors.left: iconLabel.right
anchors.leftMargin: icon == "" ? 0 : 5 anchors.leftMargin: parent.icon == "" ? 0 : 5
anchors.top: parent.top anchors.top: parent.top
height: parent.height height: parent.height
width: Math.max(85, implicitWidth) width: Math.max(85, implicitWidth)
@ -231,8 +231,8 @@ Item {
onEditingFinished: { onEditingFinished: {
if(insertButton.focus || insertPopup.focus) return if(insertButton.focus || insertPopup.focus) return
let value = text let value = text
if(value != "" && value.toString() != defValue) { if(value != "" && value.toString() != parent.defValue) {
let expr = parse(value) let expr = parent.parse(value)
if(expr != null) { if(expr != null) {
control.changed(expr) control.changed(expr)
defValue = expr.toEditableString() defValue = expr.toEditableString()
@ -280,10 +280,10 @@ Item {
acPopupContent.itemSelected = 0 acPopupContent.itemSelected = 0
if(event.text in openAndCloseMatches && autoClosing) { if(event.text in parent.openAndCloseMatches && autoClosing) {
let start = selectionStart let start = selectionStart
insert(selectionStart, event.text) insert(selectionStart, event.text)
insert(selectionEnd, openAndCloseMatches[event.text]) insert(selectionEnd, parent.openAndCloseMatches[event.text])
cursorPosition = start+1 cursorPosition = start+1
event.accepted = true event.accepted = true
} }

View file

@ -17,8 +17,6 @@
*/ */
import QtQuick import QtQuick
import QtQuick.Controls
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
/*! /*!
\qmltype ViewPositionChangeOverlay \qmltype ViewPositionChangeOverlay
@ -81,7 +79,7 @@ Item {
property int prevY property int prevY
/*! /*!
\qmlproperty double ViewPositionChangeOverlay::baseZoomMultiplier \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 property double baseZoomMultiplier: 0.1
@ -91,15 +89,15 @@ Item {
cursorShape: pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor cursorShape: pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor
property int positionChangeTimer: 0 property int positionChangeTimer: 0
function updatePosition(deltaX, deltaY) { function updatePosition(deltaX, deltaY, isEnd) {
const unauthorized = [NaN, Infinity, -Infinity] const unauthorized = [NaN, Infinity, -Infinity]
const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(settingsInstance.xmin)-deltaX)) const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(Modules.Settings.xmin)-deltaX))
const ymax = settingsInstance.ymax + deltaY/canvas.yzoom const ymax = Modules.Settings.ymax + deltaY/Modules.Settings.yzoom
if(!unauthorized.includes(xmin)) if(!unauthorized.includes(xmin))
settingsInstance.xmin = xmin Modules.Settings.set("xmin", xmin, isEnd)
if(!unauthorized.includes(ymax)) if(!unauthorized.includes(ymax))
settingsInstance.ymax = ymax.toFixed(4) Modules.Settings.set("ymax", ymax.toDecimalPrecision(6), isEnd)
settingsInstance.changed() Modules.Canvas.requestPaint()
parent.positionChanged(deltaX, deltaY) parent.positionChanged(deltaX, deltaY)
} }
@ -113,9 +111,9 @@ Item {
onPositionChanged: function(mouse) { onPositionChanged: function(mouse) {
positionChangeTimer++ positionChangeTimer++
if(positionChangeTimer == 3) { if(positionChangeTimer == 3) {
let deltaX = mouse.x - prevX let deltaX = mouse.x - parent.prevX
let deltaY = mouse.y - prevY let deltaY = mouse.y - parent.prevY
updatePosition(deltaX, deltaY) updatePosition(deltaX, deltaY, false)
prevX = mouse.x prevX = mouse.x
prevY = mouse.y prevY = mouse.y
positionChangeTimer = 0 positionChangeTimer = 0
@ -123,35 +121,35 @@ Item {
} }
onReleased: function(mouse) { onReleased: function(mouse) {
let deltaX = mouse.x - prevX let deltaX = mouse.x - parent.prevX
let deltaY = mouse.y - prevY let deltaY = mouse.y - parent.prevY
updatePosition(deltaX, deltaY) updatePosition(deltaX, deltaY, true)
parent.endPositionChange(deltaX, deltaY) parent.endPositionChange(deltaX, deltaY)
} }
onWheel: function(wheel) { onWheel: function(wheel) {
// Scrolling // Scrolling
let scrollSteps = Math.round(wheel.angleDelta.y / 120) 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* // Avoid floating-point rounding errors by removing the zoom *after*
let xZoomDelta = (settingsInstance.xzoom*zoomMultiplier - settingsInstance.xzoom) let xZoomDelta = (Modules.Settings.xzoom*zoomMultiplier - Modules.Settings.xzoom)
let yZoomDelta = (settingsInstance.yzoom*zoomMultiplier - settingsInstance.yzoom) let yZoomDelta = (Modules.Settings.yzoom*zoomMultiplier - Modules.Settings.yzoom)
if(scrollSteps < 0) { // Negative scroll if(scrollSteps < 0) { // Negative scroll
xZoomDelta *= -1 xZoomDelta *= -1
yZoomDelta *= -1 yZoomDelta *= -1
} }
let newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(0) let newXZoom = (Modules.Settings.xzoom+xZoomDelta).toDecimalPrecision(0)
let newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(0) let newYZoom = (Modules.Settings.yzoom+yZoomDelta).toDecimalPrecision(0)
// Check if we need to have more precision // Check if we need to have more precision
if(newXZoom < 10) if(newXZoom < 10)
newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(4) newXZoom = (Modules.Settings.xzoom+xZoomDelta).toDecimalPrecision(4)
if(newYZoom < 10) if(newYZoom < 10)
newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(4) newYZoom = (Modules.Settings.yzoom+yZoomDelta).toDecimalPrecision(4)
if(newXZoom > 0.5) if(newXZoom > 0.5)
settingsInstance.xzoom = newXZoom Modules.Settings.set("xzoom", newXZoom)
if(newYZoom > 0.5) if(newYZoom > 0.5)
settingsInstance.yzoom = newYZoom Modules.Settings.set("yzoom", newYZoom)
settingsInstance.changed() Modules.Canvas.requestPaint()
} }
} }
} }