Skip to content

Instantly share code, notes, and snippets.

@brianpattison
Created September 26, 2011 17:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianpattison/1242854 to your computer and use it in GitHub Desktop.
Save brianpattison/1242854 to your computer and use it in GitHub Desktop.
SproutCore Modifications for use in Titanium
// SproutCore Modifications to version 2.0.beta.3 Metal and Runtime,
// and SproutCore wrappers for several Appcelerator Titanium views
// Brian Pattison @brianpattison
///////////////////
// sproutcore.js //
///////////////////
// Added to the beginning of sproutcore.js
var window = {};
var console = {};
console.log = console.info = console.warn = console.error = Ti.API.info;
window.console = console;
// Changed SC.setPath to call the overridden set method in the SproutCore wrapped Titanium views
// This is required to make bindings propagate to the Titanium view
SC.setPath = function(root, path, value, tolerant) {
// ...
// Modified to work with Titanium
// return SC.set(root, keyName, value);
return root.set(keyName, value);
};
///////////////////
// bp.js //
///////////////////
// SproutCore Titanium Wrapper
BP = SC.Application.create();
// SproutCore relies on the window object for paths in bindings
window.BP = BP;
BP.Base = SC.Object.extend({
onClick: null,
init: function() {
var self = this,
view = this.get('view');
// Assign the options from creating the SproutCore objects to the Titanium view
for (keyName in self)
{
var value = self[keyName];
self.setTiViewProperty(keyName, value);
}
for (keyName in view)
{
SC.set(self, keyName, view[keyName]);
}
// Setup click event
var onClick = this.get('onClick');
if (onClick)
{
view.addEventListener('click', onClick);
}
},
add: function(scView) {
// Grab the Titanium views from the SproutCore objects to add them to each other
this.get('view').add(scView.get('view'));
},
remove: function(scView) {
// Grab the Titanium views from the SproutCore objects to remove
this.get('view').remove(scView.get('view'));
},
// Override set method to also change the Titanium object
set: function(keyName, value) {
this.setTiViewProperty(keyName, value);
SC.set(this, keyName, value);
return this;
},
setTiViewProperty: function(keyName, value) {
var view = this.get('view'),
keyNameLength = keyName.length,
startString = '',
endString = '',
bindingString = '';
// These conditions seem to prevent any interference between SproutCore and Titanium
if (keyNameLength >= 2) startString = keyName.substring(0, 2);
if (keyNameLength >= 4) endString = keyName.substring(keyNameLength - 4, keyNameLength);
if (keyNameLength >= 7) bindingString = keyName.substring(keyNameLength - 7, keyNameLength);
if (typeof(value) != 'function' && typeof(value) != 'undefined' && keyName != 'open' && keyName != 'view' && startString != 'is' && startString != '__' && endString != 'meta' && bindingString != 'Binding')
{
// Handle Tabs with window attributes
if (keyName == 'window')
{
view[keyName] = value.get('view');
}
// Handle TableViews with data attributes
else if (keyName == 'data' && value != null)
{
var data = [];
var addRow = function(row) {
if (row.toString() == 'BP.TableViewRow' || row.toString() == 'BP.TableViewSection')
data.push(row.get('view'));
else if (row.get('row').toString() == 'BP.TableViewRow')
addRow(row.get('row'));
else
Ti.API.warn("BP.TableView.data must be an array of BP.TableViewRow objects or objects that impliment a 'row' property that returns a BP.TableViewRow");
};
value.forEach(function(row) {
addRow(row);
});
view[keyName] = data;
}
else
{
view[keyName] = value;
}
}
}
});
BP.Button = BP.Base.extend({
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createButton());
this._super();
}
});
BP.Label = BP.Base.extend({
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createLabel());
this._super();
}
});
BP.ScrollView = BP.Base.extend({
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createScrollView());
this._super();
}
});
BP.Tab = BP.Base.extend({
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createTab());
this._super();
},
// Use the Ti.UI.Tab to complete open()
open: function(win, options) {
if (typeof(options) == 'undefined') options = {};
this.get('view').open(win.get('view'), options);
}
});
BP.TabGroup = BP.Base.extend({
scTabs: [],
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createTabGroup());
this._super();
},
// Use the Titanium objects to complete addTab()
addTab: function(scTab) {
this.get('scTabs').pushObject(scTab);
this.get('view').addTab(scTab.get('view'));
},
// Use the Ti.UI.TabGroup to complete open()
open: function() {
this.get('view').open();
},
// Use the Titanium objects to complete removeTab()
removeTab: function(scTab) {
this.get('scTabs').removeObject(scTab);
this.get('view').removeTab(scTab.get('view'));
}
});
BP.TableView = BP.Base.extend({
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createTableView());
this._super();
},
dataDidChange: function() {
this.set('data', this.get('data'));
}.observes('data.length')
});
BP.TableViewRow = BP.Base.extend({
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createTableViewRow());
this._super();
},
toString: function() {
return 'BP.TableViewRow';
}
});
BP.TableViewSection = BP.Base.extend({
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createTableViewSection());
this._super();
},
add: function(bpObject) {
var view = this.get('view');
var addRow = function(row) {
if (row.toString() == 'BP.TableViewRow')
view.add(row.get('view'));
else if (row.get('row').toString() == 'BP.TableViewRow')
addRow(row.get('row'));
else
Ti.API.warn("BP.TableViewSection.add only accepts BP.TableViewRow objects or objects that impliment a 'row' property that returns a BP.TableViewRow");
};
addRow(bpObject);
},
toString: function() {
return 'BP.TableViewSection';
}
});
BP.View = BP.Base.extend({
init: function() {
if (!this.get('view')) this.set('view', Ti.UI.createView());
this._super();
}
});
BP.Window = BP.Base.extend({
onFocus: null,
onOpen: null,
init: function() {
var view = this.get('view');
if (!view) view = Ti.UI.createWindow();
// Setup focus event
var onFocus = this.get('onFocus');
if (onFocus)
{
view.addEventListener('focus', onFocus);
}
// Setup open event
var onOpen = this.get('onOpen');
if (onOpen)
{
view.addEventListener('open', onOpen);
}
this.set('view', view);
this._super();
},
// Use the Ti.UI.Window to complete close()
close: function() {
this.get('view').close();
},
// Use the Ti.UI.Window to complete open()
open: function(options) {
if (typeof(options) == 'undefined') options = {};
this.get('view').open(options);
},
// Use the Titanium objects to complete setLeftNavButton()
setLeftNavButton: function(scButton) {
if (Ti.Platform.name == 'iPhone OS')
this.get('view').setRightNavButton(scButton.get('view'));
},
// Use the Titanium objects to complete setRightNavButton()
setRightNavButton: function(scButton) {
if (Ti.Platform.name == 'iPhone OS')
this.get('view').setRightNavButton(scButton.get('view'));
}
});
// Potential for a custom tab bar since the tab objects are SproutCore objects
BP.tabsController = SC.ArrayController.create({
content: [],
activeTab: null,
activeTabIndex: 0,
tabGroup: null,
contentDidChange: function() {
var tabGroup = this.get('tabGroup');
var contentLength = this.get('content').length;
// Create Tab Group and open it when the content is set for the first time
if (!tabGroup && contentLength > 0)
{
tabGroup = BP.TabGroup.create();
this.get('content').forEach(function(scTab) {
tabGroup.addTab(scTab);
});
tabGroup.get('view').addEventListener('focus', function(e) {
if (e.index != -1)
{
BP.tabsController.set('activeTab', e.tab);
BP.tabsController.set('activeTabIndex', e.index);
}
});
tabGroup.open();
this.set('tabGroup', tabGroup);
}
else if (tabGroup && contentLength > 0)
{
// Remove previous tabs
tabGroup.get('scTabs').forEach(function(scTab) {
tabGroup.removeTab(scTab);
});
// Add new tabs
this.get('content').forEach(function(scTab) {
tabGroup.addTab(scTab);
});
}
}.observes('content')
});
BP.tabWindowsController = SC.ArrayController.create({
openWindow: function(win, options) {
if (typeof(options) == 'undefined') options = {};
if (win.get('modal'))
{
win.open(options);
}
else
{
var activeTab = BP.tabsController.get('activeTab');
activeTab.open(win.get('view'), options);
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment