/**
* @module uifactory/window
* @author Flavio De Stefano <flavio.destefano@caffeina.com>
* @author Flavio De Stefano <andrea.jonus@caffeina.com>
*/
var UIUtil = require('T/uiutil');
var ABX = null;
var LOGNAME = "UIFactory/Window";
module.exports = function(args) {
_.defaults(args, {
/**
* **(Android only)** Set the property `displayHomeAsUp` and the relative close listener.
* @property {Boolean} [displayHomeAsUp=false]
*/
displayHomeAsUp: false,
/**
* **(Android only)** Disable the hardware back button (do nothing on click)
* @property {Boolean} [backButtonDisabled=false]
*/
backButtonDisabled: false,
/**
* **(Android only)** Use the ActionBarExtras module by Ricardo Alcocer (if included in tiapp.xml)
* @property {Boolean} [useActionBarExtras=false]
* @see {@link https://github.com/ricardoalcocer/actionbarextras}
*/
useActionBarExtras: false,
/**
* View {@link #setDeferredBackgroundImage}
* @property {String} [deferredBackgroundImage=null]
*/
deferredBackgroundImage: null,
/**
* View {@link #setBackgroundCoverImage}
* @property {String} [backgroundCoverImage=null]
*/
backgroundCoverImage: null,
/**
* View {@link #setActivityProperties}
* @property {Object} [activityProperties=null]
*/
activityProperties: null,
/**
* View {@link #setActionBarProperties}
* @property {Object} [actionBarProperties=null]
*/
actionBarProperties: null,
/**
* @property {Object} [rightNavButton=null]
* View {@link #setRightNavButton}
*/
rightNavButton: null,
/**
* View {@link #addActivityButton}
* @property {Array} [activityButtons=null]
*/
activityButtons: null,
/**
* View {@link #setActivityButton}
* @property {Object} [activityButton=null]
*/
activityButton: null,
/**
* Set an handler that kill the entire app when back button is closed
* @property {Boolean} [exitOnBack=null]
*/
exitOnBack: null
});
var $this = Ti.UI.createWindow(args);
$this.opened = false;
var onOpenFuncs = [];
function onOpen(callback) {
if ($this.opened === true) {
callback();
return;
}
onOpenFuncs.push(callback);
}
$this.addEventListener('open', function() {
$this.opened = true;
_.each(onOpenFuncs, function(openFunc){
openFunc();
});
});
/**
* When large images are requested, it's useful to set `deferredBackgroundImage` to set the background on window open.
* @method setDeferredBackgroundImage
* @param {String} val
*/
$this.setDeferredBackgroundImage = function(val) {
onOpen(function() {
$this.backgroundImage = val;
});
};
/**
* @method setBackgroundCoverImage
* @param {String} url
*/
$this.setBackgroundCoverImage = function(url) {
UIUtil.setBackgroundCoverForView($this, url, function(file) {
$this.backgroundImage = file;
});
};
/**
* Fade in this window
* @method fadeIn
*/
$this.fadeIn = function() {
$this.opacity = 0;
$this.open();
$this.animate({
opacity: 1,
duration: 300
});
};
/**
* Fade in this window
* @method fadeOut
*/
$this.fadeOut = function() {
setTimeout(function() { $this.close(); }, 300);
$this.animate({
opacity: 0,
duration: 300
});
};
if (OS_ANDROID) {
if (args.useActionBarExtras == true) {
ABX = Util.requireOrNull("com.alcoapps.actionbarextras");
if (ABX == null) {
Ti.API.error(LOGNAME + ': com.alcoapps.actionbarextras has been required but is not included in the project.');
}
}
/**
* Set the properties for the Activity
* @method setActivityProperties
* @param {Object} props
*/
$this.setActivityProperties = function(props) {
_.each(props, function(v, k) {
$this.activity[k] = v;
});
};
/**
* Set the properties for the ActionBar
* @method setActionBarProperties
* @param {Object} props
* @param {Function} callback
*/
$this.setActionBarProperties = function(props, callback) {
onOpen(function(){
if ($this.actionBar == null) return;
_.each(props, function(v, k) {
$this.actionBar[k] = v;
});
if (_.isFunction(callback)) callback($this.actionBar);
});
};
var activityButtons = [];
$this.menuItems = {};
$this.setActivityProperties({
onCreateOptionsMenu: function(e) {
_.each(activityButtons, function(btn) {
var attrs = _.extend({
title: btn.title || '',
icon: btn.icon || btn.image || '',
actionView: btn.actionView,
showAsAction: btn.showAsAction != null ? btn.showAsAction : Ti.Android.SHOW_AS_ACTION_ALWAYS,
visible: btn.visible != null ? btn.visible : true
}, btn.itemId != null ? { itemId: btn.itemId } : {});
var menuItem = e.menu.add(attrs);
menuItem.addEventListener('click', function(e){
if (_.isFunction(btn.click)) btn.click(e);
if (_.isFunction($this[btn.click])) $this[btn.click](e);
if (_.isFunction(btn.fireEvent)) btn.fireEvent('click', e);
});
if (!_.isEmpty(btn.fontIcon) && args.useActionBarExtras == true && $this.actionBar != null) {
if (btn.itemId != null) {
$this.actionBar.setMenuItemIcon(_.extend(_.pick(btn, 'color', 'size', 'fontFamily'), {
menu: e.menu,
menuItem: menuItem,
icon: btn.fontIcon
}));
} else {
Ti.API.warn(LOGNAME + ': Missing itemId from menu item. Cannot set the icon.');
}
}
if (btn.itemId != null) {
$this.menuItems[btn.itemId] = menuItem;
}
});
}
});
/**
* **Android specific**
* @method addActivityButton
* @param {Object} opt
*/
$this.addActivityButton = function(opt) {
if (opt != null) {
while (opt && opt.children && opt.children[0]) opt = opt.children[0]; // hack for Alloy, just ignore it
activityButtons.push(opt);
}
if (_.isFunction($this.activity.invalidateOptionsMenu)) $this.activity.invalidateOptionsMenu();
};
/**
* **Android specific**
* @method setActivityButton
* @param {Object} opt
*/
$this.setActivityButton = function(opt) {
activityButtons = [];
$this.menuItems = {};
$this.addActivityButton(opt);
};
/**
* @method setRightNavButton
* @see {@link setActivityButton}
*/
$this.setRightNavButton = $this.setActivityButton;
/**
* Auto-process the titles
* @method processTitles
*/
$this.processTitles = function () {
$this.setActionBarProperties({
title: ($this.title && $this.subtitle) ? $this.title : ($this.subtitle === false ? $this.title : Ti.App.name),
subtitle: ($this.title && $this.subtitle) ? $this.subtitle : ($this.subtitle === false ? null : ($this.title || null))
});
};
/**
* **Android fix**
* @method setTitle
* @param {String} value
*/
$this.setTitle = function(value) {
$this.title = value;
$this.processTitles();
};
/**
* **Android fix**
* @method setSubtitle
* @param {String} value
*/
$this.setSubtitle = function(value) {
$this.subtitle = value;
$this.processTitles();
};
}
//////////////////////
// Parse arguments //
//////////////////////
if (args.deferredBackgroundImage != null) $this.setDeferredBackgroundImage(args.deferredBackgroundImage);
if (args.backgroundCoverImage != null) $this.setBackgroundCoverImage(args.backgroundCoverImage);
if (OS_ANDROID) {
// Set the window's action bar
onOpen(function() {
if (ABX != null) {
$this.actionBar = ABX;
} else if ($this.activity != null && $this.activity.actionBar != null) {
$this.actionBar = $this.activity.actionBar;
}
});
$this.processTitles();
if (_.isFunction($this.activity.invalidateOptionsMenu)) {
$this.activity.invalidateOptionsMenu();
}
if (args.displayHomeAsUp === true && args.exitOnClose !== true) {
onOpen(function(){
// Get the real actionbar from the activity
if ($this.activity.actionBar == null) return;
$this.activity.actionBar.displayHomeAsUp = true;
$this.activity.actionBar.onHomeIconItemSelected = function() {
$this.close();
};
});
}
if (args.backButtonDisabled === true) {
$this.addEventListener('androidback', function() {
return false;
});
}
if (args.exitOnBack === true) {
$this.addEventListener('androidback', function() {
Ti.Android.currentActivity.finish();
});
}
if (args.activityProperties != null) $this.setActivityProperties(args.activityProperties);
if (args.actionBarProperties != null) $this.setActionBarProperties(args.actionBarProperties);
if (args.rightNavButton != null) $this.setRightNavButton(args.rightNavButton);
if (args.activityButtons != null) _.each(args.activityButtons, function(val) { $this.addActivityButton(val); });
if (args.activityButton != null) $this.setActivityButton(args.activityButton);
}
return $this;
};