Start listening for the event to detect path component changes.
[armadillo.git] / web_frontend / path_control.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.PathControl');
11
12 goog.require('goog.array');
13 goog.require('goog.ui.Component');
14 goog.require('goog.ui.FilteredMenu');
15 goog.require('goog.ui.LabelInput');
16 goog.require('goog.ui.MenuButton');
17 goog.require('goog.ui.MenuItem');
18
19 /**
20 * Creates a new path editing control for a given path.
21 * @param {string} path The path to create an editor for
22 * @param {bool} editLastComponent Whether the last component should be shown as an edit box
23 * @param {DomHelper} opt_domHelper Optional DOM helper
24 * @constructor
25 */
26 armadillo.PathControl = function(path, editLastComponent, opt_domHelper) {
27 goog.ui.Component.call(this, opt_domHelper);
28
29 /**
30 * Full path of the control.
31 * @type {string}
32 */
33 this.path_ = path;
34
35 /**
36 * Whether or not the last component is editable.
37 * @type {bool}
38 */
39 this.editableLastComponent_ = editLastComponent;
40
41 /**
42 * List of path components
43 * @type {Array}
44 */
45 this.components_ = new Array();
46 };
47 goog.inherits(armadillo.PathControl, goog.ui.Component);
48
49 /**
50 * Disposer
51 * @protected
52 */
53 armadillo.PathControl.prototype.disposeInternal = function() {
54 armadillo.PathControl.superClass_.disposeInternal.call(this);
55 this.components_ = null;
56 };
57
58 /**
59 * Creates a new path control object.
60 */
61 armadillo.PathControl.prototype.createDom = function() {
62 this.decorateInternal(this.dom_.createElement('div'));
63 };
64
65 /**
66 * @inheritDoc
67 */
68 armadillo.PathControl.prototype.canDecorate = function() {
69 return true;
70 };
71
72 /**
73 * Decorates the given element into a path control.
74 * @param {Element} element
75 */
76 armadillo.PathControl.prototype.decorateInternal = function(element) {
77 this.element_ = element;
78 var components = this.path_.split('/');
79
80 if (components.length == 2) {
81 // If this is an item that lives at the root, generate a special node for
82 // moving between items at the top level.
83 components[0] = '/';
84 } else {
85 // Otherwise, just remove it as the first node will list all items at the
86 // root.
87 goog.array.removeAt(components, 0);
88 }
89
90 // If the last component is emtpy, do not use it because it means a directory
91 // is being moved.
92 if (components[components.length - 1] == '') {
93 goog.array.removeAt(components, components.length - 1);
94 }
95
96 var path = '/';
97 goog.array.forEach(components, function (part, i) {
98 if (i != components.length - 1) {
99 this.addChild(this.createComponentNode_(path, part), true);
100 } else {
101 var input = new goog.ui.LabelInput(part, this.dom_);
102 this.addChild(input, true);
103 input.setEnabled(this.editableLastComponent_);
104 input.setValue(part);
105 }
106 path += part + '/';
107 }, this);
108 };
109
110 /**
111 * Creates a node for a single path component.
112 * @param {string} path The path up to this point.
113 * @param {string} name The current component after |path|.
114 */
115 armadillo.PathControl.prototype.createComponentNode_ = function(path, name) {
116 var menu = new goog.ui.FilteredMenu();
117 menu.setFilterLabel(name);
118 menu.setAllowMultiple(false);
119 menu.setOpenFollowsHighlight(true);
120 goog.events.listen(menu, goog.ui.Component.EventType.ACTION,
121 this.componentChanged_, false, this);
122 this.fetchMenuContents_(path, name, menu);
123
124 var button = new goog.ui.MenuButton(name, menu, null, this.dom_);
125 button.setFocusablePopupMenu(true);
126 button.setScrollOnOverflow(true);
127 button.setVisible(true);
128 return button;
129 };
130
131 /**
132 * Queries the back-end for all the items at a given path and attaches them to
133 * the given menu.
134 * @param {string} path The path to get a list of items in
135 * @param {string} name The name to select
136 * @param {goog.ui.Menu} The menu to attach items to
137 */
138 armadillo.PathControl.prototype.fetchMenuContents_ = function(path, name, menu) {
139 var callback = function(e) {
140 var data = e.target.getResponseJson();
141 if (data['error']) {
142 app.showError(data['message']);
143 return;
144 }
145 if (path == '') {
146 // If this is the root path element, make sure the root is accessible for
147 // moving items.
148 goog.array.insertAt(data, '/', 0);
149 }
150 goog.array.forEach(data, function (caption) {
151 // It only makes sense to be able to move into directories.
152 if (!app.isDirectory(caption)) {
153 return;
154 }
155 var item = new goog.ui.MenuItem(caption);
156 item.setValue(path + caption);
157 menu.addItem(item);
158 if (caption == name) {
159 menu.setHighlighted(item);
160 }
161 });
162 };
163 app.sendRequest('list', {'path':path}, callback);
164 };
165
166 /**
167 * Handler for changing a component of the control.
168 * @param {Event} e
169 */
170 armadillo.PathControl.prototype.componentChanged_ = function(e) {
171 console.log(e.target.getValue());
172 };