sproutcore 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest.txt +42 -29
- data/README.txt +1 -1
- data/Rakefile +5 -0
- data/app_generators/sproutcore/sproutcore_generator.rb +4 -4
- data/app_generators/sproutcore/templates/sc-config.rb +72 -0
- data/bin/sc-build +2 -0
- data/clients/sc_docs/controllers/docs.js +1 -0
- data/clients/sc_docs/english.lproj/body.rhtml +5 -0
- data/clients/sc_docs/views/doc_frame.js +1 -1
- data/clients/sc_test_runner/controllers/runner.js +2 -2
- data/clients/sc_test_runner/english.lproj/body.rhtml +5 -0
- data/clients/sc_test_runner/main.js +12 -12
- data/clients/sc_test_runner/models/test.js +3 -0
- data/clients/sc_test_runner/views/test_label.js +1 -1
- data/config/hoe.rb +2 -0
- data/frameworks/sproutcore/controllers/array.js +132 -125
- data/frameworks/sproutcore/drag/drag.js +5 -2
- data/frameworks/sproutcore/english.lproj/buttons.css +64 -64
- data/frameworks/sproutcore/english.lproj/collections.css +82 -0
- data/frameworks/sproutcore/english.lproj/images/buttons-sprite.png +0 -0
- data/frameworks/sproutcore/english.lproj/images/sproutcore-logo.png +0 -0
- data/frameworks/sproutcore/english.lproj/images/sticky-note.png +0 -0
- data/frameworks/sproutcore/english.lproj/menu.css +1 -1
- data/frameworks/sproutcore/english.lproj/theme.css +13 -4
- data/frameworks/sproutcore/foundation/array.js +24 -2
- data/frameworks/sproutcore/foundation/benchmark.js +12 -5
- data/frameworks/sproutcore/foundation/observable.js +62 -1
- data/frameworks/sproutcore/foundation/utils.js +16 -0
- data/frameworks/sproutcore/tests/views/label_item.rhtml +21 -0
- data/frameworks/sproutcore/tests/views/list.rhtml +21 -0
- data/frameworks/sproutcore/tests/views/scroll.rhtml +21 -0
- data/frameworks/sproutcore/views/collection.js +401 -73
- data/frameworks/sproutcore/views/collection/collection_item.js +36 -0
- data/frameworks/sproutcore/views/collection/grid.js +149 -0
- data/frameworks/sproutcore/views/collection/image_cell.js +154 -0
- data/frameworks/sproutcore/views/collection/list.js +115 -0
- data/frameworks/sproutcore/views/collection/text_cell.js +128 -0
- data/frameworks/sproutcore/views/image.js +1 -1
- data/frameworks/sproutcore/views/label.js +6 -2
- data/frameworks/sproutcore/views/scroll.js +34 -0
- data/frameworks/sproutcore/views/view.js +12 -4
- data/generators/client/client_generator.rb +3 -11
- data/generators/client/templates/english.lproj/body.css +75 -0
- data/generators/client/templates/english.lproj/body.rhtml +17 -2
- data/generators/model/templates/fixture.js +32 -0
- data/lib/sproutcore/build_tools/html_builder.rb +29 -11
- data/lib/sproutcore/build_tools/resource_builder.rb +1 -1
- data/lib/sproutcore/bundle.rb +19 -7
- data/lib/sproutcore/library.rb +39 -21
- data/lib/sproutcore/merb/bundle_controller.rb +3 -8
- data/lib/sproutcore/version.rb +1 -1
- data/lib/sproutcore/view_helpers.rb +7 -5
- data/lib/sproutcore/view_helpers/core_views.rb +11 -3
- data/sc-config.rb +7 -0
- data/tasks/deployment.rake +15 -2
- metadata +44 -31
- data/app_generators/sproutcore/templates/environment.yml +0 -4
- data/environment.yml +0 -9
@@ -0,0 +1,36 @@
|
|
1
|
+
// ========================================================================
|
2
|
+
// SproutCore
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
4
|
+
// ========================================================================
|
5
|
+
|
6
|
+
/**
|
7
|
+
Apply this mixin to any view class to automatically inherit most of the
|
8
|
+
basic properties you need to support to act as an item view in a collection.
|
9
|
+
|
10
|
+
In addition to this module, make sure that your view class knows how to
|
11
|
+
render the object set on the 'content' property.
|
12
|
+
|
13
|
+
This module provides both the properties and reasonable default observers.
|
14
|
+
You can override them in your own class as well.
|
15
|
+
|
16
|
+
@namespace
|
17
|
+
*/
|
18
|
+
SC.CollectionItem = {
|
19
|
+
|
20
|
+
/** Set to true when the item is selected. */
|
21
|
+
isSelected: false,
|
22
|
+
|
23
|
+
/** By default, adds the 'sel' CSS class if selected. */
|
24
|
+
isSelectedObserver: function() {
|
25
|
+
this.setClassName('sel', this.get('isSelected')) ;
|
26
|
+
}.observes('isSelected'),
|
27
|
+
|
28
|
+
/** Set to true when the item is enabled. */
|
29
|
+
isEnabled: true,
|
30
|
+
|
31
|
+
/** By default, adds the disabled CSS class if disabled. */
|
32
|
+
isEnabledObserver: function() {
|
33
|
+
this.setClassName('disabled', !this.get('isEnabled'));
|
34
|
+
}.observes('isEnabled')
|
35
|
+
|
36
|
+
};
|
@@ -0,0 +1,149 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// SC.GridView
|
3
|
+
// ==========================================================================
|
4
|
+
|
5
|
+
require('views/collection') ;
|
6
|
+
require('views/collection/text_cell');
|
7
|
+
|
8
|
+
/** @class
|
9
|
+
|
10
|
+
A grid view renders a collection of items in a grid of rows and columns.
|
11
|
+
|
12
|
+
@extends SC.CollectionView
|
13
|
+
@author Charles Jolley
|
14
|
+
@version 1.0
|
15
|
+
*/
|
16
|
+
SC.GridView = SC.CollectionView.extend(
|
17
|
+
/** @scope SC.GridView.prototype */ {
|
18
|
+
|
19
|
+
emptyElement: '<div class="grid-view"></div>',
|
20
|
+
|
21
|
+
/**
|
22
|
+
The common row height for grid items.
|
23
|
+
|
24
|
+
The value should be an integer expressed in pixels.
|
25
|
+
*/
|
26
|
+
rowHeight: 48,
|
27
|
+
|
28
|
+
/**
|
29
|
+
The minimum column width for grid items. Items will actually
|
30
|
+
be laid out as needed to completely fill the space, but the minimum
|
31
|
+
width of each item will be this value.
|
32
|
+
*/
|
33
|
+
columnWidth: 64,
|
34
|
+
|
35
|
+
/**
|
36
|
+
The default example item view will render text-based items.
|
37
|
+
|
38
|
+
You can override this as you wish.
|
39
|
+
*/
|
40
|
+
exampleView: SC.TextCellView,
|
41
|
+
|
42
|
+
insertionOrientation: SC.HORIZONTAL_ORIENTATION,
|
43
|
+
|
44
|
+
/** @private */
|
45
|
+
layoutChildViewsFor: function(parentView, startingView) {
|
46
|
+
var rowHeight = this.get('rowHeight') ;
|
47
|
+
var columnWidth = this.get('columnWidth') ;
|
48
|
+
if ((rowHeight == null) || (columnWidth == null)) return false ;
|
49
|
+
|
50
|
+
// set items per row.
|
51
|
+
parentView = parentView || this ;
|
52
|
+
var f = parentView.get('frame') ;
|
53
|
+
f.x= f.y = 0 ;
|
54
|
+
var itemsPerRow = Math.floor(f.width / (columnWidth || 1)) ;
|
55
|
+
if (this.get('itemsPerRow') != itemsPerRow) this.set('itemsPerRow', itemsPerRow);
|
56
|
+
|
57
|
+
// fix width to evenly match items per row
|
58
|
+
columnWidth = Math.floor(f.width/itemsPerRow) ;
|
59
|
+
|
60
|
+
// get the startingView and the starting X,Y
|
61
|
+
if (!startingView) startingView = parentView.firstChild ;
|
62
|
+
var x,y ;
|
63
|
+
if (startingView && startingView.previousSibling) {
|
64
|
+
var prevFrame = startingView.previousSibling.get('frame') ;
|
65
|
+
x = SC.maxX(prevFrame); y = SC.minY(prevFrame) ;
|
66
|
+
} else { x = f.x; y = f.y; }
|
67
|
+
|
68
|
+
// Now setup the default frame
|
69
|
+
var maxX = SC.maxX(f);
|
70
|
+
var minX = f.x;
|
71
|
+
f = { x: 0, y: 0, height: rowHeight, width: columnWidth } ;
|
72
|
+
var view = startingView ;
|
73
|
+
while(view) {
|
74
|
+
// loop back to beginning of next line if needed.
|
75
|
+
if (x >= maxX) {
|
76
|
+
x = minX ;
|
77
|
+
y += rowHeight ;
|
78
|
+
}
|
79
|
+
|
80
|
+
// save frame
|
81
|
+
view.set('isPositioned', true) ;
|
82
|
+
f.y = y ; f.x = x;
|
83
|
+
if (!SC.rectsEqual(view.get('frame'), f)) view.set('frame', f) ;
|
84
|
+
x += columnWidth;
|
85
|
+
view = view.nextSibling ;
|
86
|
+
}
|
87
|
+
return true;
|
88
|
+
},
|
89
|
+
|
90
|
+
// computedViewHeight: function(groupView) {
|
91
|
+
// var content = this.get('content') ;
|
92
|
+
// var rowHeight = this.get('rowHeight') ;
|
93
|
+
// var parentNode = this.get('parentNode') ;
|
94
|
+
// var minHeight = (parentNode) ? 20 : parentNode.get('frame').height ;
|
95
|
+
// var height = 0 ;
|
96
|
+
//
|
97
|
+
// if (content && rowHeight) {
|
98
|
+
// var rows = content.get('length') ;
|
99
|
+
// height = rows * rowHeight ;
|
100
|
+
// }
|
101
|
+
// if (height < minHeight) height = minHeight ;
|
102
|
+
// return height ;
|
103
|
+
// },
|
104
|
+
|
105
|
+
insertionPointClass: SC.View.extend({
|
106
|
+
emptyElement: '<div class="grid-insertion-point"><span class="anchor"></span></div>'
|
107
|
+
}),
|
108
|
+
|
109
|
+
showInsertionPointBefore: function(itemView) {
|
110
|
+
if (!itemView) return ;
|
111
|
+
|
112
|
+
if (!this._insertionPointView) {
|
113
|
+
this._insertionPointView = this.insertionPointClass.create() ;
|
114
|
+
} ;
|
115
|
+
|
116
|
+
var insertionPoint = this._insertionPointView ;
|
117
|
+
var itemViewFrame = itemView.get('frame') ;
|
118
|
+
f = { height: itemViewFrame.height - 6,
|
119
|
+
x: itemViewFrame.x,
|
120
|
+
y: itemViewFrame.y + 6,
|
121
|
+
width: 0
|
122
|
+
};
|
123
|
+
if (!SC.rectsEqual(insertionPoint.get('frame'), f)) {
|
124
|
+
insertionPoint.set('frame', f) ;
|
125
|
+
}
|
126
|
+
|
127
|
+
if (insertionPoint.parentNode != itemView.parentNode) {
|
128
|
+
itemView.parentNode.appendChild(insertionPoint) ;
|
129
|
+
}
|
130
|
+
},
|
131
|
+
|
132
|
+
hideInsertionPoint: function() {
|
133
|
+
var insertionPoint = this._insertionPointView ;
|
134
|
+
if (insertionPoint) insertionPoint.removeFromParent() ;
|
135
|
+
},
|
136
|
+
|
137
|
+
// // We can do this much faster programatically using the rowHeight
|
138
|
+
insertionIndexForLocation: function(loc) {
|
139
|
+
var f = this.get('frame') ;
|
140
|
+
loc = this.convertFrameFromView(loc, null) ;
|
141
|
+
|
142
|
+
var itemsPerRow = this.get('itemsPerRow') || 1 ;
|
143
|
+
var columnWidth = Math.floor(f.width / itemsPerRow) ;
|
144
|
+
var row = Math.floor((loc.y - f.y) / this.get('rowHeight') + 0.5) ;
|
145
|
+
var col = Math.floor((loc.x - f.x) / columnWidth + 0.5) ;
|
146
|
+
return (row*itemsPerRow) + col ;
|
147
|
+
}
|
148
|
+
|
149
|
+
}) ;
|
@@ -0,0 +1,154 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// SC.TextCellView
|
3
|
+
// ==========================================================================
|
4
|
+
|
5
|
+
require('views/collection/collection_item') ;
|
6
|
+
|
7
|
+
/** @class
|
8
|
+
|
9
|
+
An image cell displays a single image inside of a collection view. Unlike
|
10
|
+
a single imageView, the image cell will automatically position the image
|
11
|
+
inside of the view to reflect the actual size of the image on load.
|
12
|
+
|
13
|
+
@extends SC.View
|
14
|
+
@author AuthorName
|
15
|
+
@version 0.1
|
16
|
+
*/
|
17
|
+
SC.ImageCellView = SC.View.extend(SC.CollectionItem,
|
18
|
+
/** @scope SC.ImageCellView.prototype */ {
|
19
|
+
|
20
|
+
emptyElement: '<div class="image-cell collection-item"><img src="%@" style="position:relative;" /></div>'.fmt(static_url('blank')),
|
21
|
+
|
22
|
+
/**
|
23
|
+
The content object this image item view will display.
|
24
|
+
*/
|
25
|
+
content: null,
|
26
|
+
|
27
|
+
/**
|
28
|
+
The owner view of this cell. The ImageCell relies on this
|
29
|
+
view to provide many of its behavioral defaults and for
|
30
|
+
event handling.
|
31
|
+
*/
|
32
|
+
owner: null,
|
33
|
+
|
34
|
+
/**
|
35
|
+
Set this to a validator or to a function and the value
|
36
|
+
will be passed through it before being set.
|
37
|
+
|
38
|
+
This is a default default that can be overidden by the
|
39
|
+
settings in the owner view.
|
40
|
+
*/
|
41
|
+
formatter: null,
|
42
|
+
|
43
|
+
displayProperty: null,
|
44
|
+
|
45
|
+
/**
|
46
|
+
This is the required margin you want to appear around the image. Expressed in px
|
47
|
+
*/
|
48
|
+
imageMargin: 2,
|
49
|
+
|
50
|
+
/**
|
51
|
+
The imageView that will manage the image itself. No bindings are
|
52
|
+
configured for the image; the cell will simply inform it when
|
53
|
+
important changes occur.
|
54
|
+
*/
|
55
|
+
imageView: SC.ImageView.extend({
|
56
|
+
|
57
|
+
// Resizes the imageView to fix within the boundaries of its
|
58
|
+
// parent. Automatically triggered when load status changes and
|
59
|
+
// also by owner whenever it is resized.
|
60
|
+
sizeToFit: function() {
|
61
|
+
|
62
|
+
// find the best fit.
|
63
|
+
var f= this.owner.get('frame') ;
|
64
|
+
var margin = this.owner.get('imageMargin') ;
|
65
|
+
f.width -= margin*2 ;
|
66
|
+
f.height -= margin*2 ;
|
67
|
+
|
68
|
+
var w = this.get('imageWidth') ;
|
69
|
+
var h = this.get('imageHeight') ;
|
70
|
+
var wideScaleFactor = (f.width / w) ;
|
71
|
+
var tallScaleFactor = (f.height / h) ;
|
72
|
+
var scaleFactor = (tallScaleFactor < wideScaleFactor) ? tallScaleFactor : wideScaleFactor;
|
73
|
+
w = w * scaleFactor ; h = h*scaleFactor;
|
74
|
+
|
75
|
+
var f= this.owner.get('frame') ; // reset w/o margin
|
76
|
+
var newFrame = { width: w, height: h, x: Math.floor((f.width - w) /2), y: Math.floor((f.height - h) /2) };
|
77
|
+
if (!SC.rectsEqual(newFrame, this.get('frame'))) {
|
78
|
+
this.set('frame', newFrame);
|
79
|
+
}
|
80
|
+
|
81
|
+
}.observes('status')
|
82
|
+
|
83
|
+
}).outletFor('img?'),
|
84
|
+
|
85
|
+
outlets: ['imageView'],
|
86
|
+
|
87
|
+
resizeChildrenWithOldSize: function() {
|
88
|
+
if (this.get('content')) {
|
89
|
+
this.outlet('imageView').sizeToFit() ;
|
90
|
+
}
|
91
|
+
},
|
92
|
+
|
93
|
+
// invoked whenever the content object changes.
|
94
|
+
_contentObserver: function() {
|
95
|
+
var content = this.get('content') ;
|
96
|
+
if (this._content == content) return ;
|
97
|
+
var f = this._boundValueDidChange() ;
|
98
|
+
|
99
|
+
// stop observing the old display property, if there is one.
|
100
|
+
if (this._content && this._displayProperty) {
|
101
|
+
this._content.removeObserver(this._displayProperty, f) ;
|
102
|
+
}
|
103
|
+
|
104
|
+
// start observing the new display property, if there is one
|
105
|
+
this._displayProperty = this._getDefault('displayProperty') ;
|
106
|
+
this._content = content ;
|
107
|
+
if (this._content && this._displayProperty) {
|
108
|
+
this._content.addObserver(this._displayProperty, f) ;
|
109
|
+
}
|
110
|
+
|
111
|
+
// notify value did change
|
112
|
+
this._valueDidChange() ;
|
113
|
+
}.observes('content'),
|
114
|
+
|
115
|
+
/**
|
116
|
+
@private
|
117
|
+
|
118
|
+
Invoked whenever the monitored value on the content object
|
119
|
+
changes.
|
120
|
+
|
121
|
+
The value processed is either the displayProperty, if set, or
|
122
|
+
it is the content object itself.
|
123
|
+
*/
|
124
|
+
_valueDidChange: function() {
|
125
|
+
var content = this.get('content') ;
|
126
|
+
var value = (content && this._displayProperty) ? content.get(this._displayProperty) : content;
|
127
|
+
var owner = this.get('owner') ;
|
128
|
+
|
129
|
+
// prepare the value...
|
130
|
+
|
131
|
+
// 1. apply the formatter
|
132
|
+
var formatter = this._getDefault('formatter') ;
|
133
|
+
if (formatter) {
|
134
|
+
var formattedValue = ($type(formatter) == T_FUNCTION) ? formatter(value, this) : formatter.fieldValueForObject(value, this) ;
|
135
|
+
if (formattedValue != null) value = formattedValue ;
|
136
|
+
}
|
137
|
+
|
138
|
+
// 2. If the returned value is not a string, convert it.
|
139
|
+
if (($type(value) != T_NULL) && value.toString) value = value.toString() ;
|
140
|
+
|
141
|
+
// 3. Apply URL to image view.
|
142
|
+
this.outlet('imageView').set('content', value) ;
|
143
|
+
},
|
144
|
+
|
145
|
+
_boundValueDidChange: function() {
|
146
|
+
return this._boundValueDidChange = this._boundValueDidChange || this._valueDidChange.bind(this);
|
147
|
+
},
|
148
|
+
|
149
|
+
// Retrieves the default value from the owner or locally.
|
150
|
+
_getDefault: function(keyName) {
|
151
|
+
var ret = (this.owner) ? this.owner.get(keyName) : null ;
|
152
|
+
return (ret != null) ? ret : this.get(keyName) ;
|
153
|
+
}
|
154
|
+
}) ;
|
@@ -0,0 +1,115 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// SC.ListView
|
3
|
+
// ==========================================================================
|
4
|
+
|
5
|
+
require('views/collection') ;
|
6
|
+
require('views/collection/text_cell');
|
7
|
+
|
8
|
+
/** @class
|
9
|
+
|
10
|
+
A list view renders vertical lists of items. It is a specialized form of
|
11
|
+
collection view that is simpler than the table view, but more refined than
|
12
|
+
a generic collection.
|
13
|
+
|
14
|
+
You can use a list view just like a collection view, except that often you
|
15
|
+
also should provide a default rowHeight. Setting this value will allow
|
16
|
+
the ListView to optimize its rendering.
|
17
|
+
|
18
|
+
@extends SC.CollectionView
|
19
|
+
@author Charles Jolley
|
20
|
+
@version 1.0
|
21
|
+
*/
|
22
|
+
SC.ListView = SC.CollectionView.extend(
|
23
|
+
/** @scope SC.ListView.prototype */ {
|
24
|
+
|
25
|
+
emptyElement: '<div class="list-view"></div>',
|
26
|
+
|
27
|
+
/**
|
28
|
+
The common row height for list view items.
|
29
|
+
|
30
|
+
If you set this property, then the ListView will be able to use this
|
31
|
+
property to perform absolute layout of its children and to minimize t
|
32
|
+
number of actual views it has to create.
|
33
|
+
|
34
|
+
The value should be an integer expressed in pixels.
|
35
|
+
*/
|
36
|
+
rowHeight: 20,
|
37
|
+
|
38
|
+
/**
|
39
|
+
The default example item view will render text-based items.
|
40
|
+
|
41
|
+
You can override this as you wish.
|
42
|
+
*/
|
43
|
+
exampleView: SC.TextCellView,
|
44
|
+
|
45
|
+
insertionOrientation: SC.VERTICAL_ORIENTATION,
|
46
|
+
|
47
|
+
/** @private */
|
48
|
+
layoutChildViewsFor: function(parentView, startingView) {
|
49
|
+
var rowHeight = this.get('rowHeight') ;
|
50
|
+
if (rowHeight == null) return false ;
|
51
|
+
|
52
|
+
if (!startingView) startingView = parentView.firstChild ;
|
53
|
+
var y = (startingView && startingView.previousSibling) ? SC.maxY(startingView.previousSibling.get('frame')) : 0;
|
54
|
+
var f = (parentView || this).get('frame') ;
|
55
|
+
f = { x: 0, height: rowHeight } ;
|
56
|
+
var view = startingView || parentView.firstChild;
|
57
|
+
while(view) {
|
58
|
+
view.set('isPositioned', true) ;
|
59
|
+
f.y = y ;
|
60
|
+
if (!SC.rectsEqual(view.get('frame'), f)) view.set('frame', f) ;
|
61
|
+
y += rowHeight;
|
62
|
+
view = view.nextSibling ;
|
63
|
+
}
|
64
|
+
return true;
|
65
|
+
},
|
66
|
+
|
67
|
+
// computedViewHeight: function(groupView) {
|
68
|
+
// var content = this.get('content') ;
|
69
|
+
// var rowHeight = this.get('rowHeight') ;
|
70
|
+
// var parentNode = this.get('parentNode') ;
|
71
|
+
// var minHeight = (parentNode) ? 20 : parentNode.get('frame').height ;
|
72
|
+
// var height = 0 ;
|
73
|
+
//
|
74
|
+
// if (content && rowHeight) {
|
75
|
+
// var rows = content.get('length') ;
|
76
|
+
// height = rows * rowHeight ;
|
77
|
+
// }
|
78
|
+
// if (height < minHeight) height = minHeight ;
|
79
|
+
// return height ;
|
80
|
+
// },
|
81
|
+
|
82
|
+
insertionPointClass: SC.View.extend({
|
83
|
+
emptyElement: '<div class="list-insertion-point"><span class="anchor"></span></div>'
|
84
|
+
}),
|
85
|
+
|
86
|
+
showInsertionPointBefore: function(itemView) {
|
87
|
+
if (!itemView) return ;
|
88
|
+
|
89
|
+
if (!this._insertionPointView) {
|
90
|
+
this._insertionPointView = this.insertionPointClass.create() ;
|
91
|
+
} ;
|
92
|
+
|
93
|
+
var insertionPoint = this._insertionPointView ;
|
94
|
+
f = { height: 0, x: 8, y: itemView.get('frame').y, width: itemView.owner.get('frame').width };
|
95
|
+
insertionPoint.set('frame', f) ;
|
96
|
+
|
97
|
+
if (insertionPoint.parentNode != itemView.parentNode) {
|
98
|
+
itemView.parentNode.appendChild(insertionPoint) ;
|
99
|
+
}
|
100
|
+
},
|
101
|
+
|
102
|
+
hideInsertionPoint: function() {
|
103
|
+
var insertionPoint = this._insertionPointView ;
|
104
|
+
if (insertionPoint) insertionPoint.removeFromParent() ;
|
105
|
+
},
|
106
|
+
|
107
|
+
// We can do this much faster programatically using the rowHeight
|
108
|
+
insertionIndexForLocation: function(loc) {
|
109
|
+
var f = this.get('frame') ;
|
110
|
+
loc = this.convertFrameFromView(loc, null) ;
|
111
|
+
var ret = Math.floor((loc.y - f.y) / this.get('rowHeight') + 0.5) ;
|
112
|
+
return ret ;
|
113
|
+
}
|
114
|
+
|
115
|
+
}) ;
|