Fix compilation using -c.
[armadillo.git] / web_frontend / actor.js
1 //
2 // Armadillo File Manager
3 // Copyright (c) 2010, Robert Sesek <http://www.bluestatic.org>
4 //
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.
8 //
9
10 goog.provide('armadillo.Actor');
11
12 goog.require('goog.array');
13 goog.require('goog.dom');
14 goog.require('goog.events');
15 goog.require('goog.positioning.ClientPosition');
16 goog.require('goog.positioning.Corner');
17 goog.require('goog.ui.Dialog');
18 goog.require('goog.ui.Popup');
19
20 /**
21 * The Actor is a popup that displays the various actions that can be performed
22 * on a given File.
23 * @param {armadillo.File} file The file to act on.
24 * @constructor
25 */
26 armadillo.Actor = function(file) {
27 goog.Disposable.call(this);
28 this.file_ = file;
29 this.element_ = this.createElement_();
30 this.popup_ = new goog.ui.Popup(this.element_);
31 armadillo.Actor.actors_.push(this);
32 }
33 goog.inherits(armadillo.Actor, goog.Disposable);
34
35 /**
36 * An array of all the Actors that have been created.
37 */
38 armadillo.Actor.actors_ = new Array();
39
40 /**
41 * The different options that the Actor can perform.
42 */
43 armadillo.Actor.options_ = {
44 OPEN : 'open',
45 MOVE : 'move',
46 RENAME : 'rename',
47 DELETE : 'delete'
48 };
49
50 /**
51 * String values for the options.
52 */
53 armadillo.Actor.optionStrings_ = {
54 'open' : 'Open',
55 'move' : 'Move',
56 'rename' : 'Rename',
57 'delete' : 'Delete'
58 };
59
60 /**
61 * A global property that should be checked to see if an actor is present,
62 * creating a modal session.
63 */
64 armadillo.Actor.isModal = function() {
65 var isVisible = false;
66 goog.array.forEach(armadillo.Actor.actors_, function (e) {
67 isVisible |= e.popup_.isVisible();
68 });
69 return isVisible;
70 };
71
72 /**
73 * Disposer
74 * @protected
75 */
76 armadillo.Actor.prototype.disposeInternal = function() {
77 armadillo.Actor.superClass_.disposeInternal.call(this);
78
79 // Unlisten the tiles.
80 var tiles = goog.dom.getElementsByClassName('tile', this.element_);
81 goog.array.forEach(tiles, function (tile) {
82 goog.events.unlistenByKey(tile.actorListener);
83 });
84
85 // Remove the actor display element.
86 goog.dom.removeNode(this.element_);
87 this.element_ = null;
88
89 // Kill the popup.
90 this.popup_.dispose();
91 this.popup_ = null;
92
93 // Remove the actor from the list.
94 goog.array.remove(armadillo.Actor.actors_, this);
95
96 this.file_ = null;
97 };
98
99 /**
100 * Shows the popup.
101 * @param {int} x The X position to show at
102 * @param {int} y The Y position to show at
103 */
104 armadillo.Actor.prototype.show = function(x, y) {
105 if (armadillo.Actor.isModal())
106 return;
107 var firstBodyElement = goog.dom.getFirstElementChild(document.body);
108 goog.dom.insertSiblingBefore(this.element_, firstBodyElement);
109 this.popup_.setPinnedCorner(goog.positioning.Corner.TOP_LEFT);
110 this.popup_.setPosition(new goog.positioning.ClientPosition(x, y));
111 this.popup_.setHideOnEscape(true);
112 this.popup_.setVisible(true);
113 };
114
115 /**
116 * Hides the popup.
117 */
118 armadillo.Actor.prototype.hide = function() {
119 this.popup_.setVisible(false);
120 };
121
122 /**
123 * Creates the DOM Element that is inserted into the popup.
124 * @returns Element
125 */
126 armadillo.Actor.prototype.createElement_ = function() {
127 var root = goog.dom.createDom('div', 'actor');
128 for (var option in armadillo.Actor.options_) {
129 var tile = goog.dom.createDom('div', 'tile');
130 var value = armadillo.Actor.options_[option];
131 // Cannot open non-directory files.
132 if (value == armadillo.Actor.options_.OPEN && !this.file_.isDirectory()) {
133 continue;
134 }
135 var title = goog.dom.createDom('span', 'title',
136 armadillo.Actor.optionStrings_[value]);
137 goog.dom.appendChild(tile, title);
138 goog.dom.appendChild(root, tile);
139 tile.actorOption = value;
140 tile.actorListener = goog.events.listen(tile, goog.events.EventType.CLICK,
141 this.tileClickHandler_, false, this);
142 }
143 return root;
144 };
145
146 /**
147 * Click handler for individual tiles.
148 * @param {Event} e
149 */
150 armadillo.Actor.prototype.tileClickHandler_ = function(e) {
151 var option = e.target.actorOption;
152 if (option == armadillo.Actor.options_.OPEN) {
153 // TODO: assert that this.file_.isDirectory().
154 app.navigate(this.file_.getName());
155 this.hide();
156 } else if (option == armadillo.Actor.options_.MOVE) {
157 this.performMove_();
158 } else if (option == armadillo.Actor.options_.DELETE) {
159 this.performDelete_();
160 }
161 };
162
163 /**
164 * Subroutine to handle bringing up the move confirmation UI.
165 * @private
166 */
167 armadillo.Actor.prototype.performMove_ = function() {
168 var dialog = this.createActionDialog_();
169 dialog.setTitle('Move File');
170
171 var container = dialog.getContentElement();
172 goog.dom.appendChild(container,
173 goog.dom.createDom('p', null,
174 'Enter a new, absolute path for this file.'));
175 var field = goog.dom.createElement('input');
176 field.type = 'text';
177 field.value = this.file_.getFullPath();
178 goog.dom.appendChild(container, field)
179 // TODO: Suck less.
180 goog.dom.appendChild(container,
181 goog.dom.createDom('p', 'smallfont',
182 '(Please pardon this interface. Armadillo is a work-in-progress.)'));
183
184 dialog.setVisible(true);
185 field.focus();
186 };
187
188 /**
189 * Subroutine to handle bringing up the delete confirmation UI.
190 * @private
191 */
192 armadillo.Actor.prototype.performDelete_ = function() {
193 var confirm = this.createActionDialog_();
194 confirm.setTitle('Confirm Delete');
195
196 var container = confirm.getContentElement();
197 var content = goog.dom.createDom('span', null,
198 'Are you sure you want to delete:',
199 goog.dom.createElement('br'),
200 goog.dom.createDom('strong', null, this.file_.getName()));
201 goog.dom.appendChild(container, content);
202
203 var closeCallback = function(e) {
204 if (e.key != goog.ui.Dialog.DefaultButtonKeys.CANCEL) {
205 this.file_.remove();
206 }
207 };
208 // Will be removed when the event source closes.
209 goog.events.listen(confirm, goog.ui.Dialog.SELECT_EVENT,
210 closeCallback, false, this);
211
212 confirm.setVisible(true);
213 };
214
215 /**
216 * Creates a new instance of a Dialog that has some basic properties set that
217 * are common to performing actions.
218 * @private
219 */
220 armadillo.Actor.prototype.createActionDialog_ = function() {
221 var confirm = new goog.ui.Dialog();
222 confirm.setDisposeOnHide(true);
223 confirm.setEscapeToCancel(true);
224 confirm.setModal(true);
225 confirm.setDraggable(false);
226 confirm.setHasTitleCloseButton(false);
227 return confirm;
228 };