Redesigning history browser.

This commit is contained in:
Adsooi 2022-01-30 03:16:47 +01:00
parent 402061a4b1
commit 95f7e683c7
Signed by: Ad5001
GPG key ID: EF45F9C6AFE20160
21 changed files with 460 additions and 31 deletions

View file

@ -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)

View file

@ -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
}
} }

View file

@ -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)
}
}

View file

@ -0,0 +1,5 @@
module eu.ad5001.LogarithmPlotter.History
History 1.0 History.qml
HistoryBrowser 1.0 HistoryBrowser.qml
HistoryItem 1.0 HistoryItem.qml

View file

@ -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'

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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" }

View file

@ -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

View file

@ -0,0 +1 @@
../common/appearance.svg

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
../common/label.svg

View file

@ -0,0 +1 @@
../common/position.svg

View file

@ -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

View file

@ -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'
}
}

View file

@ -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,
} }