Skip to content

Instantly share code, notes, and snippets.

@SpacyRicochet
Created December 4, 2011 09:15
Show Gist options
  • Save SpacyRicochet/1429692 to your computer and use it in GitHub Desktop.
Save SpacyRicochet/1429692 to your computer and use it in GitHub Desktop.
Dynamic row size experiments
// ==========================================================================
// Project: MonsterDesigner
// Copyright: @2011 My Company, Inc.
// ==========================================================================
/*globals MonsterDesigner */
MonsterDesigner = SC.Application.create({
store: SC.Store.create().from(SC.Record.fixtures)
});
MonsterDesigner.statechart = SC.Statechart.create({
autoInitStatechart: NO,
rootState: SC.State.design({
initialSubstate: 'ready',
ready: SC.State.plugin('MonsterDesigner.ReadyState')
})
});
// The main pane is made visible on screen as soon as your app is loaded.
// Add childViews to this pane for views to display immediately on page
// load.
MonsterDesigner.pane = SC.Pane.create({
defaultResponder: 'MonsterDesigner.statechart',
childViews: 'splitView'.w(),
splitView: SC.SplitView.design({
backgroundColor: 'red',
dividerThickness: 1,
defaultThickness: 200,
layout: { centerX: 0, centerY: 0, width: 960, height: 768 },
topLeftView: SC.ScrollView.design({
layout: { top: 36, bottom: 32, left: 0, right: 0 },
contentView: SC.ListView.design({
backgroundColor: 'cyan',
contentValueKey: 'name',
contentBinding: 'MonsterDesigner.monstersController.arrangedObjects',
selectionBinding: 'MonsterDesigner.monstersController.selection',
actOnSelect: YES,
action: 'showMonster'
})
}),
bottomRightView: SC.ContainerView.design({
backgroundColor: 'purple',
layout: { left: 201 },
nowShowingBinding: 'MonsterDesigner.displayController.nowShowing'
})
})
});
SC.ready(function() {
console.log('SC.ready: starting initial statechart.');
MonsterDesigner.statechart.initStatechart();
});
/*globals MonsterDesigner */
/**
@class
@extends SC.ArrayController
*/
MonsterDesigner.monstersController = SC.ArrayController.create( SC.CollectionViewDelegate,
/** @scope MonsterDesigner.monstersController.prototype */ {
/**
* Only allow 1 row to be selected at anyone time.
* SC.CollectionView looks for this variable in it's content (which is this array)
*/
allowsMultipleSelection: NO,
// ArrayControllers have a selection property that allows them to know what object is selected in the binded CollectionView.
/**
* Returns the selected monster from the SelectionSet.
*/
selectedMonster: function() {
return this.get('selection').firstObject();
}.property('content')
});
/*globals MonsterDesigner */
MonsterDesigner.ReadyState = SC.State.extend({
// Basic state handling
initialSubstate: 'loading',
enterState: function() {
console.log('Entering MonsterDesigner.ReadyState.');
MonsterDesigner.pane.append();
},
exitState: function() {
console.log('exiting MonsterDesigner.ReadyState.');
MonsterDesigner.pane.remove();
},
// Substates
loading: SC.State.design({
// Status of the loading, for when the fetching is done asynchronously.
_loaded: 0, // This keeps track of the fetches that have been loaded already.
_total: 0, // This keeps track of how many fetches we have. Not sure why he initializes it to 0 though.
enterState: function() {
console.log('Entering MonsterDesigner.ReadyState.loading.');
// Set the status variables properly.
this._loaded = 0;
this._total = 1; // We're doing only one fetch at the moment.
// Call the fetch methods.
this._loadMonsters();
},
exitState: function() {
console.log('Exiting MonsterDesigner.ReadyState.loading.');
// Nothing in particular has to be done here.
},
_loadMonsters: function() {
console.log('Loading Monsters.');
var query = SC.Query.local(MonsterDesigner.Monster);
var data = MonsterDesigner.store.find(query);
data.addObserver('status', this, function observer() {
if(data.get('status') === SC.Record.READY_CLEAN) {
data.removeObserver('status', this, observer);
MonsterDesigner.monstersController.set('content', data);
this.get('statechart').invokeStateMethod('dataLoaded');
}
// TODO: should check for error messages as well.
});
// In case our data was already loaded (ie. synchronous).
data.notifyPropertyChange('status');
},
dataLoaded: function() {
console.log('Data has been loaded.');
// Process check. Are we done with fetching?
this._loaded++;
if(this._loaded === this._total) {
this.get('statechart').sendAction('gotoNone');
}
}
}),
none: SC.State.design({
// Basic state handling
initialSubstate: 'none',
enterState: function() {
console.log("Application ready");
},
exitState: function() {
console.log('Exiting application.');
// Nothing needs to be done here at the moment.
},
// Substates
none: SC.State,
showingMonster: SC.State.design({
// Some variables
_store : null,
// Basic state handling
enterState: function(context) {
console.log('Entering MonsterDesigner.ReadyState.showingMonster.');
// Use context to determine which monster we're showing.
var monster = context ? context.monster : null;
// Create parallel store.
var store = MonsterDesigner.store.chain();
// If we have a valid monster.
/// @todo: Why, if we already have a valid, monster, are we looking for it in the parallel store? Is that because we need a duplicate which keeps the real one safe until ready?
if(monster) {
monster = store.find(MonsterDesigner.Monster, monster.get('guid'));
MonsterDesigner.monsterController.set('content', monster);
}
this._store = store;
MonsterDesigner.displayController.set('nowShowing', 'MonsterDesigner.stackLayoutScrollView');
},
exitState: function() {
console.log('Exiting MonsterDesigner.ReadyState.showingMonster.');
this._store.discardChanges().destroy();
this._store = null;
},
// Actions
cancel: function() {
console.log('Canceling changes.');
this._store.discardChanges();
},
save: function() {
console.log('Saving changes.');
this._store.commitChanges(true);
}
}),
// Actions
showMonster: function(sender) {
console.log('Showing monster.');
var monster = MonsterDesigner.monstersController.get('selectedMonster');
this.gotoState('ready.none.showingMonster', { monster: monster });
return YES;
}
}),
// Actions
gotoNone: function() {
console.log('Going to none.');
this.gotoState('ready.none');
return YES;
}
});
/*globals MonsterDesigner */
MonsterDesigner.collectionController = SC.ArrayController.create({
content: function() {
var ary = [], idx, len;
for (idx=0, len=6; idx<len; ++idx) {
ary.push(SC.Object.create({
name: 'Item '+idx
}));
}
return ary;
}()
});
/*globals MonsterDesigner */
MonsterDesigner.stackLayoutScrollView = SC.StackedView.create({
classNames: 'scrollbars',
canReorderLayout: true,
childViews: 'collectionView'.w(),
stackedView: SC.StackedView.design({
layout: { height: 100 },
childViews: 'test1 test2 test3'.w(),
test1: SC.LabelView.create({
backgroundColor: 'blue',
layout:{ height: 50, width: 200 },
value: 'Lorem ipsum'
}),
test2: SC.LabelView.create({
backgroundColor: 'red',
layout:{ height: 30, width: 100 },
value: ' sit amet, consectetur'
}),
test3: SC.LabelView.create({
backgroundColor: 'yellow',
layout:{ height: 20, width: 100 },
value: ' adipiscing elit.'
})
}),
flowedLayout: SC.View.design( SC.FlowedLayout, {
layoutDirection: SC.LAYOUT_HORIZONTAL,
childViews: 'test1 test2 test3'.w(),
test1: SC.LabelView.create({
backgroundColor: 'purple',
layout:{ height: 20, width: 100 },
value: 'Lorem ipsum'
}),
test2: SC.LabelView.create({
backgroundColor: 'pink',
layout:{ height: 20, width: 100 },
value: ' sit amet,'
}),
test3: SC.LabelView.create({
backgroundColor: 'yellow',
layout:{ height: 20, width: 100 },
value: ' adipiscing elit.'
})
}),
collectionView: SC.CollectionView.design({
contentBinding: 'MonsterDesigner.collectionController.arrangedObjects',
selectionBinding: 'MonsterDesigner.collectionController.selection',
useStaticLayout: true,
tagName: 'ul',
exampleView: SC.View.design({
tagName: 'li',
useStaticLayout: true,
displayProperties: 'isSelected'.w(),
contentDisplayProperties: 'name'.w(),
render: function(context, firstTime) {
var content = this.get('content');
context.push(content.get('name'));
if (this.get('isSelected')) context.addClass('sel');
else context.removeClass('sel');
}
}),
// Remove 'Fake' from method name below to try out different views for each row.
createItemViewFake: function(exampleClass, idx, attrs) {
if(idx % 2 === 0) {
console.log('Showing rowType 1');
return SC.View.create({
layout: { height: 30 },
backgroundColor: 'blue',
useStaticLayout: true
});
}
else {
console.log('Showing rowType 2');
return SC.View.create({
layout: { height: 60 },
backgroundColor: 'orange',
useStaticLayout: true,
childViews: 'test'.w(),
test: SC.LabelView.create({
layout: { width: 100 },
value: "Testing if this wraps properly."
})
});
}
}
})
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment