mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-08-28 22:10:31 -04:00
Group mutations into same event.
This commit is contained in:
parent
02d60a2dbe
commit
55784580e9
4 changed files with 52 additions and 24 deletions
|
@ -227,12 +227,12 @@ Blockly.BlockSvg.terminateDrag_ = function() {
|
|||
Blockly.Events.setGroup(group);
|
||||
selected.snapToGrid();
|
||||
Blockly.Events.setGroup(false);
|
||||
}, Blockly.BUMP_DELAY / 2)
|
||||
}, Blockly.BUMP_DELAY / 2);
|
||||
setTimeout(function() {
|
||||
Blockly.Events.setGroup(group);
|
||||
selected.bumpNeighbours_();
|
||||
Blockly.Events.setGroup(false);
|
||||
}, Blockly.BUMP_DELAY)
|
||||
}, Blockly.BUMP_DELAY);
|
||||
// Fire an event to allow scrollbars to resize.
|
||||
Blockly.fireUiEvent(window, 'resize');
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ Blockly.Events.fire = function(event) {
|
|||
* @private
|
||||
*/
|
||||
Blockly.Events.fireNow_ = function() {
|
||||
var queue = Blockly.Events.filter_(Blockly.Events.FIRE_QUEUE_);
|
||||
var queue = Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_);
|
||||
Blockly.Events.FIRE_QUEUE_.length = 0;
|
||||
for (var i = 0, event; event = queue[i]; i++) {
|
||||
var workspace = Blockly.Workspace.getById(event.workspaceId);
|
||||
|
@ -111,9 +111,8 @@ Blockly.Events.fireNow_ = function() {
|
|||
* Filter the queued events and merge duplicates.
|
||||
* @param {!Array.<!Blockly.Events.Abstract>} queueIn Array of events.
|
||||
* @return {!Array.<!Blockly.Events.Abstract>} Array of filtered events.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Events.filter_ = function(queueIn) {
|
||||
Blockly.Events.filter = function(queueIn) {
|
||||
var queue = goog.array.clone(queueIn);
|
||||
// Merge duplicates. O(n^2), but n should be very small.
|
||||
for (var i = 0, event1; event1 = queue[i]; i++) {
|
||||
|
@ -145,6 +144,14 @@ Blockly.Events.filter_ = function(queueIn) {
|
|||
queue.splice(i, 1);
|
||||
}
|
||||
}
|
||||
// Move mutation events to the top of the queue.
|
||||
// Intentionally skip first event.
|
||||
for (var i = 1, event; event = queue[i]; i++) {
|
||||
if (event.type == Blockly.Events.CHANGE &&
|
||||
event.element == 'mutation') {
|
||||
queue.unshift(queue.splice(i, 1)[0]);
|
||||
}
|
||||
}
|
||||
return queue;
|
||||
};
|
||||
|
||||
|
@ -335,6 +342,8 @@ Blockly.Events.Change.prototype.run = function(forward) {
|
|||
var field = block.getField(this.name);
|
||||
if (field) {
|
||||
field.setValue(value);
|
||||
} else {
|
||||
console.warn("Can't set non-existant field: " + this.name);
|
||||
}
|
||||
break;
|
||||
case 'comment':
|
||||
|
@ -354,10 +363,17 @@ Blockly.Events.Change.prototype.run = function(forward) {
|
|||
// Close the mutator (if open) since we don't want to update it.
|
||||
block.mutator.setVisible(false);
|
||||
}
|
||||
var oldMutation = '';
|
||||
if (block.mutationToDom) {
|
||||
var oldMutationDom = block.mutationToDom();
|
||||
oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
|
||||
}
|
||||
if (block.domToMutation) {
|
||||
var dom = Blockly.Xml.textToDom('<xml>' + value + '</xml>');
|
||||
block.domToMutation(dom.firstChild);
|
||||
}
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
block, 'mutation', null, oldMutation, value));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -457,6 +473,8 @@ Blockly.Events.Move.prototype.run = function(forward) {
|
|||
var input = parentBlock.getInput(inputName);
|
||||
if (input) {
|
||||
parentConnection = input.connection;
|
||||
} else {
|
||||
console.warn("Can't connect to non-existant input: " + inputName);
|
||||
}
|
||||
} else if (blockConnection.type == Blockly.PREVIOUS_STATEMENT) {
|
||||
parentConnection = parentBlock.nextConnection;
|
||||
|
@ -466,4 +484,3 @@ Blockly.Events.Move.prototype.run = function(forward) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -280,29 +280,36 @@ Blockly.Mutator.prototype.workspaceChanged_ = function() {
|
|||
|
||||
// When the mutator's workspace changes, update the source block.
|
||||
if (this.rootBlock_.workspace == this.workspace_) {
|
||||
var oldMutationDom = this.block_.mutationToDom();
|
||||
Blockly.Events.setGroup(true);
|
||||
var block = this.block_;
|
||||
var oldMutationDom = block.mutationToDom();
|
||||
var oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
|
||||
// Switch off rendering while the source block is rebuilt.
|
||||
var savedRendered = this.block_.rendered;
|
||||
this.block_.rendered = false;
|
||||
var savedRendered = block.rendered;
|
||||
block.rendered = false;
|
||||
// Allow the source block to rebuild itself.
|
||||
this.block_.compose(this.rootBlock_);
|
||||
block.compose(this.rootBlock_);
|
||||
// Restore rendering and show the changes.
|
||||
this.block_.rendered = savedRendered;
|
||||
block.rendered = savedRendered;
|
||||
// Mutation may have added some elements that need initalizing.
|
||||
this.block_.initSvg();
|
||||
var newMutationDom = this.block_.mutationToDom();
|
||||
block.initSvg();
|
||||
var newMutationDom = block.mutationToDom();
|
||||
var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
|
||||
if (oldMutation != newMutation) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
this.block_, 'mutation', null, oldMutation, newMutation));
|
||||
goog.Timer.callOnce(
|
||||
this.block_.bumpNeighbours_, Blockly.BUMP_DELAY, this.block_);
|
||||
block, 'mutation', null, oldMutation, newMutation));
|
||||
// Ensure that any bump is part of this mutation's event group.
|
||||
var group = Blockly.Events.getGroup();
|
||||
setTimeout(function() {
|
||||
Blockly.Events.setGroup(group);
|
||||
block.bumpNeighbours_();
|
||||
}, Blockly.BUMP_DELAY);
|
||||
}
|
||||
if (this.block_.rendered) {
|
||||
this.block_.render();
|
||||
if (block.rendered) {
|
||||
block.render();
|
||||
}
|
||||
this.resizeBubble_();
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -214,15 +214,19 @@ Blockly.Workspace.prototype.undo = function(redo) {
|
|||
if (!event) {
|
||||
return;
|
||||
}
|
||||
Blockly.Events.recordUndo = false;
|
||||
event.run(redo);
|
||||
Blockly.Events.recordUndo = true;
|
||||
(redo ? this.undoStack_ : this.redoStack_).push(event);
|
||||
var events = [event];
|
||||
// Do another undo/redo if the next one is of the same group.
|
||||
if (sourceStack.length && event.group &&
|
||||
while (sourceStack.length && event.group &&
|
||||
event.group == sourceStack[sourceStack.length - 1].group) {
|
||||
this.undo(redo);
|
||||
events.push(sourceStack.pop());
|
||||
}
|
||||
events = Blockly.Events.filter(events);
|
||||
Blockly.Events.recordUndo = false;
|
||||
for (var i = 0, event; event = events[i]; i++) {
|
||||
event.run(redo);
|
||||
(redo ? this.undoStack_ : this.redoStack_).push(event);
|
||||
}
|
||||
Blockly.Events.recordUndo = true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue