]> jfr.im git - irc/quakenet/qwebirc.git/blame - js/ui/qui.js
IE fixes.
[irc/quakenet/qwebirc.git] / js / ui / qui.js
CommitLineData
e20e5a6b
CP
1qwebirc.ui.QUI = new Class({
2 Extends: qwebirc.ui.NewLoginUI,
3 initialize: function(parentElement, theme) {
4 this.parent(parentElement, qwebirc.ui.QUI.Window, "qui");
5 this.theme = theme;
6 this.parentElement = parentElement;
7 },
8 postInitialize: function() {
9 this.qjsui = new qwebirc.ui.QUI.JSUI("qwebirc-qui", this.parentElement);
bfbe72f9
CP
10 this.qjsui.addEvent("reflow", function() {
11 var w = this.getActiveWindow();
12 if($defined(w))
13 w.onResize();
14 }.bind(this));
e20e5a6b
CP
15 this.qjsui.top.addClass("tabbar");
16
17 this.qjsui.bottom.addClass("input");
18 this.qjsui.right.addClass("nicklist");
19 this.qjsui.topic.addClass("topic");
20 this.qjsui.middle.addClass("lines");
21
22 this.tabs = this.qjsui.top;
23 this.origtopic = this.topic = this.qjsui.topic;
24 this.origlines = this.lines = this.qjsui.middle;
25 this.orignicklist = this.nicklist = this.qjsui.right;
26
27 this.input = this.qjsui.bottom;
28 this.reflow = this.qjsui.reflow.bind(this.qjsui);
29
ff4befd8
CP
30 this.tabs.addEvent("mousewheel", function(x) {
31 var event = new Event(x);
32
33 /* up */
34 if(event.wheel > 0) {
35 this.nextWindow();
36 } else if(event.wheel < 0) {
37 /* down */
38 this.prevWindow();
39 }
40 event.stop();
41 }.bind(this));
42
e20e5a6b
CP
43 this.createInput();
44 this.reflow();
45 },
46 createInput: function() {
47 var form = new Element("form");
48 this.input.appendChild(form);
49 form.addClass("input");
50
51 var inputbox = new Element("input");
52 form.appendChild(inputbox);
53 this.inputbox = inputbox;
54
55 form.addEvent("submit", function(e) {
56 new Event(e).stop();
57
58 if(inputbox.value == "")
59 return;
60
3184781b 61 this.resetTabComplete();
e20e5a6b
CP
62 this.getActiveWindow().historyExec(inputbox.value);
63 inputbox.value = "";
64 }.bind(this));
65
3184781b
CP
66 inputbox.addEvent("focus", this.resetTabComplete.bind(this));
67 inputbox.addEvent("mousedown", this.resetTabComplete.bind(this));
68
e20e5a6b
CP
69 inputbox.addEvent("keydown", function(e) {
70 var resultfn;
71 var cvalue = inputbox.value;
3184781b 72
e20e5a6b
CP
73 if(e.key == "up") {
74 resultfn = this.commandhistory.upLine;
75 } else if(e.key == "down") {
76 resultfn = this.commandhistory.downLine;
3184781b
CP
77 } else if(e.key == "tab") {
78 new Event(e).stop();
79 this.tabComplete(inputbox);
80 return;
e20e5a6b 81 } else {
3184781b
CP
82 /* ideally alt and other keys wouldn't break this */
83 this.resetTabComplete();
e20e5a6b
CP
84 return;
85 }
86
3184781b 87 this.resetTabComplete();
e20e5a6b
CP
88 if((cvalue != "") && (this.lastcvalue != cvalue))
89 this.commandhistory.addLine(cvalue, true);
90
91 var result = resultfn.bind(this.commandhistory)();
92
93 new Event(e).stop();
94 if(!result)
95 result = "";
96 this.lastcvalue = result;
97
98 inputbox.value = result;
1d6756bc 99 qwebirc.util.setAtEnd(inputbox);
e20e5a6b
CP
100 }.bind(this));
101 },
102 setLines: function(lines) {
103 this.lines.parentNode.replaceChild(lines, this.lines);
104 this.qjsui.middle = this.lines = lines;
105 },
106 setChannelItems: function(nicklist, topic) {
107 if(!$defined(nicklist)) {
108 nicklist = this.orignicklist;
109 topic = this.origtopic;
110 }
111 this.nicklist.parentNode.replaceChild(nicklist, this.nicklist);
112 this.qjsui.right = this.nicklist = nicklist;
113
114 this.topic.parentNode.replaceChild(topic, this.topic);
115 this.qjsui.topic = this.topic = topic;
116 }
117});
118
119qwebirc.ui.QUI.JSUI = new Class({
bfbe72f9 120 Implements: [Events],
b1ee83f3
CP
121 initialize: function(class_, parent, sizer) {
122 this.parent = parent;
123 this.sizer = $defined(sizer)?sizer:parent;
124
24ede2cb
CP
125 this.class_ = class_;
126 this.create();
127
6c19eb8f
CP
128 this.reflowevent = null;
129
b1ee83f3 130 window.addEvent("resize", function() {
6c19eb8f 131 this.reflow(100);
b1ee83f3
CP
132 }.bind(this));
133 },
24ede2cb 134 applyClasses: function(pos, l) {
6c19eb8f 135 l.addClass("dynamicpanel");
24ede2cb 136 l.addClass(this.class_);
6c19eb8f 137
24ede2cb
CP
138 if(pos == "middle") {
139 l.addClass("leftboundpanel");
140 } else if(pos == "top") {
141 l.addClass("topboundpanel");
142 l.addClass("widepanel");
143 } else if(pos == "topic") {
144 l.addClass("widepanel");
145 } else if(pos == "right") {
146 l.addClass("rightboundpanel");
147 } else if(pos == "bottom") {
148 l.addClass("bottomboundpanel");
149 l.addClass("widepanel");
150 }
151 },
152 create: function() {
153 var XE = function(pos) {
154 var element = new Element("div");
155 this.applyClasses(pos, element);
b1ee83f3 156
24ede2cb
CP
157 this.parent.appendChild(element);
158 return element;
b1ee83f3
CP
159 }.bind(this);
160
24ede2cb
CP
161 this.top = XE("top");
162 this.topic = XE("topic");
163 this.middle = XE("middle");
164 this.right = XE("right");
165 this.bottom = XE("bottom");
b1ee83f3 166 },
6c19eb8f
CP
167 reflow: function(delay) {
168 if(!delay)
169 delay = 1;
170
171 if(this.reflowevent)
172 $clear(this.reflowevent);
173 this.__reflow();
174 this.reflowevent = this.__reflow.delay(delay, this);
175 },
176 __reflow: function() {
b1ee83f3
CP
177 var bottom = this.bottom;
178 var middle = this.middle;
179 var right = this.right;
180 var topic = this.topic;
181 var top = this.top;
182
183 var topicsize = topic.getSize();
184 var topsize = top.getSize();
185 var rightsize = right.getSize();
186 var bottomsize = bottom.getSize();
187 var docsize = this.sizer.getSize();
188
189 var mheight = (docsize.y - topsize.y - bottomsize.y - topicsize.y);
190 var mwidth = (docsize.x - rightsize.x);
191
192 topic.setStyle("top", topsize.y + "px");
193
194 middle.setStyle("top", (topsize.y + topicsize.y) + "px");
195 if(mheight > 0) {
196 middle.setStyle("height", mheight + "px");
197 right.setStyle("height", mheight + "px");
198 }
199
6c19eb8f 200 if(mwidth > 0)
b1ee83f3 201 middle.setStyle("width", mwidth + "px");
b1ee83f3
CP
202 right.setStyle("top", (topsize.y + topicsize.y) + "px");
203 right.setStyle("left", mwidth + "px");
204
205 bottom.setStyle("top", (docsize.y - bottomsize.y) + "px");
bfbe72f9 206 this.fireEvent("reflow");
b1ee83f3
CP
207 },
208 showChannel: function(state) {
209 var display = "none";
210 if(state)
211 display = "block";
212
213 this.right.setStyle("display", display);
214 this.topic.setStyle("display", display);
6c19eb8f
CP
215 },
216 showInput: function(state) {
217 this.bottom.setStyle("display", state?"block":"none");
b1ee83f3
CP
218 }
219});
35155ba7 220
e20e5a6b
CP
221qwebirc.ui.QUI.Window = new Class({
222 Extends: qwebirc.ui.Window,
f4ae92cc
CP
223
224 initialize: function(parentObject, client, type, name) {
225 this.parent(parentObject, client, type, name);
be0bd774 226
66de775f 227 this.tab = new Element("a", {"href": "#"});
f4ae92cc 228 this.tab.addClass("tab");
fd60516d
CP
229 this.tab.addEvent("focus", function() { this.blur() }.bind(this.tab));;
230
35155ba7 231 parentObject.tabs.appendChild(this.tab);
f4ae92cc
CP
232
233 this.tab.appendText(name);
66de775f
CP
234 this.tab.addEvent("click", function(e) {
235 new Event(e).stop();
f84bf379
CP
236
237 if(this.closed)
238 return;
239
f4ae92cc
CP
240 parentObject.selectWindow(this);
241 }.bind(this));
f4ae92cc 242
e20e5a6b
CP
243 if(type != qwebirc.ui.WINDOW_STATUS && type != qwebirc.ui.WINDOW_CONNECT) {
244 var tabclose = new Element("span");
245 tabclose.set("text", "X");
f4ae92cc 246 tabclose.addClass("tabclose");
f84bf379 247 var close = function(e) {
f4ae92cc
CP
248 new Event(e).stop();
249
f84bf379
CP
250 if(this.closed)
251 return;
252
e20e5a6b 253 if(type == qwebirc.ui.WINDOW_CHANNEL)
f4ae92cc
CP
254 this.client.exec("/PART " + name);
255
256 this.close();
3184781b
CP
257
258 parentObject.inputbox.focus();
f84bf379
CP
259 }.bind(this);
260
261 tabclose.addEvent("click", close);
262 this.tab.addEvent("mouseup", function(e) {
b46f79e6
CP
263 var button = 1;
264
265 if(Browser.Engine.trident)
266 button = 4;
267
268 if(e.event.button == button)
f84bf379 269 close(e);
f4ae92cc 270 }.bind(this));
52090a1f 271
f4ae92cc
CP
272 this.tab.appendChild(tabclose);
273 }
be0bd774 274
be0bd774 275 this.lines = new Element("div");
6c19eb8f 276 this.parentObject.qjsui.applyClasses("middle", this.lines);
be0bd774 277 this.lines.addClass("lines");
6c19eb8f 278
b1ee83f3
CP
279 this.lines.addEvent("scroll", function() {
280 this.scrolleddown = this.scrolledDown();
ff6a32cc 281 this.scrollpos = this.getScrollParent().getScroll();
be0bd774 282 }.bind(this));
be0bd774 283
e20e5a6b 284 if(type == qwebirc.ui.WINDOW_CHANNEL) {
be0bd774
CP
285 this.topic = new Element("div");
286 this.topic.addClass("topic");
b1ee83f3 287 this.topic.addClass("tab-invisible");
be0bd774 288 this.topic.set("html", "&nbsp;");
6c19eb8f 289 this.parentObject.qjsui.applyClasses("topic", this.topic);
be0bd774 290
52090a1f 291 this.prevNick = null;
66de775f
CP
292 this.nicklist = new Element("div");
293 this.nicklist.addClass("nicklist");
b1ee83f3 294 this.nicklist.addClass("tab-invisible");
cffd43cf 295 this.nicklist.addEvent("click", this.removePrevMenu.bind(this));
6c19eb8f 296 this.parentObject.qjsui.applyClasses("nicklist", this.nicklist);
be0bd774 297 }
b1ee83f3 298
e20e5a6b 299 if(type == qwebirc.ui.WINDOW_CHANNEL) {
359b7edd
CP
300 this.updateTopic("");
301 } else {
302 this.reflow();
303 }
b1ee83f3
CP
304 },
305 reflow: function() {
306 this.parentObject.reflow();
35155ba7
CP
307 },
308 onResize: function() {
ff6a32cc
CP
309 if(this.scrolleddown) {
310 if(Browser.Engine.trident) {
311 this.scrollToBottom.delay(5, this);
312 } else {
313 this.scrollToBottom();
314 }
315 } else if($defined(this.scrollpos)) {
316 if(Browser.Engine.trident) {
317 this.getScrollParent().scrollTo(this.scrollpos.x, this.scrollpos.y);
318 } else {
319 this.getScrollParent().scrollTo.delay(5, this, [this.scrollpos.x, this.scrollpos.y]);
320 }
321 }
359b7edd 322 },
cffd43cf 323 createMenu: function(nick, parent) {
d2512acf 324 var e = new Element("div");
cffd43cf
CP
325 parent.appendChild(e);
326 e.addClass("menu");
327
328 qwebirc.ui.MENU_ITEMS.forEach(function(x) {
d2512acf 329 var e2 = new Element("a");
cffd43cf
CP
330 e.appendChild(e2);
331
332 e2.href = "#";
333 e2.set("text", "- " + x[0]);
334
335 e2.addEvent("focus", function() { this.blur() }.bind(e2));
336 e2.addEvent("click", function(ev) { new Event(ev.stop()); this.menuClick(x[1]); }.bind(this));
337 }.bind(this));
338 return e;
339 },
340 menuClick: function(fn) {
341 /*
342 this.prevNick.removeChild(this.prevNick.menu);
343 this.prevNick.menu = null;
344 */
345 fn.bind(this)(this.prevNick.realNick);
346 this.removePrevMenu();
347 },
d8272bcb
CP
348 moveMenuClass: function() {
349 if(!this.prevNick)
350 return;
351 if(this.nicklist.firstChild == this.prevNick) {
352 this.prevNick.removeClass("selected-middle");
353 } else {
354 this.prevNick.addClass("selected-middle");
355 }
356 },
cffd43cf
CP
357 removePrevMenu: function() {
358 if(!this.prevNick)
359 return;
360
361 this.prevNick.removeClass("selected");
d8272bcb 362 this.prevNick.removeClass("selected-middle");
cffd43cf
CP
363 if(this.prevNick.menu)
364 this.prevNick.removeChild(this.prevNick.menu);
365 this.prevNick = null;
366 },
52090a1f
CP
367 nickListAdd: function(nick, position) {
368 var e = new Element("a");
369 qwebirc.ui.insertAt(position, this.nicklist, e);
f4ae92cc 370
52090a1f
CP
371 e.href = "#";
372 e.appendChild(document.createTextNode(nick));
373
374 e.realNick = this.client.stripPrefix(nick);
375
376 e.addEvent("click", function(x) {
aab6d06a
CP
377 if(this.prevNick == e) {
378 this.removePrevMenu();
379 return;
380 }
381
cffd43cf 382 this.removePrevMenu();
52090a1f
CP
383 this.prevNick = e;
384 e.addClass("selected");
d8272bcb 385 this.moveMenuClass();
cffd43cf 386 e.menu = this.createMenu(x.realNick, e);
52090a1f
CP
387 new Event(x).stop();
388 }.bind(this));
389 e.addEvent("dblclick", function(x) {
390 new Event(x).stop();
391 this.client.exec("/QUERY " + e.realNick);
392 }.bind(this));
393
fd60516d 394 e.addEvent("focus", function() { this.blur() }.bind(e));
d8272bcb 395 this.moveMenuClass();
52090a1f
CP
396 return e;
397 },
398 nickListRemove: function(nick, stored) {
399 this.nicklist.removeChild(stored);
d8272bcb 400 this.moveMenuClass();
f4ae92cc
CP
401 },
402 updateTopic: function(topic) {
f4ae92cc
CP
403 var t = this.topic;
404
405 while(t.firstChild)
406 t.removeChild(t.firstChild);
407
66de775f 408 if(topic) {
1f06a70a 409 this.parent(topic, t);
66de775f 410 } else {
359b7edd
CP
411 var e = new Element("div");
412 e.set("text", "(no topic set)");
66de775f 413 e.addClass("emptytopic");
359b7edd 414 t.appendChild(e);
66de775f 415 }
359b7edd 416 this.reflow();
f4ae92cc
CP
417 },
418 select: function() {
e20e5a6b 419 var inputVisible = this.type != qwebirc.ui.WINDOW_CONNECT && this.type != qwebirc.ui.WINDOW_CUSTOM;
6c19eb8f 420
f4ae92cc 421 this.tab.removeClass("tab-unselected");
f4ae92cc 422 this.tab.addClass("tab-selected");
359b7edd 423
6c19eb8f
CP
424 this.parentObject.setLines(this.lines);
425 this.parentObject.setChannelItems(this.nicklist, this.topic);
426 this.parentObject.qjsui.showInput(inputVisible);
427 this.parentObject.qjsui.showChannel($defined(this.nicklist));
428
429 this.reflow();
24ede2cb 430
7c633700 431 this.parent();
25be5960 432
6c19eb8f
CP
433 if(inputVisible)
434 this.parentObject.inputbox.focus();
f4ae92cc
CP
435 },
436 deselect: function() {
437 this.parent();
438
f4ae92cc
CP
439 this.tab.removeClass("tab-selected");
440 this.tab.addClass("tab-unselected");
441 },
442 close: function() {
443 this.parent();
444
f4ae92cc
CP
445 this.parentObject.tabs.removeChild(this.tab);
446 },
447 addLine: function(type, line, colour) {
f4ae92cc
CP
448 var e = new Element("div");
449
450 if(colour) {
451 e.setStyles({"background": colour});
452 } else if(this.lastcolour) {
453 e.addClass("linestyle1");
454 } else {
455 e.addClass("linestyle2");
456 }
f4ae92cc 457 this.lastcolour = !this.lastcolour;
35155ba7 458
be0bd774
CP
459 this.parent(type, line, colour, e);
460 },
461 setHilighted: function(state) {
96f28062
CP
462 laststate = this.hilighted;
463
be0bd774 464 this.parent(state);
96f28062
CP
465
466 if(state == laststate)
467 return;
468
469 this.tab.removeClass("tab-hilight-activity");
470 this.tab.removeClass("tab-hilight-us");
471 this.tab.removeClass("tab-hilight-speech");
f4ae92cc 472
96f28062
CP
473 switch(this.hilighted) {
474 case qwebirc.ui.HILIGHT_US:
475 this.tab.addClass("tab-hilight-us");
476 break;
477 case qwebirc.ui.HILIGHT_SPEECH:
478 this.tab.addClass("tab-hilight-speech");
479 break;
480 case qwebirc.ui.HILIGHT_ACTIVITY:
481 this.tab.addClass("tab-hilight-activity");
482 break;
be0bd774 483 }
f4ae92cc
CP
484 }
485});