Permalink
Browse files

Merge branch 'fohr' into packaging

  • Loading branch information...
2 parents dd283b6 + f656e98 commit 73e6cbf3b5b3e1248ec24d47c57df27fcbf54661 clinuz committed Mar 23, 2012
View
227 application/surfaces/list_view.js
@@ -0,0 +1,227 @@
+// ==========================================================================
+// Project: Blossom - Modern, Cross-Platform Application Framework
+// Copyright: ©2012 Fohr Motion Picture Studios. All rights reserved.
+// License: Licensed under the GPLv3 license (see BLOSSOM-LICENSE).
+// ==========================================================================
+/*globals sc_assert ENFORCE_BLOSSOM_2DCONTEXT_API */
+
+sc_require('surfaces/scroll_view');
+
+/** @class
+ `SC.ListView` implements a scrollable view. You can use it
+ interchangeably with `SC.View`, the only difference is the scrolling.
+
+ Setting the bounds of the scroll is important.
+
+ @extends SC.ScrollView
+ @since Blossom 1.0
+*/
+SC.ListView = SC.ScrollView.extend({
+
+ content: null,
+ contentBindingDefault: SC.Binding.multiple(),
+
+ // ..........................................................
+ // SELECTION SUPPORT
+ //
+
+ selection: null,
+
+ _sc_selection: null,
+ _sc_selectionDidChange: function() {
+ var old = this._sc_selection,
+ cur = this.get('selection'),
+ func = this.triggerRendering;
+
+ if (old === cur) return; // nothing to do
+
+ if (old) old.removeObserver('[]', this, func);
+ this._sc_selection = cur;
+ if (cur) cur.addObserver('[]', this, func);
+
+ this.triggerRendering();
+ }.observes('selection'),
+
+ rowHeight: 30,
+
+ renderRow: function(context, width, height, index, object, isSelected) {
+ context.fillStyle = isSelected? '#99CCFF' : 'white';
+ context.fillRect(0, 0, width, height);
+
+ context.strokeStyle = 'grey';
+ context.lineWidth = 1;
+
+ context.beginPath();
+ context.moveTo(0, height - 0.5);
+ context.lineTo(width, height - 0.5);
+ context.stroke();
+
+ context.font = "12pt Calibri";
+ context.fillStyle = 'black';
+ context.textAlign = 'center';
+ context.textBaseline = 'middle';
+
+ context.fillText(String(index), width/2, height/2);
+ },
+
+ updateDisplay: function() {
+ // console.log('SC.ListView#updateDisplay()', SC.guidFor(this));
+ var benchKey = 'SC.ListView#updateDisplay()';
+ SC.Benchmark.start(benchKey);
+
+ var ctx = this._sc_context;
+ sc_assert(ctx);
+ sc_assert(document.getElementById(ctx.__sc_canvas__.id));
+
+ // Clear the background if requested.
+ if (this.get('clearBackground')) ctx.clearRect(0, 0, ctx.w, ctx.h);
+
+ if (this.willRenderLayers) {
+ ctx.save();
+ this.willRenderLayers(ctx);
+ ctx.restore();
+ }
+
+ var content = this.get('content'),
+ selection = this.get('selection'),
+ idx, len, w = ctx.w, h = this.get('rowHeight');
+
+ if (content && (len = content.get('length')) > 0) {
+ for (idx=0; idx<len; ++idx) {
+ var obj = content.objectAt(idx);
+ ctx.save();
+ ctx.translate(0, idx*h);
+ this.renderRow(ctx, w, h, idx, obj, selection.contains(obj));
+ ctx.restore();
+ }
+ }
+
+ if (this.didRenderLayers) {
+ ctx.save();
+ this.didRenderLayers(ctx);
+ ctx.restore();
+ }
+
+ SC.Benchmark.end(benchKey);
+ },
+
+ mouseDown: function(evt) {
+ // console.log('SC.ListView#mouseDown()', SC.guidFor(this));
+ var idx = Math.floor((evt.pageY - evt.target.getBoundingClientRect().top) / this.get('rowHeight')),
+ content = this._sc_content,
+ selection = this._sc_selection;
+
+ if (content && selection) {
+ var obj = content.objectAt(idx);
+ if (obj && !selection.contains(obj)) {
+ var sel = SC.SelectionSet.create();
+ sel.addObject(obj);
+ this.set('selection', sel.freeze());
+
+ var action = this.get('action');
+ if (action && typeof action === 'function') {
+ action.call(this, obj, idx);
+ }
+ // TODO: Support the usual target/action paradigm.
+ }
+ }
+ },
+
+ adjustLayout: function() {
+ // console.log('SC.ListView#adjustLayout()', SC.guidFor(this));
+ var benchKey = 'SC.ListView#adjustLayout()';
+ SC.Benchmark.start(benchKey);
+
+ var frame = SC.MakeRect(this.get('frame')),
+ content = this.get('content'),
+ rowHeight = this.get('rowHeight');
+
+ var rows = content? content.get('length') : 0;
+
+ frame[0]/*x*/ = 0;
+ frame[1]/*y*/ = 0;
+ frame[2]/*w*/ = frame[2]/*w*/ - 15; // account for scroller
+ frame[3]/*h*/ = Math.max(rows*rowHeight, frame[3]/*h*/);
+
+ // We never have to offset in this manner.
+ var scrollTranslation = this._sc_scrollTranslation;
+ scrollTranslation[0]/*x*/ = 0;
+ scrollTranslation[1]/*y*/ = 0;
+
+ this._sc_scrollingCanvas.set('frame', frame);
+
+ SC.Benchmark.end(benchKey);
+ },
+
+ _sc_content: null,
+ _sc_contentPropertyDidChange: function() {
+ // console.log('SC.ListView#_sc_contentPropertyDidChange()', SC.guidFor(this));
+ var func = this._sc_contentLengthDidChange,
+ old = this._sc_content,
+ cur = this.get('content');
+
+ if (old === cur) return;
+
+ if (old) {
+ this._sc_removeContentRangeObserver();
+ old.removeObserver('length', this, func);
+ }
+
+ this._sc_content = cur;
+
+ if (cur) {
+ cur.addObserver('length', this, func);
+ this._sc_updateContentRangeObserver();
+ }
+
+ this._sc_contentLengthDidChange();
+ }.observes('content'),
+
+ _sc_contentLengthDidChange: function() {
+ // console.log('SC.ListView#_sc_contentLengthDidChange()', SC.guidFor(this));
+ this._sc_updateContentRangeObserver();
+ this.triggerLayoutAndRendering();
+ },
+
+ _sc_contentRangeObserver: null,
+ _sc_updateContentRangeObserver: function() {
+ // console.log('SC.ListView#_sc_updateContentRangeObserver()', SC.guidFor(this));
+ var observer = this._sc_contentRangeObserver,
+ content = this.get('content');
+
+ if (!content) return ; // nothing to do
+
+ var nowShowing = SC.IndexSet.create(0, content.get('length'));
+
+ if (observer) {
+ content.updateRangeObserver(observer, nowShowing);
+ } else {
+ var func = this._sc_contentRangeDidChange;
+ observer = content.addRangeObserver(nowShowing, this, func, null, true);
+ this._sc_contentRangeObserver = observer;
+ }
+ },
+
+ _sc_contentRangeDidChange: function() {
+ // console.log('SC.ListView#_sc_contentRangeDidChange()', SC.guidFor(this));
+ this.triggerRendering();
+ },
+
+ _sc_removeContentRangeObserver: function() {
+ // console.log('SC.ListView#_sc_removeContentRangeObserver()', SC.guidFor(this));
+ var content = this.get('content'),
+ observer = this._sc_contentRangeObserver ;
+
+ if (observer) {
+ if (content) content.removeRangeObserver(observer);
+ this._sc_contentRangeObserver = null ;
+ }
+ },
+
+ init: function() {
+ arguments.callee.base.apply(this, arguments);
+ this._sc_contentPropertyDidChange();
+ this._sc_selectionDidChange();
+ }
+
+});
View
6 application/surfaces/private/psurface.js
@@ -132,6 +132,12 @@ SC.Psurface = function(surface) {
element.style.webkitBoxShadow = "0px 5px 15px rgba(1,1,1,0.5)";
}
+ var frame = surface.get('frame');
+ style.left = frame[0]/*x*/ + 'px';
+ style.top = frame[1]/*y*/ + 'px';
+ style.width = frame[2]/*width*/ + 'px';
+ style.height = frame[3]/*height*/ + 'px';
+
surface.didCreateElement(element);
this.parent = null;
View
21 application/surfaces/scroll_view.js
@@ -84,13 +84,11 @@ SC.ScrollView = SC.View.extend({
div.style.overflowY = this.get('hasVerticalScroller')? 'scroll' : 'hidden';
},
- updateLayout: function() {
- // console.log('SC.ScrollView#updateLayout()', SC.guidFor(this));
- var benchKey = 'SC.ScrollView#updateLayout()';
+ adjustLayout: function() {
+ // console.log('SC.ScrollView#adjustLayout()', SC.guidFor(this));
+ var benchKey = 'SC.ScrollView#adjustLayout()';
SC.Benchmark.start(benchKey);
- arguments.callee.base.apply(this, arguments);
-
// Our layers have been been updated. Calculate the union of the the
// AABB of all their frames in our own coordinate system.
var frame = SC.MakeRect(this.get('frame')),
@@ -121,6 +119,12 @@ SC.ScrollView = SC.View.extend({
SC.Benchmark.end(benchKey);
},
+ updateLayout: function() {
+ arguments.callee.base.apply(this, arguments);
+
+ this.adjustLayout();
+ },
+
_sc_scrollingCanvas: null,
init: function() {
@@ -144,7 +148,13 @@ SC.InternalScrollViewCanvas = SC.LeafSurface.extend({
__scrollView__: null,
+ surface: function() {
+ // console.log('SC.InternalScrollViewCanvas@surface');
+ return this.__scrollView__;
+ }.property().cacheable(),
+
didCreateElement: function(canvas) {
+ // console.log('SC.InternalScrollViewCanvas#didCreateElement()', SC.guidFor(this));
arguments.callee.base.apply(this, arguments);
var ctx = canvas.getContext('2d');
@@ -153,6 +163,7 @@ SC.InternalScrollViewCanvas = SC.LeafSurface.extend({
if (ENFORCE_BLOSSOM_2DCONTEXT_API) delete ctx.canvas;
this.__scrollView__._sc_context = ctx;
+ this.__scrollView__.triggerRendering();
}
});
View
1 application/surfaces/view.js
@@ -197,6 +197,7 @@ SC.View = SC.LeafSurface.extend({
if (ENFORCE_BLOSSOM_2DCONTEXT_API) delete ctx.canvas;
this._sc_context = ctx;
+ this.triggerRendering();
},
_sc_scrollTranslation: null,
View
2 application/widgets/text_field.js
@@ -168,7 +168,7 @@ SC.TextFieldWidget = SC.TextLayer.extend(SC.DelegateSupport, {
else if (this.get('isInputResponder')) {
SC.BeginEditingTextLayer(this);
}
- return false;
+ return true;
},
color: function() {
View
2 buildtools/buildtools.js
@@ -116,7 +116,7 @@ BT.File = BT.BuildNode.extend({
var sourcePath = this.get('sourcePath'),
sourceTree = path.normalize(this.get('sourceTree'));
- return sourcePath.slice(sourceTree.length+1);
+ return sourcePath.slice(sourceTree.length+1).replace(/\\/g, '/');
}.property().cacheable(),
contents: function() {
View
2 buildtools/server.js
@@ -50,7 +50,7 @@ BT.Server = BT.Object.extend({
that = this;
this._bt_server = http.createServer(function (req, res) {
- var url = path.normalize(req.url);
+ var url = path.normalize(req.url).replace(/\\/g, '/');
var start = new Date().getTime();
// if the url is in the project, send it back
View
4 datastore/models/child_attribute.js
@@ -25,7 +25,9 @@ sc_require('models/record_attribute');
*/
SC.ChildAttribute = SC.RecordAttribute.extend(
/** @scope SC.ChildAttribute.prototype */ {
-
+
+ isChildAttribute: true,
+
isNestedRecordTransform: true,
// ..........................................................
View
4 datastore/models/children_attribute.js
@@ -27,7 +27,9 @@ sc_require('system/child_array');
*/
SC.ChildrenAttribute = SC.ChildAttribute.extend(
/** @scope SC.ChildrenAttribute.prototype */ {
-
+
+ isChildrenAttribute: true,
+
// ..........................................................
// LOW-LEVEL METHODS
//
View
5 foundation/mixins/array.js
@@ -376,7 +376,7 @@ SC.Array = {
@param {Object} context optional context
@returns {SC.RangeObserver} range observer
*/
- addRangeObserver: function(indexes, target, method, context) {
+ addRangeObserver: function(indexes, target, method, context, isDeep) {
var rangeob = this._array_rangeObservers;
if (!rangeob) rangeob = this._array_rangeObservers = SC.CoreSet.create() ;
@@ -387,8 +387,7 @@ SC.Array = {
}
var C = this.rangeObserverClass ;
- var isDeep = false; //disable this feature for now
- var ret = C.create(this, indexes, target, method, context, isDeep) ;
+ var ret = C.create(this, indexes, target, method, context, !!isDeep) ;
rangeob.add(ret);
// first time a range observer is added, begin observing the [] property
View
6 foundation/system/index_set.js
@@ -4,9 +4,11 @@
// Portions ©2008-2010 Apple Inc. All rights reserved.
// License: Licensed under MIT license (see license.js)
// ==========================================================================
+/*globals global */
-sc_require('mixins/enumerable') ;
-sc_require('mixins/observable') ;
+sc_require('mixins/enumerable');
+sc_require('mixins/observable');
+sc_require('private/observer_queue');
sc_require('mixins/freezable');
sc_require('mixins/copyable');

0 comments on commit 73e6cbf

Please sign in to comment.