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()
|
||||
height: visible ? implicitHeight : 0
|
||||
icon.name: modelData
|
||||
icon.source: './icons/' + modelData + '.svg'
|
||||
icon.source: './icons/objects/' + modelData + '.svg'
|
||||
icon.color: sysPalette.buttonText
|
||||
onTriggered: {
|
||||
var newObj = Objects.createNewRegisteredObject(modelData)
|
||||
|
|
|
@ -45,7 +45,12 @@ ScrollView {
|
|||
\qmlproperty int HistoryBrowser::actionHeight
|
||||
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 {
|
||||
width: parent.width
|
||||
|
@ -68,6 +73,7 @@ ScrollView {
|
|||
height: actionHeight
|
||||
isRedo: true
|
||||
idx: index
|
||||
darkTheme: historyBrowser.darkTheme
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +121,7 @@ ScrollView {
|
|||
height: actionHeight
|
||||
isRedo: false
|
||||
idx: index
|
||||
darkTheme: historyBrowser.darkTheme
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,4 +137,15 @@ ScrollView {
|
|||
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
|
||||
height: 30
|
||||
label: qsTr("Name")
|
||||
icon: "icons/common/label.svg"
|
||||
icon: "common/label.svg"
|
||||
min: 1
|
||||
width: dlgProperties.width
|
||||
value: objEditor.obj.name
|
||||
|
@ -105,7 +105,7 @@ D.Dialog {
|
|||
label: qsTr("Label content")
|
||||
model: [qsTr("null"), qsTr("name"), qsTr("name + value")]
|
||||
property var idModel: ["null", "name", "name + value"]
|
||||
icon: "icons/common/label.svg"
|
||||
icon: "common/label.svg"
|
||||
currentIndex: idModel.indexOf(objEditor.obj.labelContent)
|
||||
onActivated: function(newIndex) {
|
||||
if(idModel[newIndex] != objEditor.obj.labelContent) {
|
||||
|
@ -144,7 +144,7 @@ D.Dialog {
|
|||
height: visible ? 30 : 0
|
||||
width: parent.width
|
||||
label: parent.label
|
||||
icon: `icons/settings/custom/${parent.icon}.svg`
|
||||
icon: `settings/custom/${parent.icon}.svg`
|
||||
isDouble: modelData[1] == 'number'
|
||||
visible: paramTypeIn(modelData[1], ['Expression', 'Domain', 'string', 'number'])
|
||||
defValue: visible ? {
|
||||
|
@ -180,7 +180,7 @@ D.Dialog {
|
|||
height: visible ? 20 : 0
|
||||
width: parent.width
|
||||
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
|
||||
onClicked: {
|
||||
|
@ -200,7 +200,7 @@ D.Dialog {
|
|||
width: dlgProperties.width
|
||||
height: visible ? 30 : 0
|
||||
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.
|
||||
property bool selectObjMode: paramTypeIn(modelData[1], ['ObjectType'])
|
||||
property bool isRealObject: !selectObjMode || (modelData[1].objType != "ExecutableObject" && modelData[1].objType != "DrawableObject")
|
||||
|
@ -262,7 +262,7 @@ D.Dialog {
|
|||
|
||||
visible: paramTypeIn(modelData[1], ['List', 'Dict'])
|
||||
label: parent.label
|
||||
//icon: `icons/settings/custom/${parent.icon}.svg`
|
||||
//icon: `settings/custom/${parent.icon}.svg`
|
||||
dictionaryMode: paramTypeIn(modelData[1], ['Dict'])
|
||||
keyType: dictionaryMode ? modelData[1].keyType : 'string'
|
||||
valueType: visible ? modelData[1].valueType : 'string'
|
||||
|
|
|
@ -54,7 +54,7 @@ Column {
|
|||
height: visible ? implicitHeight : 0
|
||||
display: AbstractButton.TextUnderIcon
|
||||
icon.name: modelData
|
||||
icon.source: '../icons/' + modelData + '.svg'
|
||||
icon.source: '../icons/objects/' + modelData + '.svg'
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: sysPalette.buttonText
|
||||
|
|
|
@ -140,7 +140,7 @@ ListView {
|
|||
anchors.rightMargin: 5
|
||||
anchors.topMargin: 5
|
||||
icon.name: 'position'
|
||||
icon.source: '../icons/position.svg'
|
||||
icon.source: '../icons/common/position.svg'
|
||||
icon.color: sysPalette.buttonText
|
||||
property bool hasXProp: Objects.types[objType].properties().hasOwnProperty('x')
|
||||
property bool hasYProp: Objects.types[objType].properties().hasOwnProperty('y')
|
||||
|
@ -168,7 +168,7 @@ ListView {
|
|||
anchors.rightMargin: 5
|
||||
anchors.topMargin: 5
|
||||
icon.name: 'delete'
|
||||
icon.source: '../icons/delete.svg'
|
||||
icon.source: '../icons/common/delete.svg'
|
||||
icon.color: sysPalette.buttonText
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Delete %1 %2").arg(Objects.types[objType].displayType()).arg(obj.name)
|
||||
|
|
|
@ -103,7 +103,7 @@ Item {
|
|||
id: iconLabel
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: icon == "" ? 0 : 3
|
||||
source: control.visible ? "../" + control.icon : ""
|
||||
source: control.visible ? "../icons/" + control.icon : ""
|
||||
width: height
|
||||
height: icon == "" && visible ? 0 : 24
|
||||
color: sysPalette.windowText
|
||||
|
|
|
@ -86,7 +86,7 @@ Column {
|
|||
id: iconLabel
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: icon == "" ? 0 : 3
|
||||
source: control.visible ? "../" + control.icon : ""
|
||||
source: control.visible ? "../icons/" + control.icon : ""
|
||||
width: height
|
||||
height: icon == "" || !visible ? 0 : 24
|
||||
color: sysPalette.windowText
|
||||
|
@ -198,7 +198,7 @@ Column {
|
|||
id: deleteButton
|
||||
width: visible ? parent.height : 0
|
||||
height: width
|
||||
icon.source: './icons/delete.svg'
|
||||
icon.source: './icons/common/delete.svg'
|
||||
icon.name: 'delete'
|
||||
visible: !control.forbidAdding
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ Item {
|
|||
id: iconLabel
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: icon == "" ? 0 : 3
|
||||
source: control.visible ? "../" + control.icon : ""
|
||||
source: control.visible ? "../icons/" + control.icon : ""
|
||||
width: height
|
||||
height: icon == "" || !visible ? 0 : 24
|
||||
color: sysPalette.windowText
|
||||
|
|
|
@ -156,7 +156,7 @@ ScrollView {
|
|||
isDouble: true
|
||||
label: qsTr("X Zoom")
|
||||
min: 1
|
||||
icon: "icons/settings/xzoom.svg"
|
||||
icon: "settings/xzoom.svg"
|
||||
width: settings.settingWidth
|
||||
value: settings.xzoom.toFixed(2)
|
||||
onChanged: function(newValue) {
|
||||
|
@ -170,7 +170,7 @@ ScrollView {
|
|||
height: 30
|
||||
isDouble: true
|
||||
label: qsTr("Y Zoom")
|
||||
icon: "icons/settings/yzoom.svg"
|
||||
icon: "settings/yzoom.svg"
|
||||
width: settings.settingWidth
|
||||
value: settings.yzoom.toFixed(2)
|
||||
onChanged: function(newValue) {
|
||||
|
@ -186,7 +186,7 @@ ScrollView {
|
|||
isDouble: true
|
||||
min: -Infinity
|
||||
label: qsTr("Min X")
|
||||
icon: "icons/settings/xmin.svg"
|
||||
icon: "settings/xmin.svg"
|
||||
width: settings.settingWidth
|
||||
defValue: settings.xmin
|
||||
onChanged: function(newValue) {
|
||||
|
@ -205,7 +205,7 @@ ScrollView {
|
|||
isDouble: true
|
||||
min: -Infinity
|
||||
label: qsTr("Max Y")
|
||||
icon: "icons/settings/ymax.svg"
|
||||
icon: "settings/ymax.svg"
|
||||
width: settings.settingWidth
|
||||
defValue: settings.ymax
|
||||
onChanged: function(newValue) {
|
||||
|
@ -220,7 +220,7 @@ ScrollView {
|
|||
isDouble: true
|
||||
min: -Infinity
|
||||
label: qsTr("Max X")
|
||||
icon: "icons/settings/xmax.svg"
|
||||
icon: "settings/xmax.svg"
|
||||
width: settings.settingWidth
|
||||
value: canvas.px2x(canvas.canvasSize.width).toFixed(2)
|
||||
onChanged: function(xvaluemax) {
|
||||
|
@ -239,7 +239,7 @@ ScrollView {
|
|||
isDouble: true
|
||||
min: -Infinity
|
||||
label: qsTr("Min Y")
|
||||
icon: "icons/settings/ymin.svg"
|
||||
icon: "settings/ymin.svg"
|
||||
width: settings.settingWidth
|
||||
defValue: canvas.px2y(canvas.canvasSize.height).toFixed(2)
|
||||
onChanged: function(yvaluemin) {
|
||||
|
@ -256,7 +256,7 @@ ScrollView {
|
|||
id: xAxisStep
|
||||
height: 30
|
||||
label: qsTr("X Axis Step")
|
||||
icon: "icons/settings/xaxisstep.svg"
|
||||
icon: "settings/xaxisstep.svg"
|
||||
width: settings.settingWidth
|
||||
defValue: settings.xaxisstep
|
||||
visible: !settings.logscalex
|
||||
|
@ -270,7 +270,7 @@ ScrollView {
|
|||
id: yAxisStep
|
||||
height: 30
|
||||
label: qsTr("Y Axis Step")
|
||||
icon: "icons/settings/yaxisstep.svg"
|
||||
icon: "settings/yaxisstep.svg"
|
||||
width: settings.settingWidth
|
||||
defValue: settings.yaxisstep
|
||||
onChanged: function(newValue) {
|
||||
|
@ -285,7 +285,7 @@ ScrollView {
|
|||
isDouble: true
|
||||
label: qsTr("Line width")
|
||||
min: 1
|
||||
icon: "icons/settings/linewidth.svg"
|
||||
icon: "settings/linewidth.svg"
|
||||
width: settings.settingWidth
|
||||
defValue: settings.linewidth
|
||||
onChanged: function(newValue) {
|
||||
|
@ -300,7 +300,7 @@ ScrollView {
|
|||
isDouble: true
|
||||
label: qsTr("Text size (px)")
|
||||
min: 1
|
||||
icon: "icons/settings/textsize.svg"
|
||||
icon: "settings/textsize.svg"
|
||||
width: settings.settingWidth
|
||||
defValue: settings.textsize
|
||||
onChanged: function(newValue) {
|
||||
|
@ -314,7 +314,7 @@ ScrollView {
|
|||
height: 30
|
||||
width: settings.settingWidth
|
||||
label: qsTr('X Label')
|
||||
icon: "icons/settings/xlabel.svg"
|
||||
icon: "settings/xlabel.svg"
|
||||
model: ListModel {
|
||||
ListElement { text: "" }
|
||||
ListElement { text: "x" }
|
||||
|
@ -340,7 +340,7 @@ ScrollView {
|
|||
height: 30
|
||||
width: settings.settingWidth
|
||||
label: qsTr('Y Label')
|
||||
icon: "icons/settings/ylabel.svg"
|
||||
icon: "settings/ylabel.svg"
|
||||
model: ListModel {
|
||||
ListElement { text: "" }
|
||||
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(){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.
|
||||
constructor(targetName = "", targetType = "Point") {
|
||||
this.targetName = targetName
|
||||
|
@ -55,6 +61,10 @@ class CreateNewObject extends Action {
|
|||
// Action used for the creation of an object
|
||||
type(){return 'CreateNewObject'}
|
||||
|
||||
icon(){return 'create'}
|
||||
|
||||
color(darkVer=false){return darkVer ? 'green' : 'lime'}
|
||||
|
||||
constructor(targetName = "", targetType = "Point", properties = []) {
|
||||
super(targetName, targetType)
|
||||
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.
|
||||
type(){return 'DeleteObject'}
|
||||
|
||||
icon(){return 'delete'}
|
||||
|
||||
color(darkVer=false){return darkVer ? 'darkred' : 'salmon'}
|
||||
|
||||
undo() {
|
||||
super.redo()
|
||||
}
|
||||
|
@ -101,6 +115,10 @@ class EditedProperty extends Action {
|
|||
// Action used everytime an object's property has been changed
|
||||
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) {
|
||||
super(targetName, targetType)
|
||||
this.targetProperty = targetProperty
|
||||
|
@ -109,10 +127,10 @@ class EditedProperty extends Action {
|
|||
this.newValue = newValue
|
||||
this.propertyType = Objects.types[targetType].properties()[targetProperty]
|
||||
if(valueIsExpressionNeedingImport) {
|
||||
if(propertyType == "Expression") {
|
||||
if(this.propertyType == "Expression") {
|
||||
this.previousValue = new MathLib.Expression(this.previousValue);
|
||||
this.newValue = new MathLib.Expression(this.newValue);
|
||||
} else if(propertyType == "Domain") {
|
||||
} else if(this.propertyType == "Domain") {
|
||||
this.previousValue = MathLib.parseDomain(this.previousValue);
|
||||
this.newValue = MathLib.parseDomain(this.newValue);
|
||||
} else {
|
||||
|
@ -178,10 +196,22 @@ class EditedVisibility extends EditedProperty {
|
|||
// Action used everytime an object's property has been changed
|
||||
type(){return 'EditedVisibility'}
|
||||
|
||||
icon(){return 'visibility'}
|
||||
|
||||
color(darkVer=false){
|
||||
return this.newValue ?
|
||||
(darkVer ? 'darkgray' : 'whitesmoke') :
|
||||
(darkVer ? 'dimgray' : 'lightgray')
|
||||
}
|
||||
|
||||
constructor(targetName = "", targetType = "Point", newValue = true) {
|
||||
super(targetName, targetType, "visible", !newValue, newValue)
|
||||
}
|
||||
|
||||
export() {
|
||||
return [this.targetName, this.targetType, this.newValue]
|
||||
}
|
||||
|
||||
getReadableString() {
|
||||
if(this.newValue) {
|
||||
return qsTr('%1 %2 shown.').arg(this.targetType).arg(this.targetName)
|
||||
|
@ -193,12 +223,21 @@ class EditedVisibility extends EditedProperty {
|
|||
|
||||
class NameChanged extends EditedProperty {
|
||||
// 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 = "") {
|
||||
super(targetName, targetType, "name", targetName, newName)
|
||||
}
|
||||
|
||||
export() {
|
||||
return [this.targetName, this.targetType, this.newValue]
|
||||
}
|
||||
|
||||
undo() {
|
||||
Objects.getObjectByName(this.newValue, this.targetType)['name'] = this.previousValue
|
||||
}
|
||||
|
@ -206,6 +245,29 @@ class NameChanged extends EditedProperty {
|
|||
redo() {
|
||||
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 = {
|
||||
|
@ -214,4 +276,6 @@ var Actions = {
|
|||
"DeleteObject": DeleteObject,
|
||||
"EditedProperty": EditedProperty,
|
||||
"EditedVisibility": EditedVisibility,
|
||||
"NameChanged": NameChanged,
|
||||
"ColorChanged": ColorChanged,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue