LogarithmPlotter/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml

465 lines
14 KiB
QML

/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2022 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.Controls 2.12
import QtQuick 2.12
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
import "js/utils.js" as Utils
/*!
\qmltype Settings
\inqmlmodule eu.ad5001.LogarithmPlotter
\brief Tab of the drawer that allows the user to customize how the diagram looks.
All canvas settings can found in this scrollable view, as well as buttons to copy and save the graph.
\sa LogarithmPlotter, LogGraphCanvas
*/
ScrollView {
id: settings
signal changed()
property int settingWidth: settings.width - ScrollBar.vertical.width
property Canvas canvas
/*!
\qmlproperty double Settings::xzoom
Zoom on the x axis of the diagram, provided from settings.
\sa Settings
*/
property double xzoom: 100
/*!
\qmlproperty double Settings::yzoom
Zoom on the y axis of the diagram, provided from settings.
\sa Settings
*/
property double yzoom: 10
/*!
\qmlproperty double Settings::xmin
Minimum x of the diagram, provided from settings.
\sa Settings
*/
property double xmin: 5/10
/*!
\qmlproperty double Settings::ymax
Maximum y of the diagram, provided from settings.
\sa Settings
*/
property double ymax: 25
/*!
\qmlproperty string Settings::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 Settings::yaxisstep
Step of the y axis graduation, provided from settings.
\sa Settings
*/
property string yaxisstep: "4"
/*!
\qmlproperty string Settings::xlabel
Label used on the x axis, provided from settings.
\sa Settings
*/
property string xlabel: ""
/*!
\qmlproperty string Settings::ylabel
Label used on the y axis, provided from settings.
\sa Settings
*/
property string ylabel: ""
/*!
\qmlproperty double Settings::linewidth
Width of lines that will be drawn into the canvas, provided from settings.
\sa Settings
*/
property double linewidth: 1
/*!
\qmlproperty double Settings::textsize
Font size of the text that will be drawn into the canvas, provided from settings.
\sa Settings
*/
property double textsize: 14
/*!
\qmlproperty bool Settings::logscalex
true if the canvas should be in logarithmic mode, false otherwise.
Provided from settings.
\sa Settings
*/
property bool logscalex: true
/*!
\qmlproperty bool Settings::showxgrad
true if the x graduation should be shown, false otherwise.
Provided from settings.
\sa Settings
*/
property bool showxgrad: true
/*!
\qmlproperty bool Settings::showygrad
true if the y graduation should be shown, false otherwise.
Provided from settings.
\sa Settings
*/
property bool showygrad: true
/*!
\qmlproperty bool Settings::saveFilename
Path of the currently opened file. Empty if no file is opened.
*/
property string saveFilename: ""
Column {
spacing: 10
width: parent.width
bottomPadding: 20
Popup.FileDialog {
id: fdiag
onAccepted: {
var filePath = fileUrl.toString().substr(7)
settings.saveFilename = filePath
if(exportMode) {
root.saveDiagram(filePath)
} else {
root.loadDiagram(filePath)
if(xAxisLabel.find(settings.xlabel) == -1) xAxisLabel.model.append({text: settings.xlabel})
xAxisLabel.editText = settings.xlabel
if(yAxisLabel.find(settings.ylabel) == -1) yAxisLabel.model.append({text: settings.ylabel})
yAxisLabel.editText = settings.ylabel
}
}
}
// Zoom
Setting.TextSetting {
id: zoomX
height: 30
isDouble: true
label: qsTr("X Zoom")
min: 1
icon: "settings/xzoom.svg"
width: settings.settingWidth
value: settings.xzoom.toFixed(2)
onChanged: function(newValue) {
settings.xzoom = newValue
settings.changed()
}
}
Setting.TextSetting {
id: zoomY
height: 30
isDouble: true
label: qsTr("Y Zoom")
icon: "settings/yzoom.svg"
width: settings.settingWidth
value: settings.yzoom.toFixed(2)
onChanged: function(newValue) {
settings.yzoom = newValue
settings.changed()
}
}
// Positioning the graph
Setting.TextSetting {
id: minX
height: 30
isDouble: true
min: -Infinity
label: qsTr("Min X")
icon: "settings/xmin.svg"
width: settings.settingWidth
defValue: settings.xmin
onChanged: function(newValue) {
if(parseFloat(maxX.value) > newValue) {
settings.xmin = newValue
settings.changed()
} else {
alert.show("Minimum x value must be inferior to maximum.")
}
}
}
Setting.TextSetting {
id: maxY
height: 30
isDouble: true
min: -Infinity
label: qsTr("Max Y")
icon: "settings/ymax.svg"
width: settings.settingWidth
defValue: settings.ymax
onChanged: function(newValue) {
settings.ymax = newValue
settings.changed()
}
}
Setting.TextSetting {
id: maxX
height: 30
isDouble: true
min: -Infinity
label: qsTr("Max X")
icon: "settings/xmax.svg"
width: settings.settingWidth
value: canvas.px2x(canvas.canvasSize.width).toFixed(2)
onChanged: function(xvaluemax) {
if(xvaluemax > settings.xmin) {
settings.xzoom = settings.xzoom * canvas.canvasSize.width/(canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point)
settings.changed()
} else {
alert.show("Maximum x value must be superior to minimum.")
}
}
}
Setting.TextSetting {
id: minY
height: 30
isDouble: true
min: -Infinity
label: qsTr("Min Y")
icon: "settings/ymin.svg"
width: settings.settingWidth
defValue: canvas.px2y(canvas.canvasSize.height).toFixed(2)
onChanged: function(yvaluemin) {
if(yvaluemin < settings.ymax) {
settings.yzoom = settings.yzoom * canvas.canvasSize.height/(canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point)
settings.changed()
} else {
alert.show("Minimum y value must be inferior to maximum.")
}
}
}
Setting.TextSetting {
id: xAxisStep
height: 30
label: qsTr("X Axis Step")
icon: "settings/xaxisstep.svg"
width: settings.settingWidth
defValue: settings.xaxisstep
visible: !settings.logscalex
onChanged: function(newValue) {
settings.xaxisstep = newValue
settings.changed()
}
}
Setting.TextSetting {
id: yAxisStep
height: 30
label: qsTr("Y Axis Step")
icon: "settings/yaxisstep.svg"
width: settings.settingWidth
defValue: settings.yaxisstep
onChanged: function(newValue) {
settings.yaxisstep = newValue
settings.changed()
}
}
Setting.TextSetting {
id: lineWidth
height: 30
isDouble: true
label: qsTr("Line width")
min: 1
icon: "settings/linewidth.svg"
width: settings.settingWidth
defValue: settings.linewidth
onChanged: function(newValue) {
settings.linewidth = newValue
settings.changed()
}
}
Setting.TextSetting {
id: textSize
height: 30
isDouble: true
label: qsTr("Text size (px)")
min: 1
icon: "settings/textsize.svg"
width: settings.settingWidth
defValue: settings.textsize
onChanged: function(newValue) {
settings.textsize = newValue
settings.changed()
}
}
Setting.ComboBoxSetting {
id: xAxisLabel
height: 30
width: settings.settingWidth
label: qsTr('X Label')
icon: "settings/xlabel.svg"
model: ListModel {
ListElement { text: "" }
ListElement { text: "x" }
ListElement { text: "ω (rad/s)" }
}
currentIndex: find(settings.xlabel)
editable: true
onAccepted: function(){
editText = Utils.parseName(editText, false)
if (find(editText) === -1) model.append({text: editText})
settings.xlabel = editText
settings.changed()
}
onActivated: function(selectedId) {
settings.xlabel = model.get(selectedId).text
settings.changed()
}
Component.onCompleted: editText = settings.xlabel
}
Setting.ComboBoxSetting {
id: yAxisLabel
height: 30
width: settings.settingWidth
label: qsTr('Y Label')
icon: "settings/ylabel.svg"
model: ListModel {
ListElement { text: "" }
ListElement { text: "y" }
ListElement { text: "G (dB)" }
ListElement { text: "φ (°)" }
ListElement { text: "φ (deg)" }
ListElement { text: "φ (rad)" }
}
currentIndex: find(settings.ylabel)
editable: true
onAccepted: function(){
editText = Utils.parseName(editText, false)
if (find(editText) === -1) model.append({text: editText, yaxisstep: root.yaxisstep})
settings.ylabel = editText
settings.changed()
}
onActivated: function(selectedId) {
settings.ylabel = model.get(selectedId).text
settings.changed()
}
Component.onCompleted: editText = settings.ylabel
}
CheckBox {
id: logScaleX
checked: settings.logscalex
text: qsTr('X Log scale')
onClicked: {
settings.logscalex = checked
settings.changed()
}
}
CheckBox {
id: showXGrad
checked: settings.showxgrad
text: qsTr('Show X graduation')
onClicked: {
settings.showxgrad = checked
settings.changed()
}
}
CheckBox {
id: showYGrad
checked: settings.showygrad
text: qsTr('Show Y graduation')
onClicked: {
settings.showygrad = checked
settings.changed()
}
}
Button {
id: copyToClipboard
height: 30
width: settings.settingWidth
text: qsTr("Copy to clipboard")
icon.name: 'editcopy'
onClicked: root.copyDiagramToClipboard()
}
Button {
id: saveDiagram
height: 30
width: settings.settingWidth
text: qsTr("Save plot")
icon.name: 'document-save'
onClicked: save()
}
Button {
id: saveDiagramAs
height: 30
width: settings.settingWidth
text: qsTr("Save plot as")
icon.name: 'document-save-as'
onClicked: saveAs()
}
Button {
id: loadDiagram
height: 30
width: settings.settingWidth
text: qsTr("Load plot")
icon.name: 'document-open'
onClicked: load()
}
}
/*!
\qmlmethod void LogGraphCanvas::save()
Saves the current canvas in the opened file. If no file is currently opened, prompts to pick a save location.
*/
function save() {
if(settings.saveFilename == "") {
saveAs()
} else {
root.saveDiagram(settings.saveFilename)
}
}
/*!
\qmlmethod void LogGraphCanvas::saveAs()
Prompts the user to pick a new save location.
*/
function saveAs() {
fdiag.exportMode = true
fdiag.open()
}
/*!
\qmlmethod void LogGraphCanvas::saveAs()
Prompts the user to pick a diagram to load.
*/
function load() {
fdiag.exportMode = false
fdiag.open()
}
}