2 // Armadillo File Manager
3 // Copyright (c) 2010, Robert Sesek <http://www.bluestatic.org>
5 // This program is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free Software
7 // Foundation, either version 3 of the License, or any later version.
10 goog
.provide('armadillo.Actor');
11 goog
.provide('armadillo.Actor.TileControlRenderer_');
13 goog
.require('armadillo.PathControl');
14 goog
.require('armadillo.TVRenamer');
15 goog
.require('goog.array');
16 goog
.require('goog.dom');
17 goog
.require('goog.events');
18 goog
.require('goog.events.EventHandler');
19 goog
.require('goog.style');
20 goog
.require('goog.ui.Button');
21 goog
.require('goog.ui.Container');
22 goog
.require('goog.ui.Dialog');
25 * The Actor is a popup that displays the various actions that can be performed
27 * @param {armadillo.File} file The file to act on.
28 * @param {goog.dom.DomHelper} opt_domHelper
31 armadillo
.Actor
= function(file
, opt_domHelper
) {
32 goog
.ui
.Container
.call(this, null, null, opt_domHelper
);
34 this.setFocusable(false);
35 this.setFocusableChildrenAllowed(true);
38 * The file object on which this acts.
39 * @type {armadillo.File}
44 * Registrar for all the Actor's events.
45 * @type {goog.events.EventHandler}
47 this.eh_
= new goog
.events
.EventHandler();
50 * The UI element used for a specific action.
51 * @type {goog.Disposable}
53 this.actionObject_
= null;
56 * Controls for the current action.
57 * @type {goog.ui.Control}
59 this.controlContainer_
= null;
61 goog
.inherits(armadillo
.Actor
, goog
.ui
.Container
);
64 * The different options that the Actor can perform.
66 armadillo
.Actor
.options_
= {
71 TV_RENAME
: 'tv-rename'
75 * String values for the options.
77 armadillo
.Actor
.optionStrings_
= {
82 'tv-rename' : 'Rename TV Episode'
89 armadillo
.Actor
.prototype.disposeInternal
= function() {
90 armadillo
.Actor
.superClass_
.disposeInternal
.call(this);
94 if (this.controlContainer_
)
95 this.controlContainer_
.dispose();
96 this.controlContainer_
= null;
98 // Remove the actor display element.
99 goog
.dom
.removeNode(this.element_
);
100 this.element_
= null;
102 if (this.actionObject_
) {
103 this.actionObject_
.dispose();
104 this.actionObject_
= null;
110 armadillo
.Actor
.prototype.createDom
= function() {
111 this.setElementInternal(this.dom_
.createDom('div'));
112 this.decorate(this.getElement());
116 * Decorates the given element into a path control.
117 * @param {Element} element
119 armadillo
.Actor
.prototype.decorateInternal
= function(element
) {
120 this.element_
= element
;
121 goog
.dom
.classes
.add(this.element_
, 'actor');
122 this.dom_
.removeChildren(this.element_
);
123 for (var option
in armadillo
.Actor
.options_
) {
124 var tile
= this.createTile_(option
);
126 this.addChild(tile
, true);
129 this.controlContainer_
= new goog
.ui
.Control();
130 this.controlContainer_
.setSupportedState(goog
.ui
.Component
.State
.FOCUSED
, false);
131 this.addChild(this.controlContainer_
, true);
135 * Creates the DOM Element that is inserted into the popup.
136 * @param {armadillo.Actor.options_} Key of the option to create
137 * @returns {goog.ui.Control}
139 armadillo
.Actor
.prototype.createTile_
= function(option
) {
140 var value
= armadillo
.Actor
.options_
[option];
142 // Create the title element.
143 var title
= this.dom_
.createDom('span', 'title',
144 armadillo
.Actor
.optionStrings_
[value]);
146 var tile
= new goog
.ui
.Control(title
, new armadillo
.Actor
.TileControlRenderer_());
147 tile
.actorOption
= value
;
149 // Cannot open non-directory files.
150 if (value
== armadillo
.Actor
.options_
.OPEN
&& !this.file_
.isDirectory()) {
154 this.eh_
.listen(tile
, goog
.ui
.Component
.EventType
.ACTION
,
155 this.tileClickHandler_
, false, this);
160 * Click handler for individual tiles.
163 armadillo
.Actor
.prototype.tileClickHandler_
= function(e
) {
164 var option
= e
.target
.actorOption
;
165 this.controlContainer_
.removeChildren(true);
166 this.controlContainer_
.setVisible(true);
167 if (option
== armadillo
.Actor
.options_
.OPEN
) {
168 // TODO: assert that this.file_.isDirectory().
169 app
.navigate(this.file_
.getName());
170 } else if (option
== armadillo
.Actor
.options_
.MOVE
||
171 option
== armadillo
.Actor
.options_
.RENAME
) {
173 } else if (option
== armadillo
.Actor
.options_
.DELETE
) {
174 this.performDelete_();
175 } else if (option
== armadillo
.Actor
.options_
.TV_RENAME
) {
176 this.performTVRename_();
181 * Subroutine to handle bringing up the move confirmation UI.
184 armadillo
.Actor
.prototype.performMove_
= function() {
185 var editor
= new armadillo
.PathControl(this.file_
.getFullPath(), true);
186 this.controlContainer_
.addChild(editor
, true);
188 var okCallback
= function(e
) {
189 var newPath
= editor
.getPath();
190 this.file_
.move(newPath
);
192 this.createOkCancel_(goog
.bind(okCallback
, this), null);
196 * Subroutine to handle bringing up the delete confirmation UI.
199 armadillo
.Actor
.prototype.performDelete_
= function() {
200 this.actionObject_
= this.createActionDialog_();
201 this.actionObject_
.setTitle('Confirm Delete');
203 var container
= this.actionObject_
.getContentElement();
204 var content
= goog
.dom
.createDom('span', null,
205 'Are you sure you want to delete:',
206 goog
.dom
.createElement('br'),
207 goog
.dom
.createDom('strong', null, this.file_
.getName()));
208 goog
.dom
.appendChild(container
, content
);
210 var closeCallback
= function(e
) {
211 if (e
.key
!= goog
.ui
.Dialog
.DefaultButtonKeys
.CANCEL
) {
215 // Will be removed when the event source closes.
216 this.eh_
.listen(this.actionObject_
, goog
.ui
.Dialog
.SELECT_EVENT
,
217 closeCallback
, false, this);
219 this.actionObject_
.setVisible(true);
223 * Subroutine that renames a file to it's title based on season and episode.
226 armadillo
.Actor
.prototype.performTVRename_
= function() {
227 var renamer
= new armadillo
.TVRenamer(this.file_
);
232 * Creates a new instance of a Dialog that has some basic properties set that
233 * are common to performing actions.
236 armadillo
.Actor
.prototype.createActionDialog_
= function() {
237 var confirm
= new goog
.ui
.Dialog();
238 confirm
.setDisposeOnHide(true);
239 confirm
.setEscapeToCancel(true);
240 confirm
.setModal(true);
241 confirm
.setDraggable(false);
242 confirm
.setHasTitleCloseButton(false);
247 * Creates two buttons: one for OK one for Cancel and attahes them to the
248 * |controlContainer_|.
249 * @param {function(Event)?} okCallback
250 * @param {function(Event)?} cancelCallback
252 armadillo
.Actor
.prototype.createOkCancel_
= function(okCallback
, cancelCallback
) {
253 var ok
= new goog
.ui
.Button('OK');
255 this.eh_
.listen(ok
, goog
.ui
.Component
.EventType
.ACTION
, okCallback
);
256 var cancel
= new goog
.ui
.Button('Cancel');
258 cancelCallback
= goog
.bind(this.defaultCancelCallback_
, this);
259 this.eh_
.listen(cancel
, goog
.ui
.Component
.EventType
.ACTION
, cancelCallback
);
260 this.controlContainer_
.addChild(ok
, true);
261 this.controlContainer_
.addChild(cancel
, true);
265 * The default cancel callback for the above createOkCancel_().
269 armadillo
.Actor
.prototype.defaultCancelCallback_
= function(e
) {
270 this.controlContainer_
.removeChildren(true);
274 * Tile Control Renderer
277 armadillo
.Actor
.TileControlRenderer_
= function() {
278 goog
.ui
.ControlRenderer
.call(this);
280 goog
.inherits(armadillo
.Actor
.TileControlRenderer_
, goog
.ui
.ControlRenderer
);
283 * Returns the control's contents wrapped in a DIV, with the renderer's own
284 * CSS class and additional state-specific classes applied to it.
285 * @param {goog.ui.Control} control Control to render.
286 * @return {Element} Root element for the control.
288 armadillo
.Actor
.TileControlRenderer_
.prototype.createDom
= function(control
) {
289 // Create and return DIV wrapping contents.
290 return control
.getDomHelper().createDom('div', 'tile', control
.getContent());