]> jfr.im git - irc/quakenet/qwebirc.git/blobdiff - js/ui/qui.js
Add basic branding.
[irc/quakenet/qwebirc.git] / js / ui / qui.js
index 62fca0b9736e01fe0316e99e2a6e9685ecf50711..5380befbec343cdc55ba5c52cb4861991e3142ab 100644 (file)
@@ -1,4 +1,123 @@
-var QJSUI = new Class({
+qwebirc.ui.QUI = new Class({
+  Extends: qwebirc.ui.NewLoginUI,
+  initialize: function(parentElement, theme, options) {
+    this.parent(parentElement, qwebirc.ui.QUI.Window, "qui", options);
+    this.theme = theme;
+    this.parentElement = parentElement;
+  },
+  postInitialize: function() {
+    this.qjsui = new qwebirc.ui.QUI.JSUI("qwebirc-qui", this.parentElement);
+    this.qjsui.addEvent("reflow", function() {
+      var w = this.getActiveWindow();
+      if($defined(w))
+        w.onResize();
+    }.bind(this));
+    this.qjsui.top.addClass("tabbar");
+    
+    this.qjsui.bottom.addClass("input");
+    this.qjsui.right.addClass("nicklist");
+    this.qjsui.topic.addClass("topic");
+    this.qjsui.middle.addClass("lines");
+    
+    this.tabs = this.qjsui.top;
+    this.origtopic = this.topic = this.qjsui.topic;
+    this.origlines = this.lines = this.qjsui.middle;
+    this.orignicklist = this.nicklist = this.qjsui.right;
+    
+    this.input = this.qjsui.bottom;
+    this.reflow = this.qjsui.reflow.bind(this.qjsui);
+    
+    this.tabs.addEvent("mousewheel", function(x) {
+      var event = new Event(x);
+      
+      /* up */
+      if(event.wheel > 0) {
+        this.nextWindow();
+      } else if(event.wheel < 0) {
+        /* down */
+        this.prevWindow();        
+      }
+      event.stop();
+    }.bind(this));
+    
+    this.createInput();
+    this.reflow();
+  },
+  createInput: function() {
+    var form = new Element("form");
+    this.input.appendChild(form);
+    form.addClass("input");
+    
+    var inputbox = new Element("input");
+    form.appendChild(inputbox);
+    this.inputbox = inputbox;
+    
+    form.addEvent("submit", function(e) {
+      new Event(e).stop();
+    
+      if(inputbox.value == "")
+        return;
+        
+      this.resetTabComplete();
+      this.getActiveWindow().historyExec(inputbox.value);
+      inputbox.value = "";
+    }.bind(this));
+    
+    inputbox.addEvent("focus", this.resetTabComplete.bind(this));
+    inputbox.addEvent("mousedown", this.resetTabComplete.bind(this));
+    
+    inputbox.addEvent("keydown", function(e) {
+      var resultfn;
+      var cvalue = inputbox.value;
+      
+      if(e.key == "up") {
+        resultfn = this.commandhistory.upLine;
+      } else if(e.key == "down") {
+        resultfn = this.commandhistory.downLine;
+      } else if(e.key == "tab") {
+        new Event(e).stop();
+        this.tabComplete(inputbox);
+        return;
+      } else {
+        /* ideally alt and other keys wouldn't break this */
+        this.resetTabComplete();
+        return;
+      }
+      
+      this.resetTabComplete();
+      if((cvalue != "") && (this.lastcvalue != cvalue))
+        this.commandhistory.addLine(cvalue, true);
+      
+      var result = resultfn.bind(this.commandhistory)();
+      
+      new Event(e).stop();
+      if(!result)
+        result = "";
+      this.lastcvalue = result;
+        
+      inputbox.value = result;
+      qwebirc.util.setAtEnd(inputbox);
+    }.bind(this));
+  },
+  setLines: function(lines) {
+    this.lines.parentNode.replaceChild(lines, this.lines);
+    this.qjsui.middle = this.lines = lines;
+  },
+  setChannelItems: function(nicklist, topic) {
+    if(!$defined(nicklist)) {
+      nicklist = this.orignicklist;
+      topic = this.origtopic;
+    }
+    this.nicklist.parentNode.replaceChild(nicklist, this.nicklist);
+    this.qjsui.right = this.nicklist = nicklist;
+
+    this.topic.parentNode.replaceChild(topic, this.topic);
+    this.qjsui.topic = this.topic = topic;
+  }
+});
+
+qwebirc.ui.QUI.JSUI = new Class({
+  Implements: [Events],
   initialize: function(class_, parent, sizer) {
     this.parent = parent;
     this.sizer = $defined(sizer)?sizer:parent;
@@ -84,6 +203,7 @@ var QJSUI = new Class({
     right.setStyle("left", mwidth + "px");
     
     bottom.setStyle("top", (docsize.y - bottomsize.y) + "px");
+    this.fireEvent("reflow");
   },
   showChannel: function(state) {
     var display = "none";
@@ -98,59 +218,87 @@ var QJSUI = new Class({
   }
 });
 
-var QUIWindow = new Class({
-  Extends: UIWindow,
+qwebirc.ui.QUI.Window = new Class({
+  Extends: qwebirc.ui.Window,
   
-  initialize: function(parentObject, client, type, name) {
-    this.parent(parentObject, client, type, name);
+  initialize: function(parentObject, client, type, name, identifier) {
+    this.parent(parentObject, client, type, name, identifier);
 
     this.tab = new Element("a", {"href": "#"});
     this.tab.addClass("tab");
+    this.tab.addEvent("focus", function() { this.blur() }.bind(this.tab));;
+    
     parentObject.tabs.appendChild(this.tab);
     
     this.tab.appendText(name);
     this.tab.addEvent("click", function(e) {
       new Event(e).stop();
+      
+      if(this.closed)
+        return;
+        
       parentObject.selectWindow(this);
     }.bind(this));
     
-    if(type != WINDOW_STATUS && type != WINDOW_CONNECT) {
-      tabclose = new Element("span");
+    if(type != qwebirc.ui.WINDOW_STATUS && type != qwebirc.ui.WINDOW_CONNECT) {
+      var tabclose = new Element("span");
+      tabclose.set("text", "X");
       tabclose.addClass("tabclose");
-      tabclose.addEvent("click", function(e) {
+      var close = function(e) {
         new Event(e).stop();
         
-        if(type == WINDOW_CHANNEL)
+        if(this.closed)
+          return;
+          
+        if(type == qwebirc.ui.WINDOW_CHANNEL)
           this.client.exec("/PART " + name);
 
         this.close();
-      }.bind(this));
+        
+        parentObject.inputbox.focus();
+      }.bind(this);
+      
+      tabclose.addEvent("click", close);
+      this.tab.addEvent("mouseup", function(e) {
+        var button = 1;
+        
+        if(Browser.Engine.trident)
+          button = 4;
 
+        if(e.event.button == button)
+          close(e);
+      }.bind(this));
+      
       this.tab.appendChild(tabclose);
     }
 
     this.lines = new Element("div");
     this.parentObject.qjsui.applyClasses("middle", this.lines);
     this.lines.addClass("lines");
+    if(type != qwebirc.ui.WINDOW_CUSTOM && type != qwebirc.ui.WINDOW_CONNECT)
+      this.lines.addClass("ircwindow");
     
     this.lines.addEvent("scroll", function() {
       this.scrolleddown = this.scrolledDown();
+      this.scrollpos = this.getScrollParent().getScroll();
     }.bind(this));
     
-    if(type == WINDOW_CHANNEL) {
+    if(type == qwebirc.ui.WINDOW_CHANNEL) {
       this.topic = new Element("div");
       this.topic.addClass("topic");
       this.topic.addClass("tab-invisible");
       this.topic.set("html", "&nbsp;");
       this.parentObject.qjsui.applyClasses("topic", this.topic);
       
+      this.prevNick = null;
       this.nicklist = new Element("div");
       this.nicklist.addClass("nicklist");
       this.nicklist.addClass("tab-invisible");
+      this.nicklist.addEvent("click", this.removePrevMenu.bind(this));
       this.parentObject.qjsui.applyClasses("nicklist", this.nicklist);
     }
     
-    if(type == WINDOW_CHANNEL) {
+    if(type == qwebirc.ui.WINDOW_CHANNEL) {
       this.updateTopic("");
     } else {
       this.reflow();
@@ -160,32 +308,107 @@ var QUIWindow = new Class({
     this.parentObject.reflow();
   },
   onResize: function() {
-    if(this.scrolleddown)
-      this.scrollToBottom();
+    if(this.scrolleddown) {
+      if(Browser.Engine.trident) {
+        this.scrollToBottom.delay(5, this);
+      } else {
+        this.scrollToBottom();
+      }
+    } else if($defined(this.scrollpos)) {
+      if(Browser.Engine.trident) {
+        this.getScrollParent().scrollTo(this.scrollpos.x, this.scrollpos.y);
+      } else {
+        this.getScrollParent().scrollTo.delay(5, this, [this.scrollpos.x, this.scrollpos.y]);
+      }
+    }
   },
-  updateNickList: function(nicks) {
-    this.parent(nicks);
+  createMenu: function(nick, parent) {
+    var e = new Element("div");
+    parent.appendChild(e);
+    e.addClass("menu");
     
-    var n = this.nicklist;
-    while(n.firstChild)
-      n.removeChild(n.firstChild);
-
-    nicks.each(function(nick) {
-      var e = new Element("div");
-      n.appendChild(e);
-      e.appendChild(document.createTextNode(nick));
-    });
+    qwebirc.ui.MENU_ITEMS.forEach(function(x) {
+      var e2 = new Element("a");
+      e.appendChild(e2);
+      
+      e2.href = "#";
+      e2.set("text", "- " + x[0]);
+      
+      e2.addEvent("focus", function() { this.blur() }.bind(e2));
+      e2.addEvent("click", function(ev) { new Event(ev.stop()); this.menuClick(x[1]); }.bind(this));
+    }.bind(this));
+    return e;
   },
-  updateTopic: function(topic) {
-    this.parent(topic);
+  menuClick: function(fn) {
+    /*
+    this.prevNick.removeChild(this.prevNick.menu);
+    this.prevNick.menu = null;
+    */
+    fn.bind(this)(this.prevNick.realNick);
+    this.removePrevMenu();
+  },
+  moveMenuClass: function() {
+    if(!this.prevNick)
+      return;
+    if(this.nicklist.firstChild == this.prevNick) {
+      this.prevNick.removeClass("selected-middle");
+    } else {
+      this.prevNick.addClass("selected-middle");
+    }
+  },
+  removePrevMenu: function() {
+    if(!this.prevNick)
+      return;
+      
+    this.prevNick.removeClass("selected");
+    this.prevNick.removeClass("selected-middle");
+    if(this.prevNick.menu)
+      this.prevNick.removeChild(this.prevNick.menu);
+    this.prevNick = null;
+  },
+  nickListAdd: function(nick, position) {
+    var e = new Element("a");
+    qwebirc.ui.insertAt(position, this.nicklist, e);
     
+    e.href = "#";
+    e.appendChild(document.createTextNode(nick));
+    
+    e.realNick = this.client.stripPrefix(nick);
+    
+    e.addEvent("click", function(x) {
+      if(this.prevNick == e) {
+        this.removePrevMenu();
+        return;
+      }
+      
+      this.removePrevMenu();
+      this.prevNick = e;
+      e.addClass("selected");
+      this.moveMenuClass();
+      e.menu = this.createMenu(x.realNick, e);
+      new Event(x).stop();
+    }.bind(this));
+    e.addEvent("dblclick", function(x) {
+      new Event(x).stop();
+      this.client.exec("/QUERY " + e.realNick);
+    }.bind(this));
+    
+    e.addEvent("focus", function() { this.blur() }.bind(e));
+    this.moveMenuClass();
+    return e;
+  },
+  nickListRemove: function(nick, stored) {
+    this.nicklist.removeChild(stored);
+    this.moveMenuClass();
+  },
+  updateTopic: function(topic) {
     var t = this.topic;
     
     while(t.firstChild)
       t.removeChild(t.firstChild);
 
     if(topic) {
-      Colourise("[" + topic + "]", t);
+      this.parent(topic, t);
     } else {
       var e = new Element("div");
       e.set("text", "(no topic set)");
@@ -195,7 +418,7 @@ var QUIWindow = new Class({
     this.reflow();
   },
   select: function() {
-    var inputVisible = this.type != WINDOW_CONNECT && this.type != WINDOW_CUSTOM;
+    var inputVisible = this.type != qwebirc.ui.WINDOW_CONNECT && this.type != qwebirc.ui.WINDOW_CUSTOM;
     
     this.tab.removeClass("tab-unselected");
     this.tab.addClass("tab-selected");
@@ -238,102 +461,27 @@ var QUIWindow = new Class({
     this.parent(type, line, colour, e);
   },
   setHilighted: function(state) {
-    this.parent(state);
-    
-    if(state) {
-      this.tab.addClass("tab-hilighted");
-    } else {
-      this.tab.removeClass("tab-hilighted");
-    }
-  }
-});
-
-var QUI = new Class({
-  Extends: NewLoginUI,
-  initialize: function(parentElement, theme) {
-    this.parent(parentElement, QUIWindow, "qui");
-    this.theme = theme;
-    this.parentElement = parentElement;
-  },
-  postInitialize: function() {
-    this.qjsui = new QJSUI("qwebirc-qui", this.parentElement);
-    
-    this.qjsui.top.addClass("tabbar");
+    laststate = this.hilighted;
     
-    this.qjsui.bottom.addClass("input");
-    this.qjsui.right.addClass("nicklist");
-    this.qjsui.topic.addClass("topic");
-    this.qjsui.middle.addClass("lines");
-    
-    this.tabs = this.qjsui.top;
-    this.origtopic = this.topic = this.qjsui.topic;
-    this.origlines = this.lines = this.qjsui.middle;
-    this.orignicklist = this.nicklist = this.qjsui.right;
-    
-    this.input = this.qjsui.bottom;
-    this.reflow = this.qjsui.reflow.bind(this.qjsui);
-    
-    this.createInput();
-    this.reflow();
-  },
-  createInput: function() {
-    var form = new Element("form");
-    this.input.appendChild(form);
-    form.addClass("input");
-    
-    var inputbox = new Element("input");
-    form.appendChild(inputbox);
-    this.inputbox = inputbox;
-    
-    form.addEvent("submit", function(e) {
-      new Event(e).stop();
-    
-      if(inputbox.value == "")
-        return;
-        
-      this.getActiveWindow().historyExec(inputbox.value);
-      inputbox.value = "";
-    }.bind(this));
-    
-    inputbox.addEvent("keydown", function(e) {
-      var resultfn;
-      var cvalue = inputbox.value;
+    this.parent(state);
 
-      if(e.key == "up") {
-        resultfn = this.commandhistory.upLine;
-      } else if(e.key == "down") {
-        resultfn = this.commandhistory.downLine;
-      } else {
-        return;
-      }
+    if(state == laststate)
+      return;
       
-      if((cvalue != "") && (this.lastcvalue != cvalue))
-        this.commandhistory.addLine(cvalue, true);
-      
-      var result = resultfn.bind(this.commandhistory)();
-      
-      new Event(e).stop();
-      if(!result)
-        result = "";
-      this.lastcvalue = result;
-        
-      inputbox.value = result;
-      setAtEnd(inputbox);
-    }.bind(this));
-  },
-  setLines: function(lines) {
-    this.lines.parentNode.replaceChild(lines, this.lines);
-    this.qjsui.middle = this.lines = lines;
-  },
-  setChannelItems: function(nicklist, topic) {
-    if(!$defined(nicklist)) {
-      nicklist = this.orignicklist;
-      topic = this.origtopic;
+    this.tab.removeClass("tab-hilight-activity");
+    this.tab.removeClass("tab-hilight-us");
+    this.tab.removeClass("tab-hilight-speech");
+    
+    switch(this.hilighted) {
+      case qwebirc.ui.HILIGHT_US:
+        this.tab.addClass("tab-hilight-us");
+        break;
+      case qwebirc.ui.HILIGHT_SPEECH:
+        this.tab.addClass("tab-hilight-speech");
+        break;
+      case qwebirc.ui.HILIGHT_ACTIVITY:
+        this.tab.addClass("tab-hilight-activity");
+        break;
     }
-    this.nicklist.parentNode.replaceChild(nicklist, this.nicklist);
-    this.qjsui.right = this.nicklist = nicklist;
-
-    this.topic.parentNode.replaceChild(topic, this.topic);
-    this.qjsui.topic = this.topic = topic;
   }
 });