From 70ed6c1e32be4a1bcca71ce1f4f226fb8f05f92b Mon Sep 17 00:00:00 2001 From: Jono Brandel Date: Wed, 9 Feb 2011 13:50:24 -0800 Subject: [PATCH 1/7] modified demo.css for expansion animations --- demo/demo.css | 11 ++++++++--- index.html | 19 ++++++++----------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/demo/demo.css b/demo/demo.css index b52bc5e..5c607d6 100644 --- a/demo/demo.css +++ b/demo/demo.css @@ -50,7 +50,7 @@ h2 { h2.section { margin: 0; - padding: 20px 0px 0px 0px; + padding: 20px 0px 20px 0px; cursor: pointer; border-top: 1px dotted #ccc; -webkit-transition: color 0.15s linear; @@ -67,12 +67,16 @@ div.collapsed h2, div.expanded h2 { cursor: pointer; } +.last { margin-bottom: 0px !important; } +.first { margin-top: 0px; } + div.trans { border-top: 1px dotted #ccc; margin: 0px 0px 20px 0px; } ol#secrets { - padding: 0px 0px 20px 0px; + padding: 0px; + margin: 0px; } div.expanded h2:before { content: '-'; @@ -93,13 +97,14 @@ div.expanded h2:before, div.collapsed h2:before { div.collapsable { overflow: hidden; clear: both; - margin-bottom: 20px; -moz-transition: height .2s ease-out; -webkit-transition: height .2s ease-out; transition: height .2s ease-out; } div.collapsable div { + padding-bottom: 20px; + margin-bottom: -20px; height: auto; } diff --git a/index.html b/index.html index fb2cd3f..91bf68a 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,4 @@ - - - + gui-dat @@ -183,7 +180,7 @@ window.onload = function() {

The simplest way to save your parameters is via GUI.saveURL(). This method directs your browser to a URL containing the current GUI settings.

-
+		    	
 // Make a button for the url function
 gui.add(GUI, "saveURL");
@@ -216,7 +213,7 @@ var gui = new GUI(); gui.add(someObject, "someProperty"); gui.add(someObject, "someOtherProperty"); -

Save strings won't work if you change the order in which you've added properties to your gui objects, or the order of the gui objects themselves.. If you want to add more parameters to your gui and use an old save string, make sure they're added after the properties whose values you've saved.

+

Save strings won't work if you change the order in which you've added properties to your gui objects, or the order of the gui objects themselves.. If you want to add more parameters to your gui and use an old save string, make sure they're added after the properties whose values you've saved.

@@ -226,7 +223,7 @@ gui.add(someObject, "someOtherProperty");

Choosing from a list of values

-
gui.add(obj, "propertyName").options(1, 2, 3, 5, 8);
+
gui.add(obj, "propertyName").options(1, 2, 3, 5, 8);
 
 // Alternatively, you can specify custom labels using object syntax
 gui.add(obj, "propertyName").options({'Small': 1, 'Medium': 2, 'Large': 3});
@@ -247,7 +244,7 @@ gui.add(obj, "propertyName").options({'Small': 1, 'Medium': 2, 'Large': 3});
    alert("You just finished changing me to " + newValue);
 });

Finally, if you'd like to do a little something extra when a function is called, use the following:

-
gui.add(obj, "functionName").onFire(function() {
+		    	
gui.add(obj, "functionName").onFire(function() {
    alert("You called a function with gui-dat");
 });
@@ -258,7 +255,7 @@ gui.add(obj, "propertyName").options({'Small': 1, 'Medium': 2, 'Large': 3});

Let's say you have a variable that changes by itself from time to time. If you'd like the GUI to reflect those changes, use the listen() method.

-
gui.add(obj, "changingProperty").listen();
+
gui.add(obj, "changingProperty").listen();
@@ -278,7 +275,7 @@ setInterval(function() { }, 1000 / 60);

Alternatively, you can forego calling listen() on individual controllers, and instead choose to monitor changes in all values controlled by your gui.

-
+		    	
 gui.autoListen = false; // disables internal interval
 gui.add(obj, "add");
 gui.add(obj, "lotsa");
@@ -305,7 +302,7 @@ gui1.name("Utilities");
 gui2.name("Camera Placement");

By default, gui-dat panels will be automatically added to the HTML document and fixed to the top of the screen. You can disable this behavior / styling and append the gui DOM element to a container of your choosing.

-
+		    	
 // Notice this belongs to the GUI class (uppercase) 
 // and not an instance thereof.
 GUI.autoPlace = false; 

From 765ade71e9f15480608970799e7e383342d8a366 Mon Sep 17 00:00:00 2001
From: Jono Brandel 
Date: Thu, 10 Feb 2011 12:16:51 -0800
Subject: [PATCH 2/7] gui styling adaptation for scrollbars width

---
 gui.js | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/gui.js b/gui.js
index 5de51bf..845b5ae 100644
--- a/gui.js
+++ b/gui.js
@@ -138,22 +138,14 @@ var GUI = function() {
 			
 			_this.toggle();
 
-			// Clears lingering slider column
-			_this.domElement.style.width = (width+1)+'px';
-			setTimeout(function() {
-				_this.domElement.style.width = width+'px';
-			}, 1);
+			
 		}
 		
 		if (togglePressed && toggleDragged) {
 		
 			if (dragDisplacementX == 0) {
 			
-				// Clears lingering slider column
-				_this.domElement.style.width = (width+1)+'px';
-				setTimeout(function() {
-					_this.domElement.style.width = width+'px';
-				}, 1);
+				adaptToScrollbar()
 	
 			}
 		
@@ -420,6 +412,8 @@ var GUI = function() {
 		curControllerContainerHeight += (resizeTo - curControllerContainerHeight)*0.6;
 		if (Math.abs(curControllerContainerHeight-resizeTo) < 1) {
 			curControllerContainerHeight = resizeTo;
+			adaptToScrollbar();
+			
 		} else { 
 			resizeTimeout = setTimeout(beginResize, 1000/30);
 		}
@@ -427,6 +421,14 @@ var GUI = function() {
 		checkForOverflow();
 	}
 	
+	var adaptToScrollbar = function() {
+		// Clears lingering slider column
+		_this.domElement.style.width = (width+1)+'px';
+		setTimeout(function() {
+			_this.domElement.style.width = width+'px';
+		}, 1);
+	};
+	
 	// Load saved appearance:
 
 	if (GUI.guiIndex < GUI.savedAppearanceVars.length) {

From 9520275b4d97bdd3a062660c368637ff222d6e18 Mon Sep 17 00:00:00 2001
From: Szymon Nowak 
Date: Thu, 10 Feb 2011 21:50:57 +0100
Subject: [PATCH 3/7] Removed trailing whitespace. Converted tabs to 4 spaces.

---
 controllers/controller.boolean.js  |   42 +-
 controllers/controller.function.js |   54 +-
 controllers/controller.js          |  108 +--
 controllers/controller.number.js   |  190 +++---
 controllers/controller.string.js   |   50 +-
 controllers/slider.js              |  130 ++--
 gui.js                             | 1020 ++++++++++++++--------------
 7 files changed, 797 insertions(+), 797 deletions(-)

diff --git a/controllers/controller.boolean.js b/controllers/controller.boolean.js
index 66808ca..839564b 100644
--- a/controllers/controller.boolean.js
+++ b/controllers/controller.boolean.js
@@ -1,39 +1,39 @@
 GUI.BooleanController = function() {
 
-	this.type = "boolean";
-	GUI.Controller.apply(this, arguments);
+    this.type = "boolean";
+    GUI.Controller.apply(this, arguments);
 
-	var _this = this;
+    var _this = this;
     var input = document.createElement('input');
     input.setAttribute('type', 'checkbox');
-    
+
     this.domElement.addEventListener('click', function(e) {
-    	input.checked = !input.checked;
-    	e.preventDefault();
-    	_this.setValue(input.checked);
+        input.checked = !input.checked;
+        e.preventDefault();
+        _this.setValue(input.checked);
     }, false);
-    
+
     input.addEventListener('mouseup', function(e) {
-    	input.checked = !input.checked; // counteracts default.
+        input.checked = !input.checked; // counteracts default.
     }, false);
-    
+
     this.domElement.style.cursor = "pointer";
     this.propertyNameElement.style.cursor = "pointer";
     this.domElement.appendChild(input);
-    
+
     this.updateDisplay = function() {
-    	input.checked = _this.getValue();
+        input.checked = _this.getValue();
     };
-    
-    
+
+
     this.setValue = function(val) {
-		if (typeof val != "boolean") {
-			try { 
-				val = eval(val);
-			} catch (e) {}
-		}
-		return GUI.Controller.prototype.setValue.call(this, val);
+        if (typeof val != "boolean") {
+            try {
+                val = eval(val);
+            } catch (e) {}
+        }
+        return GUI.Controller.prototype.setValue.call(this, val);
     }
 
 };
-GUI.extendController(GUI.BooleanController);
\ No newline at end of file
+GUI.extendController(GUI.BooleanController);
diff --git a/controllers/controller.function.js b/controllers/controller.function.js
index ee0b831..63690fa 100644
--- a/controllers/controller.function.js
+++ b/controllers/controller.function.js
@@ -1,30 +1,30 @@
 GUI.FunctionController = function() {
-	
-	this.type = "function";
-	
-	var _this = this;
-	
-	GUI.Controller.apply(this, arguments);
-	
-	this.domElement.addEventListener('click', function() {
-		_this.fire();
-	}, false);
-	
-	this.domElement.style.cursor = "pointer";
-	this.propertyNameElement.style.cursor = "pointer";
-	
-	var fireFunction = null;
-	this.onFire = function(fnc) {
-		fireFunction = fnc;
-		return this;
-	}
-	
-	this.fire = function() {
-		if (fireFunction != null) {
-			fireFunction.call(this);
-		}
-		_this.object[_this.propertyName].call(_this.object);
-	};
-	
+
+    this.type = "function";
+
+    var _this = this;
+
+    GUI.Controller.apply(this, arguments);
+
+    this.domElement.addEventListener('click', function() {
+        _this.fire();
+    }, false);
+
+    this.domElement.style.cursor = "pointer";
+    this.propertyNameElement.style.cursor = "pointer";
+
+    var fireFunction = null;
+    this.onFire = function(fnc) {
+        fireFunction = fnc;
+        return this;
+    }
+
+    this.fire = function() {
+        if (fireFunction != null) {
+            fireFunction.call(this);
+        }
+        _this.object[_this.propertyName].call(_this.object);
+    };
+
 };
 GUI.extendController(GUI.FunctionController);
diff --git a/controllers/controller.js b/controllers/controller.js
index c2f6eef..6a2916a 100644
--- a/controllers/controller.js
+++ b/controllers/controller.js
@@ -1,96 +1,96 @@
 GUI.Controller = function() {
 
-	this.parent = arguments[0];
+    this.parent = arguments[0];
     this.object = arguments[1];
     this.propertyName = arguments[2];
 
-	if (arguments.length > 0) this.initialValue = this.propertyName[this.object];
+    if (arguments.length > 0) this.initialValue = this.propertyName[this.object];
 
     this.domElement = document.createElement('div');
     this.domElement.setAttribute('class', 'guidat-controller ' + this.type);
-    
+
     this.propertyNameElement = document.createElement('span');
     this.propertyNameElement.setAttribute('class', 'guidat-propertyname');
     this.name(this.propertyName);
     this.domElement.appendChild(this.propertyNameElement);
-    
+
     GUI.makeUnselectable(this.domElement);
-    
+
 };
 
 GUI.Controller.prototype.changeFunction = null;
 GUI.Controller.prototype.finishChangeFunction = null;
 
 GUI.Controller.prototype.name = function(n) {
-	this.propertyNameElement.innerHTML = n;
-	return this;
+    this.propertyNameElement.innerHTML = n;
+    return this;
 };
 
 GUI.Controller.prototype.reset = function() {
-	this.setValue(this.initialValue);
-	return this;
+    this.setValue(this.initialValue);
+    return this;
 };
 
 GUI.Controller.prototype.listen = function() {
-	this.parent.listenTo(this);
-	return this;
+    this.parent.listenTo(this);
+    return this;
 }
 
 GUI.Controller.prototype.unlisten = function() {
-	this.parent.unlistenTo(this); // <--- hasn't been tested yet
-	return this;
+    this.parent.unlistenTo(this); // <--- hasn't been tested yet
+    return this;
 }
-    
+
 GUI.Controller.prototype.setValue = function(n) {
-	this.object[this.propertyName] = n;
-	if (this.changeFunction != null) {
-		this.changeFunction.call(this, n);
-	}
-	this.updateDisplay();
-	return this;
+    this.object[this.propertyName] = n;
+    if (this.changeFunction != null) {
+        this.changeFunction.call(this, n);
+    }
+    this.updateDisplay();
+    return this;
 }
-    
+
 GUI.Controller.prototype.getValue = function() {
-	return this.object[this.propertyName];
+    return this.object[this.propertyName];
 }
 
 GUI.Controller.prototype.updateDisplay = function() {}
-    
+
 GUI.Controller.prototype.onChange = function(fnc) {
-	this.changeFunction = fnc;
-	return this;
+    this.changeFunction = fnc;
+    return this;
 }
 GUI.Controller.prototype.onFinishChange = function(fnc) {
-	this.finishChangeFunction = fnc;
-	return this;
+    this.finishChangeFunction = fnc;
+    return this;
 }
 
 GUI.Controller.prototype.options = function() {
-	var _this = this;
-	var select = document.createElement('select');
-	if (arguments.length == 1) {
-		var arr = arguments[0];
-		for (var i in arr) {
-			var opt = document.createElement('option');
-			opt.innerHTML = i;
-			opt.setAttribute('value', arr[i]);
-			select.appendChild(opt);
-		}
-	} else { 
-		for (var i = 0; i < arguments.length; i++) {
-			var opt = document.createElement('option');
-			opt.innerHTML = arguments[i];
-			opt.setAttribute('value', arguments[i]);
-			select.appendChild(opt);
-		}
-	}
-	
-	select.addEventListener('change', function() {
-		_this.setValue(this.value);
-		if (_this.finishChangeFunction != null) {
-			_this.finishChangeFunction.call(this, _this.getValue());
-		}
-	});
-	_this.domElement.appendChild(select);
-	return this;
+    var _this = this;
+    var select = document.createElement('select');
+    if (arguments.length == 1) {
+        var arr = arguments[0];
+        for (var i in arr) {
+            var opt = document.createElement('option');
+            opt.innerHTML = i;
+            opt.setAttribute('value', arr[i]);
+            select.appendChild(opt);
+        }
+    } else {
+        for (var i = 0; i < arguments.length; i++) {
+            var opt = document.createElement('option');
+            opt.innerHTML = arguments[i];
+            opt.setAttribute('value', arguments[i]);
+            select.appendChild(opt);
+        }
+    }
+
+    select.addEventListener('change', function() {
+        _this.setValue(this.value);
+        if (_this.finishChangeFunction != null) {
+            _this.finishChangeFunction.call(this, _this.getValue());
+        }
+    });
+    _this.domElement.appendChild(select);
+    return this;
 }
diff --git a/controllers/controller.number.js b/controllers/controller.number.js
index 4a63372..8ffb01f 100644
--- a/controllers/controller.number.js
+++ b/controllers/controller.number.js
@@ -1,150 +1,150 @@
 GUI.NumberController = function() {
 
-	this.type = "number";
-    
+    this.type = "number";
+
     GUI.Controller.apply(this, arguments);
-    
+
     var _this = this;
-    
+
     // If we simply click and release a number field, we want to highlight it.
     // This variable keeps track of whether or not we've dragged
     var draggedNumberField = false;
-    
+
     var clickedNumberField = false;
-    
+
     var y = py = 0;
-    
+
     var min = arguments[3];
     var max = arguments[4];
     var step = arguments[5];
-    
+
     if (!step) {
-    	if (min != undefined && max != undefined) {
-    		step = (max-min)*0.01;
-    	} else {
-    		step = 1;
-    	}	
+        if (min != undefined && max != undefined) {
+            step = (max-min)*0.01;
+        } else {
+            step = 1;
+        }
     }
-    
+
     var numberField = document.createElement('input');
     numberField.setAttribute('id', this.propertyName);
     numberField.setAttribute('type', 'text');
     numberField.setAttribute('value', this.getValue());
-    
+
     if (step) numberField.setAttribute('step', step);
-    
+
     this.domElement.appendChild(numberField);
-    
+
     var slider;
-    
+
     if (min != undefined && max != undefined) {
-    	slider = new GUI.Slider(this, min, max, step, this.getValue());
-    	this.domElement.appendChild(slider.domElement);
+        slider = new GUI.Slider(this, min, max, step, this.getValue());
+        this.domElement.appendChild(slider.domElement);
     }
-    
+
     numberField.addEventListener('blur', function(e) {
         var val = parseFloat(this.value);
         console.log(val);
         if (!isNaN(val)) {
-	        _this.setValue(val);
+            _this.setValue(val);
         }
     }, false);
-    
+
     numberField.addEventListener('mousewheel', function(e) {
-    	e.preventDefault();
-    	_this.setValue(_this.getValue() + Math.abs(e.wheelDeltaY)/e.wheelDeltaY*step);
-    	return false;
-    }, false);
-    
-    numberField.addEventListener('mousedown', function(e) {
-        py = y = e.pageY;
-		clickedNumberField = true;
-        document.addEventListener('mousemove', dragNumberField, false);
-		document.addEventListener('mouseup', mouseup, false);
+        e.preventDefault();
+        _this.setValue(_this.getValue() + Math.abs(e.wheelDeltaY)/e.wheelDeltaY*step);
+        return false;
+    }, false);
+
+    numberField.addEventListener('mousedown', function(e) {
+        py = y = e.pageY;
+        clickedNumberField = true;
+        document.addEventListener('mousemove', dragNumberField, false);
+        document.addEventListener('mouseup', mouseup, false);
+    }, false);
+
+    // Handle up arrow and down arrow
+    numberField.addEventListener('keydown', function(e) {
+        switch(e.keyCode) {
+            case 38:    // up
+                var newVal = _this.getValue() + step;
+                _this.setValue(newVal);
+                break;
+            case 40:    // down
+                var newVal = _this.getValue() - step;
+                _this.setValue(newVal);
+                break;
+        }
     }, false);
 
-	// Handle up arrow and down arrow
-	numberField.addEventListener('keydown', function(e) {
-		switch(e.keyCode) {
-			case 38: 	// up
-				var newVal = _this.getValue() + step;
-				_this.setValue(newVal);
-				break;
-			case 40: 	// down
-				var newVal = _this.getValue() - step;
-				_this.setValue(newVal);
-				break;
-		}
-	}, false);
-    
     var mouseup = function(e) {
         document.removeEventListener('mousemove', dragNumberField, false);
-        GUI.makeSelectable(_this.parent.domElement); 
+        GUI.makeSelectable(_this.parent.domElement);
         GUI.makeSelectable(numberField);
-        if (clickedNumberField && !draggedNumberField) { 
-	        numberField.focus();
-	        numberField.select();
+        if (clickedNumberField && !draggedNumberField) {
+            numberField.focus();
+            numberField.select();
         }
         draggedNumberField = false;
         clickedNumberField = false;
-		if (_this.finishChangeFunction != null) {
-			_this.finishChangeFunction.call(this, _this.getValue());
-		}
-		document.removeEventListener('mouseup', mouseup, false);
-	}
+        if (_this.finishChangeFunction != null) {
+            _this.finishChangeFunction.call(this, _this.getValue());
+        }
+        document.removeEventListener('mouseup', mouseup, false);
+    }
+
+
 
-    
-    
     var dragNumberField = function(e) {
-    	draggedNumberField = true;
-		e.preventDefault();
+        draggedNumberField = true;
+        e.preventDefault();
 
-		// We don't want to be highlighting this field as we scroll.
-		// Or any other fields in this gui for that matter ...
-		// TODO: Make makeUselectable go through each element and child element.
+        // We don't want to be highlighting this field as we scroll.
+        // Or any other fields in this gui for that matter ...
+        // TODO: Make makeUselectable go through each element and child element.
 
-		GUI.makeUnselectable(_this.parent.domElement);
-		GUI.makeUnselectable(numberField);
-		
-		py = y;
-		y = e.pageY;
-		var dy = py - y;
-		var newVal = _this.getValue() + dy*step;	
-		_this.setValue(newVal);
-		return false;
+        GUI.makeUnselectable(_this.parent.domElement);
+        GUI.makeUnselectable(numberField);
+
+        py = y;
+        y = e.pageY;
+        var dy = py - y;
+        var newVal = _this.getValue() + dy*step;
+        _this.setValue(newVal);
+        return false;
     }
-    
+
     this.options = function() {
-    	_this.noSlider();
-    	_this.domElement.removeChild(numberField);
-    	return GUI.Controller.prototype.options.apply(this, arguments);
+        _this.noSlider();
+        _this.domElement.removeChild(numberField);
+        return GUI.Controller.prototype.options.apply(this, arguments);
     };
-    
+
     this.noSlider = function() {
-    	if (slider) {
-    		_this.domElement.removeChild(slider.domElement);
-    	}
-    	return this;
+        if (slider) {
+            _this.domElement.removeChild(slider.domElement);
+        }
+        return this;
     };
-    
+
     this.setValue = function(val) {
-    
-		val = parseFloat(val);
-		
-    	if (min != undefined && val <= min) {
-    		val = min;
-    	} else if (max != undefined && val >= max) { 
-    		val = max;
-    	}
-    	
-    	return GUI.Controller.prototype.setValue.call(this, val);
-    	
+
+        val = parseFloat(val);
+
+        if (min != undefined && val <= min) {
+            val = min;
+        } else if (max != undefined && val >= max) {
+            val = max;
+        }
+
+        return GUI.Controller.prototype.setValue.call(this, val);
+
     }
-    
+
     this.updateDisplay = function() {
         numberField.value = GUI.roundToDecimal(_this.getValue(), 4);
         if (slider) slider.value = _this.getValue();
-	}
+    }
 };
 
 GUI.extendController(GUI.NumberController);
diff --git a/controllers/controller.string.js b/controllers/controller.string.js
index 9167358..bceb44c 100644
--- a/controllers/controller.string.js
+++ b/controllers/controller.string.js
@@ -1,47 +1,47 @@
 GUI.StringController = function() {
 
-	this.type = "string";
-	
-	var _this = this;
+    this.type = "string";
+
+    var _this = this;
     GUI.Controller.apply(this, arguments);
-    
+
     var input = document.createElement('input');
-    
+
     var initialValue = this.getValue();
-    
+
     input.setAttribute('value', initialValue);
     input.setAttribute('spellcheck', 'false');
-    
+
     this.domElement.addEventListener('mouseup', function() {
-    	input.focus();
-    	input.select();
+        input.focus();
+        input.select();
     }, false);
-    
+
     // TODO: getting messed up on ctrl a
     input.addEventListener('keyup', function(e) {
-    	if (e.keyCode == 13 && _this.finishChangeFunction != null) {
-			_this.finishChangeFunction.call(this, _this.getValue());
-		}
+        if (e.keyCode == 13 && _this.finishChangeFunction != null) {
+            _this.finishChangeFunction.call(this, _this.getValue());
+        }
         _this.setValue(input.value);
     }, false);
-    
+
     input.addEventListener('blur', function() {
-		if (_this.finishChangeFunction != null) {
-			_this.finishChangeFunction.call(this, _this.getValue());
-		}
+        if (_this.finishChangeFunction != null) {
+            _this.finishChangeFunction.call(this, _this.getValue());
+        }
     }, false);
-    
+
     this.updateDisplay = function() {
-    	input.value = _this.getValue();
+        input.value = _this.getValue();
     }
-    
+
     this.options = function() {
-    	_this.domElement.removeChild(input);
-    	return GUI.Controller.prototype.options.apply(this, arguments);
+        _this.domElement.removeChild(input);
+        return GUI.Controller.prototype.options.apply(this, arguments);
     };
-    
+
     this.domElement.appendChild(input);
-    
+
 };
 
-GUI.extendController(GUI.StringController);
\ No newline at end of file
+GUI.extendController(GUI.StringController);
diff --git a/controllers/slider.js b/controllers/slider.js
index b3ad28a..fc7c989 100644
--- a/controllers/slider.js
+++ b/controllers/slider.js
@@ -1,69 +1,69 @@
 GUI.Slider = function(numberController, min, max, step, initValue) {
-	
-	var min = min;
-	var max = max;
-	var step = step;
-	
-	var clicked = false;
-	var _this = this;
-	
-	var x, px;
-	
-	this.domElement = document.createElement('div');
-	this.domElement.setAttribute('class', 'guidat-slider-bg');
-	
-	this.fg = document.createElement('div');
-	this.fg.setAttribute('class', 'guidat-slider-fg');
-	
-	this.domElement.appendChild(this.fg);
-	
-	var findPos = function(obj) {
-		var curleft = curtop = 0;
-		if (obj.offsetParent) {
-			do {
-				curleft += obj.offsetLeft;
-				curtop += obj.offsetTop;
-			} while (obj = obj.offsetParent);
-			return [curleft,curtop];
-		}
-	}
-	
-	this.__defineSetter__('value', function(e) {
-		var pct = GUI.map(e, min, max, 0, 100);
-		this.fg.style.width = pct+"%";
-	});
 
-	var onDrag = function(e) {
-		if (!clicked) return;
-		var pos = findPos(_this.domElement);
-		var val = GUI.map(e.pageX, pos[0], pos[0] + _this.domElement.offsetWidth, min, max);
-		val = Math.round(val/step)*step;
-		numberController.setValue(val);
-	}
-	
-	this.domElement.addEventListener('mousedown', function(e) {
-		clicked = true;
-		x = px = e.pageX;
-		_this.domElement.setAttribute('class', 'guidat-slider-bg active');
-		_this.fg.setAttribute('class', 'guidat-slider-fg active');
-		onDrag(e);
-		document.addEventListener('mouseup', mouseup, false);
-	}, false);
-	
-	
-	var mouseup = function(e) { 
-		_this.domElement.setAttribute('class', 'guidat-slider-bg');
-		_this.fg.setAttribute('class', 'guidat-slider-fg');
-		clicked = false;			
-		if (numberController.finishChangeFunction != null) {
-			numberController.finishChangeFunction.call(this, numberController.getValue());
-		}
-		document.removeEventListener('mouseup', mouseup, false);
-	};
+    var min = min;
+    var max = max;
+    var step = step;
+
+    var clicked = false;
+    var _this = this;
+
+    var x, px;
+
+    this.domElement = document.createElement('div');
+    this.domElement.setAttribute('class', 'guidat-slider-bg');
+
+    this.fg = document.createElement('div');
+    this.fg.setAttribute('class', 'guidat-slider-fg');
+
+    this.domElement.appendChild(this.fg);
+
+    var findPos = function(obj) {
+        var curleft = curtop = 0;
+        if (obj.offsetParent) {
+            do {
+                curleft += obj.offsetLeft;
+                curtop += obj.offsetTop;
+            } while (obj = obj.offsetParent);
+            return [curleft,curtop];
+        }
+    }
+
+    this.__defineSetter__('value', function(e) {
+        var pct = GUI.map(e, min, max, 0, 100);
+        this.fg.style.width = pct+"%";
+    });
+
+    var onDrag = function(e) {
+        if (!clicked) return;
+        var pos = findPos(_this.domElement);
+        var val = GUI.map(e.pageX, pos[0], pos[0] + _this.domElement.offsetWidth, min, max);
+        val = Math.round(val/step)*step;
+        numberController.setValue(val);
+    }
+
+    this.domElement.addEventListener('mousedown', function(e) {
+        clicked = true;
+        x = px = e.pageX;
+        _this.domElement.setAttribute('class', 'guidat-slider-bg active');
+        _this.fg.setAttribute('class', 'guidat-slider-fg active');
+        onDrag(e);
+        document.addEventListener('mouseup', mouseup, false);
+    }, false);
+
+
+    var mouseup = function(e) {
+        _this.domElement.setAttribute('class', 'guidat-slider-bg');
+        _this.fg.setAttribute('class', 'guidat-slider-fg');
+        clicked = false;
+        if (numberController.finishChangeFunction != null) {
+            numberController.finishChangeFunction.call(this, numberController.getValue());
+        }
+        document.removeEventListener('mouseup', mouseup, false);
+    };
+
+
+    document.addEventListener('mousemove', onDrag, false);
+
+    this.value = initValue;
 
-	
-	document.addEventListener('mousemove', onDrag, false);
-	
-	this.value = initValue;	
-		
 }
diff --git a/gui.js b/gui.js
index 5de51bf..884ff53 100644
--- a/gui.js
+++ b/gui.js
@@ -1,377 +1,274 @@
 var GUI = function() {
 
-	var _this = this;
-	
-	var MIN_WIDTH = 240;
-	var MAX_WIDTH = 500;
-	
-	var controllers = [];
-	var listening = [];
-	
-	var autoListen = true;
-	
-	var listenInterval;
-	
-	// Sum total of heights of controllers in this gui
-	var controllerHeight;
-	
-	var curControllerContainerHeight = 0;
-	
-	var _this = this;
-	
-	var open = false;
-	var width = 280;
-	
-	// Prevents checkForOverflow bug in which loaded gui appearance
-	// settings are not respected by presence of scrollbar.
-	var explicitOpenHeight = false;
-	
-	// How big we get when we open
-	var openHeight;
-	
-	var name;
-	
-	var resizeTo = 0;
-	var resizeTimeout;
-	
-	this.domElement = document.createElement('div');
-	this.domElement.setAttribute('class', 'guidat');
-	this.domElement.style.width = width+'px';
+    var _this = this;
 
-	var controllerContainer = document.createElement('div');
-	controllerContainer.setAttribute('class', 'guidat-controllers');
-	
-	// Firefox hack to prevent horizontal scrolling
-	controllerContainer.addEventListener('DOMMouseScroll', function(e) {
-		
-		var scrollAmount = this.scrollTop;
-		
-		if (e.wheelDelta) {
-			scrollAmount+=e.wheelDelta; 
-		} else if (e.detail) {
-			scrollAmount+=e.detail;
-		}
-			
-		if (e.preventDefault) {
-			e.preventDefault();
-		}
-		e.returnValue = false;
-		
-		controllerContainer.scrollTop = scrollAmount;
-		
-	}, false);
-	
-	controllerContainer.style.height = '0px';
+    var MIN_WIDTH = 240;
+    var MAX_WIDTH = 500;
 
-	var toggleButton = document.createElement('a');
-	toggleButton.setAttribute('class', 'guidat-toggle');
-	toggleButton.setAttribute('href', '#');
-	toggleButton.innerHTML = "Show Controls";
-	
-	var toggleDragged = false;
-	var dragDisplacementY = 0;
-	var togglePressed = false;
-	
-	var my, pmy, mx, pmx;
-	
-	var resize = function(e) {
-		pmy = my;
-		pmx = mx;
-		my = e.pageY;
-		mx = e.pageX;
-		
-		var dmy = my - pmy;
-				
-		if (!open) { 
-			if (dmy > 0) {
-				open = true;
-				curControllerContainerHeight = openHeight = 1;
-				toggleButton.innerHTML = name || "Hide Controls";
-			} else {
-				return;
-			}
-		}
-		
-		// TODO: Flip this if you want to resize to the left.
-		var dmx = pmx - mx;
-		
-		if (dmy > 0 && 
-			curControllerContainerHeight > controllerHeight) {
-			var d = GUI.map(curControllerContainerHeight, controllerHeight, controllerHeight + 100, 1, 0);
-			dmy *= d;
-		}
-		
-		toggleDragged = true;
-		dragDisplacementY += dmy;
-		dragDisplacementX += dmx;
-		openHeight += dmy;
-		width += dmx;
-		curControllerContainerHeight += dmy;
-		controllerContainer.style.height = openHeight+'px';
-		width = GUI.constrain(width, MIN_WIDTH, MAX_WIDTH);
-		_this.domElement.style.width = width+'px';
-		checkForOverflow();
-	};
-	
-	toggleButton.addEventListener('mousedown', function(e) {
-		pmy = my = e.pageY;
-		pmx = mx = e.pageX;
-		togglePressed = true;
-		e.preventDefault();
-		dragDisplacementY = 0;
-		dragDisplacementX = 0;
-		document.addEventListener('mousemove', resize, false);
-		return false;
+    var controllers = [];
+    var listening = [];
 
-	}, false);
-	
-	
-	toggleButton.addEventListener('click', function(e) {
-		e.preventDefault();
-		return false;
-	}, false);
-	
-	
-	document.addEventListener('mouseup', function(e) {
-		
-		if (togglePressed && !toggleDragged) {
-			
-			_this.toggle();
+    var autoListen = true;
 
-			// Clears lingering slider column
-			_this.domElement.style.width = (width+1)+'px';
-			setTimeout(function() {
-				_this.domElement.style.width = width+'px';
-			}, 1);
-		}
-		
-		if (togglePressed && toggleDragged) {
-		
-			if (dragDisplacementX == 0) {
-			
-				// Clears lingering slider column
-				_this.domElement.style.width = (width+1)+'px';
-				setTimeout(function() {
-					_this.domElement.style.width = width+'px';
-				}, 1);
-	
-			}
-		
-			if (openHeight > controllerHeight) {
-			
-				clearTimeout(resizeTimeout);
-				openHeight = resizeTo = controllerHeight;
-				beginResize();
-				
-			} else if (controllerContainer.children.length >= 1) {
+    var listenInterval;
 
-				var singleControllerHeight = controllerContainer.children[0].offsetHeight;			
-				clearTimeout(resizeTimeout);
-				var target = Math.round(curControllerContainerHeight/singleControllerHeight)*singleControllerHeight-1;
-				resizeTo = target;
-				if (resizeTo <= 0) {
-					_this.hide();
-					openHeight = singleControllerHeight*2;
-				} else { 
-					openHeight = resizeTo;		
-					beginResize();			
-				}
-			}
-			
-			
-			
-		}
-		
-		
-		document.removeEventListener('mousemove', resize, false);
-		e.preventDefault();
-		toggleDragged = false;
-		togglePressed = false;
-		
-		return false;
+    // Sum total of heights of controllers in this gui
+    var controllerHeight;
 
-	}, false);
-	
-	this.domElement.appendChild(controllerContainer);
-	this.domElement.appendChild(toggleButton);
+    var curControllerContainerHeight = 0;
 
-	if (GUI.autoPlace) {
-		if(GUI.autoPlaceContainer == null) {
-			GUI.autoPlaceContainer = document.createElement('div');
-			GUI.autoPlaceContainer.setAttribute("id", "guidat");
-			
-			document.body.appendChild(GUI.autoPlaceContainer);
-		}
-		GUI.autoPlaceContainer.appendChild(this.domElement);
-	}
+    var _this = this;
 
-	this.autoListenIntervalTime = 1000/60;
+    var open = false;
+    var width = 280;
 
-	var createListenInterval = function() {
-		listenInterval = setInterval(function() {
-			_this.listen();
-		}, this.autoListenIntervalTime);
-	}
-	
-	this.__defineSetter__("autoListen", function(v) {
-		autoListen = v;
-		if (!autoListen) {
-			clearInterval(listenInterval);
-		} else { 
-			if (listening.length > 0) createListenInterval();
-		}
-	});
-	
-	this.__defineGetter__("autoListen", function(v) {
-		return autoListen;
-	});
-	
-	this.listenTo = function(controller) {
-	 	// TODO: check for duplicates
-	 	if (listening.length == 0) {
-	 		createListenInterval();
-	 	}
-		listening.push(controller);
-	};
-	
-	this.unlistenTo = function(controller) {
-		// TODO: test this
-		for(var i = 0; i < listening.length; i++) {
-			if(listening[i] == controller) listening.splice(i, 1);
-		}
-		if(listening.length <= 0) {
-			clearInterval(listenInterval);
-		}
-	};
-	
-	this.listen = function(whoToListenTo) {
-		var arr = whoToListenTo || listening;
-		for (var i in arr) {
-			arr[i].updateDisplay();
-		}
-	};
-	
-	this.listenAll = function() {
-		this.listen(controllers);
-	}
-	
-	this.autoListen = true;
+    // Prevents checkForOverflow bug in which loaded gui appearance
+    // settings are not respected by presence of scrollbar.
+    var explicitOpenHeight = false;
 
-	var alreadyControlled = function(object, propertyName) {
-		for (var i in controllers) {
-			if (controllers[i].object == object &&
-				controllers[i].propertyName == propertyName) {
-				return true;
-			}
-		}
-		return false;
-	};
+    // How big we get when we open
+    var openHeight;
+
+    var name;
+
+    var resizeTo = 0;
+    var resizeTimeout;
+
+    this.domElement = document.createElement('div');
+    this.domElement.setAttribute('class', 'guidat');
+    this.domElement.style.width = width+'px';
+
+    var controllerContainer = document.createElement('div');
+    controllerContainer.setAttribute('class', 'guidat-controllers');
+
+    // Firefox hack to prevent horizontal scrolling
+    controllerContainer.addEventListener('DOMMouseScroll', function(e) {
+
+        var scrollAmount = this.scrollTop;
+
+        if (e.wheelDelta) {
+            scrollAmount+=e.wheelDelta;
+        } else if (e.detail) {
+            scrollAmount+=e.detail;
+        }
+
+        if (e.preventDefault) {
+            e.preventDefault();
+        }
+        e.returnValue = false;
+
+        controllerContainer.scrollTop = scrollAmount;
+
+    }, false);
+
+    controllerContainer.style.height = '0px';
+
+    var toggleButton = document.createElement('a');
+    toggleButton.setAttribute('class', 'guidat-toggle');
+    toggleButton.setAttribute('href', '#');
+    toggleButton.innerHTML = "Show Controls";
+
+    var toggleDragged = false;
+    var dragDisplacementY = 0;
+    var togglePressed = false;
+
+    var my, pmy, mx, pmx;
+
+    var resize = function(e) {
+        pmy = my;
+        pmx = mx;
+        my = e.pageY;
+        mx = e.pageX;
+
+        var dmy = my - pmy;
+
+        if (!open) {
+            if (dmy > 0) {
+                open = true;
+                curControllerContainerHeight = openHeight = 1;
+                toggleButton.innerHTML = name || "Hide Controls";
+            } else {
+                return;
+            }
+        }
+
+        // TODO: Flip this if you want to resize to the left.
+        var dmx = pmx - mx;
+
+        if (dmy > 0 &&
+            curControllerContainerHeight > controllerHeight) {
+            var d = GUI.map(curControllerContainerHeight, controllerHeight, controllerHeight + 100, 1, 0);
+            dmy *= d;
+        }
+
+        toggleDragged = true;
+        dragDisplacementY += dmy;
+        dragDisplacementX += dmx;
+        openHeight += dmy;
+        width += dmx;
+        curControllerContainerHeight += dmy;
+        controllerContainer.style.height = openHeight+'px';
+        width = GUI.constrain(width, MIN_WIDTH, MAX_WIDTH);
+        _this.domElement.style.width = width+'px';
+        checkForOverflow();
+    };
+
+    toggleButton.addEventListener('mousedown', function(e) {
+        pmy = my = e.pageY;
+        pmx = mx = e.pageX;
+        togglePressed = true;
+        e.preventDefault();
+        dragDisplacementY = 0;
+        dragDisplacementX = 0;
+        document.addEventListener('mousemove', resize, false);
+        return false;
+
+    }, false);
 
 
-	var construct = function(constructor, args) {
-		function F() {
-		    return constructor.apply(this, args);
-		}
-		F.prototype = constructor.prototype;
-		return new F();
-	};
+    toggleButton.addEventListener('click', function(e) {
+        e.preventDefault();
+        return false;
+    }, false);
 
-	this.add = function() {
 
-		var object = arguments[0];
-		var propertyName = arguments[1];
+    document.addEventListener('mouseup', function(e) {
 
-		// Have we already added this?
-		if (alreadyControlled(object, propertyName)) {
-		//	GUI.error("Controller for \"" + propertyName+"\" already added.");
-		//	return;
-		}
+        if (togglePressed && !toggleDragged) {
 
-		var value = object[propertyName];
+            _this.toggle();
 
-		// Does this value exist? Is it accessible?
-		if (value == undefined) {
-			GUI.error(object + " either has no property \""+propertyName+"\", or the property is inaccessible.");
-			return;
-		}
+            // Clears lingering slider column
+            _this.domElement.style.width = (width+1)+'px';
+            setTimeout(function() {
+                _this.domElement.style.width = width+'px';
+            }, 1);
+        }
 
-		var type = typeof value;
-		var handler = handlerTypes[type];
+        if (togglePressed && toggleDragged) {
 
-		// Do we know how to deal with this data type?
-		if (handler == undefined) {
-			GUI.error("Cannot create controller for data type \""+type+"\"");
-			return;
-		}
-	
-		var args = [this]; // Set first arg (parent) to this 
-		for (var j = 0; j < arguments.length; j++) {
-			args.push(arguments[j]);
-		}
-	
-		var controllerObject = construct(handler, args);
-		
-		// Were we able to make the controller?
-		if (!controllerObject) {
-			GUI.error("Error creating controller for \""+propertyName+"\".");
-			return;
-		}
+            if (dragDisplacementX == 0) {
 
-		// Success.
-		controllerContainer.appendChild(controllerObject.domElement);
-		controllers.push(controllerObject);
-		GUI.allControllers.push(controllerObject);
+                // Clears lingering slider column
+                _this.domElement.style.width = (width+1)+'px';
+                setTimeout(function() {
+                    _this.domElement.style.width = width+'px';
+                }, 1);
 
-		// Do we have a saved value for this controller?
-		if (type != "function" && 
-			GUI.saveIndex < GUI.savedValues.length) {
-			controllerObject.setValue(GUI.savedValues[GUI.saveIndex]);
-			GUI.saveIndex++;
-		}
-	
-		// Compute sum height of controllers.
-		checkForOverflow();
-		
-		// Prevents checkForOverflow bug in which loaded gui appearance
-		// settings are not respected by presence of scrollbar.
-		if (!explicitOpenHeight) {
-			openHeight = controllerHeight;
-		}
-		
-		return controllerObject;
-		
-	}
-	
-	var checkForOverflow = function() {
-		controllerHeight = 0;
-		for (var i in controllers) {
-			controllerHeight += controllers[i].domElement.offsetHeight;
-		}
-		if (controllerHeight - 1 > openHeight) {
-			controllerContainer.style.overflowY = "auto";
-		} else {
-			controllerContainer.style.overflowY = "hidden";
-		}	
-	}
-	
-	var handlerTypes = {
-		"number": GUI.NumberController,
-		"string": GUI.StringController,
-		"boolean": GUI.BooleanController,
-		"function": GUI.FunctionController
-	};
-	
-	var alreadyControlled = function(object, propertyName) {
-		for (var i in controllers) {
-			if (controllers[i].object == object &&
-				controllers[i].propertyName == propertyName) {
-				return true;
-			}
-		}
-		return false;
-	};
-	
-	var construct = function(constructor, args) {
+            }
+
+            if (openHeight > controllerHeight) {
+
+                clearTimeout(resizeTimeout);
+                openHeight = resizeTo = controllerHeight;
+                beginResize();
+
+            } else if (controllerContainer.children.length >= 1) {
+
+                var singleControllerHeight = controllerContainer.children[0].offsetHeight;
+                clearTimeout(resizeTimeout);
+                var target = Math.round(curControllerContainerHeight/singleControllerHeight)*singleControllerHeight-1;
+                resizeTo = target;
+                if (resizeTo <= 0) {
+                    _this.hide();
+                    openHeight = singleControllerHeight*2;
+                } else {
+                    openHeight = resizeTo;
+                    beginResize();
+                }
+            }
+
+
+
+        }
+
+
+        document.removeEventListener('mousemove', resize, false);
+        e.preventDefault();
+        toggleDragged = false;
+        togglePressed = false;
+
+        return false;
+
+    }, false);
+
+    this.domElement.appendChild(controllerContainer);
+    this.domElement.appendChild(toggleButton);
+
+    if (GUI.autoPlace) {
+        if(GUI.autoPlaceContainer == null) {
+            GUI.autoPlaceContainer = document.createElement('div');
+            GUI.autoPlaceContainer.setAttribute("id", "guidat");
+
+            document.body.appendChild(GUI.autoPlaceContainer);
+        }
+        GUI.autoPlaceContainer.appendChild(this.domElement);
+    }
+
+    this.autoListenIntervalTime = 1000/60;
+
+    var createListenInterval = function() {
+        listenInterval = setInterval(function() {
+            _this.listen();
+        }, this.autoListenIntervalTime);
+    }
+
+    this.__defineSetter__("autoListen", function(v) {
+        autoListen = v;
+        if (!autoListen) {
+            clearInterval(listenInterval);
+        } else {
+            if (listening.length > 0) createListenInterval();
+        }
+    });
+
+    this.__defineGetter__("autoListen", function(v) {
+        return autoListen;
+    });
+
+    this.listenTo = function(controller) {
+        // TODO: check for duplicates
+        if (listening.length == 0) {
+            createListenInterval();
+        }
+        listening.push(controller);
+    };
+
+    this.unlistenTo = function(controller) {
+        // TODO: test this
+        for(var i = 0; i < listening.length; i++) {
+            if(listening[i] == controller) listening.splice(i, 1);
+        }
+        if(listening.length <= 0) {
+            clearInterval(listenInterval);
+        }
+    };
+
+    this.listen = function(whoToListenTo) {
+        var arr = whoToListenTo || listening;
+        for (var i in arr) {
+            arr[i].updateDisplay();
+        }
+    };
+
+    this.listenAll = function() {
+        this.listen(controllers);
+    }
+
+    this.autoListen = true;
+
+    var alreadyControlled = function(object, propertyName) {
+        for (var i in controllers) {
+            if (controllers[i].object == object &&
+                controllers[i].propertyName == propertyName) {
+                return true;
+            }
+        }
+        return false;
+    };
+
+
+    var construct = function(constructor, args) {
         function F() {
             return constructor.apply(this, args);
         }
@@ -379,84 +276,187 @@ var GUI = function() {
         return new F();
     };
 
-	this.reset = function() {
-		// TODO
-	}
+    this.add = function() {
 
-	// GUI ... GUI
-	
-	this.toggle = function() {
-		open ? this.hide() : this.show();
-	};
+        var object = arguments[0];
+        var propertyName = arguments[1];
 
-	this.show = function() {
-		toggleButton.innerHTML = name || "Hide Controls";
-		resizeTo = openHeight;
-		clearTimeout(resizeTimeout);
-		beginResize();
-		open = true;
-	}
+        // Have we already added this?
+        if (alreadyControlled(object, propertyName)) {
+        //	GUI.error("Controller for \"" + propertyName+"\" already added.");
+        //	return;
+        }
 
-	this.hide = function() {
-		toggleButton.innerHTML = name || "Show Controls";
-		resizeTo = 0;
-		clearTimeout(resizeTimeout);
-		beginResize();
-		open = false;
-	}
-	
-	this.name = function(n) {
-		name = n;
-		toggleButton.innerHTML = n;
-	}
-	
-	// used in saveURL
-	this.appearanceVars = function() {
-		return [open, width, openHeight, controllerContainer.scrollTop]
-	}
-	
-	var beginResize = function() {
-		//console.log("Resizing from " + curControllerContainerHeight + " to " + resizeTo);
-		curControllerContainerHeight += (resizeTo - curControllerContainerHeight)*0.6;
-		if (Math.abs(curControllerContainerHeight-resizeTo) < 1) {
-			curControllerContainerHeight = resizeTo;
-		} else { 
-			resizeTimeout = setTimeout(beginResize, 1000/30);
-		}
-		controllerContainer.style.height = Math.round(curControllerContainerHeight)+'px';
-		checkForOverflow();
-	}
-	
-	// Load saved appearance:
+        var value = object[propertyName];
 
-	if (GUI.guiIndex < GUI.savedAppearanceVars.length) {
+        // Does this value exist? Is it accessible?
+        if (value == undefined) {
+            GUI.error(object + " either has no property \""+propertyName+"\", or the property is inaccessible.");
+            return;
+        }
 
-	
-		width = parseInt(GUI.savedAppearanceVars[GUI.guiIndex][1]);
-		_this.domElement.style.width = width+"px";
-		
-		openHeight = parseInt(GUI.savedAppearanceVars[GUI.guiIndex][2]);
-		explicitOpenHeight = true;
-		if (eval(GUI.savedAppearanceVars[GUI.guiIndex][0]) == true) {
-			curControllerContainerHeight = openHeight;
-			var t = GUI.savedAppearanceVars[GUI.guiIndex][3]
-			
-			// Hack.
-			setTimeout(function() {
-				controllerContainer.scrollTop = t;
-			}, 0);
-			
-			if (GUI.scrollTop > -1) {
-				document.body.scrollTop = GUI.scrollTop;
-			}
-			resizeTo = openHeight;
-			this.show();
-		}
+        var type = typeof value;
+        var handler = handlerTypes[type];
 
-		GUI.guiIndex++;
-	}
+        // Do we know how to deal with this data type?
+        if (handler == undefined) {
+            GUI.error("Cannot create controller for data type \""+type+"\"");
+            return;
+        }
 
-	GUI.allGuis.push(this);
+        var args = [this]; // Set first arg (parent) to this
+        for (var j = 0; j < arguments.length; j++) {
+            args.push(arguments[j]);
+        }
+
+        var controllerObject = construct(handler, args);
+
+        // Were we able to make the controller?
+        if (!controllerObject) {
+            GUI.error("Error creating controller for \""+propertyName+"\".");
+            return;
+        }
+
+        // Success.
+        controllerContainer.appendChild(controllerObject.domElement);
+        controllers.push(controllerObject);
+        GUI.allControllers.push(controllerObject);
+
+        // Do we have a saved value for this controller?
+        if (type != "function" &&
+            GUI.saveIndex < GUI.savedValues.length) {
+            controllerObject.setValue(GUI.savedValues[GUI.saveIndex]);
+            GUI.saveIndex++;
+        }
+
+        // Compute sum height of controllers.
+        checkForOverflow();
+
+        // Prevents checkForOverflow bug in which loaded gui appearance
+        // settings are not respected by presence of scrollbar.
+        if (!explicitOpenHeight) {
+            openHeight = controllerHeight;
+        }
+
+        return controllerObject;
+
+    }
+
+    var checkForOverflow = function() {
+        controllerHeight = 0;
+        for (var i in controllers) {
+            controllerHeight += controllers[i].domElement.offsetHeight;
+        }
+        if (controllerHeight - 1 > openHeight) {
+            controllerContainer.style.overflowY = "auto";
+        } else {
+            controllerContainer.style.overflowY = "hidden";
+        }
+    }
+
+    var handlerTypes = {
+        "number": GUI.NumberController,
+        "string": GUI.StringController,
+        "boolean": GUI.BooleanController,
+        "function": GUI.FunctionController
+    };
+
+    var alreadyControlled = function(object, propertyName) {
+        for (var i in controllers) {
+            if (controllers[i].object == object &&
+                controllers[i].propertyName == propertyName) {
+                return true;
+            }
+        }
+        return false;
+    };
+
+    var construct = function(constructor, args) {
+        function F() {
+            return constructor.apply(this, args);
+        }
+        F.prototype = constructor.prototype;
+        return new F();
+    };
+
+    this.reset = function() {
+        // TODO
+    }
+
+    // GUI ... GUI
+
+    this.toggle = function() {
+        open ? this.hide() : this.show();
+    };
+
+    this.show = function() {
+        toggleButton.innerHTML = name || "Hide Controls";
+        resizeTo = openHeight;
+        clearTimeout(resizeTimeout);
+        beginResize();
+        open = true;
+    }
+
+    this.hide = function() {
+        toggleButton.innerHTML = name || "Show Controls";
+        resizeTo = 0;
+        clearTimeout(resizeTimeout);
+        beginResize();
+        open = false;
+    }
+
+    this.name = function(n) {
+        name = n;
+        toggleButton.innerHTML = n;
+    }
+
+    // used in saveURL
+    this.appearanceVars = function() {
+        return [open, width, openHeight, controllerContainer.scrollTop]
+    }
+
+    var beginResize = function() {
+        //console.log("Resizing from " + curControllerContainerHeight + " to " + resizeTo);
+        curControllerContainerHeight += (resizeTo - curControllerContainerHeight)*0.6;
+        if (Math.abs(curControllerContainerHeight-resizeTo) < 1) {
+            curControllerContainerHeight = resizeTo;
+        } else {
+            resizeTimeout = setTimeout(beginResize, 1000/30);
+        }
+        controllerContainer.style.height = Math.round(curControllerContainerHeight)+'px';
+        checkForOverflow();
+    }
+
+    // Load saved appearance:
+
+    if (GUI.guiIndex < GUI.savedAppearanceVars.length) {
+
+
+        width = parseInt(GUI.savedAppearanceVars[GUI.guiIndex][1]);
+        _this.domElement.style.width = width+"px";
+
+        openHeight = parseInt(GUI.savedAppearanceVars[GUI.guiIndex][2]);
+        explicitOpenHeight = true;
+        if (eval(GUI.savedAppearanceVars[GUI.guiIndex][0]) == true) {
+            curControllerContainerHeight = openHeight;
+            var t = GUI.savedAppearanceVars[GUI.guiIndex][3]
+
+            // Hack.
+            setTimeout(function() {
+                controllerContainer.scrollTop = t;
+            }, 0);
+
+            if (GUI.scrollTop > -1) {
+                document.body.scrollTop = GUI.scrollTop;
+            }
+            resizeTo = openHeight;
+            this.show();
+        }
+
+        GUI.guiIndex++;
+    }
+
+    GUI.allGuis.push(this);
 
 };
 
@@ -467,27 +467,27 @@ GUI.autoPlaceContainer = null;
 GUI.allControllers = [];
 GUI.allGuis = [];
 
-GUI.saveURL = function() { 
-	title = window.location;
-	url = GUI.replaceGetVar("saveString", GUI.getSaveString());
-	window.location = url;
+GUI.saveURL = function() {
+    title = window.location;
+    url = GUI.replaceGetVar("saveString", GUI.getSaveString());
+    window.location = url;
 };
 
 GUI.scrollTop = -1;
 
 GUI.load = function(saveString) {
 
-	//GUI.savedAppearanceVars = [];
-	var vals = saveString.split(",");
-	var numGuis = parseInt(vals[0]);
-	GUI.scrollTop = parseInt(vals[1]);
-	for (var i = 0; i < numGuis; i++) {
-		var appr = vals.splice(2, 4);
-		GUI.savedAppearanceVars.push(appr);
-	}
-	
-	GUI.savedValues = vals.splice(2, vals.length);
-	
+    //GUI.savedAppearanceVars = [];
+    var vals = saveString.split(",");
+    var numGuis = parseInt(vals[0]);
+    GUI.scrollTop = parseInt(vals[1]);
+    for (var i = 0; i < numGuis; i++) {
+        var appr = vals.splice(2, 4);
+        GUI.savedAppearanceVars.push(appr);
+    }
+
+    GUI.savedValues = vals.splice(2, vals.length);
+
 };
 
 GUI.savedValues = [];
@@ -495,39 +495,39 @@ GUI.savedAppearanceVars = [];
 
 GUI.getSaveString = function() {
 
-	var vals = [];
-	
-	vals.push(GUI.allGuis.length);
-	vals.push(document.body.scrollTop);
-	
-	
-	for (var i in GUI.allGuis) {
-		var av = GUI.allGuis[i].appearanceVars();
-		for (var j = 0; j < av.length; j++) {
-			vals.push(av[j]);
-		}
-	}	
-	
-	for (var i in GUI.allControllers) {
-	
-		// We don't save values for functions.
-		if (GUI.allControllers[i].type == "function") {
-			continue;
-		}
-		
-		var v = GUI.allControllers[i].getValue();
-		
-		// Round numbers so they don't get enormous
-		if (GUI.allControllers[i].type == "number") {
-			v = GUI.roundToDecimal(v, 4);
-		}
-		
-		vals.push(v);
-		
-	}
-	
-	return vals.join(',');
-	
+    var vals = [];
+
+    vals.push(GUI.allGuis.length);
+    vals.push(document.body.scrollTop);
+
+
+    for (var i in GUI.allGuis) {
+        var av = GUI.allGuis[i].appearanceVars();
+        for (var j = 0; j < av.length; j++) {
+            vals.push(av[j]);
+        }
+    }
+
+    for (var i in GUI.allControllers) {
+
+        // We don't save values for functions.
+        if (GUI.allControllers[i].type == "function") {
+            continue;
+        }
+
+        var v = GUI.allControllers[i].getValue();
+
+        // Round numbers so they don't get enormous
+        if (GUI.allControllers[i].type == "number") {
+            v = GUI.roundToDecimal(v, 4);
+        }
+
+        vals.push(v);
+
+    }
+
+    return vals.join(',');
+
 }
 
 GUI.getVarFromURL = function(v) {
@@ -536,14 +536,14 @@ GUI.getVarFromURL = function(v) {
     var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
 
     for (var i = 0; i < hashes.length; i++) {
- 		hash = hashes[i].split("=")
+        hash = hashes[i].split("=")
         if (hash == undefined) continue;
-		if (hash[0] == v) {
-			return hash[1];
-		}
+        if (hash[0] == v) {
+            return hash[1];
+        }
     }
-	
-	return null;
+
+    return null;
 
 };
 
@@ -554,69 +554,69 @@ GUI.replaceGetVar = function(varName, val) {
     var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
 
     for (var i = 0; i < hashes.length; i++) {
- 		hash = hashes[i].split("=")
+        hash = hashes[i].split("=")
         if (hash == undefined) continue;
-		if (hash[0] == varName) {
-			return loc.replace(hash[1], val);
-		}
+        if (hash[0] == varName) {
+            return loc.replace(hash[1], val);
+        }
     }
-	
-	if (window.location.href.indexOf('?') != -1) {
-		return loc + "&"+varName+"="+val;
-	}
-	
-	return loc+"?"+varName+"="+val;
-	
+
+    if (window.location.href.indexOf('?') != -1) {
+        return loc + "&"+varName+"="+val;
+    }
+
+    return loc+"?"+varName+"="+val;
+
 };
 
 GUI.saveIndex = 0;
 GUI.guiIndex = 0;
 
 GUI.showSaveString = function() {
-	alert(GUI.getSaveString());
+    alert(GUI.getSaveString());
 }
 
 // Util functions
 
 GUI.makeUnselectable = function(elem) {
-	elem.onselectstart = function() { return false; };
-	elem.style.MozUserSelect = "none";
-	elem.style.KhtmlUserSelect = "none";
-	elem.unselectable = "on";
+    elem.onselectstart = function() { return false; };
+    elem.style.MozUserSelect = "none";
+    elem.style.KhtmlUserSelect = "none";
+    elem.unselectable = "on";
 }
-    
+
 GUI.makeSelectable = function(elem) {
-	elem.onselectstart = function() { };
-	elem.style.MozUserSelect = "auto";
-	elem.style.KhtmlUserSelect = "auto";
-	elem.unselectable = "off";
+    elem.onselectstart = function() { };
+    elem.style.MozUserSelect = "auto";
+    elem.style.KhtmlUserSelect = "auto";
+    elem.unselectable = "off";
 }
 
 GUI.map = function(v, i1, i2, o1, o2) {
-	var v = o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
-	return v;
+    var v = o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
+    return v;
 }
 
 GUI.constrain = function (v, o1, o2) {
-	if (v < o1) v = o1;
-	else if (v > o2) v = o2;
-	return v;
+    if (v < o1) v = o1;
+    else if (v > o2) v = o2;
+    return v;
 }
 
 GUI.error = function(str) {
-	if (typeof console.error == 'function') {
-		console.error("[GUI ERROR] " + str);
-	}
+    if (typeof console.error == 'function') {
+        console.error("[GUI ERROR] " + str);
+    }
 };
 
 GUI.roundToDecimal = function(n, decimals) {
-	var t = Math.pow(10, decimals);
-	return Math.round(n*t)/t;
+    var t = Math.pow(10, decimals);
+    return Math.round(n*t)/t;
 }
 
 GUI.extendController = function(clazz) {
-	clazz.prototype = new GUI.Controller();
-	clazz.prototype.constructor = clazz;
+    clazz.prototype = new GUI.Controller();
+    clazz.prototype.constructor = clazz;
 }
 
-if (GUI.getVarFromURL('saveString') != null) GUI.load(GUI.getVarFromURL('saveString'));
\ No newline at end of file
+if (GUI.getVarFromURL('saveString') != null) GUI.load(GUI.getVarFromURL('saveString'));

From 151879cdffe393eb7bfce9737a4b4bc912a0d31f Mon Sep 17 00:00:00 2001
From: Szymon Nowak 
Date: Thu, 10 Feb 2011 22:00:01 +0100
Subject: [PATCH 4/7] Fixed missing semicolons and implied globals.

---
 controllers/controller.boolean.js  |  2 +-
 controllers/controller.function.js |  2 +-
 controllers/controller.js          | 19 ++++---
 controllers/controller.number.js   | 17 +++---
 controllers/controller.string.js   |  2 +-
 controllers/slider.js              | 14 ++---
 gui.js                             | 88 +++++++++++-------------------
 7 files changed, 58 insertions(+), 86 deletions(-)

diff --git a/controllers/controller.boolean.js b/controllers/controller.boolean.js
index 839564b..2cb68b3 100644
--- a/controllers/controller.boolean.js
+++ b/controllers/controller.boolean.js
@@ -33,7 +33,7 @@ GUI.BooleanController = function() {
             } catch (e) {}
         }
         return GUI.Controller.prototype.setValue.call(this, val);
-    }
+    };
 
 };
 GUI.extendController(GUI.BooleanController);
diff --git a/controllers/controller.function.js b/controllers/controller.function.js
index 63690fa..586c17f 100644
--- a/controllers/controller.function.js
+++ b/controllers/controller.function.js
@@ -17,7 +17,7 @@ GUI.FunctionController = function() {
     this.onFire = function(fnc) {
         fireFunction = fnc;
         return this;
-    }
+    };
 
     this.fire = function() {
         if (fireFunction != null) {
diff --git a/controllers/controller.js b/controllers/controller.js
index 6a2916a..c054fa0 100644
--- a/controllers/controller.js
+++ b/controllers/controller.js
@@ -34,12 +34,12 @@ GUI.Controller.prototype.reset = function() {
 GUI.Controller.prototype.listen = function() {
     this.parent.listenTo(this);
     return this;
-}
+};
 
 GUI.Controller.prototype.unlisten = function() {
     this.parent.unlistenTo(this); // <--- hasn't been tested yet
     return this;
-}
+};
 
 GUI.Controller.prototype.setValue = function(n) {
     this.object[this.propertyName] = n;
@@ -48,22 +48,23 @@ GUI.Controller.prototype.setValue = function(n) {
     }
     this.updateDisplay();
     return this;
-}
+};
 
 GUI.Controller.prototype.getValue = function() {
     return this.object[this.propertyName];
-}
+};
 
-GUI.Controller.prototype.updateDisplay = function() {}
+GUI.Controller.prototype.updateDisplay = function() {};
 
 GUI.Controller.prototype.onChange = function(fnc) {
     this.changeFunction = fnc;
     return this;
-}
+};
+
 GUI.Controller.prototype.onFinishChange = function(fnc) {
     this.finishChangeFunction = fnc;
     return this;
-}
+};
 
 GUI.Controller.prototype.options = function() {
     var _this = this;
@@ -90,7 +91,7 @@ GUI.Controller.prototype.options = function() {
         if (_this.finishChangeFunction != null) {
             _this.finishChangeFunction.call(this, _this.getValue());
         }
-    });
+    }, false);
     _this.domElement.appendChild(select);
     return this;
-}
+};
diff --git a/controllers/controller.number.js b/controllers/controller.number.js
index 8ffb01f..eae0a2b 100644
--- a/controllers/controller.number.js
+++ b/controllers/controller.number.js
@@ -12,7 +12,7 @@ GUI.NumberController = function() {
 
     var clickedNumberField = false;
 
-    var y = py = 0;
+    var y = 0, py = 0;
 
     var min = arguments[3];
     var max = arguments[4];
@@ -65,13 +65,14 @@ GUI.NumberController = function() {
 
     // Handle up arrow and down arrow
     numberField.addEventListener('keydown', function(e) {
+        var newVal;
         switch(e.keyCode) {
             case 38:    // up
-                var newVal = _this.getValue() + step;
+                newVal = _this.getValue() + step;
                 _this.setValue(newVal);
                 break;
             case 40:    // down
-                var newVal = _this.getValue() - step;
+                newVal = _this.getValue() - step;
                 _this.setValue(newVal);
                 break;
         }
@@ -91,9 +92,7 @@ GUI.NumberController = function() {
             _this.finishChangeFunction.call(this, _this.getValue());
         }
         document.removeEventListener('mouseup', mouseup, false);
-    }
-
-
+    };
 
     var dragNumberField = function(e) {
         draggedNumberField = true;
@@ -112,7 +111,7 @@ GUI.NumberController = function() {
         var newVal = _this.getValue() + dy*step;
         _this.setValue(newVal);
         return false;
-    }
+    };
 
     this.options = function() {
         _this.noSlider();
@@ -139,12 +138,12 @@ GUI.NumberController = function() {
 
         return GUI.Controller.prototype.setValue.call(this, val);
 
-    }
+    };
 
     this.updateDisplay = function() {
         numberField.value = GUI.roundToDecimal(_this.getValue(), 4);
         if (slider) slider.value = _this.getValue();
-    }
+    };
 };
 
 GUI.extendController(GUI.NumberController);
diff --git a/controllers/controller.string.js b/controllers/controller.string.js
index bceb44c..1b6fa45 100644
--- a/controllers/controller.string.js
+++ b/controllers/controller.string.js
@@ -33,7 +33,7 @@ GUI.StringController = function() {
 
     this.updateDisplay = function() {
         input.value = _this.getValue();
-    }
+    };
 
     this.options = function() {
         _this.domElement.removeChild(input);
diff --git a/controllers/slider.js b/controllers/slider.js
index fc7c989..83841eb 100644
--- a/controllers/slider.js
+++ b/controllers/slider.js
@@ -1,9 +1,5 @@
 GUI.Slider = function(numberController, min, max, step, initValue) {
 
-    var min = min;
-    var max = max;
-    var step = step;
-
     var clicked = false;
     var _this = this;
 
@@ -18,15 +14,15 @@ GUI.Slider = function(numberController, min, max, step, initValue) {
     this.domElement.appendChild(this.fg);
 
     var findPos = function(obj) {
-        var curleft = curtop = 0;
+        var curleft = 0, curtop = 0;
         if (obj.offsetParent) {
             do {
                 curleft += obj.offsetLeft;
                 curtop += obj.offsetTop;
-            } while (obj = obj.offsetParent);
+            } while ((obj = obj.offsetParent));
             return [curleft,curtop];
         }
-    }
+    };
 
     this.__defineSetter__('value', function(e) {
         var pct = GUI.map(e, min, max, 0, 100);
@@ -39,7 +35,7 @@ GUI.Slider = function(numberController, min, max, step, initValue) {
         var val = GUI.map(e.pageX, pos[0], pos[0] + _this.domElement.offsetWidth, min, max);
         val = Math.round(val/step)*step;
         numberController.setValue(val);
-    }
+    };
 
     this.domElement.addEventListener('mousedown', function(e) {
         clicked = true;
@@ -66,4 +62,4 @@ GUI.Slider = function(numberController, min, max, step, initValue) {
 
     this.value = initValue;
 
-}
+};
diff --git a/gui.js b/gui.js
index 884ff53..7eeeef6 100644
--- a/gui.js
+++ b/gui.js
@@ -17,8 +17,6 @@ var GUI = function() {
 
     var curControllerContainerHeight = 0;
 
-    var _this = this;
-
     var open = false;
     var width = 280;
 
@@ -68,9 +66,10 @@ var GUI = function() {
     toggleButton.setAttribute('href', '#');
     toggleButton.innerHTML = "Show Controls";
 
-    var toggleDragged = false;
-    var dragDisplacementY = 0;
-    var togglePressed = false;
+    var toggleDragged = false,
+        dragDisplacementX = 0,
+        dragDisplacementY = 0,
+        togglePressed = false;
 
     var my, pmy, mx, pmx;
 
@@ -177,12 +176,8 @@ var GUI = function() {
                     beginResize();
                 }
             }
-
-
-
         }
 
-
         document.removeEventListener('mousemove', resize, false);
         e.preventDefault();
         toggleDragged = false;
@@ -211,7 +206,7 @@ var GUI = function() {
         listenInterval = setInterval(function() {
             _this.listen();
         }, this.autoListenIntervalTime);
-    }
+    };
 
     this.__defineSetter__("autoListen", function(v) {
         autoListen = v;
@@ -253,7 +248,7 @@ var GUI = function() {
 
     this.listenAll = function() {
         this.listen(controllers);
-    }
+    };
 
     this.autoListen = true;
 
@@ -340,7 +335,7 @@ var GUI = function() {
 
         return controllerObject;
 
-    }
+    };
 
     var checkForOverflow = function() {
         controllerHeight = 0;
@@ -352,7 +347,7 @@ var GUI = function() {
         } else {
             controllerContainer.style.overflowY = "hidden";
         }
-    }
+    };
 
     var handlerTypes = {
         "number": GUI.NumberController,
@@ -361,27 +356,9 @@ var GUI = function() {
         "function": GUI.FunctionController
     };
 
-    var alreadyControlled = function(object, propertyName) {
-        for (var i in controllers) {
-            if (controllers[i].object == object &&
-                controllers[i].propertyName == propertyName) {
-                return true;
-            }
-        }
-        return false;
-    };
-
-    var construct = function(constructor, args) {
-        function F() {
-            return constructor.apply(this, args);
-        }
-        F.prototype = constructor.prototype;
-        return new F();
-    };
-
     this.reset = function() {
         // TODO
-    }
+    };
 
     // GUI ... GUI
 
@@ -395,7 +372,7 @@ var GUI = function() {
         clearTimeout(resizeTimeout);
         beginResize();
         open = true;
-    }
+    };
 
     this.hide = function() {
         toggleButton.innerHTML = name || "Show Controls";
@@ -403,17 +380,17 @@ var GUI = function() {
         clearTimeout(resizeTimeout);
         beginResize();
         open = false;
-    }
+    };
 
     this.name = function(n) {
         name = n;
         toggleButton.innerHTML = n;
-    }
+    };
 
     // used in saveURL
     this.appearanceVars = function() {
-        return [open, width, openHeight, controllerContainer.scrollTop]
-    }
+        return [open, width, openHeight, controllerContainer.scrollTop];
+    };
 
     var beginResize = function() {
         //console.log("Resizing from " + curControllerContainerHeight + " to " + resizeTo);
@@ -425,7 +402,7 @@ var GUI = function() {
         }
         controllerContainer.style.height = Math.round(curControllerContainerHeight)+'px';
         checkForOverflow();
-    }
+    };
 
     // Load saved appearance:
 
@@ -439,7 +416,7 @@ var GUI = function() {
         explicitOpenHeight = true;
         if (eval(GUI.savedAppearanceVars[GUI.guiIndex][0]) == true) {
             curControllerContainerHeight = openHeight;
-            var t = GUI.savedAppearanceVars[GUI.guiIndex][3]
+            var t = GUI.savedAppearanceVars[GUI.guiIndex][3];
 
             // Hack.
             setTimeout(function() {
@@ -468,8 +445,7 @@ GUI.allControllers = [];
 GUI.allGuis = [];
 
 GUI.saveURL = function() {
-    title = window.location;
-    url = GUI.replaceGetVar("saveString", GUI.getSaveString());
+    var url = GUI.replaceGetVar("saveString", GUI.getSaveString());
     window.location = url;
 };
 
@@ -495,20 +471,21 @@ GUI.savedAppearanceVars = [];
 
 GUI.getSaveString = function() {
 
-    var vals = [];
+    var vals = [],
+        i;
 
     vals.push(GUI.allGuis.length);
     vals.push(document.body.scrollTop);
 
 
-    for (var i in GUI.allGuis) {
+    for (i in GUI.allGuis) {
         var av = GUI.allGuis[i].appearanceVars();
         for (var j = 0; j < av.length; j++) {
             vals.push(av[j]);
         }
     }
 
-    for (var i in GUI.allControllers) {
+    for (i in GUI.allControllers) {
 
         // We don't save values for functions.
         if (GUI.allControllers[i].type == "function") {
@@ -528,7 +505,7 @@ GUI.getSaveString = function() {
 
     return vals.join(',');
 
-}
+};
 
 GUI.getVarFromURL = function(v) {
 
@@ -536,7 +513,7 @@ GUI.getVarFromURL = function(v) {
     var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
 
     for (var i = 0; i < hashes.length; i++) {
-        hash = hashes[i].split("=")
+        hash = hashes[i].split("=");
         if (hash == undefined) continue;
         if (hash[0] == v) {
             return hash[1];
@@ -554,7 +531,7 @@ GUI.replaceGetVar = function(varName, val) {
     var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
 
     for (var i = 0; i < hashes.length; i++) {
-        hash = hashes[i].split("=")
+        hash = hashes[i].split("=");
         if (hash == undefined) continue;
         if (hash[0] == varName) {
             return loc.replace(hash[1], val);
@@ -574,7 +551,7 @@ GUI.guiIndex = 0;
 
 GUI.showSaveString = function() {
     alert(GUI.getSaveString());
-}
+};
 
 // Util functions
 
@@ -583,25 +560,24 @@ GUI.makeUnselectable = function(elem) {
     elem.style.MozUserSelect = "none";
     elem.style.KhtmlUserSelect = "none";
     elem.unselectable = "on";
-}
+};
 
 GUI.makeSelectable = function(elem) {
     elem.onselectstart = function() { };
     elem.style.MozUserSelect = "auto";
     elem.style.KhtmlUserSelect = "auto";
     elem.unselectable = "off";
-}
+};
 
 GUI.map = function(v, i1, i2, o1, o2) {
-    var v = o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
-    return v;
-}
+    return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
+};
 
 GUI.constrain = function (v, o1, o2) {
     if (v < o1) v = o1;
     else if (v > o2) v = o2;
     return v;
-}
+};
 
 GUI.error = function(str) {
     if (typeof console.error == 'function') {
@@ -612,11 +588,11 @@ GUI.error = function(str) {
 GUI.roundToDecimal = function(n, decimals) {
     var t = Math.pow(10, decimals);
     return Math.round(n*t)/t;
-}
+};
 
 GUI.extendController = function(clazz) {
     clazz.prototype = new GUI.Controller();
     clazz.prototype.constructor = clazz;
-}
+};
 
 if (GUI.getVarFromURL('saveString') != null) GUI.load(GUI.getVarFromURL('saveString'));

From d3cc444cad1fed8b436df0af5b9baa5f850dce77 Mon Sep 17 00:00:00 2001
From: Jono Brandel 
Date: Thu, 10 Feb 2011 14:51:52 -0800
Subject: [PATCH 5/7] hooked class attributeses properly on Number Controller
 and Slider

---
 controllers/controller.number.js | 3 +++
 controllers/slider.js            | 2 ++
 gui.css                          | 3 ++-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/controllers/controller.number.js b/controllers/controller.number.js
index 4a63372..1af4683 100644
--- a/controllers/controller.number.js
+++ b/controllers/controller.number.js
@@ -85,6 +85,7 @@ GUI.NumberController = function() {
 	        numberField.focus();
 	        numberField.select();
         }
+		if(slider) slider.domElement.className = slider.domElement.className.replace(' active', '');
         draggedNumberField = false;
         clickedNumberField = false;
 		if (_this.finishChangeFunction != null) {
@@ -106,6 +107,8 @@ GUI.NumberController = function() {
 		GUI.makeUnselectable(_this.parent.domElement);
 		GUI.makeUnselectable(numberField);
 		
+		if(slider) slider.domElement.className += ' active';
+		
 		py = y;
 		y = e.pageY;
 		var dy = py - y;
diff --git a/controllers/slider.js b/controllers/slider.js
index b3ad28a..d129942 100644
--- a/controllers/slider.js
+++ b/controllers/slider.js
@@ -46,6 +46,7 @@ GUI.Slider = function(numberController, min, max, step, initValue) {
 		x = px = e.pageX;
 		_this.domElement.setAttribute('class', 'guidat-slider-bg active');
 		_this.fg.setAttribute('class', 'guidat-slider-fg active');
+		numberController.domElement.className += ' active';
 		onDrag(e);
 		document.addEventListener('mouseup', mouseup, false);
 	}, false);
@@ -54,6 +55,7 @@ GUI.Slider = function(numberController, min, max, step, initValue) {
 	var mouseup = function(e) { 
 		_this.domElement.setAttribute('class', 'guidat-slider-bg');
 		_this.fg.setAttribute('class', 'guidat-slider-fg');
+		numberController.domElement.className = numberController.domElement.className.replace(' active', '');
 		clicked = false;			
 		if (numberController.finishChangeFunction != null) {
 			numberController.finishChangeFunction.call(this, numberController.getValue());
diff --git a/gui.css b/gui.css
index db24012..5543fd5 100644
--- a/gui.css
+++ b/gui.css
@@ -86,7 +86,8 @@ a.guidat-toggle:hover {
 	float: right;
 }
 
-.guidat-controller input:hover { 
+.guidat-controller input:hover.
+.guidat-controller.number.active { 
 	background-color: #444;
 }
 

From 01156d55134fd67720dd21ad532bfafe79feacdb Mon Sep 17 00:00:00 2001
From: Jono Brandel 
Date: Fri, 11 Feb 2011 10:46:40 -0800
Subject: [PATCH 6/7] updated FunctionController.onFire to be after .fire

---
 controllers/controller.function.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/controllers/controller.function.js b/controllers/controller.function.js
index ee0b831..94e5427 100644
--- a/controllers/controller.function.js
+++ b/controllers/controller.function.js
@@ -20,10 +20,10 @@ GUI.FunctionController = function() {
 	}
 	
 	this.fire = function() {
+		_this.object[_this.propertyName].call(_this.object);
 		if (fireFunction != null) {
 			fireFunction.call(this);
 		}
-		_this.object[_this.propertyName].call(_this.object);
 	};
 	
 };

From fe1597a19b6a65a0182cf9997e3367e94d0ff4d9 Mon Sep 17 00:00:00 2001
From: Jono Brandel 
Date: Fri, 11 Feb 2011 11:18:40 -0800
Subject: [PATCH 7/7] cleaning up

---
 controllers/slider.js | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/controllers/slider.js b/controllers/slider.js
index 2243a92..c7cec99 100644
--- a/controllers/slider.js
+++ b/controllers/slider.js
@@ -1,8 +1,18 @@
 GUI.Slider = function(numberController, min, max, step, initValue) {
-    
+
     var clicked = false;
     var _this = this;
 
+    var x, px;
+
+    this.domElement = document.createElement('div');
+    this.domElement.setAttribute('class', 'guidat-slider-bg');
+
+    this.fg = document.createElement('div');
+    this.fg.setAttribute('class', 'guidat-slider-fg');
+
+    this.domElement.appendChild(this.fg);
+    
     var onDrag = function(e) {
         if (!clicked) return;
         var pos = findPos(_this.domElement);
@@ -32,16 +42,6 @@ GUI.Slider = function(numberController, min, max, step, initValue) {
         document.removeEventListener('mouseup', mouseup, false);
     };
 
-    var x, px;
-
-    this.domElement = document.createElement('div');
-    this.domElement.setAttribute('class', 'guidat-slider-bg');
-
-    this.fg = document.createElement('div');
-    this.fg.setAttribute('class', 'guidat-slider-fg');
-
-    this.domElement.appendChild(this.fg);
-
     var findPos = function(obj) {
         var curleft = 0, curtop = 0;
         if (obj.offsetParent) {