Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
328 lines
7.8 KiB
JavaScript
Executable file
328 lines
7.8 KiB
JavaScript
Executable file
define(function(require, exports, module) {
|
|
'use strict';
|
|
|
|
/**
|
|
* Dependencies
|
|
*/
|
|
|
|
var debug = require('debug')('controller:controls');
|
|
var ControlsView = require('views/controls');
|
|
var bindAll = require('lib/bind-all');
|
|
|
|
/**
|
|
* Exports
|
|
*/
|
|
|
|
module.exports = function(app) { return new ControlsController(app); };
|
|
module.exports.ControlsController = ControlsController;
|
|
|
|
/**
|
|
* Initialize a new `ControlsController`
|
|
*
|
|
* @param {App} app
|
|
*/
|
|
function ControlsController(app) {
|
|
bindAll(this);
|
|
this.app = app;
|
|
this.activity = app.activity;
|
|
this.createView();
|
|
this.bindEvents();
|
|
debug('initialized');
|
|
}
|
|
|
|
/**
|
|
* Event bindings.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.bindEvents = function() {
|
|
this.app.settings.mode.on('change:selected', this.view.setMode);
|
|
this.app.settings.mode.on('change:options', this.configureMode);
|
|
|
|
// App
|
|
this.app.on('change:recording', this.onRecordingChange);
|
|
this.app.on('camera:shutter', this.captureHighlightOff);
|
|
this.app.on('camera:willchange', this.onCameraWillChange);
|
|
this.app.on('camera:configured', this.onCameraConfigured);
|
|
this.app.on('newthumbnail', this.onNewThumbnail);
|
|
this.app.once('loaded', this.onceAppLoaded);
|
|
this.app.on('busy', this.onCameraBusy);
|
|
this.app.on('localized', this.view.localize);
|
|
|
|
// View
|
|
this.view.on('modechanged', this.onViewModeChanged);
|
|
this.view.on('click:thumbnail', this.app.firer('preview'));
|
|
this.view.on('click:cancel', this.onCancelButtonClick);
|
|
this.view.on('click:capture', this.onCaptureClick);
|
|
|
|
// Timer
|
|
this.app.on('countdown:started', this.onCountdownStarted);
|
|
this.app.on('countdown:ended', this.onCountdownStopped);
|
|
|
|
// Settings
|
|
this.app.on('settings:opened', this.onSettingsOpened);
|
|
this.app.on('settings:closed', this.onSettingsClosed);
|
|
|
|
// Preview gallery
|
|
this.app.on('previewgallery:opened', this.view.hide);
|
|
this.app.on('previewgallery:closed', this.view.show);
|
|
|
|
debug('events bound');
|
|
};
|
|
|
|
/**
|
|
* Create and configure the view.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.createView = function() {
|
|
var initialMode = this.app.settings.mode.selected('key');
|
|
var cancellable = !!this.app.activity.pick;
|
|
|
|
// Create the view (test hook)
|
|
this.view = this.app.views.controls || new ControlsView();
|
|
|
|
// The gallery button should not
|
|
// be shown if an activity is pending
|
|
// or the application is in 'secure mode'.
|
|
this.view.set('cancel', cancellable);
|
|
this.view.setMode(initialMode);
|
|
|
|
// Disable view until camera
|
|
// 'ready' enables it.
|
|
this.view.disable();
|
|
|
|
// Put it in the DOM
|
|
this.view.appendTo(this.app.el);
|
|
|
|
debug('cancelable: %s', cancellable);
|
|
debug('mode: %s', initialMode);
|
|
};
|
|
|
|
/**
|
|
* Disables the switch if there is
|
|
* only one modes available.
|
|
*
|
|
* This is only the case if an activity
|
|
* indicated it only supports one mode,
|
|
* just 'picture' or 'video'.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.configureMode = function() {
|
|
var switchable = this.app.settings.mode.get('options').length > 1;
|
|
if (!switchable) { this.view.disable('switch'); }
|
|
};
|
|
|
|
/**
|
|
* Once the app is loaded, we can enable
|
|
* the controls. We also bind a listener
|
|
* that enabled the controls whenever
|
|
* the camera becomes 'ready' from
|
|
* hereon after.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onceAppLoaded = function() {
|
|
this.app.on('ready', this.restore);
|
|
this.view.enable();
|
|
};
|
|
|
|
/**
|
|
* Keep capture button pressed and
|
|
* fire the `capture` event to allow
|
|
* the camera to repond.
|
|
*
|
|
* When the 'camera:shutter' event fires
|
|
* we remove the capture butter pressed
|
|
* state so that it times with the
|
|
* capture sound effect.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onCaptureClick = function() {
|
|
this.captureHighlightOn();
|
|
this.app.emit('capture');
|
|
};
|
|
|
|
/**
|
|
* Prevent the mode switch from being changed
|
|
* by the user when we are in the process of
|
|
* configuring the camera.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onCameraWillChange = function() {
|
|
this.view.suspendModeSwitch(true);
|
|
};
|
|
|
|
ControlsController.prototype.onCameraConfigured = function() {
|
|
this.view.suspendModeSwitch(false);
|
|
};
|
|
|
|
/**
|
|
* Set the recording attribute on
|
|
* the view to allow it to style
|
|
* accordingly.
|
|
*
|
|
* @param {Boolean} recording
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onRecordingChange = function(recording) {
|
|
this.view.set('recording', recording);
|
|
if (!recording) { this.onRecordingEnd(); }
|
|
// Update capture button label when recording changes.
|
|
this.view.setCaptureLabel(recording);
|
|
};
|
|
|
|
/**
|
|
* Remove the capture highlight,
|
|
* once recording has finished.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onRecordingEnd = function() {
|
|
this.captureHighlightOff();
|
|
};
|
|
|
|
/**
|
|
* When the thumbnail changes, update it in the view.
|
|
* This method is triggered by the 'newthumbnail' event.
|
|
* That event is emitted by the preview gallery controller when the a new
|
|
* photo or video is added, or when the preview is closed and the first
|
|
* photo or video has changed (because of a file deletion).
|
|
*/
|
|
ControlsController.prototype.onNewThumbnail = function(thumbnailBlob) {
|
|
if (thumbnailBlob) {
|
|
this.view.setThumbnail(thumbnailBlob);
|
|
} else {
|
|
this.view.removeThumbnail();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Forces the capture button to
|
|
* look pressed while the countdown is
|
|
* counting down and hides controls.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onCountdownStarted = function() {
|
|
this.captureHighlightOn();
|
|
this.view.set('countdown', 'active');
|
|
};
|
|
|
|
/**
|
|
* Forces the capture button to
|
|
* look unpressed when the countdown
|
|
* stops and shows controls.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onCountdownStopped = function() {
|
|
this.captureHighlightOff();
|
|
this.view.set('countdown', 'inactive');
|
|
};
|
|
|
|
/**
|
|
* Make controls invisible to the screen reader since they are behind settings
|
|
* overlay.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onSettingsOpened = function() {
|
|
this.view.setScreenReaderVisible(false);
|
|
};
|
|
|
|
/**
|
|
* Make controls visible to the screen reader again when settings are closed.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onSettingsClosed = function() {
|
|
this.view.setScreenReaderVisible(true);
|
|
};
|
|
|
|
ControlsController.prototype.onCameraBusy = function() {
|
|
this.view.disable();
|
|
};
|
|
|
|
/**
|
|
* Restores the capture button to its
|
|
* unpressed state and re-enables buttons.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.restore = function() {
|
|
debug('restore');
|
|
this.captureHighlightOff();
|
|
this.view.enable();
|
|
};
|
|
|
|
/**
|
|
* Make the capture button
|
|
* appear pressed.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.captureHighlightOn = function() {
|
|
this.view.set('capture-active');
|
|
};
|
|
|
|
/**
|
|
* Remove the pressed apperance
|
|
* from the capture button.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.captureHighlightOff = function() {
|
|
this.view.unset('capture-active');
|
|
};
|
|
|
|
/**
|
|
* Switch to the next capture mode:
|
|
* 'picture' or 'video', when the
|
|
* mode is changed via the view.
|
|
*
|
|
* Them mode can be changed by either
|
|
* tapping or swiping the mode switch.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onViewModeChanged = function() {
|
|
debug('view mode changed');
|
|
this.app.settings.mode.next();
|
|
};
|
|
|
|
ControlsController.prototype.onCancelButtonClick = function() {
|
|
this.app.emit('activitycanceled');
|
|
};
|
|
|
|
/**
|
|
* Open the gallery app when the
|
|
* gallery button is pressed.
|
|
*
|
|
* @private
|
|
*/
|
|
ControlsController.prototype.onGalleryButtonClick = function(event) {
|
|
event.stopPropagation();
|
|
var MozActivity = window.MozActivity;
|
|
|
|
// Can't launch the gallery if the lockscreen is locked.
|
|
// The button shouldn't even be visible in this case, but
|
|
// let's be really sure here.
|
|
if (this.app.inSecureMode) { return; }
|
|
|
|
// Launch the gallery with an activity
|
|
this.mozActivity = new MozActivity({
|
|
name: 'browse',
|
|
data: { type: 'photos' }
|
|
});
|
|
|
|
// Wait 2000ms before re-enabling the
|
|
// Gallery to be launched (Bug 957709)
|
|
this.view.disable();
|
|
setTimeout(this.view.enable, 2000);
|
|
};
|
|
|
|
});
|