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