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