Redesigning history browser.
This commit is contained in:
parent
402061a4b1
commit
95f7e683c7
21 changed files with 460 additions and 31 deletions
|
@ -108,7 +108,7 @@ MenuBar {
|
||||||
visible: Objects.types[modelData].createable()
|
visible: Objects.types[modelData].createable()
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
icon.name: modelData
|
icon.name: modelData
|
||||||
icon.source: './icons/' + modelData + '.svg'
|
icon.source: './icons/objects/' + modelData + '.svg'
|
||||||
icon.color: sysPalette.buttonText
|
icon.color: sysPalette.buttonText
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
var newObj = Objects.createNewRegisteredObject(modelData)
|
var newObj = Objects.createNewRegisteredObject(modelData)
|
||||||
|
|
|
@ -45,7 +45,12 @@ ScrollView {
|
||||||
\qmlproperty int HistoryBrowser::actionHeight
|
\qmlproperty int HistoryBrowser::actionHeight
|
||||||
Height of the actions.
|
Height of the actions.
|
||||||
*/
|
*/
|
||||||
property int actionHeight: 30
|
property int actionHeight: 40
|
||||||
|
/*!
|
||||||
|
\qmlproperty int HistoryBrowser::darkTheme
|
||||||
|
true when the system is running with a dark theme, false otherwise.
|
||||||
|
*/
|
||||||
|
property bool darkTheme: isDarkTheme()
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -68,6 +73,7 @@ ScrollView {
|
||||||
height: actionHeight
|
height: actionHeight
|
||||||
isRedo: true
|
isRedo: true
|
||||||
idx: index
|
idx: index
|
||||||
|
darkTheme: historyBrowser.darkTheme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +121,7 @@ ScrollView {
|
||||||
height: actionHeight
|
height: actionHeight
|
||||||
isRedo: false
|
isRedo: false
|
||||||
idx: index
|
idx: index
|
||||||
|
darkTheme: historyBrowser.darkTheme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,4 +137,15 @@ ScrollView {
|
||||||
visible: history.undoCount > 0
|
visible: history.undoCount > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlmethod bool HistoryBrowser::isDarkTheme()
|
||||||
|
Checks whether the system is running with a light or dark theme.
|
||||||
|
*/
|
||||||
|
function isDarkTheme() {
|
||||||
|
let hex = sysPalette.windowText.toString()
|
||||||
|
// We only check the first parameter, as on all normal OSes, text color is grayscale.
|
||||||
|
return parseInt(hex.substr(1,2), 16) > 128
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/**
|
||||||
|
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition 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 QtGraphicalEffects 1.15
|
||||||
|
import "../js/utils.js" as Utils
|
||||||
|
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype HistoryItem
|
||||||
|
\inqmlmodule eu.ad5001.LogarithmPlotter.History
|
||||||
|
\brief Item representing an history action.
|
||||||
|
|
||||||
|
Creates a scrollable view containing a list of history actions based on the redo stack, then a "Now" indicator
|
||||||
|
followed by the entirety of the saved undo stack. Each action can be click to restore a state of the graph at
|
||||||
|
some point of the history.
|
||||||
|
|
||||||
|
\sa HistoryBrowser
|
||||||
|
*/
|
||||||
|
Button {
|
||||||
|
id: redoButton
|
||||||
|
flat: true
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty bool HistoryItem::isRedo
|
||||||
|
true if the action is in the redo stack, false othewise.
|
||||||
|
*/
|
||||||
|
property bool isRedo
|
||||||
|
/*!
|
||||||
|
\qmlproperty int HistoryItem::idx
|
||||||
|
Index of the item within the HistoryBrowser list.
|
||||||
|
*/
|
||||||
|
property int idx
|
||||||
|
/*!
|
||||||
|
\qmlproperty int HistoryItem::idx
|
||||||
|
true when the system is running with a dark theme, false otherwise.
|
||||||
|
*/
|
||||||
|
property bool darkTheme
|
||||||
|
/*!
|
||||||
|
\qmlproperty int HistoryItem::historyAction
|
||||||
|
Associated history action.
|
||||||
|
*/
|
||||||
|
readonly property var historyAction: isRedo ? history.redoStack[idx] : history.undoStack[history.undoCount-idx-1]
|
||||||
|
|
||||||
|
LinearGradient {
|
||||||
|
anchors.fill: parent
|
||||||
|
start: Qt.point(0, 0)
|
||||||
|
end: Qt.point(parent.width, 0)
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 0.1; color: "transparent" }
|
||||||
|
GradientStop { position: 1.5; color: historyAction.color(darkTheme) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Setting.Icon {
|
||||||
|
id: icon
|
||||||
|
width: 18
|
||||||
|
height: 18
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: (parent.height-height)/2
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
color: sysPalette.windowText
|
||||||
|
source: `../icons/history/${historyAction.icon()}.svg`
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: label
|
||||||
|
anchors.left: icon.right
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.leftMargin: 4
|
||||||
|
anchors.rightMargin: (parent.height-height)/2
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: 14
|
||||||
|
text: historyAction.getReadableString()
|
||||||
|
clip: true
|
||||||
|
}
|
||||||
|
|
||||||
|
//text: historyAction.getReadableString()
|
||||||
|
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: label.text
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if(isRedo)
|
||||||
|
history.redoMultipleDefered(history.redoCount-idx)
|
||||||
|
else
|
||||||
|
history.undoMultipleDefered(+idx+1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
module eu.ad5001.LogarithmPlotter.History
|
||||||
|
|
||||||
|
History 1.0 History.qml
|
||||||
|
HistoryBrowser 1.0 HistoryBrowser.qml
|
||||||
|
HistoryItem 1.0 HistoryItem.qml
|
|
@ -78,7 +78,7 @@ D.Dialog {
|
||||||
id: nameProperty
|
id: nameProperty
|
||||||
height: 30
|
height: 30
|
||||||
label: qsTr("Name")
|
label: qsTr("Name")
|
||||||
icon: "icons/common/label.svg"
|
icon: "common/label.svg"
|
||||||
min: 1
|
min: 1
|
||||||
width: dlgProperties.width
|
width: dlgProperties.width
|
||||||
value: objEditor.obj.name
|
value: objEditor.obj.name
|
||||||
|
@ -105,7 +105,7 @@ D.Dialog {
|
||||||
label: qsTr("Label content")
|
label: qsTr("Label content")
|
||||||
model: [qsTr("null"), qsTr("name"), qsTr("name + value")]
|
model: [qsTr("null"), qsTr("name"), qsTr("name + value")]
|
||||||
property var idModel: ["null", "name", "name + value"]
|
property var idModel: ["null", "name", "name + value"]
|
||||||
icon: "icons/common/label.svg"
|
icon: "common/label.svg"
|
||||||
currentIndex: idModel.indexOf(objEditor.obj.labelContent)
|
currentIndex: idModel.indexOf(objEditor.obj.labelContent)
|
||||||
onActivated: function(newIndex) {
|
onActivated: function(newIndex) {
|
||||||
if(idModel[newIndex] != objEditor.obj.labelContent) {
|
if(idModel[newIndex] != objEditor.obj.labelContent) {
|
||||||
|
@ -144,7 +144,7 @@ D.Dialog {
|
||||||
height: visible ? 30 : 0
|
height: visible ? 30 : 0
|
||||||
width: parent.width
|
width: parent.width
|
||||||
label: parent.label
|
label: parent.label
|
||||||
icon: `icons/settings/custom/${parent.icon}.svg`
|
icon: `settings/custom/${parent.icon}.svg`
|
||||||
isDouble: modelData[1] == 'number'
|
isDouble: modelData[1] == 'number'
|
||||||
visible: paramTypeIn(modelData[1], ['Expression', 'Domain', 'string', 'number'])
|
visible: paramTypeIn(modelData[1], ['Expression', 'Domain', 'string', 'number'])
|
||||||
defValue: visible ? {
|
defValue: visible ? {
|
||||||
|
@ -180,7 +180,7 @@ D.Dialog {
|
||||||
height: visible ? 20 : 0
|
height: visible ? 20 : 0
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: parent.label
|
text: parent.label
|
||||||
//icon: visible ? `icons/settings/custom/${parent.icon}.svg` : ''
|
//icon: visible ? `settings/custom/${parent.icon}.svg` : ''
|
||||||
|
|
||||||
checked: visible ? objEditor.obj[modelData[0]] : false
|
checked: visible ? objEditor.obj[modelData[0]] : false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -200,7 +200,7 @@ D.Dialog {
|
||||||
width: dlgProperties.width
|
width: dlgProperties.width
|
||||||
height: visible ? 30 : 0
|
height: visible ? 30 : 0
|
||||||
label: parent.label
|
label: parent.label
|
||||||
icon: visible ? `icons/settings/custom/${parent.icon}.svg` : ''
|
icon: visible ? `settings/custom/${parent.icon}.svg` : ''
|
||||||
// True to select an object of type, false for enums.
|
// True to select an object of type, false for enums.
|
||||||
property bool selectObjMode: paramTypeIn(modelData[1], ['ObjectType'])
|
property bool selectObjMode: paramTypeIn(modelData[1], ['ObjectType'])
|
||||||
property bool isRealObject: !selectObjMode || (modelData[1].objType != "ExecutableObject" && modelData[1].objType != "DrawableObject")
|
property bool isRealObject: !selectObjMode || (modelData[1].objType != "ExecutableObject" && modelData[1].objType != "DrawableObject")
|
||||||
|
@ -262,7 +262,7 @@ D.Dialog {
|
||||||
|
|
||||||
visible: paramTypeIn(modelData[1], ['List', 'Dict'])
|
visible: paramTypeIn(modelData[1], ['List', 'Dict'])
|
||||||
label: parent.label
|
label: parent.label
|
||||||
//icon: `icons/settings/custom/${parent.icon}.svg`
|
//icon: `settings/custom/${parent.icon}.svg`
|
||||||
dictionaryMode: paramTypeIn(modelData[1], ['Dict'])
|
dictionaryMode: paramTypeIn(modelData[1], ['Dict'])
|
||||||
keyType: dictionaryMode ? modelData[1].keyType : 'string'
|
keyType: dictionaryMode ? modelData[1].keyType : 'string'
|
||||||
valueType: visible ? modelData[1].valueType : 'string'
|
valueType: visible ? modelData[1].valueType : 'string'
|
||||||
|
|
|
@ -54,7 +54,7 @@ Column {
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
display: AbstractButton.TextUnderIcon
|
display: AbstractButton.TextUnderIcon
|
||||||
icon.name: modelData
|
icon.name: modelData
|
||||||
icon.source: '../icons/' + modelData + '.svg'
|
icon.source: '../icons/objects/' + modelData + '.svg'
|
||||||
icon.width: 24
|
icon.width: 24
|
||||||
icon.height: 24
|
icon.height: 24
|
||||||
icon.color: sysPalette.buttonText
|
icon.color: sysPalette.buttonText
|
||||||
|
|
|
@ -140,7 +140,7 @@ ListView {
|
||||||
anchors.rightMargin: 5
|
anchors.rightMargin: 5
|
||||||
anchors.topMargin: 5
|
anchors.topMargin: 5
|
||||||
icon.name: 'position'
|
icon.name: 'position'
|
||||||
icon.source: '../icons/position.svg'
|
icon.source: '../icons/common/position.svg'
|
||||||
icon.color: sysPalette.buttonText
|
icon.color: sysPalette.buttonText
|
||||||
property bool hasXProp: Objects.types[objType].properties().hasOwnProperty('x')
|
property bool hasXProp: Objects.types[objType].properties().hasOwnProperty('x')
|
||||||
property bool hasYProp: Objects.types[objType].properties().hasOwnProperty('y')
|
property bool hasYProp: Objects.types[objType].properties().hasOwnProperty('y')
|
||||||
|
@ -168,7 +168,7 @@ ListView {
|
||||||
anchors.rightMargin: 5
|
anchors.rightMargin: 5
|
||||||
anchors.topMargin: 5
|
anchors.topMargin: 5
|
||||||
icon.name: 'delete'
|
icon.name: 'delete'
|
||||||
icon.source: '../icons/delete.svg'
|
icon.source: '../icons/common/delete.svg'
|
||||||
icon.color: sysPalette.buttonText
|
icon.color: sysPalette.buttonText
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.text: qsTr("Delete %1 %2").arg(Objects.types[objType].displayType()).arg(obj.name)
|
ToolTip.text: qsTr("Delete %1 %2").arg(Objects.types[objType].displayType()).arg(obj.name)
|
||||||
|
|
|
@ -103,7 +103,7 @@ Item {
|
||||||
id: iconLabel
|
id: iconLabel
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: icon == "" ? 0 : 3
|
anchors.topMargin: icon == "" ? 0 : 3
|
||||||
source: control.visible ? "../" + control.icon : ""
|
source: control.visible ? "../icons/" + control.icon : ""
|
||||||
width: height
|
width: height
|
||||||
height: icon == "" && visible ? 0 : 24
|
height: icon == "" && visible ? 0 : 24
|
||||||
color: sysPalette.windowText
|
color: sysPalette.windowText
|
||||||
|
|
|
@ -86,7 +86,7 @@ Column {
|
||||||
id: iconLabel
|
id: iconLabel
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: icon == "" ? 0 : 3
|
anchors.topMargin: icon == "" ? 0 : 3
|
||||||
source: control.visible ? "../" + control.icon : ""
|
source: control.visible ? "../icons/" + control.icon : ""
|
||||||
width: height
|
width: height
|
||||||
height: icon == "" || !visible ? 0 : 24
|
height: icon == "" || !visible ? 0 : 24
|
||||||
color: sysPalette.windowText
|
color: sysPalette.windowText
|
||||||
|
@ -198,7 +198,7 @@ Column {
|
||||||
id: deleteButton
|
id: deleteButton
|
||||||
width: visible ? parent.height : 0
|
width: visible ? parent.height : 0
|
||||||
height: width
|
height: width
|
||||||
icon.source: './icons/delete.svg'
|
icon.source: './icons/common/delete.svg'
|
||||||
icon.name: 'delete'
|
icon.name: 'delete'
|
||||||
visible: !control.forbidAdding
|
visible: !control.forbidAdding
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ Item {
|
||||||
id: iconLabel
|
id: iconLabel
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: icon == "" ? 0 : 3
|
anchors.topMargin: icon == "" ? 0 : 3
|
||||||
source: control.visible ? "../" + control.icon : ""
|
source: control.visible ? "../icons/" + control.icon : ""
|
||||||
width: height
|
width: height
|
||||||
height: icon == "" || !visible ? 0 : 24
|
height: icon == "" || !visible ? 0 : 24
|
||||||
color: sysPalette.windowText
|
color: sysPalette.windowText
|
||||||
|
|
|
@ -156,7 +156,7 @@ ScrollView {
|
||||||
isDouble: true
|
isDouble: true
|
||||||
label: qsTr("X Zoom")
|
label: qsTr("X Zoom")
|
||||||
min: 1
|
min: 1
|
||||||
icon: "icons/settings/xzoom.svg"
|
icon: "settings/xzoom.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
value: settings.xzoom.toFixed(2)
|
value: settings.xzoom.toFixed(2)
|
||||||
onChanged: function(newValue) {
|
onChanged: function(newValue) {
|
||||||
|
@ -170,7 +170,7 @@ ScrollView {
|
||||||
height: 30
|
height: 30
|
||||||
isDouble: true
|
isDouble: true
|
||||||
label: qsTr("Y Zoom")
|
label: qsTr("Y Zoom")
|
||||||
icon: "icons/settings/yzoom.svg"
|
icon: "settings/yzoom.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
value: settings.yzoom.toFixed(2)
|
value: settings.yzoom.toFixed(2)
|
||||||
onChanged: function(newValue) {
|
onChanged: function(newValue) {
|
||||||
|
@ -186,7 +186,7 @@ ScrollView {
|
||||||
isDouble: true
|
isDouble: true
|
||||||
min: -Infinity
|
min: -Infinity
|
||||||
label: qsTr("Min X")
|
label: qsTr("Min X")
|
||||||
icon: "icons/settings/xmin.svg"
|
icon: "settings/xmin.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
defValue: settings.xmin
|
defValue: settings.xmin
|
||||||
onChanged: function(newValue) {
|
onChanged: function(newValue) {
|
||||||
|
@ -205,7 +205,7 @@ ScrollView {
|
||||||
isDouble: true
|
isDouble: true
|
||||||
min: -Infinity
|
min: -Infinity
|
||||||
label: qsTr("Max Y")
|
label: qsTr("Max Y")
|
||||||
icon: "icons/settings/ymax.svg"
|
icon: "settings/ymax.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
defValue: settings.ymax
|
defValue: settings.ymax
|
||||||
onChanged: function(newValue) {
|
onChanged: function(newValue) {
|
||||||
|
@ -220,7 +220,7 @@ ScrollView {
|
||||||
isDouble: true
|
isDouble: true
|
||||||
min: -Infinity
|
min: -Infinity
|
||||||
label: qsTr("Max X")
|
label: qsTr("Max X")
|
||||||
icon: "icons/settings/xmax.svg"
|
icon: "settings/xmax.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
value: canvas.px2x(canvas.canvasSize.width).toFixed(2)
|
value: canvas.px2x(canvas.canvasSize.width).toFixed(2)
|
||||||
onChanged: function(xvaluemax) {
|
onChanged: function(xvaluemax) {
|
||||||
|
@ -239,7 +239,7 @@ ScrollView {
|
||||||
isDouble: true
|
isDouble: true
|
||||||
min: -Infinity
|
min: -Infinity
|
||||||
label: qsTr("Min Y")
|
label: qsTr("Min Y")
|
||||||
icon: "icons/settings/ymin.svg"
|
icon: "settings/ymin.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
defValue: canvas.px2y(canvas.canvasSize.height).toFixed(2)
|
defValue: canvas.px2y(canvas.canvasSize.height).toFixed(2)
|
||||||
onChanged: function(yvaluemin) {
|
onChanged: function(yvaluemin) {
|
||||||
|
@ -256,7 +256,7 @@ ScrollView {
|
||||||
id: xAxisStep
|
id: xAxisStep
|
||||||
height: 30
|
height: 30
|
||||||
label: qsTr("X Axis Step")
|
label: qsTr("X Axis Step")
|
||||||
icon: "icons/settings/xaxisstep.svg"
|
icon: "settings/xaxisstep.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
defValue: settings.xaxisstep
|
defValue: settings.xaxisstep
|
||||||
visible: !settings.logscalex
|
visible: !settings.logscalex
|
||||||
|
@ -270,7 +270,7 @@ ScrollView {
|
||||||
id: yAxisStep
|
id: yAxisStep
|
||||||
height: 30
|
height: 30
|
||||||
label: qsTr("Y Axis Step")
|
label: qsTr("Y Axis Step")
|
||||||
icon: "icons/settings/yaxisstep.svg"
|
icon: "settings/yaxisstep.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
defValue: settings.yaxisstep
|
defValue: settings.yaxisstep
|
||||||
onChanged: function(newValue) {
|
onChanged: function(newValue) {
|
||||||
|
@ -285,7 +285,7 @@ ScrollView {
|
||||||
isDouble: true
|
isDouble: true
|
||||||
label: qsTr("Line width")
|
label: qsTr("Line width")
|
||||||
min: 1
|
min: 1
|
||||||
icon: "icons/settings/linewidth.svg"
|
icon: "settings/linewidth.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
defValue: settings.linewidth
|
defValue: settings.linewidth
|
||||||
onChanged: function(newValue) {
|
onChanged: function(newValue) {
|
||||||
|
@ -300,7 +300,7 @@ ScrollView {
|
||||||
isDouble: true
|
isDouble: true
|
||||||
label: qsTr("Text size (px)")
|
label: qsTr("Text size (px)")
|
||||||
min: 1
|
min: 1
|
||||||
icon: "icons/settings/textsize.svg"
|
icon: "settings/textsize.svg"
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
defValue: settings.textsize
|
defValue: settings.textsize
|
||||||
onChanged: function(newValue) {
|
onChanged: function(newValue) {
|
||||||
|
@ -314,7 +314,7 @@ ScrollView {
|
||||||
height: 30
|
height: 30
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
label: qsTr('X Label')
|
label: qsTr('X Label')
|
||||||
icon: "icons/settings/xlabel.svg"
|
icon: "settings/xlabel.svg"
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
ListElement { text: "" }
|
ListElement { text: "" }
|
||||||
ListElement { text: "x" }
|
ListElement { text: "x" }
|
||||||
|
@ -340,7 +340,7 @@ ScrollView {
|
||||||
height: 30
|
height: 30
|
||||||
width: settings.settingWidth
|
width: settings.settingWidth
|
||||||
label: qsTr('Y Label')
|
label: qsTr('Y Label')
|
||||||
icon: "icons/settings/ylabel.svg"
|
icon: "settings/ylabel.svg"
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
ListElement { text: "" }
|
ListElement { text: "" }
|
||||||
ListElement { text: "y" }
|
ListElement { text: "y" }
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg"><rect style="fill:#000;fill-rule:evenodd;stroke-width:3" width="2" height="18" x="11" y="3" ry="0"/><path style="fill:#000;fill-rule:evenodd;stroke-width:3" d="M3 11h18v2H3z"/></svg>
|
|
Before Width: | Height: | Size: 245 B |
|
@ -0,0 +1 @@
|
||||||
|
../common/appearance.svg
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg6"
|
||||||
|
sodipodi:docname="add.svg"
|
||||||
|
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs10" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview8"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="34.458333"
|
||||||
|
inkscape:cx="12"
|
||||||
|
inkscape:cy="12.01451"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1007"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg6" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-rule:evenodd;stroke-width:3.67423"
|
||||||
|
width="3"
|
||||||
|
height="18"
|
||||||
|
x="10.5"
|
||||||
|
y="3"
|
||||||
|
ry="0"
|
||||||
|
id="rect2" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-rule:evenodd;stroke-width:3.67423"
|
||||||
|
d="m 3,10.5 h 18 v 3 H 3 Z"
|
||||||
|
id="path4" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg6"
|
||||||
|
sodipodi:docname="remove.svg"
|
||||||
|
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs10" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview8"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="34.458333"
|
||||||
|
inkscape:cx="12"
|
||||||
|
inkscape:cy="10.505441"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1007"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg6">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid822" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<path
|
||||||
|
id="rect2"
|
||||||
|
style="fill-rule:evenodd;stroke-width:3.16228"
|
||||||
|
transform="rotate(135)"
|
||||||
|
d="M -1.4142136,-26.870058 H 1.4142136 V -7.0710678 H -1.4142136 Z"
|
||||||
|
sodipodi:nodetypes="ccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-rule:evenodd;stroke-width:3.16228"
|
||||||
|
d="M 20,6 6,20 4,18 18,4 Z"
|
||||||
|
id="path4"
|
||||||
|
sodipodi:nodetypes="ccccc" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg6"
|
||||||
|
sodipodi:docname="modify.svg"
|
||||||
|
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs10" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview8"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="34.458333"
|
||||||
|
inkscape:cx="11.767836"
|
||||||
|
inkscape:cy="11.085853"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1007"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg6">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid827" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<path
|
||||||
|
id="rect2"
|
||||||
|
style="fill-rule:evenodd;stroke-width:3.16228"
|
||||||
|
d="m 8,1 h 8 V 9 L 13,6 3,16 1,14 11,4 Z"
|
||||||
|
sodipodi:nodetypes="cccccccc" />
|
||||||
|
<path
|
||||||
|
id="rect2-3"
|
||||||
|
style="fill-rule:evenodd;stroke-width:3.16228"
|
||||||
|
d="M 16,23 H 8 v -8 l 3,3 10,-10 2,2 -10,10 z"
|
||||||
|
sodipodi:nodetypes="cccccccc" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1 @@
|
||||||
|
../common/label.svg
|
|
@ -0,0 +1 @@
|
||||||
|
../common/position.svg
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="visibility.svg"
|
||||||
|
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="34.458333"
|
||||||
|
inkscape:cx="12"
|
||||||
|
inkscape:cy="12.01451"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1007"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid896" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<path
|
||||||
|
d="m 12.015,7 c 4.751,0 8.063,3.012 9.504,4.636 C 20.118,13.473 16.806,17 12.015,17 7.595,17 4.085,13.464 2.537,11.593 4.03,9.946 7.354,7 12.015,7 Z m 0,-2 C 4.446,5 0,11.551 0,11.551 0,11.551 4.835,19 12.015,19 19.748,19 24,11.551 24,11.551 24,11.551 19.709,5 12.015,5 Z"
|
||||||
|
fill="#000000"
|
||||||
|
id="path2"
|
||||||
|
sodipodi:nodetypes="scscsscscs" />
|
||||||
|
<path
|
||||||
|
id="path894"
|
||||||
|
style="fill:#000000;fill-rule:evenodd;stroke-width:3"
|
||||||
|
d="M 12 8.5 A 3.5 3.5 0 0 0 8.5 12 A 3.5 3.5 0 0 0 12 15.5 A 3.5 3.5 0 0 0 15.5 12 A 3.5 3.5 0 0 0 12 8.5 z M 11 9.5 A 1.5 1.5 0 0 1 12.5 11 A 1.5 1.5 0 0 1 11 12.5 A 1.5 1.5 0 0 1 9.5 11 A 1.5 1.5 0 0 1 11 9.5 z " />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.pragma library
|
||||||
|
|
||||||
|
|
||||||
|
class Action {
|
||||||
|
// Type of the action done.
|
||||||
|
type(){return 'Unknown'}
|
||||||
|
|
||||||
|
// Icon associated with the item
|
||||||
|
|
||||||
|
// TargetName is the name of the object that's targeted by the event.
|
||||||
|
constructor(targetName = "", targetType = "Point") {
|
||||||
|
this.targetName = targetName
|
||||||
|
this.targetType = targetType
|
||||||
|
}
|
||||||
|
|
||||||
|
undo() {}
|
||||||
|
|
||||||
|
redo() {}
|
||||||
|
|
||||||
|
export() {
|
||||||
|
return [this.targetName, this.targetType]
|
||||||
|
}
|
||||||
|
|
||||||
|
getReadableString() {
|
||||||
|
return 'Unknown action'
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,12 @@ class Action {
|
||||||
// Type of the action done.
|
// Type of the action done.
|
||||||
type(){return 'Unknown'}
|
type(){return 'Unknown'}
|
||||||
|
|
||||||
|
// Icon of the action to be used in history browser.
|
||||||
|
icon(){return 'unknown'}
|
||||||
|
|
||||||
|
// Color associated with the action.
|
||||||
|
color(darkVer=false){return darkVer ? 'black' : 'white'}
|
||||||
|
|
||||||
// TargetName is the name of the object that's targeted by the event.
|
// TargetName is the name of the object that's targeted by the event.
|
||||||
constructor(targetName = "", targetType = "Point") {
|
constructor(targetName = "", targetType = "Point") {
|
||||||
this.targetName = targetName
|
this.targetName = targetName
|
||||||
|
@ -55,6 +61,10 @@ class CreateNewObject extends Action {
|
||||||
// Action used for the creation of an object
|
// Action used for the creation of an object
|
||||||
type(){return 'CreateNewObject'}
|
type(){return 'CreateNewObject'}
|
||||||
|
|
||||||
|
icon(){return 'create'}
|
||||||
|
|
||||||
|
color(darkVer=false){return darkVer ? 'green' : 'lime'}
|
||||||
|
|
||||||
constructor(targetName = "", targetType = "Point", properties = []) {
|
constructor(targetName = "", targetType = "Point", properties = []) {
|
||||||
super(targetName, targetType)
|
super(targetName, targetType)
|
||||||
this.targetProperties = properties
|
this.targetProperties = properties
|
||||||
|
@ -84,6 +94,10 @@ class DeleteObject extends CreateNewObject {
|
||||||
// Action used at the deletion of an object. Basicly the same thing as creating a new object, except Redo & Undo are reversed.
|
// Action used at the deletion of an object. Basicly the same thing as creating a new object, except Redo & Undo are reversed.
|
||||||
type(){return 'DeleteObject'}
|
type(){return 'DeleteObject'}
|
||||||
|
|
||||||
|
icon(){return 'delete'}
|
||||||
|
|
||||||
|
color(darkVer=false){return darkVer ? 'darkred' : 'salmon'}
|
||||||
|
|
||||||
undo() {
|
undo() {
|
||||||
super.redo()
|
super.redo()
|
||||||
}
|
}
|
||||||
|
@ -101,6 +115,10 @@ class EditedProperty extends Action {
|
||||||
// Action used everytime an object's property has been changed
|
// Action used everytime an object's property has been changed
|
||||||
type(){return 'EditedProperty'}
|
type(){return 'EditedProperty'}
|
||||||
|
|
||||||
|
icon(){return 'modify'}
|
||||||
|
|
||||||
|
color(darkVer=false){return darkVer ? 'darkslateblue' : 'cyan'}
|
||||||
|
|
||||||
constructor(targetName = "", targetType = "Point", targetProperty = "visible", previousValue = false, newValue = true, valueIsExpressionNeedingImport = false) {
|
constructor(targetName = "", targetType = "Point", targetProperty = "visible", previousValue = false, newValue = true, valueIsExpressionNeedingImport = false) {
|
||||||
super(targetName, targetType)
|
super(targetName, targetType)
|
||||||
this.targetProperty = targetProperty
|
this.targetProperty = targetProperty
|
||||||
|
@ -109,10 +127,10 @@ class EditedProperty extends Action {
|
||||||
this.newValue = newValue
|
this.newValue = newValue
|
||||||
this.propertyType = Objects.types[targetType].properties()[targetProperty]
|
this.propertyType = Objects.types[targetType].properties()[targetProperty]
|
||||||
if(valueIsExpressionNeedingImport) {
|
if(valueIsExpressionNeedingImport) {
|
||||||
if(propertyType == "Expression") {
|
if(this.propertyType == "Expression") {
|
||||||
this.previousValue = new MathLib.Expression(this.previousValue);
|
this.previousValue = new MathLib.Expression(this.previousValue);
|
||||||
this.newValue = new MathLib.Expression(this.newValue);
|
this.newValue = new MathLib.Expression(this.newValue);
|
||||||
} else if(propertyType == "Domain") {
|
} else if(this.propertyType == "Domain") {
|
||||||
this.previousValue = MathLib.parseDomain(this.previousValue);
|
this.previousValue = MathLib.parseDomain(this.previousValue);
|
||||||
this.newValue = MathLib.parseDomain(this.newValue);
|
this.newValue = MathLib.parseDomain(this.newValue);
|
||||||
} else {
|
} else {
|
||||||
|
@ -178,10 +196,22 @@ class EditedVisibility extends EditedProperty {
|
||||||
// Action used everytime an object's property has been changed
|
// Action used everytime an object's property has been changed
|
||||||
type(){return 'EditedVisibility'}
|
type(){return 'EditedVisibility'}
|
||||||
|
|
||||||
|
icon(){return 'visibility'}
|
||||||
|
|
||||||
|
color(darkVer=false){
|
||||||
|
return this.newValue ?
|
||||||
|
(darkVer ? 'darkgray' : 'whitesmoke') :
|
||||||
|
(darkVer ? 'dimgray' : 'lightgray')
|
||||||
|
}
|
||||||
|
|
||||||
constructor(targetName = "", targetType = "Point", newValue = true) {
|
constructor(targetName = "", targetType = "Point", newValue = true) {
|
||||||
super(targetName, targetType, "visible", !newValue, newValue)
|
super(targetName, targetType, "visible", !newValue, newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export() {
|
||||||
|
return [this.targetName, this.targetType, this.newValue]
|
||||||
|
}
|
||||||
|
|
||||||
getReadableString() {
|
getReadableString() {
|
||||||
if(this.newValue) {
|
if(this.newValue) {
|
||||||
return qsTr('%1 %2 shown.').arg(this.targetType).arg(this.targetName)
|
return qsTr('%1 %2 shown.').arg(this.targetType).arg(this.targetName)
|
||||||
|
@ -193,12 +223,21 @@ class EditedVisibility extends EditedProperty {
|
||||||
|
|
||||||
class NameChanged extends EditedProperty {
|
class NameChanged extends EditedProperty {
|
||||||
// Action used everytime an object's property has been changed
|
// Action used everytime an object's property has been changed
|
||||||
type(){return 'EditedVisibility'}
|
type(){return 'NameChanged'}
|
||||||
|
|
||||||
|
icon(){return 'name'}
|
||||||
|
|
||||||
|
|
||||||
|
color(darkVer=false){return darkVer ? 'darkorange' : 'orange'}
|
||||||
|
|
||||||
constructor(targetName = "", targetType = "Point", newName = "") {
|
constructor(targetName = "", targetType = "Point", newName = "") {
|
||||||
super(targetName, targetType, "name", targetName, newName)
|
super(targetName, targetType, "name", targetName, newName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export() {
|
||||||
|
return [this.targetName, this.targetType, this.newValue]
|
||||||
|
}
|
||||||
|
|
||||||
undo() {
|
undo() {
|
||||||
Objects.getObjectByName(this.newValue, this.targetType)['name'] = this.previousValue
|
Objects.getObjectByName(this.newValue, this.targetType)['name'] = this.previousValue
|
||||||
}
|
}
|
||||||
|
@ -206,6 +245,29 @@ class NameChanged extends EditedProperty {
|
||||||
redo() {
|
redo() {
|
||||||
Objects.getObjectByName(this.previousValue, this.targetType)[this.targetProperty] = this.newValue
|
Objects.getObjectByName(this.previousValue, this.targetType)[this.targetProperty] = this.newValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getReadableString() {
|
||||||
|
return qsTr('Name of %1 %2 changed to %3.')
|
||||||
|
.arg(Objects.types[this.targetType].displayType())
|
||||||
|
.arg(this.targetName).arg(this.newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColorChanged extends EditedProperty {
|
||||||
|
// Action used everytime an object's property has been changed
|
||||||
|
type(){return 'ColorChanged'}
|
||||||
|
|
||||||
|
icon(){return 'appearance'}
|
||||||
|
|
||||||
|
|
||||||
|
color(darkVer=false){return darkVer ? 'purple' : 'plum'}
|
||||||
|
|
||||||
|
getReadableString() {
|
||||||
|
return qsTr('%1 of %2 %3 changed from "%4" to "%5".')
|
||||||
|
.arg(QT_TRANSLATE_NOOP('prop','color'))
|
||||||
|
.arg(Objects.types[this.targetType].displayType())
|
||||||
|
.arg(this.targetName).arg(this.previousValue).arg(this.newValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var Actions = {
|
var Actions = {
|
||||||
|
@ -214,4 +276,6 @@ var Actions = {
|
||||||
"DeleteObject": DeleteObject,
|
"DeleteObject": DeleteObject,
|
||||||
"EditedProperty": EditedProperty,
|
"EditedProperty": EditedProperty,
|
||||||
"EditedVisibility": EditedVisibility,
|
"EditedVisibility": EditedVisibility,
|
||||||
|
"NameChanged": NameChanged,
|
||||||
|
"ColorChanged": ColorChanged,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue