Created
September 26, 2011 17:50
-
-
Save brianpattison/1242854 to your computer and use it in GitHub Desktop.
SproutCore Modifications for use in Titanium
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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