Create our own 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.ModalDialog');
13 goog.require('armadillo.PathControl');
14 goog.require('goog.array');
15 goog.require('goog.dom');
16 goog.require('goog.events');
17 goog.require('goog.positioning.ClientPosition');
18 goog.require('goog.positioning.Corner');
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 this.performMove_();
160 } else if (option == armadillo.Actor.options_.DELETE) {
161 this.performDelete_();
162 } else if (option == armadillo.Actor.options_.RENAME) {
163 var dialog = new armadillo.ModalDialog();
164 dialog.render();
165 dialog.setVisible(true);
166 }
167 };
168
169 /**
170 * Subroutine to handle bringing up the move confirmation UI.
171 * @private
172 */
173 armadillo.Actor.prototype.performMove_ = function() {
174 var dialog = this.createActionDialog_();
175 dialog.setTitle('Move File');
176
177 var editor = new armadillo.PathControl(this.file_.getFullPath(), false);
178 dialog.addChild(editor, true);
179
180 dialog.setVisible(true);
181 };
182
183 /**
184 * Subroutine to handle bringing up the delete confirmation UI.
185 * @private
186 */
187 armadillo.Actor.prototype.performDelete_ = function() {
188 var confirm = this.createActionDialog_();
189 confirm.setTitle('Confirm Delete');
190
191 var container = confirm.getContentElement();
192 var content = goog.dom.createDom('span', null,
193 'Are you sure you want to delete:',
194 goog.dom.createElement('br'),
195 goog.dom.createDom('strong', null, this.file_.getName()));
196 goog.dom.appendChild(container, content);
197
198 var closeCallback = function(e) {
199 if (e.key != goog.ui.Dialog.DefaultButtonKeys.CANCEL) {
200 this.file_.remove();
201 }
202 };
203 // Will be removed when the event source closes.
204 goog.events.listen(confirm, goog.ui.Dialog.SELECT_EVENT,
205 closeCallback, false, this);
206
207 confirm.setVisible(true);
208 };
209
210 /**
211 * Creates a new instance of a Dialog that has some basic properties set that
212 * are common to performing actions.
213 * @private
214 */
215 armadillo.Actor.prototype.createActionDialog_ = function() {
216 var confirm = new goog.ui.Dialog();
217 confirm.setDisposeOnHide(true);
218 confirm.setEscapeToCancel(true);
219 confirm.setModal(true);
220 confirm.setDraggable(false);
221 confirm.setHasTitleCloseButton(false);
222 return confirm;
223 };