Add global undo for graph

This commit is contained in:
Oleg Sh 2021-07-17 21:53:21 +02:00
parent 50f1d0b936
commit 112e2b37ae
6 changed files with 97 additions and 40 deletions

View File

@ -734,6 +734,11 @@ Application.prototype.SetHandlerMode = function(mode)
var setupBackgroundStyle = new SetupBackgroundStyle(this);
setupBackgroundStyle.show();
}
else if (mode == "graphUndo")
{
if (!this.IsUndoStackEmpty())
this.Undo();
}
else if (g_AlgorithmIds.indexOf(mode) >= 0)
{
this.handler = new AlgorithmGraphHandler(this, g_Algorithms[g_AlgorithmIds.indexOf(mode)](this.graph, this));
@ -819,6 +824,9 @@ Application.prototype.onPostLoadEvent = function()
}
}
if (this.IsUndoStackEmpty())
document.getElementById('GraphUndo').style.display = 'none';
this.updateMessage();
this.redrawGraph();
}
@ -1341,14 +1349,18 @@ Application.prototype.PushToStack = function(actionName)
{
var object = {};
object.actionName = actionName;
object.graphSave = this.graph.SaveToXML("");
object.graphSave = this.graph.SaveToXML(this.SaveUserSettings());
this.undoStack.push(object);
while (this.undoStack.length > this.maxUndoStackSize)
{
this.undoStack.shift();
}
//console.log("push undo:" + object.actionName + " size =" + this.undoStack.length);
document.getElementById('GraphUndo').style.display = 'inline-block';
}
Application.prototype.Undo = function()
@ -1358,9 +1370,18 @@ Application.prototype.Undo = function()
var state = this.undoStack.pop();
this.graph = new Graph();
var empty;
this.graph.LoadFromXML(state.graphSave, empty);
var userSettings = {};
this.graph.LoadFromXML(state.graphSave, userSettings);
if (userSettings.hasOwnProperty("data") && userSettings["data"].length > 0)
this.LoadUserSettings(userSettings["data"]);
this.redrawGraph();
//console.log("undo:" + state.actionName + " size =" + this.undoStack.length);
if (this.IsUndoStackEmpty())
document.getElementById('GraphUndo').style.display = 'none';
}
Application.prototype.ClearUndoStack = function()

View File

@ -50,4 +50,4 @@ BaseBackgroundDrawer.prototype.Draw = function(style, width, height, position, s
context.fillRect(-rect.minPoint.x, -rect.minPoint.y, rect.size().x + 1, rect.size().y + 1);
context.globalAlpha = 1.0;
}
}
}

View File

@ -175,6 +175,8 @@ TextEnumVertexsCustom.prototype.ShowDialog = function(callback, buttonText, titl
var dialogButtons = {};
app = this.app;
dialogButtons[buttonText] = function() {
app.PushToStack("RenameVertex");
callback(new TextEnumTitle(app, $("#VertexTitle").val()));
$( this ).dialog( "close" );
};

View File

@ -15,7 +15,7 @@ function BaseHandler(app)
this.app = app;
this.app.setRenderPath([]);
this.app.ClearUndoStack();
//this.app.ClearUndoStack();
}
// Need redraw or nor.
@ -212,6 +212,7 @@ function DefaultHandler(app)
this.groupingSelect = false;
this.selectedLogRect = false;
this.selectedLogCtrl = false;
this.saveUndo = false;
}
// inheritance.
@ -225,12 +226,24 @@ DefaultHandler.prototype.MouseMove = function(pos)
{
if (this.dragObject)
{
if (!this.saveUndo)
{
this.app.PushToStack("Move");
this.saveUndo = true;
}
this.dragObject.position.x = pos.x;
this.dragObject.position.y = pos.y;
this.needRedraw = true;
}
else if (this.selectedObjects.length > 0 && this.pressed && !this.groupingSelect)
{
if (!this.saveUndo)
{
this.app.PushToStack("Move");
this.saveUndo = true;
}
var offset = (new Point(pos.x, pos.y)).subtract(this.prevPosition);
for (var i = 0; i < this.selectedObjects.length; i ++)
{
@ -241,7 +254,7 @@ DefaultHandler.prototype.MouseMove = function(pos)
}
}
this.prevPosition = pos;
this.needRedraw = true;
this.needRedraw = true;
}
else if (this.pressed)
{
@ -332,6 +345,7 @@ DefaultHandler.prototype.RenameVertex = function(text)
DefaultHandler.prototype.MouseUp = function(pos)
{
this.saveUndo = false;
this.message = g_textsSelectAndMove + " <span class=\"hidden-phone\">" + g_selectGroupText + "</span>";
this.dragObject = null;
this.pressed = false;
@ -361,7 +375,7 @@ DefaultHandler.prototype.MouseUp = function(pos)
};
$('#message').unbind();
$('#message').on('click', '#renameButton', function(){
var customEnum = new TextEnumVertexsCustom();
var customEnum = new TextEnumVertexsCustom(handler.app);
customEnum.ShowDialog(callback, g_rename, g_renameVertex, handler.selectedObject.mainText);
});
$('#message').on('click', '#changeCommonStyle', function(){
@ -399,6 +413,8 @@ DefaultHandler.prototype.MouseUp = function(pos)
var dialogButtons = {};
dialogButtons[g_save] = function() {
handler.app.PushToStack("ChangeCurvelEdge");
handler.selectedObject.SetWeight(document.getElementById('EdgeWeight').value);
handler.selectedObject.SetUpText(document.getElementById('EdgeLable').value);
@ -441,12 +457,16 @@ DefaultHandler.prototype.MouseUp = function(pos)
});
$('#message').on('click', '#incCurvel', function(){
handler.app.PushToStack("ChangeCurvelEdge");
handler.selectedObject.model.ChangeCurvedValue(DefaultHandler.prototype.curvedValue);
handler.needRedraw = true;
handler.app.redrawGraph();
userAction("Edge.Bend");
});
$('#message').on('click', '#decCurvel', function(){
handler.app.PushToStack("ChangeCurvelEdge");
handler.selectedObject.model.ChangeCurvedValue(-DefaultHandler.prototype.curvedValue);
handler.needRedraw = true;
handler.app.redrawGraph();
@ -514,6 +534,8 @@ DefaultHandler.prototype.MouseUp = function(pos)
$('#message').unbind();
$('#message').on('click', '#DublicateSelected', function(){
handler.app.PushToStack("DublicateSelection");
userAction("GroupSelected.Dublicate");
var newSelected = [];
@ -578,6 +600,8 @@ DefaultHandler.prototype.MouseUp = function(pos)
});
$('#message').on('click', '#RemoveSelected', function(){
handler.app.PushToStack("RemoveSelection");
userAction("GroupSelected.Remove");
for(var i = 0; i < handler.selectedObjects.length; i ++)
@ -660,6 +684,8 @@ AddGraphHandler.prototype = Object.create(BaseHandler.prototype);
AddGraphHandler.prototype.MouseDown = function(pos)
{
this.app.PushToStack("Add");
this.app.CreateNewGraph(pos.x, pos.y);
this.needRedraw = true;
this.inited = false;
@ -750,11 +776,13 @@ ConnectionGraphHandler.prototype.SelectVertex = function(selectedObject)
}
dialogButtons[g_orintEdge] = function() {
handler.AddNewEdge(selectedObject, true);
handler.app.PushToStack("Connect");
handler.AddNewEdge(selectedObject, true);
$( this ).dialog( "close" );
};
dialogButtons[g_notOrintEdge] = function() {
handler.AddNewEdge(selectedObject, false);
handler.app.PushToStack("Connect");
handler.AddNewEdge(selectedObject, false);
$( this ).dialog( "close" );
};
@ -882,31 +910,6 @@ DeleteGraphHandler.prototype.MouseDown = function(pos)
this.app.PushToStack("Delete");
this.app.DeleteObject(selectedObject);
this.needRedraw = true;
this.UpdateUndoButton();
}
DeleteGraphHandler.prototype.UpdateUndoButton = function()
{
if (!this.app.IsUndoStackEmpty())
{
this.message = g_selectObjectToDelete + "<span style=\"float:right;\"><button type=\"button\" id=\"undoDelete\" class=\"btn btn-default btn-xs\"> " + g_Undo + " </button>";
var handler = this;
$('#message').unbind();
$('#message').on('click', '#undoDelete', function(){
handler.app.Undo();
userAction("Undo.Delete");
handler.UpdateUndoButton();
});
}
else
{
this.message = g_selectObjectToDelete;
}
this.app.updateMessage();
}
/**
@ -923,6 +926,8 @@ DeleteAllHandler.prototype = Object.create(BaseHandler.prototype);
DeleteAllHandler.prototype.clear = function()
{
this.app.PushToStack("DeleteAll");
// Selected Graph.
this.app.graph = new Graph();
this.app.savedGraphName = "";
@ -966,6 +971,7 @@ ShowAdjacencyMatrix.prototype.show = function()
});
dialogButtons[g_save] = function() {
handler.app.PushToStack("ChangeAdjacencyMatrix");
handler.app.SetAdjacencyMatrixSmart($( "#AdjacencyMatrixField" ).val());
$( this ).dialog( "close" );
};
@ -1029,7 +1035,8 @@ ShowIncidenceMatrix.prototype.show = function()
});
dialogButtons[g_save] = function() {
handler.app.SetIncidenceMatrixSmart($( "#IncidenceMatrixField" ).val());
handler.app.PushToStack("IncidenceMatrixChanged");
handler.app.SetIncidenceMatrixSmart($( "#IncidenceMatrixField" ).val());
$( this ).dialog( "close" );
};
dialogButtons[g_cancel] = function() {
@ -1409,6 +1416,8 @@ GroupRenameVertices.prototype.show = function()
var app = this.app;
dialogButtons[g_save] = function() {
app.PushToStack("Rename");
var titlesList = $( "#VertextTitleList" ).val().split('\n');
for (i = 0; i < Math.min(graph.vertices.length, titlesList.length); i ++)
{
@ -1622,6 +1631,8 @@ SetupVertexStyle.prototype.show = function(index, selectedVertexes)
class : "MarginLeft",
click : function() {
app.PushToStack("ChangeStyle");
applyDiameter(forAll ? (new VertexModel()).diameter : app.GetDefaultVertexSize());
var indexes = [];
@ -1655,6 +1666,8 @@ SetupVertexStyle.prototype.show = function(index, selectedVertexes)
dialogButtons[g_save] = function() {
app.PushToStack("ChangeStyle");
applyDiameter(parseInt($( "#vertexSize" ).val()));
var indexes = [];
@ -1915,6 +1928,8 @@ SetupEdgeStyle.prototype.show = function(index, selectedEdges)
text : g_default,
class : "MarginLeft",
click : function() {
app.PushToStack("ChangeStyle");
applyWidth(forAll ? (new EdgeModel()).width : app.GetDefaultEdgeWidth());
var indexes = [];
if (self.index == "all")
@ -1947,6 +1962,8 @@ SetupEdgeStyle.prototype.show = function(index, selectedEdges)
dialogButtons[g_save] = function() {
app.PushToStack("ChangeStyle");
applyWidth(parseInt($( "#edgeWidth" ).val()));
var indexes = [];
@ -2040,7 +2057,7 @@ SetupBackgroundStyle.prototype.show = function()
var dialogButtons = {};
var graph = this.app.graph;
var app = this.app;
var style = Object.assign({}, app.backgroundCommonStyle);
var style = FullObjectCopy(app.backgroundCommonStyle);
var fillFields = function()
{
@ -2069,6 +2086,9 @@ SetupBackgroundStyle.prototype.show = function()
text : g_default,
class : "MarginLeft",
click : function() {
app.PushToStack("ChangeBackground");
app.ResetBackgroundStyle();
app.redrawGraph();
$( this ).dialog( "close" );
@ -2076,6 +2096,7 @@ SetupBackgroundStyle.prototype.show = function()
};
dialogButtons[g_save] = function() {
app.PushToStack("ChangeBackground");
app.SetBackgroundStyle(style);
app.redrawGraph();
$( this ).dialog( "close" );

View File

@ -240,6 +240,8 @@ function postLoadPage()
var key = getChar(event);
var code = getCharCode(event);
console.log(key + " code=" + code);
var evtobj = window.event ? event : e;
var isCtrl = evtobj ? evtobj.ctrlKey : false;
var moveValue = 10;
if (code == 61 || code == 43) // +
@ -289,6 +291,11 @@ function postLoadPage()
{
selectHandler('Default', 'default');
}
else if (code == 26 && isCtrl)
{
userAction("Key_GraphUndo");
application.SetHandlerMode("graphUndo");
}
}
$(document).keydown(function(event) {
@ -463,6 +470,12 @@ function postLoadPage()
userAction(this.id);
application.SetHandlerMode("setupBackgroundStyle");
}
document.getElementById('GraphUndo').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("graphUndo");
}
document.getElementById('runUserScript').onclick = function ()
{
@ -652,8 +665,6 @@ function postLoadPage()
});
var devTools = document.getElementById('developerTools');
devTools.style.left = 0;
resizeCanvas();

View File

@ -10,7 +10,7 @@
<script src="<?= Root('i/js/dev/jquery-ui.js')?>"></script>
<script src="<?= Root('i/js/dev/jquery.feedback_me.js')?>"></script>
<script src="<?= Root("script/example.js?v=46")?>" ></script>
<script src="<?= Root("script/example.js?v=47")?>" ></script>
</head>
<!--
<div class="pull-right">
@ -134,6 +134,8 @@
</ul>
</div>
<button type="button" class="btn btn-default btn-sm" id="GraphUndo"><span class="glyphicon glyphicon-arrow-left fa-fw"></span><span class="hidden-phone"> <?= L('undo')?> <sub style="color:#AAAAAA">crtl+z</sub></span></button>
<!--
<? if (!$wasVote && count($voteTopics) > 0): ?>
<button type="button" class="btn btn-success" id="VoteButton"><span class="glyphicon glyphicon-thumbs-up"></span> <?= L('vote') ?></button>