Compare commits
4 commits
8da10497d2
...
727dda2623
Author | SHA1 | Date | |
---|---|---|---|
727dda2623 | |||
27c9fe0473 | |||
e6de739d0c | |||
f52ee65c56 |
31 changed files with 246 additions and 73 deletions
|
@ -22,7 +22,7 @@ import { babel } from "@rollup/plugin-babel"
|
||||||
import cleanup from "rollup-plugin-cleanup"
|
import cleanup from "rollup-plugin-cleanup"
|
||||||
|
|
||||||
const src = "./src/index.mjs"
|
const src = "./src/index.mjs"
|
||||||
const dest = "../build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs"
|
const dest = "../build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/index.mjs"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input: src,
|
input: src,
|
||||||
|
|
|
@ -95,11 +95,15 @@ export class Action {
|
||||||
if(!Latex.enabled)
|
if(!Latex.enabled)
|
||||||
throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.")
|
throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.")
|
||||||
const imgDepth = History.imageDepth
|
const imgDepth = History.imageDepth
|
||||||
const { source, width, height } = await Latex.requestAsyncRender(
|
const renderArguments = [
|
||||||
latexString,
|
latexString,
|
||||||
imgDepth * (History.fontSize + 2),
|
imgDepth * (History.fontSize + 2),
|
||||||
History.themeTextColor
|
History.themeTextColor
|
||||||
)
|
]
|
||||||
|
let render = Latex.findPrerendered(...renderArguments)
|
||||||
|
if(render === null)
|
||||||
|
render = await Latex.requestAsyncRender(...renderArguments)
|
||||||
|
const { source, width, height } = render
|
||||||
return `<img src="${source}" width="${width / imgDepth}" height="${height / imgDepth}" style="vertical-align: middle"/>`
|
return `<img src="${source}" width="${width / imgDepth}" height="${height / imgDepth}" style="vertical-align: middle"/>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,10 @@ import Objects from "./objects.mjs"
|
||||||
import History from "./history.mjs"
|
import History from "./history.mjs"
|
||||||
import Settings from "./settings.mjs"
|
import Settings from "./settings.mjs"
|
||||||
|
|
||||||
|
|
||||||
class CanvasAPI extends Module {
|
class CanvasAPI extends Module {
|
||||||
|
|
||||||
|
|
||||||
/** @type {CanvasInterface} */
|
/** @type {CanvasInterface} */
|
||||||
#canvas = null
|
#canvas = null
|
||||||
/** @type {CanvasRenderingContext2D} */
|
/** @type {CanvasRenderingContext2D} */
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Module } from "./common.mjs"
|
import { Module } from "./common.mjs"
|
||||||
|
import { BaseEvent } from "../events.mjs"
|
||||||
import * as Instruction from "../lib/expr-eval/instruction.mjs"
|
import * as Instruction from "../lib/expr-eval/instruction.mjs"
|
||||||
import { escapeValue } from "../lib/expr-eval/expression.mjs"
|
import { escapeValue } from "../lib/expr-eval/expression.mjs"
|
||||||
import { HelperInterface, LatexInterface } from "./interface.mjs"
|
import { HelperInterface, LatexInterface } from "./interface.mjs"
|
||||||
|
@ -44,6 +45,28 @@ const equivalchars = ["\\pi", "\\infty",
|
||||||
"{}_{4}", "{}_{5}", "{}_{6}", "{}_{7}", "{}_{8}", "{}_{9}", "{}_{0}",
|
"{}_{4}", "{}_{5}", "{}_{6}", "{}_{7}", "{}_{8}", "{}_{9}", "{}_{0}",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class AsyncRenderStartedEvent extends BaseEvent {
|
||||||
|
constructor(markup, fontSize, color) {
|
||||||
|
super("async-render-started")
|
||||||
|
this.markup = markup
|
||||||
|
this.fontSize = fontSize
|
||||||
|
this.color = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AsyncRenderFinishedEvent extends BaseEvent {
|
||||||
|
constructor(markup, fontSize, color) {
|
||||||
|
super("async-render-finished")
|
||||||
|
this.markup = markup
|
||||||
|
this.fontSize = fontSize
|
||||||
|
this.color = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class containing the result of a LaTeX render.
|
* Class containing the result of a LaTeX render.
|
||||||
*
|
*
|
||||||
|
@ -60,6 +83,8 @@ class LatexRenderResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
class LatexAPI extends Module {
|
class LatexAPI extends Module {
|
||||||
|
static emits = ["async-render-started", "async-render-finished"]
|
||||||
|
|
||||||
/** @type {LatexInterface} */
|
/** @type {LatexInterface} */
|
||||||
#latex = null
|
#latex = null
|
||||||
|
|
||||||
|
@ -113,10 +138,14 @@ 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 render
|
let render
|
||||||
if(this.#latex.supportsAsyncRender)
|
if(this.#latex.supportsAsyncRender) {
|
||||||
|
console.trace()
|
||||||
|
this.emit(new AsyncRenderStartedEvent(markup, fontSize, color))
|
||||||
render = await this.#latex.renderAsync(markup, fontSize, color)
|
render = await this.#latex.renderAsync(markup, fontSize, color)
|
||||||
else
|
this.emit(new AsyncRenderFinishedEvent(markup, fontSize, color))
|
||||||
|
} else {
|
||||||
render = this.#latex.renderSync(markup, fontSize, color)
|
render = this.#latex.renderSync(markup, fontSize, color)
|
||||||
|
}
|
||||||
const args = render.split(",")
|
const args = render.split(",")
|
||||||
return new LatexRenderResult(...args)
|
return new LatexRenderResult(...args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,9 @@ export default class Function extends ExecutableObject {
|
||||||
*/
|
*/
|
||||||
static drawFunction(canvas, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) {
|
static drawFunction(canvas, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) {
|
||||||
let pxprecision = 10
|
let pxprecision = 10
|
||||||
let previousX = canvas.px2x(0)
|
const startDrawFrom = canvas.x2px(1)%pxprecision-pxprecision
|
||||||
|
let previousX = canvas.px2x(startDrawFrom)
|
||||||
|
// console.log("Starting draw from", previousX, startDrawFrom, canvas.x2px(1))
|
||||||
let previousY = null
|
let previousY = null
|
||||||
if(definitionDomain instanceof SpecialDomain && definitionDomain.moveSupported) {
|
if(definitionDomain instanceof SpecialDomain && definitionDomain.moveSupported) {
|
||||||
// Point based functions.
|
// Point based functions.
|
||||||
|
@ -160,7 +162,7 @@ export default class Function extends ExecutableObject {
|
||||||
// Calculate the previousY at the start of the canvas
|
// Calculate the previousY at the start of the canvas
|
||||||
if(definitionDomain.includes(previousX))
|
if(definitionDomain.includes(previousX))
|
||||||
previousY = expr.execute(previousX)
|
previousY = expr.execute(previousX)
|
||||||
for(let px = pxprecision; px < canvas.width; px += pxprecision) {
|
for(let px = pxprecision; px-pxprecision < canvas.width; px += pxprecision) {
|
||||||
let currentX = canvas.px2x(px)
|
let currentX = canvas.px2x(px)
|
||||||
if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) {
|
if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) {
|
||||||
// Should draw up to currentX, but NOT at previousX.
|
// Should draw up to currentX, but NOT at previousX.
|
||||||
|
@ -169,7 +171,7 @@ export default class Function extends ExecutableObject {
|
||||||
do {
|
do {
|
||||||
tmpPx++
|
tmpPx++
|
||||||
previousX = canvas.px2x(tmpPx)
|
previousX = canvas.px2x(tmpPx)
|
||||||
} while(!definitionDomain.includes(previousX))
|
} while(!definitionDomain.includes(previousX) && currentX > previousX)
|
||||||
// Recaclulate previousY
|
// Recaclulate previousY
|
||||||
previousY = expr.execute(previousX)
|
previousY = expr.execute(previousX)
|
||||||
} else if(!definitionDomain.includes(currentX)) {
|
} else if(!definitionDomain.includes(currentX)) {
|
||||||
|
@ -179,7 +181,7 @@ export default class Function extends ExecutableObject {
|
||||||
do {
|
do {
|
||||||
tmpPx--
|
tmpPx--
|
||||||
currentX = canvas.px2x(tmpPx)
|
currentX = canvas.px2x(tmpPx)
|
||||||
} while(!definitionDomain.includes(currentX) && currentX !== previousX)
|
} while(!definitionDomain.includes(currentX) && currentX > previousX)
|
||||||
}
|
}
|
||||||
// This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...)
|
// This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...)
|
||||||
let maxvariation = (canvas.px2y(0) - canvas.px2y(canvas.height))
|
let maxvariation = (canvas.px2y(0) - canvas.px2y(canvas.height))
|
||||||
|
|
|
@ -47,8 +47,8 @@ class EnableLatex extends BoolSetting {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ENABLE_LATEX_ASYNC = new BoolSetting(
|
const ENABLE_LATEX_ASYNC = new BoolSetting(
|
||||||
qsTranslate("general", "Enable asynchronous LaTeX renderer"),
|
qsTranslate("general", "Enable threaded LaTeX renderer (experimental)"),
|
||||||
"enable_latex_async",
|
"enable_latex_threaded",
|
||||||
"new"
|
"new"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ const DEFAULT_SETTINGS = {
|
||||||
"reset_redo_stack": true,
|
"reset_redo_stack": true,
|
||||||
"last_install_greet": "0",
|
"last_install_greet": "0",
|
||||||
"enable_latex": true,
|
"enable_latex": true,
|
||||||
"enable_latex_async": true,
|
"enable_latex_threaded": true,
|
||||||
"expression_editor": {
|
"expression_editor": {
|
||||||
"autoclose": true,
|
"autoclose": true,
|
||||||
"colorize": true,
|
"colorize": true,
|
||||||
|
@ -113,4 +113,4 @@ export class MockHelper {
|
||||||
throw new Error(`File not found.`)
|
throw new Error(`File not found.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import QtQuick
|
||||||
import Qt.labs.platform as Native
|
import Qt.labs.platform as Native
|
||||||
//import QtQuick.Controls 2.15
|
//import QtQuick.Controls 2.15
|
||||||
import eu.ad5001.MixedMenu 1.1
|
import eu.ad5001.MixedMenu 1.1
|
||||||
import "js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
|
JS 1.0 index.mjs
|
|
@ -24,7 +24,7 @@ import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmltype HistoryBrowser
|
\qmltype Browser
|
||||||
\inqmlmodule eu.ad5001.LogarithmPlotter.History
|
\inqmlmodule eu.ad5001.LogarithmPlotter.History
|
||||||
\brief Tab of the drawer that allows to navigate through the undo and redo history.
|
\brief Tab of the drawer that allows to navigate through the undo and redo history.
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ Item {
|
||||||
Repeater {
|
Repeater {
|
||||||
model: historyBrowser.redoCount
|
model: historyBrowser.redoCount
|
||||||
|
|
||||||
HistoryItem {
|
SingleItem {
|
||||||
id: redoButton
|
id: redoButton
|
||||||
width: historyBrowser.actionWidth
|
width: historyBrowser.actionWidth
|
||||||
//height: actionHeight
|
//height: actionHeight
|
||||||
|
@ -147,7 +147,7 @@ Item {
|
||||||
model: historyBrowser.undoCount
|
model: historyBrowser.undoCount
|
||||||
|
|
||||||
|
|
||||||
HistoryItem {
|
SingleItem {
|
||||||
id: undoButton
|
id: undoButton
|
||||||
width: historyBrowser.actionWidth
|
width: historyBrowser.actionWidth
|
||||||
//height: actionHeight
|
//height: actionHeight
|
|
@ -22,7 +22,7 @@ import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmltype HistoryItem
|
\qmltype SingleItem
|
||||||
\inqmlmodule eu.ad5001.LogarithmPlotter.History
|
\inqmlmodule eu.ad5001.LogarithmPlotter.History
|
||||||
\brief Item representing an history action.
|
\brief Item representing an history action.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module eu.ad5001.LogarithmPlotter.History
|
module eu.ad5001.LogarithmPlotter.History
|
||||||
|
|
||||||
HistoryBrowser 1.0 HistoryBrowser.qml
|
Browser 1.0 Browser.qml
|
||||||
HistoryItem 1.0 HistoryItem.qml
|
SingleItem 1.0 SingleItem.qml
|
||||||
|
|
|
@ -17,16 +17,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import QtQml
|
import QtQml
|
||||||
import QtQuick.Controls
|
|
||||||
import eu.ad5001.MixedMenu 1.1
|
|
||||||
import QtQuick.Layouts 1.12
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import eu.ad5001.MixedMenu 1.1
|
||||||
|
|
||||||
// Auto loading all modules.
|
// Auto loading all modules.
|
||||||
import "js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
import eu.ad5001.LogarithmPlotter.History 1.0
|
import eu.ad5001.LogarithmPlotter.History 1.0 as History
|
||||||
import eu.ad5001.LogarithmPlotter.ObjectLists 1.0
|
import eu.ad5001.LogarithmPlotter.ObjectLists 1.0
|
||||||
|
import eu.ad5001.LogarithmPlotter.Overlay 1.0 as Overlay
|
||||||
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
|
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -120,16 +121,16 @@ ApplicationWindow {
|
||||||
|
|
||||||
ObjectLists {
|
ObjectLists {
|
||||||
id: objectLists
|
id: objectLists
|
||||||
onChanged: drawCanvas.requestPaint()
|
onChanged: Modules.Canvas.requestPaint()
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
id: settings
|
id: settings
|
||||||
canvas: drawCanvas
|
canvas: drawCanvas
|
||||||
onChanged: drawCanvas.requestPaint()
|
onChanged: Modules.Canvas.requestPaint()
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryBrowser {
|
History.Browser {
|
||||||
id: historyBrowser
|
id: historyBrowser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,19 +155,21 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewPositionChangeOverlay {
|
Overlay.ViewPositionChange {
|
||||||
id: viewPositionChanger
|
id: viewPositionChanger
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
canvas: parent
|
|
||||||
settingsInstance: settings
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PickLocationOverlay {
|
Overlay.PickLocation {
|
||||||
id: positionPicker
|
id: positionPicker
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
canvas: parent
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Overlay.Loading {
|
||||||
|
id: loadingOverlay
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: delayRefreshTimer
|
id: delayRefreshTimer
|
||||||
|
|
|
@ -20,7 +20,7 @@ import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import Qt.labs.platform as Native
|
import Qt.labs.platform as Native
|
||||||
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
import "../../js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmltype CustomPropertyList
|
\qmltype CustomPropertyList
|
||||||
|
|
|
@ -18,11 +18,10 @@
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Dialogs as D
|
|
||||||
import Qt.labs.platform as Native
|
import Qt.labs.platform as Native
|
||||||
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
|
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
|
||||||
import "../../js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmltype Dialog
|
\qmltype Dialog
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
import "../js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -56,7 +56,7 @@ ScrollView {
|
||||||
property var editingRows: []
|
property var editingRows: []
|
||||||
model: Modules.Objects.currentObjects[objType]
|
model: Modules.Objects.currentObjects[objType]
|
||||||
width: objectsListView.width
|
width: objectsListView.width
|
||||||
implicitHeight: contentItem.childrenRect.height
|
height: contentItem.childrenRect.height + 10
|
||||||
visible: model != undefined && model.length > 0
|
visible: model != undefined && model.length > 0
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import QtQuick.Dialogs
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Window
|
import QtQuick.Window
|
||||||
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
import "../js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
/**
|
||||||
|
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
|
||||||
|
* Copyright (C) 2021-2024 Ad5001
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Loading
|
||||||
|
\inqmlmodule eu.ad5001.LogarithmPlotter.Overlay
|
||||||
|
\brief Overlay notifiying the user when a file is loading.
|
||||||
|
|
||||||
|
Provides an overlay over the canvas that is shown when the user loads a new file, both to lock the ViewPositionChange
|
||||||
|
overlay and inform the user of what is loading and how much remains.
|
||||||
|
|
||||||
|
\sa Common, ViewPositionChange
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: loadingRoot
|
||||||
|
opacity: 0
|
||||||
|
visible: opacity !== 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
property int currentlyLoading: 0
|
||||||
|
property int maxCurrentLoadingSteps: 0
|
||||||
|
|
||||||
|
Behavior on opacity { PropertyAnimation {} }
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: sysPalette.window
|
||||||
|
opacity: 0.85
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 5
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: loadingTitle
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
font.pixelSize: 20
|
||||||
|
color: sysPalette.windowText
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressBar {
|
||||||
|
id: progress
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: 300
|
||||||
|
from: 0
|
||||||
|
value: loadingRoot.maxCurrentLoadingSteps - loadingRoot.currentlyLoading
|
||||||
|
to: loadingRoot.maxCurrentLoadingSteps
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: lastFinishedStep
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: sysPalette.windowText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: picker
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: parent.visible
|
||||||
|
cursorShape: Qt.ArrowCursor
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlmethod void Loading::addedLoadingStep()
|
||||||
|
Registers one new loading step that will eventually call \c finishedLoadingStep.
|
||||||
|
*/
|
||||||
|
function addedLoadingStep() {
|
||||||
|
if(loadingRoot.maxCurrentLoadingSteps === 1) {
|
||||||
|
// Only when several ones need to be loaded.
|
||||||
|
const fileName = Modules.Settings.saveFilename.split('/').pop().split('\\').pop()
|
||||||
|
loadingTitle.text = qsTr("Loading...")
|
||||||
|
loadingRoot.opacity = 1
|
||||||
|
}
|
||||||
|
loadingRoot.currentlyLoading++
|
||||||
|
loadingRoot.maxCurrentLoadingSteps++
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlmethod void Loading::finishedLoadingStep()
|
||||||
|
Marks a loading step as finished and displays the message to the user.
|
||||||
|
*/
|
||||||
|
function finishedLoadingStep(message) {
|
||||||
|
loadingRoot.currentlyLoading--
|
||||||
|
const current = loadingRoot.maxCurrentLoadingSteps - loadingRoot.currentlyLoading
|
||||||
|
lastFinishedStep.text = `${message} (${current}/${loadingRoot.maxCurrentLoadingSteps})`
|
||||||
|
if(loadingRoot.currentlyLoading === 0) {
|
||||||
|
loadingRoot.maxCurrentLoadingSteps = 0
|
||||||
|
loadingRoot.opacity = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Component.onCompleted: function() {
|
||||||
|
Modules.Latex.on("async-render-started", (e) => {
|
||||||
|
addedLoadingStep()
|
||||||
|
})
|
||||||
|
Modules.Latex.on("async-render-finished", (e) => {
|
||||||
|
const markup = e.markup.length > 20 ? e.markup.substring(0, 15)+"..." : e.markup
|
||||||
|
finishedLoadingStep(qsTr("Finished rendering of %1").arg(markup))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,12 +18,12 @@
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
import eu.ad5001.LogarithmPlotter.Setting as Setting
|
||||||
import "js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmltype PickLocationOverlay
|
\qmltype PickLocation
|
||||||
\inqmlmodule eu.ad5001.LogarithmPlotter
|
\inqmlmodule eu.ad5001.LogarithmPlotter.Overlay
|
||||||
\brief Overlay used to pick a new location for an object.
|
\brief Overlay used to pick a new location for an object.
|
||||||
|
|
||||||
Provides an overlay over the canvas that can be shown when the user clicks the "Set position" button
|
Provides an overlay over the canvas that can be shown when the user clicks the "Set position" button
|
||||||
|
@ -36,7 +36,7 @@ Item {
|
||||||
id: pickerRoot
|
id: pickerRoot
|
||||||
visible: false
|
visible: false
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlsignal PickLocationOverlay::picked(var obj)
|
\qmlsignal PickLocationOverlay::picked(var obj)
|
||||||
|
|
||||||
|
@ -97,9 +97,9 @@ Item {
|
||||||
readonly property bool userPickY: pickY && pickYCheckbox.checked
|
readonly property bool userPickY: pickY && pickYCheckbox.checked
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
color: sysPalette.window
|
color: sysPalette.window
|
||||||
opacity: 0.35
|
opacity: 0.35
|
||||||
anchors.fill: parent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
|
@ -19,7 +19,7 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmltype ViewPositionChangeOverlay
|
\qmltype ViewPositionChange.Overlay
|
||||||
\inqmlmodule eu.ad5001.LogarithmPlotter
|
\inqmlmodule eu.ad5001.LogarithmPlotter
|
||||||
\brief Overlay used allow the user to drag the canvas' position and change the zoom level.
|
\brief Overlay used allow the user to drag the canvas' position and change the zoom level.
|
||||||
|
|
||||||
|
@ -57,16 +57,6 @@ Item {
|
||||||
*/
|
*/
|
||||||
signal endPositionChange(int deltaX, int deltaY)
|
signal endPositionChange(int deltaX, int deltaY)
|
||||||
|
|
||||||
/*!
|
|
||||||
\qmlproperty var ViewPositionChangeOverlay::canvas
|
|
||||||
LogGraphCanvas instance.
|
|
||||||
*/
|
|
||||||
property var canvas
|
|
||||||
/*!
|
|
||||||
\qmlproperty var ViewPositionChangeOverlay::settingsInstance
|
|
||||||
Settings instance.
|
|
||||||
*/
|
|
||||||
property var settingsInstance
|
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty int ViewPositionChangeOverlay::prevX
|
\qmlproperty int ViewPositionChangeOverlay::prevX
|
||||||
The x coordinate (on the mousearea) at the last change of the canvas position.
|
The x coordinate (on the mousearea) at the last change of the canvas position.
|
|
@ -0,0 +1,5 @@
|
||||||
|
module eu.ad5001.LogarithmPlotter.Overlay
|
||||||
|
|
||||||
|
Loading 1.0 Loading.qml
|
||||||
|
PickLocation 1.0 PickLocation.qml
|
||||||
|
ViewPositionChange 1.0 ViewPositionChange.qml
|
|
@ -20,7 +20,7 @@ import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
import "../js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmltype Preferences
|
\qmltype Preferences
|
||||||
|
|
|
@ -20,7 +20,7 @@ import QtQuick.Controls
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Qt.labs.platform as Native
|
import Qt.labs.platform as Native
|
||||||
import eu.ad5001.LogarithmPlotter.Popup 1.0 as P
|
import eu.ad5001.LogarithmPlotter.Popup 1.0 as P
|
||||||
import "../js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -20,7 +20,7 @@ import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
|
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
|
||||||
import "js/index.mjs" as JS
|
import eu.ad5001.LogarithmPlotter.Common
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmltype Settings
|
\qmltype Settings
|
||||||
|
|
|
@ -2,6 +2,4 @@ module eu.ad5001.LogarithmPlotter
|
||||||
|
|
||||||
AppMenuBar 1.0 AppMenuBar.qml
|
AppMenuBar 1.0 AppMenuBar.qml
|
||||||
LogGraphCanvas 1.0 LogGraphCanvas.qml
|
LogGraphCanvas 1.0 LogGraphCanvas.qml
|
||||||
PickLocationOverlay 1.0 PickLocationOverlay.qml
|
|
||||||
Settings 1.0 Settings.qml
|
Settings 1.0 Settings.qml
|
||||||
ViewPositionChangeOverlay 1.0 ViewPositionChangeOverlay.qml
|
|
|
@ -28,7 +28,7 @@ DEFAULT_SETTINGS = {
|
||||||
"reset_redo_stack": True,
|
"reset_redo_stack": True,
|
||||||
"last_install_greet": "0",
|
"last_install_greet": "0",
|
||||||
"enable_latex": which("latex") is not None and which("dvipng") is not None,
|
"enable_latex": which("latex") is not None and which("dvipng") is not None,
|
||||||
"enable_latex_async": True,
|
"enable_latex_threaded": True,
|
||||||
"expression_editor": {
|
"expression_editor": {
|
||||||
"autoclose": True,
|
"autoclose": True,
|
||||||
"colorize": True,
|
"colorize": True,
|
||||||
|
|
|
@ -22,9 +22,9 @@ from os import path
|
||||||
from re import compile
|
from re import compile
|
||||||
|
|
||||||
CURRENT_PATH = path.dirname(path.realpath(__file__))
|
CURRENT_PATH = path.dirname(path.realpath(__file__))
|
||||||
SOURCEMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/js/index.mjs.map")
|
SOURCEMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/Common/index.mjs.map")
|
||||||
SOURCEMAP_INDEX = None
|
SOURCEMAP_INDEX = None
|
||||||
INDEX_REG = compile(r"build\/runtime-pyside6\/LogarithmPlotter\/qml\/eu\/ad5001\/LogarithmPlotter\/js\/index.mjs:(\d+)")
|
INDEX_REG = compile(r"build\/runtime-pyside6\/LogarithmPlotter\/qml\/eu\/ad5001\/LogarithmPlotter\/Common\/index.mjs:(\d+)")
|
||||||
|
|
||||||
|
|
||||||
class LOG_COLORS:
|
class LOG_COLORS:
|
||||||
|
|
|
@ -91,7 +91,7 @@ class Latex(QObject):
|
||||||
|
|
||||||
@Property(bool)
|
@Property(bool)
|
||||||
def supportsAsyncRender(self) -> bool:
|
def supportsAsyncRender(self) -> bool:
|
||||||
return config.getSetting("enable_latex_async")
|
return config.getSetting("enable_latex_threaded")
|
||||||
|
|
||||||
@Slot(result=bool)
|
@Slot(result=bool)
|
||||||
def checkLatexInstallation(self) -> bool:
|
def checkLatexInstallation(self) -> bool:
|
||||||
|
@ -181,7 +181,6 @@ class Latex(QObject):
|
||||||
"""
|
"""
|
||||||
markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color)
|
markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color)
|
||||||
if self.latexSupported and not path.exists(export_path + ".png"):
|
if self.latexSupported and not path.exists(export_path + ".png"):
|
||||||
print("Rendering", latex_markup)
|
|
||||||
# Generating file
|
# Generating file
|
||||||
latex_path = path.join(self.tempdir, str(markup_hash))
|
latex_path = path.join(self.tempdir, str(markup_hash))
|
||||||
# If the formula is just recolored or the font is just changed, no need to recreate the DVI.
|
# If the formula is just recolored or the font is just changed, no need to recreate the DVI.
|
||||||
|
|
|
@ -100,6 +100,7 @@ class PyPromise(QObject):
|
||||||
Starts the thread that will run the promise.
|
Starts the thread that will run the promise.
|
||||||
"""
|
"""
|
||||||
if not self._started: # Avoid getting started twice.
|
if not self._started: # Avoid getting started twice.
|
||||||
|
print("Starting", self._runner.args)
|
||||||
QThreadPool.globalInstance().start(self._runner)
|
QThreadPool.globalInstance().start(self._runner)
|
||||||
self._started = True
|
self._started = True
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ class PyPromise(QObject):
|
||||||
def _fulfill(self, data):
|
def _fulfill(self, data):
|
||||||
self._state = "fulfilled"
|
self._state = "fulfilled"
|
||||||
no_return = [None, QJSValue.SpecialValue.UndefinedValue]
|
no_return = [None, QJSValue.SpecialValue.UndefinedValue]
|
||||||
|
print("Finished", self._runner.args)
|
||||||
for i in range(len(self._fulfills)):
|
for i in range(len(self._fulfills)):
|
||||||
try:
|
try:
|
||||||
result = self._fulfills[i](data)
|
result = self._fulfills[i](data)
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
cd "$DIR/.." || exit 1
|
cd "$DIR/.." || exit 1
|
||||||
|
|
||||||
|
BUILD_DIR="build/runtime-pyside6"
|
||||||
|
BUILD_QML_DIR="$BUILD_DIR/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter"
|
||||||
|
|
||||||
|
|
||||||
box() {
|
box() {
|
||||||
len=${#1}
|
len=${#1}
|
||||||
echo "┌─$(printf '─%.0s' $(seq 1 "$len"))─┐"
|
echo "┌─$(printf '─%.0s' $(seq 1 "$len"))─┐"
|
||||||
|
@ -30,20 +34,22 @@ box() {
|
||||||
}
|
}
|
||||||
|
|
||||||
rm -rf build
|
rm -rf build
|
||||||
mkdir -p build/runtime-pyside6
|
mkdir -p "$BUILD_DIR"
|
||||||
|
|
||||||
# Copy python
|
# Copy python
|
||||||
box "Copying pyside6 python runtime..."
|
box "Copying pyside6 python runtime..."
|
||||||
cp -r runtime-pyside6/{setup.py,LogarithmPlotter} build/runtime-pyside6
|
cp -r runtime-pyside6/{setup.py,LogarithmPlotter} "$BUILD_DIR"
|
||||||
|
|
||||||
box "Building ecmascript modules..."
|
box "Building ecmascript modules..."
|
||||||
mkdir -p build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js
|
mkdir -p "$BUILD_QML_DIR/js"
|
||||||
cd common && (npm run build || exit) && cd ..
|
cd common && \
|
||||||
|
(npm run build || exit) && \
|
||||||
|
cd ..
|
||||||
|
|
||||||
box "Building translations..."
|
box "Building translations..."
|
||||||
cd assets/i18n/ && (bash release.sh || exit) && cd ../../
|
cd assets/i18n/ && (bash release.sh || exit) && cd ../../
|
||||||
mkdir -p build/runtime-pyside6/LogarithmPlotter/i18n && cp assets/i18n/*.qm build/runtime-pyside6/LogarithmPlotter/i18n/
|
mkdir -p "$BUILD_DIR/LogarithmPlotter/i18n" && cp assets/i18n/*.qm "$BUILD_DIR/LogarithmPlotter/i18n/"
|
||||||
|
|
||||||
box "Building icons..."
|
box "Building icons..."
|
||||||
cp -r assets/icons build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/
|
cp -r assets/icons "$BUILD_QML_DIR"
|
||||||
cp assets/logarithmplotter.svg build/runtime-pyside6/LogarithmPlotter/
|
cp assets/logarithmplotter.svg "$BUILD_DIR/LogarithmPlotter/"
|
||||||
|
|
Loading…
Reference in a new issue