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');
12 goog
.require('armadillo.PathControl');
13 goog
.require('goog.array');
14 goog
.require('goog.dom');
15 goog
.require('goog.events');
16 goog
.require('goog.positioning.ClientPosition');
17 goog
.require('goog.positioning.Corner');
18 goog
.require('goog.style');
19 goog
.require('goog.ui.Dialog');
20 goog
.require('goog.ui.Popup');
23 * The Actor is a popup that displays the various actions that can be performed
25 * @param {armadillo.File} file The file to act on.
28 armadillo
.Actor
= function(file
) {
29 goog
.Disposable
.call(this);
32 * The file object on which this acts.
33 * @type {armadillo.File}
38 * The HTML element that draws the actor buttons
41 this.element_
= this.createElement_();
44 * The Container that holds the display element.
45 * @type {goog.ui.Popup}
47 this.popup_
= new goog
.ui
.Popup(this.element_
);
48 goog
.events
.listenOnce(this.popup_
, goog
.ui
.PopupBase
.EventType
.HIDE
,
49 this.onPopupClosed_
, false, this);
52 * The UI element used for a specific action.
53 * @type {goog.Disposable}
55 this.actionObject_
= null;
57 armadillo
.Actor
.actors_
.push(this);
59 goog
.inherits(armadillo
.Actor
, goog
.Disposable
);
62 * An array of all the Actors that have been created.
64 armadillo
.Actor
.actors_
= new Array();
67 * The different options that the Actor can perform.
69 armadillo
.Actor
.options_
= {
77 * String values for the options.
79 armadillo
.Actor
.optionStrings_
= {
87 * A global property that should be checked to see if an actor is present,
88 * creating a modal session.
90 armadillo
.Actor
.isModal
= function() {
91 var isVisible
= false;
92 goog
.array
.forEach(armadillo
.Actor
.actors_
, function (e
) {
93 isVisible
|= e
.popup_
.isVisible();
102 armadillo
.Actor
.prototype.disposeInternal
= function() {
103 armadillo
.Actor
.superClass_
.disposeInternal
.call(this);
105 // Unlisten the tiles.
106 var tiles
= goog
.dom
.getElementsByClass('tile', this.element_
);
107 goog
.array
.forEach(tiles
, function (tile
) {
108 goog
.events
.unlistenByKey(tile
.actorListener
);
111 // Remove the actor display element.
112 goog
.dom
.removeNode(this.element_
);
113 this.element_
= null;
116 this.popup_
.dispose();
119 if (this.actionObject_
) {
120 this.actionObject_
.dispose();
121 this.actionObject_
= null;
124 // Remove the actor from the list.
125 goog
.array
.remove(armadillo
.Actor
.actors_
, this);
132 * @param {int} x The X position to show at
133 * @param {int} y The Y position to show at
135 armadillo
.Actor
.prototype.show
= function(x
, y
) {
136 if (armadillo
.Actor
.isModal())
138 var firstBodyElement
= goog
.dom
.getFirstElementChild(document
.body
);
139 goog
.dom
.insertSiblingBefore(this.element_
, firstBodyElement
);
140 this.popup_
.setPinnedCorner(goog
.positioning
.Corner
.TOP_LEFT
);
141 this.popup_
.setPosition(new goog
.positioning
.ClientPosition(x
, y
));
142 this.popup_
.setHideOnEscape(true);
143 this.popup_
.setVisible(true);
149 armadillo
.Actor
.prototype.hide
= function() {
150 this.popup_
.setVisible(false);
154 * Creates the DOM Element that is inserted into the popup.
157 armadillo
.Actor
.prototype.createElement_
= function() {
158 var root
= goog
.dom
.createDom('div', 'actor');
159 for (var option
in armadillo
.Actor
.options_
) {
160 var tile
= goog
.dom
.createDom('div', 'tile');
161 var value
= armadillo
.Actor
.options_
[option];
162 // Cannot open non-directory files.
163 if (value
== armadillo
.Actor
.options_
.OPEN
&& !this.file_
.isDirectory()) {
166 var title
= goog
.dom
.createDom('span', 'title',
167 armadillo
.Actor
.optionStrings_
[value]);
168 goog
.dom
.appendChild(tile
, title
);
169 goog
.dom
.appendChild(root
, tile
);
170 tile
.actorOption
= value
;
171 tile
.actorListener
= goog
.events
.listen(tile
, goog
.events
.EventType
.CLICK
,
172 this.tileClickHandler_
, false, this);
178 * Click handler for individual tiles.
181 armadillo
.Actor
.prototype.tileClickHandler_
= function(e
) {
182 var option
= e
.target
.actorOption
;
183 if (option
== armadillo
.Actor
.options_
.OPEN
) {
184 // TODO: assert that this.file_.isDirectory().
185 app
.navigate(this.file_
.getName());
186 } else if (option
== armadillo
.Actor
.options_
.MOVE
||
187 option
== armadillo
.Actor
.options_
.RENAME
) {
189 } else if (option
== armadillo
.Actor
.options_
.DELETE
) {
190 this.performDelete_();
196 * Subroutine to handle bringing up the move confirmation UI.
199 armadillo
.Actor
.prototype.performMove_
= function() {
200 this.actionObject_
= this.createActionDialog_();
201 this.actionObject_
.setTitle('Move File');
203 var editor
= new armadillo
.PathControl(this.file_
.getFullPath(), true);
204 this.actionObject_
.addChild(editor
, true);
206 var closeCallback
= function(e
) {
207 if (e
.key
!= goog
.ui
.Dialog
.DefaultButtonKeys
.CANCEL
) {
208 var newPath
= editor
.getPath();
209 this.file_
.move(newPath
);
213 // Will be removed when the event source closes.
214 goog
.events
.listen(this.actionObject_
, goog
.ui
.Dialog
.SELECT_EVENT
,
215 closeCallback
, false, this);
217 this.actionObject_
.setVisible(true);
218 var position
= goog
.style
.getPosition(this.actionObject_
.getElement());
219 goog
.style
.setPosition(this.actionObject_
.getElement(), position
.x
, '10%');
223 * Subroutine to handle bringing up the delete confirmation UI.
226 armadillo
.Actor
.prototype.performDelete_
= function() {
227 this.actionObject_
= this.createActionDialog_();
228 this.actionObject_
.setTitle('Confirm Delete');
230 var container
= this.actionObject_
.getContentElement();
231 var content
= goog
.dom
.createDom('span', null,
232 'Are you sure you want to delete:',
233 goog
.dom
.createElement('br'),
234 goog
.dom
.createDom('strong', null, this.file_
.getName()));
235 goog
.dom
.appendChild(container
, content
);
237 var closeCallback
= function(e
) {
238 if (e
.key
!= goog
.ui
.Dialog
.DefaultButtonKeys
.CANCEL
) {
243 // Will be removed when the event source closes.
244 goog
.events
.listen(this.actionObject_
, goog
.ui
.Dialog
.SELECT_EVENT
,
245 closeCallback
, false, this);
247 this.actionObject_
.setVisible(true);
251 * Creates a new instance of a Dialog that has some basic properties set that
252 * are common to performing actions.
255 armadillo
.Actor
.prototype.createActionDialog_
= function() {
256 var confirm
= new goog
.ui
.Dialog();
257 confirm
.setDisposeOnHide(true);
258 confirm
.setEscapeToCancel(true);
259 confirm
.setModal(true);
260 confirm
.setDraggable(false);
261 confirm
.setHasTitleCloseButton(false);
266 * Event handler for when this.popup_ closes.
269 armadillo
.Actor
.prototype.onPopupClosed_
= function(e
) {
270 // If an action is not being performed, then dispose the Actor. Otherwise,
271 // this will get cleaned up after the actionObject_ closes.
272 if (!this.actionObject_
) {