]> jfr.im git - irc/quakenet/qwebirc.git/blob - js/ui/qui.js
Works everywhere!
[irc/quakenet/qwebirc.git] / js / ui / qui.js
1 var QJSUI = new Class({
2 initialize: function(class_, parent, sizer) {
3 this.parent = parent;
4 this.sizer = $defined(sizer)?sizer:parent;
5
6 this.class_ = class_;
7 this.create();
8
9 this.reflowevent = null;
10
11 window.addEvent("resize", function() {
12 this.reflow(100);
13 }.bind(this));
14 },
15 applyClasses: function(pos, l) {
16 l.addClass("dynamicpanel");
17 l.addClass(this.class_);
18
19 if(pos == "middle") {
20 l.addClass("leftboundpanel");
21 } else if(pos == "top") {
22 l.addClass("topboundpanel");
23 l.addClass("widepanel");
24 } else if(pos == "topic") {
25 l.addClass("widepanel");
26 } else if(pos == "right") {
27 l.addClass("rightboundpanel");
28 } else if(pos == "bottom") {
29 l.addClass("bottomboundpanel");
30 l.addClass("widepanel");
31 }
32 },
33 create: function() {
34 var XE = function(pos) {
35 var element = new Element("div");
36 this.applyClasses(pos, element);
37
38 this.parent.appendChild(element);
39 return element;
40 }.bind(this);
41
42 this.top = XE("top");
43 this.topic = XE("topic");
44 this.middle = XE("middle");
45 this.right = XE("right");
46 this.bottom = XE("bottom");
47 },
48 reflow: function(delay) {
49 if(!delay)
50 delay = 1;
51
52 if(this.reflowevent)
53 $clear(this.reflowevent);
54 this.__reflow();
55 this.reflowevent = this.__reflow.delay(delay, this);
56 },
57 __reflow: function() {
58 var bottom = this.bottom;
59 var middle = this.middle;
60 var right = this.right;
61 var topic = this.topic;
62 var top = this.top;
63
64 var topicsize = topic.getSize();
65 var topsize = top.getSize();
66 var rightsize = right.getSize();
67 var bottomsize = bottom.getSize();
68 var docsize = this.sizer.getSize();
69
70 var mheight = (docsize.y - topsize.y - bottomsize.y - topicsize.y);
71 var mwidth = (docsize.x - rightsize.x);
72
73 topic.setStyle("top", topsize.y + "px");
74
75 middle.setStyle("top", (topsize.y + topicsize.y) + "px");
76 if(mheight > 0) {
77 middle.setStyle("height", mheight + "px");
78 right.setStyle("height", mheight + "px");
79 }
80
81 if(mwidth > 0)
82 middle.setStyle("width", mwidth + "px");
83 right.setStyle("top", (topsize.y + topicsize.y) + "px");
84 right.setStyle("left", mwidth + "px");
85
86 bottom.setStyle("top", (docsize.y - bottomsize.y) + "px");
87 },
88 showChannel: function(state) {
89 var display = "none";
90 if(state)
91 display = "block";
92
93 this.right.setStyle("display", display);
94 this.topic.setStyle("display", display);
95 },
96 showInput: function(state) {
97 this.bottom.setStyle("display", state?"block":"none");
98 }
99 });
100
101 var QUIWindow = new Class({
102 Extends: UIWindow,
103
104 initialize: function(parentObject, client, type, name) {
105 this.parent(parentObject, client, type, name);
106
107 this.tab = new Element("a", {"href": "#"});
108 this.tab.addClass("tab");
109 parentObject.tabs.appendChild(this.tab);
110
111 this.tab.appendText(name);
112 this.tab.addEvent("click", function(e) {
113 new Event(e).stop();
114 parentObject.selectWindow(this);
115 }.bind(this));
116
117 if(type != WINDOW_STATUS && type != WINDOW_CONNECT) {
118 tabclose = new Element("span");
119 tabclose.addClass("tabclose");
120 tabclose.addEvent("click", function(e) {
121 new Event(e).stop();
122
123 if(type == WINDOW_CHANNEL)
124 this.client.exec("/PART " + name);
125
126 this.close();
127 }.bind(this));
128
129 this.tab.appendChild(tabclose);
130 }
131
132 this.lines = new Element("div");
133 this.parentObject.qjsui.applyClasses("middle", this.lines);
134 this.lines.addClass("lines");
135
136 this.lines.addEvent("scroll", function() {
137 this.scrolleddown = this.scrolledDown();
138 }.bind(this));
139
140 if(type == WINDOW_CHANNEL) {
141 this.topic = new Element("div");
142 this.topic.addClass("topic");
143 this.topic.addClass("tab-invisible");
144 this.topic.set("html", " ");
145 this.parentObject.qjsui.applyClasses("topic", this.topic);
146
147 this.nicklist = new Element("div");
148 this.nicklist.addClass("nicklist");
149 this.nicklist.addClass("tab-invisible");
150 this.parentObject.qjsui.applyClasses("nicklist", this.nicklist);
151 }
152
153 if(type == WINDOW_CHANNEL) {
154 this.updateTopic("");
155 } else {
156 this.reflow();
157 }
158 },
159 reflow: function() {
160 this.parentObject.reflow();
161 },
162 onResize: function() {
163 if(this.scrolleddown)
164 this.scrollToBottom();
165 },
166 updateNickList: function(nicks) {
167 this.parent(nicks);
168
169 var n = this.nicklist;
170 while(n.firstChild)
171 n.removeChild(n.firstChild);
172
173 nicks.each(function(nick) {
174 var e = new Element("div");
175 n.appendChild(e);
176 e.appendChild(document.createTextNode(nick));
177 });
178 },
179 updateTopic: function(topic) {
180 this.parent(topic);
181
182 var t = this.topic;
183
184 while(t.firstChild)
185 t.removeChild(t.firstChild);
186
187 if(topic) {
188 Colourise("[" + topic + "]", t);
189 } else {
190 var e = new Element("div");
191 e.set("text", "(no topic set)");
192 e.addClass("emptytopic");
193 t.appendChild(e);
194 }
195 this.reflow();
196 },
197 select: function() {
198 var inputVisible = this.type != WINDOW_CONNECT && this.type != WINDOW_CUSTOM;
199
200 this.tab.removeClass("tab-unselected");
201 this.tab.addClass("tab-selected");
202
203 this.parentObject.setLines(this.lines);
204 this.parentObject.setChannelItems(this.nicklist, this.topic);
205 this.parentObject.qjsui.showInput(inputVisible);
206 this.parentObject.qjsui.showChannel($defined(this.nicklist));
207
208 this.reflow();
209
210 this.parent();
211
212 if(inputVisible)
213 this.parentObject.inputbox.focus();
214 },
215 deselect: function() {
216 this.parent();
217
218 this.tab.removeClass("tab-selected");
219 this.tab.addClass("tab-unselected");
220 },
221 close: function() {
222 this.parent();
223
224 this.parentObject.tabs.removeChild(this.tab);
225 },
226 addLine: function(type, line, colour) {
227 var e = new Element("div");
228
229 if(colour) {
230 e.setStyles({"background": colour});
231 } else if(this.lastcolour) {
232 e.addClass("linestyle1");
233 } else {
234 e.addClass("linestyle2");
235 }
236 this.lastcolour = !this.lastcolour;
237
238 this.parent(type, line, colour, e);
239 },
240 setHilighted: function(state) {
241 this.parent(state);
242
243 if(state) {
244 this.tab.addClass("tab-hilighted");
245 } else {
246 this.tab.removeClass("tab-hilighted");
247 }
248 }
249 });
250
251 var QUI = new Class({
252 Extends: NewLoginUI,
253 initialize: function(parentElement, theme) {
254 this.parent(parentElement, QUIWindow, "qui");
255 this.theme = theme;
256 this.parentElement = parentElement;
257 },
258 postInitialize: function() {
259 this.qjsui = new QJSUI("qwebirc-qui", this.parentElement);
260
261 this.qjsui.top.addClass("tabbar");
262
263 this.qjsui.bottom.addClass("input");
264 this.qjsui.right.addClass("nicklist");
265 this.qjsui.topic.addClass("topic");
266 this.qjsui.middle.addClass("lines");
267
268 this.tabs = this.qjsui.top;
269 this.origtopic = this.topic = this.qjsui.topic;
270 this.origlines = this.lines = this.qjsui.middle;
271 this.orignicklist = this.nicklist = this.qjsui.right;
272
273 this.input = this.qjsui.bottom;
274 this.reflow = this.qjsui.reflow.bind(this.qjsui);
275
276 this.createInput();
277 this.reflow();
278 },
279 createInput: function() {
280 var form = new Element("form");
281 this.input.appendChild(form);
282 form.addClass("input");
283
284 var inputbox = new Element("input");
285 form.appendChild(inputbox);
286 this.inputbox = inputbox;
287
288 form.addEvent("submit", function(e) {
289 new Event(e).stop();
290
291 if(inputbox.value == "")
292 return;
293
294 this.getActiveWindow().historyExec(inputbox.value);
295 inputbox.value = "";
296 }.bind(this));
297
298 inputbox.addEvent("keydown", function(e) {
299 var resultfn;
300 var cvalue = inputbox.value;
301
302 if(e.key == "up") {
303 resultfn = this.commandhistory.upLine;
304 } else if(e.key == "down") {
305 resultfn = this.commandhistory.downLine;
306 } else {
307 return;
308 }
309
310 if((cvalue != "") && (this.lastcvalue != cvalue))
311 this.commandhistory.addLine(cvalue, true);
312
313 var result = resultfn.bind(this.commandhistory)();
314
315 new Event(e).stop();
316 if(!result)
317 result = "";
318 this.lastcvalue = result;
319
320 inputbox.value = result;
321 setAtEnd(inputbox);
322 }.bind(this));
323 },
324 setLines: function(lines) {
325 this.lines.parentNode.replaceChild(lines, this.lines);
326 this.qjsui.middle = this.lines = lines;
327 },
328 setChannelItems: function(nicklist, topic) {
329 if(!$defined(nicklist)) {
330 nicklist = this.orignicklist;
331 topic = this.origtopic;
332 }
333 this.nicklist.parentNode.replaceChild(nicklist, this.nicklist);
334 this.qjsui.right = this.nicklist = nicklist;
335
336 this.topic.parentNode.replaceChild(topic, this.topic);
337 this.qjsui.topic = this.topic = topic;
338 }
339 });