Skip to content

Commit b0282b9

Browse files
committed
Change Segment to be aware of its index in the segment list and have the curves list update automatically on each change to segments.
1 parent 0680a50 commit b0282b9

4 files changed

Lines changed: 80 additions & 53 deletions

File tree

src/path/Curve.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,6 @@ var Curve = this.Curve = Base.extend({
117117
return this._index1;
118118
},
119119

120-
_setIndex: function(index) {
121-
this._index1 = index;
122-
this._updateSegments();
123-
},
124-
125120
getNext: function() {
126121
// TODO: No need to call getCurves() here?
127122
var curves = this._path && this._path._curves;

src/path/Path.js

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ var Path = this.Path = PathItem.extend({
4949
this._add(Segment.read(segments, i, 1));
5050
},
5151

52+
getFirstSegment: function() {
53+
return this._segments[0];
54+
},
55+
56+
getLastSegment: function() {
57+
return this._segments[this._segments.length - 1];
58+
},
59+
5260
/**
5361
* The curves contained within the path.
5462
*/
@@ -65,6 +73,15 @@ var Path = this.Path = PathItem.extend({
6573
return this._curves;
6674
},
6775

76+
getFirstCurve: function() {
77+
return this.getCurves()[0];
78+
},
79+
80+
getLastCurve: function() {
81+
var curves = this.getCurves();
82+
return curves[curves.length - 1];
83+
},
84+
6885
getClosed: function() {
6986
return this._closed;
7087
},
@@ -88,23 +105,6 @@ var Path = this.Path = PathItem.extend({
88105
}
89106
},
90107

91-
getFirstSegment: function() {
92-
return this._segments[0];
93-
},
94-
95-
getLastSegment: function() {
96-
return this._segments[this._segments.length - 1];
97-
},
98-
99-
getFirstCurve: function() {
100-
return this.getCurves()[0];
101-
},
102-
103-
getLastCurve: function() {
104-
var curves = this.getCurves();
105-
return curves[curves.length - 1];
106-
},
107-
108108
// TODO: Consider adding getSubPath(a, b), returning a part of the current
109109
// path, with the added benefit that b can be < a, and closed looping is
110110
// taken into account.
@@ -121,45 +121,87 @@ var Path = this.Path = PathItem.extend({
121121
/**
122122
* Private method that adds a segment to the segment list. It assumes that
123123
* the passed object is a segment already and does not perform any checks.
124+
* If a curves list was requested, it will kept in sync with the segments
125+
* list automatically.
124126
*/
127+
// TODO: Add support for adding multiple segments at once
125128
_add: function(segment, index) {
126129
// If this segment belongs to another path already, clone it before
127130
// adding.
128131
if (segment._path)
129132
segment = new Segment(segment);
130-
segment._path = this;
131133
if (index === undefined) {
132-
this._segments.push(segment);
134+
// Insert at the end
135+
index = this._segments.push(segment) - 1;
133136
} else {
137+
// Insert somewhere else
134138
this._segments.splice(index, 0, segment);
139+
// Adjust the indices of the segments above.
140+
for (var i = index + 1, l = this._segments.length; i < l; i++)
141+
this._segments[i]._index = i;
142+
}
143+
segment._path = this;
144+
segment._index = index;
145+
// Keep the curves list in sync all the time in case it as requested
146+
// already. We need to step one index down from the inserted segment to
147+
// get its curve:
148+
if (this._curves && --index >= 0) {
149+
// Insert a new curve as well and update the curves above
150+
this._curves.splice(index, 0, Curve.create(this, index));
151+
// Adjust indices now for the curves above this one.
152+
for (var i = index + 1, l = this._curves.length; i < l; i++) {
153+
var curve = this._curves[i];
154+
curve._index1 = i;
155+
// This is wrong for the last closing curve but it will be
156+
// corrected further down.
157+
curve._index2 = i + 1;
158+
}
159+
// The curve that comes right after will has changed beyond a simple
160+
// shift in indices, so it needs an update:
161+
this._curves[index + 1]._updateSegments();
162+
// If this is a closed path, also update the closing curve
163+
if (this._closed)
164+
this._curves[l - 1]._updateSegments();
135165
}
136166
return segment;
137167
},
138168

139-
// TODO: Support multiple segments?
169+
// TODO: Add support for adding multiple segments at once
140170
add: function(segment) {
141171
segment = Segment.read(arguments);
142172
return segment ? this._add(segment) : null;
143173
},
144174

145-
// TODO: Support multiple segments?
175+
// TODO: Add support for adding multiple segments at once
146176
insert: function(index, segment) {
147177
segment = Segment.read(arguments, 1);
148178
return segment ? this._add(segment, index) : null;
149179
},
150180

151181
// TODO: Port back to Sg
152182
removeSegment: function(index) {
153-
var segment = this._segments[index]
154-
return segment && segment.remove() ? segment : null;
183+
var segments = this.removeSegments(index, index + 1);
184+
return segments ? segments[0] : null;
155185
},
156186

157187
// TODO: Port back to Sg
158188
removeSegments: function(from, to) {
159-
var i = Base.pick(to, this._segments.length - 1),
160-
from = from || 0;
161-
while (i >= from)
162-
this.removeSegment(i--);
189+
from = from || 0;
190+
to = Base.pick(to, this._segments.length - 1);
191+
var amount = to - from,
192+
segments = this._segments.splice(from, amount);
193+
if (segments.length == amount) {
194+
// TODO: Keep _curves in sync
195+
for (var i = 0; i < amount; i++) {
196+
var segment = segments[0];
197+
if (segment._selectionState) {
198+
this._selectedSegmentCount--;
199+
segment._selectionState = 0;
200+
}
201+
}
202+
return segments;
203+
}
204+
return null;
163205
},
164206

165207
isSelected: function() {

src/path/Segment.js

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ var Segment = this.Segment = Base.extend({
2121
if (arguments.length == 0) {
2222
this._point = SegmentPoint.create(this, 0, 0);
2323
} else if (arguments.length == 1) {
24-
// TODO: If beans are not activated, this won't copy from
25-
// an existing segment. OK?
24+
// TODO: If beans are not activated, this won't copy from n existing
25+
// segment. OK?
2626
if (arg0.point) {
2727
this._point = SegmentPoint.create(this, arg0.point);
2828
this._handleIn = SegmentPoint.create(this, arg0.handleIn);
@@ -96,19 +96,17 @@ var Segment = this.Segment = Base.extend({
9696
? null : this._handleOut;
9797
},
9898

99-
getIndex: function() {
100-
// TODO: Cache and update indices instead of searching?
101-
// TODO: Return null instead of -1?
102-
return this._path ? this._path._segments.indexOf(this) : -1;
103-
},
104-
10599
getPath: function() {
106100
return this._path;
107101
},
108102

103+
getIndex: function() {
104+
return this._index;
105+
},
106+
109107
getCurve: function() {
110108
if (this._path != null) {
111-
var index = this.getIndex();
109+
var index = this._index;
112110
// The last segment of an open path belongs to the last curve
113111
if (!this._path._closed && index == this._path._segments.length - 1)
114112
index--;
@@ -119,13 +117,13 @@ var Segment = this.Segment = Base.extend({
119117

120118
getNext: function() {
121119
var segments = this._path && this._path._segments;
122-
return segments && (segments[this.getIndex() + 1]
120+
return segments && (segments[this._index + 1]
123121
|| this._path._closed && segments[0]) || null;
124122
},
125123

126124
getPrevious: function() {
127125
var segments = this._path && this._path._segments;
128-
return segments && (segments[this.getIndex() - 1]
126+
return segments && (segments[this._index - 1]
129127
|| this._path._closed && segments[segments.length - 1]) || null;
130128
},
131129

@@ -206,15 +204,7 @@ var Segment = this.Segment = Base.extend({
206204
},
207205

208206
remove: function() {
209-
if (this._path) {
210-
this._path._segments.splice(this.getIndex(), 1);
211-
if (this._selectionState) {
212-
this._path._selectedSegmentCount--;
213-
this._selectionState = 0;
214-
}
215-
return true;
216-
}
217-
return false;
207+
return this._path ? !!this._path.removeSegment(this._index) : false;
218208
},
219209

220210
toString: function() {

test/tests/Path.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ test('path.remove()', function() {
6969
path.removeSegment(0);
7070
equals(path.segments.length, 2);
7171

72-
path.removeSegments(0, 1);
72+
path.removeSegments(0, 2);
7373
equals(path.segments.length, 0);
7474

7575
path.remove();

0 commit comments

Comments
 (0)