Add Base.splice() to handle lists of items with _index referneces and use it for paper.documents and Item#children.

This commit is contained in:
Jürg Lehni 2011-05-07 16:11:05 +01:00
parent b44e796475
commit 8c7b253bc2
4 changed files with 46 additions and 18 deletions

View file

@ -50,12 +50,12 @@ var Document = this.Document = Base.extend({
this._size = Size.read(arguments) || new Size(1024, 768); this._size = Size.read(arguments) || new Size(1024, 768);
this.canvas = CanvasProvider.getCanvas(this._size); this.canvas = CanvasProvider.getCanvas(this._size);
} }
// TODO: currently we don't do anything with Document#bounds.. What // TODO: Currently we don't do anything with Document#bounds.
// does it mean to change the bounds of the document? (JP) // What does it mean to change the bounds of the document? (JP)
this.bounds = Rectangle.create(0, 0, this._size.width, this.bounds = Rectangle.create(0, 0, this._size.width,
this._size.height); this._size.height);
this.context = this.canvas.getContext('2d'); this.context = this.canvas.getContext('2d');
paper.documents.push(this); Base.splice(paper.documents, [this]);
this.activate(); this.activate();
this.layers = []; this.layers = [];
this.activeLayer = new Layer(); this.activeLayer = new Layer();
@ -65,7 +65,7 @@ var Document = this.Document = Base.extend({
this.views = [this.activeView]; this.views = [this.activeView];
this._selectedItems = {}; this._selectedItems = {};
this._selectedItemCount = 0; this._selectedItemCount = 0;
// TODO: test this on IE: // TODO: Test this on IE:
if (this.canvas.attributes.stats) { if (this.canvas.attributes.stats) {
this.stats = new Stats(); this.stats = new Stats();
// Align top-left to the canvas // Align top-left to the canvas
@ -102,6 +102,7 @@ var Document = this.Document = Base.extend({
}, },
activate: function() { activate: function() {
// TODO: Remove indexOf()
var index = paper.documents.indexOf(this); var index = paper.documents.indexOf(this);
if (index != -1) { if (index != -1) {
paper.document = this; paper.document = this;

View file

@ -251,24 +251,21 @@ var Item = this.Item = Base.extend({
* The next item on the same level as this item. * The next item on the same level as this item.
*/ */
getNextSibling: function() { getNextSibling: function() {
return this.parent && this.parent.children[this.getIndex() + 1] || null; return this.parent && this.parent.children[this._index + 1] || null;
}, },
/** /**
* The previous item on the same level as this item. * The previous item on the same level as this item.
*/ */
getPreviousSibling: function() { getPreviousSibling: function() {
return this.parent && this.parent.children[this.getIndex() - 1] || null; return this.parent && this.parent.children[this._index - 1] || null;
}, },
/** /**
* The index of this item within the list of it's parent's children. * The index of this item within the list of it's parent's children.
*/ */
getIndex: function() { getIndex: function() {
// TODO: Relying on indexOf() here is slow, especially since it is return this._index !== undefined ? this._index : null;
// used for getPrevious/NextSibling().
// We need linked lists instead.
return this.parent && this.parent.children.indexOf(this) || null;
}, },
/** /**
@ -276,8 +273,8 @@ var Item = this.Item = Base.extend({
*/ */
_removeFromParent: function() { _removeFromParent: function() {
if (this.parent) { if (this.parent) {
var ok = !!this.parent.children.splice(this.getIndex(), 1).length; var ok = !!Base.splice(this.parent.children, null,
// TODO: Reassign _index this._index, 1).length;
this.parent = null; this.parent = null;
return ok; return ok;
} }
@ -812,8 +809,7 @@ var Item = this.Item = Base.extend({
return function(item) { return function(item) {
item._removeFromParent(); item._removeFromParent();
if (this.children) { if (this.children) {
this.children.splice(top ? this.children.length : 0, 0, item); Base.splice(this.children, [item], top ? undefined : 0, 0);
// TODO: Reassign _index
item.parent = this; item.parent = this;
item._setDocument(this._document); item._setDocument(this._document);
return true; return true;
@ -826,9 +822,8 @@ var Item = this.Item = Base.extend({
return function(item) { return function(item) {
// first remove the item from its parent's children list // first remove the item from its parent's children list
if (item.parent && this._removeFromParent()) { if (item.parent && this._removeFromParent()) {
item.parent.children.splice(item.getIndex() Base.splice(item.parent.children, [this],
+ (above ? 1 : -1), 0, this); item._index + (above ? 1 : -1), 0);
// TODO: Reassign _index
this.parent = item.parent; this.parent = item.parent;
this._setDocument(item._document); this._setDocument(item._document);
return true; return true;

View file

@ -79,6 +79,38 @@ Base.inject({
return res; return res;
}, },
/**
* Utility function for adding and removing items from a list of which
* each entry keeps a reference to its index in the list in the private
* _index property. Used for paper.documents and Item#children.
*/
splice: function(list, items, index, remove) {
var amount = items && items.length,
append = index === undefined;
index = append ? list.length : index;
// Update _index on the items to be added first.
for (var i = 0; i < amount; i++) {
items[i]._index = index + i;
}
if (append) {
// Append them all at the end by using push
list.push.apply(list, items);
// Nothing removed, and nothing to adjust above
return [];
} else {
// Insert somewhere else and/or remove
var args = [index, remove];
if (items)
args.push.apply(args, items);
var removed = list.splice.apply(list, args);
// Adjust the indices of the items above.
for (var i = index + amount, l = list.length; i < l; i++) {
list[i]._index = i;
}
return removed;
}
},
capitalize: function(str) { capitalize: function(str) {
return str.replace(/\b[a-z]/g, function(match) { return str.replace(/\b[a-z]/g, function(match) {
return match.toUpperCase(); return match.toUpperCase();

View file

@ -145,7 +145,7 @@ var Path = this.Path = PathItem.extend({
var segments = this._segments, var segments = this._segments,
curves = this._curves, curves = this._curves,
amount = segs.length, amount = segs.length,
append = index === undefined, append = index == null,
index = append ? segments.length : index; index = append ? segments.length : index;
// Scan through segments to add first, convert if necessary and set // Scan through segments to add first, convert if necessary and set
// _path and _index references on them. // _path and _index references on them.