]> jfr.im git - irc/quakenet/qwebirc.git/blobdiff - js/ui/baseui.js
add shift+tab to go back through tab completion
[irc/quakenet/qwebirc.git] / js / ui / baseui.js
index 52d353857775e6f50f5c4de52a735fa2d3c03c8d..86e1ba9b214955337fbf86bb88ff398c8593fffc 100644 (file)
@@ -6,15 +6,16 @@ qwebirc.ui.WINDOW_CONNECT =  0x10;
 qwebirc.ui.WINDOW_MESSAGES = 0x20;
 
 qwebirc.ui.CUSTOM_CLIENT = "custom";
+qwebirc.ui.DEFAULT_HUE = 210; /* nice blue */
 
 qwebirc.ui.BaseUI = new Class({
   Implements: [Events],
   initialize: function(parentElement, windowClass, uiName, options) {
     this.options = options;
     
-    this.windows = {};
-    this.clients = {};
-    this.windows[qwebirc.ui.CUSTOM_CLIENT] = {};
+    this.windows = new QHash();
+    this.clients = new QHash();
+    this.windows.put(qwebirc.ui.CUSTOM_CLIENT, new QHash());
     this.windowArray = [];
     this.windowClass = windowClass;
     this.parentElement = parentElement;
@@ -49,17 +50,19 @@ qwebirc.ui.BaseUI = new Class({
     }
   },
   newClient: function(client) {
-    client.id = this.clientId++;
+    client.id = String(this.clientId++);
     client.hilightController = new qwebirc.ui.HilightController(client);
-    
-    this.windows[client.id] = {}
-    this.clients[client.id] = client;
+    client.addEvent("signedOn", function() {
+      this.fireEvent("signedOn", client);
+    }.bind(this));
+    this.windows.put(client.id, new QHash());
+    this.clients.put(client.id, client);
     var w = this.newWindow(client, qwebirc.ui.WINDOW_STATUS, "Status");
     this.selectWindow(w);
     if(!this.firstClient) {
       this.firstClient = true;
       w.addLine("", "qwebirc v" + qwebirc.VERSION);
-      w.addLine("", "Copyright (C) 2008-2012 Chris Porter and the qwebirc project.");
+      w.addLine("", "Copyright (C) 2008-2014 Chris Porter and the qwebirc project.");
       w.addLine("", "http://www.qwebirc.org");
       w.addLine("", "Licensed under the GNU General Public License, Version 2.");
     }
@@ -89,24 +92,25 @@ qwebirc.ui.BaseUI = new Class({
       return w;
       
     var wId = this.getWindowIdentifier(client, type, name);
-    var w = this.windows[this.getClientId(client)][wId] = new this.windowClass(this, client, type, name, wId);
+    var w = new this.windowClass(this, client, type, name, wId);
+    this.windows.get(this.getClientId(client)).put(wId, w);
     this.windowArray.push(w);
     
     return w;
   },
   getWindow: function(client, type, name) {
-    var c = this.windows[this.getClientId(client)];
+    var c = this.windows.get(this.getClientId(client));
     if(!$defined(c))
       return null;
       
-    return c[this.getWindowIdentifier(client, type, name)];
+    return c.get(this.getWindowIdentifier(client, type, name));
   },
   getActiveWindow: function() {
     return this.active;
   },
   getActiveIRCWindow: function(client) {
     if(!this.active || this.active.type == qwebirc.ui.WINDOW_CUSTOM) {
-      return this.windows[this.getClientId(client)][this.getWindowIdentifier(client, qwebirc.ui.WINDOW_STATUS)];
+      return this.windows.get(this.getClientId(client)).get(this.getWindowIdentifier(client, qwebirc.ui.WINDOW_STATUS));
     } else {
       return this.active;
     }
@@ -123,13 +127,13 @@ qwebirc.ui.BaseUI = new Class({
     if(index == -1)
       return null;
     
-    delete this.windows[clientId][window.identifier];
+    this.windows.get(clientId).remove(window.identifier);
     
     var window = this.windowArray[index];
     window.name = name;
     window.identifier = this.getWindowIdentifier(window.client, window.type, window.name);
     
-    this.windows[clientId][window.identifier] = this.windowArray[index];
+    this.windows.get(clientId).put(window.identifier, this.windowArray[index]);
     
     if(window.active)
       this.updateTitle(window.name + " - " + this.options.appTitle);
@@ -187,7 +191,7 @@ qwebirc.ui.BaseUI = new Class({
     }
     
     this.windowArray = this.windowArray.erase(window);
-    delete this.windows[this.getClientId(window.client)][window.identifier];
+    this.windows.get(this.getClientId(window.client)).remove(window.identifier);
   },
     /*
       this shouldn't be called by overriding classes!
@@ -212,37 +216,40 @@ qwebirc.ui.StandardUI = new Class({
   initialize: function(parentElement, windowClass, uiName, options) {
     this.parent(parentElement, windowClass, uiName, options);
 
+    this.__styleValues = {hue: qwebirc.ui.DEFAULT_HUE, saturation: 0, lightness: 0, textHue: null, textSaturation: null, textLightness: null};
+    if($defined(this.options.hue)) this.__styleValues.hue = this.options.hue;
     this.tabCompleter = new qwebirc.ui.TabCompleterFactory(this);
     this.uiOptions = new qwebirc.ui.DefaultOptionsClass(this, options.uiOptionsArg);
-    this.customWindows = {};
-    
-    this.__styleValues = {hue: this.uiOptions.STYLE_HUE, saturation: 0, lightness: 0};
-    if($defined(this.options.hue)) this.__styleValues.hue = this.options.hue;
+    this.customWindows = new QHash();
+
     if($defined(this.options.saturation)) this.__styleValues.saturation = this.options.saturation;
     if($defined(this.options.lightness)) this.__styleValues.lightness = this.options.lightness;
-    
-    var ev;
-    if(Browser.Engine.trident) {
-      ev = "keydown";
+    if($defined(this.options.tsaturation)) this.__styleValues.textSaturation = this.options.tsaturation;
+    if($defined(this.options.tlightness)) this.__styleValues.textLightness = this.options.tlightness;
+
+    if($defined(this.options.hue)) { /* overridden in url */
+      /* ugh... this will go away when we add proper options for hue/sat/light for text and background */
+      this.uiOptions.setValueByPrefix("STYLE_HUE", this.__styleValues.hue);
     } else {
-      ev = "keypress";
+      this.__styleValues.hue = this.uiOptions.STYLE_HUE; /* otherwise copy from serialised store */
     }
-    document.addEvent(ev, this.__handleHotkey.bind(this));
+    this.__styleValues.textHue = $defined(this.options.thue) ? this.options.thue : this.__styleValues.hue;
+
+    document.addEvent("keydown", this.__handleHotkey.bind(this));
   },
   __handleHotkey: function(x) {
-    if(!x.alt || x.control) {
-      if(x.key == "backspace" || x.key == "/")
-        if(!this.getInputFocused(x))
-          new Event(x).stop();
-      return;
-    }
     var success = false;
-    if(x.key == "a" || x.key == "A") {
+    if(!x.alt && !x.control && !x.shift && !x.meta) {
+      if((x.key == "backspace" || x.key == "/") && !this.getInputFocused(x)) {
+        success = true;
+      }
+    } else if(!x.alt || x.control || x.meta) {
+      /* do nothing */
+    } else if(x.key == "a" || x.key == "A") {
       var highestNum = 0;
       var highestIndex = -1;
       success = true;
-      
-      new Event(x).stop();
+
       for(var i=0;i<this.windowArray.length;i++) {
         var h = this.windowArray[i].hilighted;
         if(h > highestNum) {
@@ -252,7 +259,7 @@ qwebirc.ui.StandardUI = new Class({
       }
       if(highestIndex > -1)
         this.selectWindow(this.windowArray[highestIndex]);
-    } else if(x.key >= '0' && x.key <= '9') {
+    } else if((x.key >= '0' && x.key <= '9') && !x.shift) {
       success = true;
       
       number = x.key - '0';
@@ -265,15 +272,18 @@ qwebirc.ui.StandardUI = new Class({
         return;
         
       this.selectWindow(this.windowArray[number]);
-    } else if(x.key == "left") {
+    } else if((x.key == "left" || x.key == "up") && !x.shift) {
       this.prevWindow();
       success = true;
-    } else if(x.key == "right") {
+    } else if((x.key == "right" || x.key == "down") && !x.shift) {
       this.nextWindow();
       success = true;
     }
-    if(success)
+
+    if(success) {
       new Event(x).stop();
+      x.preventDefault();
+    }
   },
   getInputFocused: function(x) {
     if($$("input").indexOf(x.target) == -1 && $$("textarea").indexOf(x.target) == -1)
@@ -286,7 +296,7 @@ qwebirc.ui.StandardUI = new Class({
       
     var w = this.newWindow(qwebirc.ui.CUSTOM_CLIENT, type, name);
     w.addEvent("close", function(w) {
-      delete this.windows[qwebirc.ui.CUSTOM_CLIENT][w.identifier];
+      this.windows.get(qwebirc.ui.CUSTOM_CLIENT).remove(w.identifier);
     }.bind(this));
     
     if(select)
@@ -298,16 +308,16 @@ qwebirc.ui.StandardUI = new Class({
     if(!$defined(options))
       options = {};
       
-    if(this.customWindows[windowName]) {
-      this.selectWindow(this.customWindows[windowName]);
+    if(this.customWindows.contains(windowName)) {
+      this.selectWindow(this.customWindows.get(windowName));
       return;
     }
     
     var d = this.newCustomWindow(windowName, true);
-    this.customWindows[windowName] = d;
+    this.customWindows.put(windowName, d);
     
     d.addEvent("close", function() {
-      this.customWindows[windowName] = null;
+      this.customWindows.remove(windowName);
     }.bind(this));
         
     if(cssClass)
@@ -337,8 +347,8 @@ qwebirc.ui.StandardUI = new Class({
   feedbackWindow: function() {
     this.addCustomWindow("Feedback", qwebirc.ui.FeedbackPane, "feedbackpane", this.uiOptions);
   },
-  faqWindow: function() {
-    this.addCustomWindow("FAQ", qwebirc.ui.FAQPane, "faqpane", this.uiOptions);
+  helpWindow: function() {
+    this.addCustomWindow("Help!", qwebirc.ui.HelpPane, "helppane", this.uiOptions);
   },
   urlDispatcher: function(name, window) {
     if(name == "embedded")
@@ -360,8 +370,8 @@ qwebirc.ui.StandardUI = new Class({
 
     return null;
   },
-  tabComplete: function(element) {
-    this.tabCompleter.tabComplete(element);
+  tabComplete: function(element, backwards) {
+    this.tabCompleter.tabComplete(element, backwards);
   },
   resetTabComplete: function() {
     this.tabCompleter.reset();
@@ -371,19 +381,30 @@ qwebirc.ui.StandardUI = new Class({
     this.setModifiableStylesheetValues({});
   },
   setModifiableStylesheetValues: function(values) {
-    for(var k in values)
+    for (var k in values)
       this.__styleValues[k] = values[k];
-      
-    if(!$defined(this.__styleSheet))
+
+    if (!$defined(this.__styleSheet))
       return;
-      
-    var hue = this.__styleValues.hue, lightness = this.__styleValues.lightness, saturation = this.__styleValues.saturation;
-    
+
+    var back = {hue: this.__styleValues.hue, lightness: this.__styleValues.lightness, saturation: this.__styleValues.saturation};
+    var front;
+    if (!$defined(this.__styleValues.textHue) && !$defined(this.__styleValues.textLightness) && !$defined(this.__styleValues.textSaturation)) {
+      front = back;
+    } else {
+      front = {hue: Number(this.__styleValues.textHue), lightness: Number(this.__styleValues.textLightness), saturation: Number(this.__styleValues.textSaturation)}
+    }
+    var colours = {
+      back: back,
+      front: front
+    };
+
     this.__styleSheet.set(function() {
       var mode = arguments[0];
       if(mode == "c") {
+        var t = colours[arguments[2]];
         var x = new Color(arguments[1]);
-        var c = x.setHue(hue).setSaturation(x.hsb[1] + saturation).setBrightness(x.hsb[2] + lightness);
+        var c = x.setHue(t.hue).setSaturation(x.hsb[1] + t.saturation).setBrightness(x.hsb[2] + t.lightness);
         if(c == "255,255,255") /* IE confuses white with transparent... */
           c = "255,255,254";
         
@@ -402,16 +423,25 @@ qwebirc.ui.NotificationUI = new Class({
     
     this.__beeper = new qwebirc.ui.Beeper(this.uiOptions);
     this.__flasher = new qwebirc.ui.Flasher(this.uiOptions);
-    
-    this.beep = this.__beeper.beep.bind(this.__beeper);
-    
-    this.flash = this.__flasher.flash.bind(this.__flasher);
+    this.__notifier = new qwebirc.ui.Notifier(this.uiOptions);
+
     this.cancelFlash = this.__flasher.cancelFlash.bind(this.__flasher);
   },
+  beep: function() {
+    this.__beeper.beep();
+  },
+  notify: function(title, message, callback) {
+    this.__beeper.beep();
+    this.__flasher.flash();
+    this.__notifier.notify(title, message, callback);
+  },
   setBeepOnMention: function(value) {
     if(value)
       this.__beeper.soundInit();
   },
+  setNotifications: function(value) {
+    this.__notifier.setEnabled(value);
+  },
   updateTitle: function(text) {
     if(this.__flasher.updateTitle(text))
       this.parent(text);
@@ -419,6 +449,7 @@ qwebirc.ui.NotificationUI = new Class({
   focusChange: function(value) {
     this.parent(value);
     this.__flasher.focusChange(value);
+    this.__notifier.focusChange(value);
   }
 });
 
@@ -428,7 +459,7 @@ qwebirc.ui.NewLoginUI = new Class({
     this.postInitialize();
 
     /* I'd prefer something shorter and snappier! */
-    var w = this.newCustomWindow("Connection details", true, qwebirc.ui.WINDOW_CONNECT);
+    var w = this.newCustomWindow("Connect", true, qwebirc.ui.WINDOW_CONNECT);
     var callback = function(args) {
       w.close();
       callbackfn(args);
@@ -452,9 +483,9 @@ qwebirc.ui.QuakeNetUI = new Class({
     if(!qwebirc.auth.loggedin())
       return;
     if(confirm("Log out?")) {
-      for(var client in this.clients) {
-        this.clients[client].quit("Logged out");
-      };
+      this.clients.each(function(k, v) {
+        v.quit("Logged out");
+      }, this);
       
       /* HACK */
       var foo = function() { document.location = qwebirc.global.dynamicBaseURL + "auth?logout=1"; };