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