Skip to content

Instantly share code, notes, and snippets.

@pec1985
Created September 20, 2012 22:20
Show Gist options
  • Save pec1985/3758713 to your computer and use it in GitHub Desktop.
Save pec1985/3758713 to your computer and use it in GitHub Desktop.
Best UI CommonJS module ever
var UI = require('ui');
UI.Window({
subviews:[
UI.Label({
width: Ti.UI.SIZE,
height: Ti.UI.SIZE,
color: "#000",
text: 'here',
onClick: function() {
alert('on label click')
}
}),
UI.ImageView({
image: 'appcelerator_logo.png',
width: 100
})
],
backgroundColor: '#ccc',
fullscreen: false
}).open();
/*
* Create by Pedro Enrique
* September 2012
* Twitter: @pecdev
*
* Use at your own risk without guaranteed support, although I will do my
* best to answer any questions and/or fix any bugs
*
* Please, try to understand the code and read the bold letters bellow
*/
var UI = exports;
(function(){
var Android = Ti.Platform.osname == 'android';
var iPhone = Ti.Platform.osname == 'iphone';
var iPad = Ti.Platform.osname == 'ipad';
UI.WINDOW_SIZE = { WIDTH: Ti.Platform.displayCaps.platformWidth ,HEIGHT: Ti.Platform.displayCaps.platformHeight };
/**
* Create Ti.UI.Stuff with callback functions. The callbacks will not be inserted into the proxy
* @param {Ti.UI.Proxy} TiElement Proxy to create - must be in the form of Ti.UI.createView
* @param {Object} Options Parameters to pass
* @return {Ti.UI.Proxy}
*/
var createElement = UI.createElement = function (TiElement, Options) {
/**
* Checks wether a key-value pair is an event callback
* @param {string} key String has to be on[Uppercase]
* @param {object} value Must be a function to be a callback
* @return {Boolean} True or False
*/
function isCallback(key, value) {
var begin = key.slice(0,2); // gets the first two characters
var next = key.slice(2,3); // gets the third
// The first two characters must be "on", the next one must be upper case
// and the value must be a function
// For example: onClick: function() { }
if(begin == 'on' && next == next.toUpperCase() && typeof value == 'function')
return true;
return false;
}
/**
* Adds events to Ti.UI.ViewProxy
* @param {Ti.UI.ViewProxy} TiElement Ti.UI.Element
* @param {String} EventName Name of event, ie. onClick
* @param {Function} Event Actual event callback
*/
function addEvent(TiElement , EventName, Event) {
if(!Event) return;
var name = String(EventName).replace('on', '').toLowerCase();
TiElement.addEventListener(name, Event);
}
// Create the subviews array
var subviews = [];
// Create the object to hold the events
var callbacks = {};
// Iterate through the arguments to fetch the callbacks and the subviews
// Once added to the object, delete from the Options object
// Passing custom functions or Ti.Proxies to Ti.Proxies is bad practice!
for(var key in Options) {
if(isCallback(key, Options[key])){
callbacks[key] = Options[key];
delete Options[key];
}
if(key == 'subviews') {
subviews = Options[key];
delete Options[key];
}
}
// Once the event callbacks are extracted, create the proxy
var el = TiElement(Options);
// Add the event listeners to the proxy
for(var key in callbacks) {
addEvent(el, key, callbacks[key]);
}
// Yes, this is possible too (only in iOS as far as I'm aware)
// :)
if((iPhone || iPad) && subviews.length) {
el.add(subviews);
} else {
for(var i = 0, len = subviews.length; i < len; i++) {
el.add(subviews[i]);
}
}
// Null out variables, not sure if necessary, who knows!
callbacks = null;
Options = null;
TiElement = null;
subviews = null;
return el;
}
/**
* Example on how to use functions bellow which return the function above:
*
* var UI = exports('ui'); // this file
* var button = UI.Button({
* width: 100,
* height: 40,
* title: 'Hello World!',
* onClick: function() {
* alert('clicked!');
* }
* });
* var win = UI.Window({
* backgroundColor: '#ccc',
* onOpen: function() { alert('window opened') },
* subviews: [ btn ]
* });
* win.open();
*/
function throwException(foo, platform) {
throw new Error(foo + ' is only supported in ' + platform);
}
////////////////////////////////////////////////////////////////////////
// IMPORTANT!!
////////////////////////////////////////////////////////////////////////
// REMOVE ANY UNUSED "UI" FUNCTION BELLOW WHEN DEPLOYING THE APP TO
// EITHER THE APPSTORE OR THE GOOGLE MARKET
//
// WHY?
// THE TITANIUM COMPILER WILL READ ALL THE JAVASCRIPT FILES WHEN
// COMPILING, AND WILL ADD ALL THE INTERNAL CLASSES THAT HAVE A
// REFERENCE IN THE JAVASCRIPT
//
// FOR EXAMPLE, IF THE COMPILER SEES THIS:
// Ti.UI.createButton
// THE INTERNAL TiUIButtonProxy CLASS WILL BE ADDED TO THE FINAL BUILD,
// THUS ADDING UNNECESSARY CODE AND MAKING THE APP LARGER THAN IT NEEDS
// TO BE
//
// YOU HAVE BEEN WARNED
////////////////////////////////////////////////////////////////////////
// Note:
// This could be a lot easier by creating an array and creating the
// function in a loop, but the builder.py looks for these to include
// them in the final build.
UI.AdView = function(args) {
args = args || {};
if(Android) throwException('UI.createAdView', 'iOS');
return createElement(Ti.UI.iOS.createAdView, args);
};
UI.ActivityIndicator = function(args) {
args = args || {};
return createElement(Ti.UI.createActivityIndicator, args);
};
UI.AlertDialog = function(args) {
args = args || {};
return createElement(Ti.UI.createAlertDialog, args);
};
UI.Animation = function(args) {
args = args || {};
return createElement(Ti.UI.createAnimation, args);
};
UI.Button = function(args) {
args = args || {};
return createElement(Ti.UI.createButton, args);
};
UI.CoverFlowView = function(args) {
args = args || {};
if(Android) throwException('UI.CoverFlowView', 'iOS');
return createElement(Ti.UI.iOS.createCoverFlowView, args);
};
UI.DocumentViewer = function(args) {
args = args || {};
if(!iPad) throwException('UI.DocumentViewer', 'iPad');
return createElement(Ti.UI.iPad.createDocumentViewer, args);
};
UI.DashboardView = function(args) {
args = args || {};
return createElement(Ti.UI.createDashboardView, args);
};
UI.EmailDialog = function(args) {
args = args || {};
return createElement(Ti.UI.createEmailDialog, args);
};
UI.ImageView = function(args) {
args = args || {};
return createElement(Ti.UI.createImageView, args);
};
UI.Label = function(args) {
args = args || {};
return createElement(Ti.UI.createLabel, args);
};
UI.Matrix2D = function(args) {
args = args || {};
return createElement(Ti.UI.create2dMatrix, args);
};
UI.Matrix3D = function(args) {
args = args || {};
if(Android) throwException('Ti.UI.iOS.create3dMatrix', 'iOS');
return createElement(Ti.UI.iOS.create3dMatrix, args);
};
UI.MapView = function(args) {
args = args || {};
return createElement(Ti.Map.createMapView, args);
};
UI.MapPin = function(args) {
args = args || {};
return createElement(Ti.Map.createAnnotation, args);
};
UI.MaskedImage = function(args) {
args = args || {};
return createElement(Ti.UI.createMaskedImage, args);
};
UI.OptionDialog = function(args) {
args = args || {};
return createElement(Ti.UI.createOptionDialog, args);
};
UI.Picker = function(args) {
args = args || {};
return createElement(Ti.UI.createPicker, args);
};
UI.Popover = function(args) {
args = args || {};
if(!iPad) throwException('UI.Popover', 'iPad');
return createElement(Ti.UI.iPad.createPopover, args);
};
UI.ProgressBar = function(args) {
args = args || {};
return createElement(Ti.UI.createProgressBar, args);
};
UI.ScrollView = function(args) {
args = args || {};
return createElement(Ti.UI.createScrollView, args);
};
UI.ScrollableView = function(args) {
args = args || {};
return createElement(Ti.UI.createScrollableView, args);
};
UI.SearchBar = function(args) {
args = args || {};
return createElement(Ti.UI.createSearchBar, args);
};
UI.Slider = function(args) {
args = args || {};
return createElement(Ti.UI.createSlider, args);
};
UI.SplitWindow = function(args) {
args = args || {};
if(!iPad) throwException('UI.SplitWindow', 'iPad');
return createElement(Ti.UI.iPad.createSplitWindow, args);
};
UI.Switch = function(args) {
args = args || {};
return createElement(Ti.UI.createSwitch, args);
};
UI.Tab = function(args) {
args = args || {};
return createElement(Ti.UI.createTab, args);
};
UI.TabGroup = function(args) {
args = args || {};
return createElement(Ti.UI.createTabGroup, args);
};
UI.TabbedBar = function(args) {
args = args || {};
if(Android) throwException('UI.TabbedBar', 'iOS');
return createElement(Ti.UI.iOS.createTabbedBar, args);
};
UI.ToolBar = function(args) {
args = args || {};
if(Android) throwException('UI.ToolBar', 'iOS');
return createElement(Ti.UI.iOS.createToolBar, args);
};
UI.TableView = function(args) {
args = args || {};
return createElement(Ti.UI.createTableView, args);
};
UI.TableViewRow = function(args) {
args = args || {};
return createElement(Ti.UI.createTableViewRow, args);
};
UI.TextArea = function(args) {
args = args || {};
return createElement(Ti.UI.createTextArea, args);
};
UI.TextField = function(args) {
args = args || {};
return createElement(Ti.UI.createTextField, args);
};
UI.View = function(args) {
args = args || {};
return createElement(Ti.UI.createView, args);
};
UI.WebView = function(args) {
args = args || {};
return createElement(Ti.UI.createWebView, args);
};
UI.Window = function(args) {
args = args || {};
return createElement(Ti.UI.createWindow, args);
};
// The end.
//
// Enjoy
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment