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