Revision: 2194
          http://vexi.svn.sourceforge.net/vexi/?rev=2194&view=rev
Author:   clrg
Date:     2007-09-14 14:57:20 -0700 (Fri, 14 Sep 2007)

Log Message:
-----------
New util widget orderedlist

Modified Paths:
--------------
    trunk/widgets/org.vexi.widgets/src/vexi/util/orderedlist.t

Added Paths:
-----------
    trunk/widgets/org.vexi.widgets/src_vunit/test/util/
    trunk/widgets/org.vexi.widgets/src_vunit/test/util/orderedlist_simple.t

Modified: trunk/widgets/org.vexi.widgets/src/vexi/util/orderedlist.t
===================================================================
--- trunk/widgets/org.vexi.widgets/src/vexi/util/orderedlist.t  2007-09-14 
12:49:31 UTC (rev 2193)
+++ trunk/widgets/org.vexi.widgets/src/vexi/util/orderedlist.t  2007-09-14 
21:57:20 UTC (rev 2194)
@@ -5,9 +5,9 @@
         <author>Charles Goodwin</author>
         <name>Ordered List</name>
         <desc>
-            A list of ordered values that can be iterated over.  When a
-            value is inserted, the order of the list is maintained.  It
-            only maintains one entry for a given value.
+            A list of ordered key:val pairs that can be iterated over.
+            It only maintains one entry for a given key.  The values do
+            not need to be unique, but define the order for iterating.
         </desc>
         <usage>
         </usage>
@@ -28,12 +28,10 @@
     <ui:box>
         
         var count = 0;
-        var keys = [];
+        var vals = [];
+        var keyrefs = {};
         var comp;
         var flag;
-        var hi;
-        var lo;
-        var mid;
         
         /** compares two strings */
         var compString = function(a, b) { return a.toLowerCase() > 
b.toLowerCase(); }
@@ -41,95 +39,97 @@
         /** compares two numbers */
         var compNumber = function(a, b) { return a > b; }
         
-        /** returns true iff a key is already present in the list */
-        thisbox.contains = function(v) {
-            flag = null;
-            lo = 0;
-            hi = count-1;
-            if (lo >= hi) return false;
-            if (keys[lo] == v) { flag = lo; return true; }
-            if (keys[hi] == v) { flag = hi; return true; }
-            if (comp(keys[lo], v) { flag == 0; return false; }
-            if (comp(v, keys[hi]) { flag == count; return false; }
-            mid = vexi.math.ceil(hi/2);
-            // binary search
-            do {
-                // above mid
-                if (comp(v, keys[mid]) lo = mid;
-                // below mid
-                else if (comp(keys[mid], v)) hi = mid;
-                // equal to mid
-                else { flag= mid; return true; }
-                // new mid
-                mid = vexi.math.ceil(lo+((hi-lo)/2));
-            // using ceil, mid will never equal lo
-            } while (hi != mid);
-            
-            flag = hi;    // insertion point
-            return false; // no matches found
+        /** returns true if a key is already present in the list */
+        thisbox.contains = function(v) { return (keyrefs[v] != null); }
+        
+        /** remove any instances of value v from the list */
+        thisbox.remove = function(v) {
+            if (keyrefs[v] != null) {
+                for (var i=0; count>i; i++) {
+                    if (vals[i] == v) {
+                        vals.splice(i, 1);
+                        keyrefs[v] = null;
+                        if (flag != null and flag > i)
+                            flag--;
+                        count--;
+                        return true;
+                    }
+                }
+            } else return false;
         }
         
         /** inserts a value into the correct position in the list */
-        thisbox.insert = function(v) {
+        thisbox.insert = function(v, key) {
+            // no duplicates
+            remove(v);
             // initialize list
             if (count == 0) {
-                comp = (typeof(v) == "string") ? compString : compNumber;
-                keys[0] = v;
+                comp = (typeof(key) == "string") ? compString : compNumber;
+                vals[0] = v;
+                keyrefs[v] = key;
                 count++;
             // attempt insertion
-            } else if (!contains(v)) {
-                keys.splice(flag, 0, v);
+            } else {
+                for (var i=0; count>i; i++) {
+                    if (comp(keyrefs[vals[i]], key)) {
+                        vals.splice(i, 0, v);
+                        keyrefs[v] = key;
+                        if (flag != null and flag > i)
+                            flag++;
+                        count++;
+                        return;
+                    }
+                }
+                vals[count] = v;
+                keyrefs[v] = key;
                 count++;
+                return;
             }
         }
         
-        /** remove any instances of value v from the list */
-        thisbox.remove = function(v) {
-            if (contains(v)) {
-                keys.splice(flag, 1);
-                count--;
-            }
+        /** get the value in the list after the marked value */
+        thisbox.after = function() {
+            return count-1 > flag ? null : vals[flag+1];
         }
         
-        /** get the value in the list after v */
-        thisbox.after = function(v) {
-            if (contains(v))
-                return count-1 > flag ? null : keys[flag+1];
-            return keys[flag+1];
-        }
+        /** get the value in the list before the marked value */
+        thisbox.before = function() { return flag == 0 ? null : vals[flag-1]; }
         
-        /** get the value in the list before v */
-        thisbox.before = function(v) {
-            if (contains(v))
-                return flag == 0 ? null : keys[flag-1];
-            return keys[flag];
-        }
-        
         /** mark at the value nearest to v */
         thisbox.mark = function(v) {
-            if (!contains(v))
-                if (flag)
+            // mark() marks the first
+            if (arguments.length == 0) {
+                flag = 0;
+                return true;
+            // else mark the flag at the given index
+            } if (keyrefs[v] != null) {
+                for (var i=0; count>i; i++) {
+                    if (vals[i] == v) {
+                        flag = i;
+                        return true;
+                    }
+                }
+            // element v not in this list
+            } else return false;
         }
         
         /** returns the currently marked value */
-        thisbox.current = function() {
-            return flag != null : keys[flag] : null;
-        }
+        thisbox.current = function() { return flag != null ? vals[flag] : 
null; }
         
         /** returns the next value after the current mark */
         thisbox.next = function() {
             flag++;
-            if (count > flag) return keys[flag];
+            if (count > flag) return vals[flag];
             flag = null;
-            return null; 
+            return null;
         }
         
         /** returns the next value after the current mark */
         thisbox.back = function() {
             flag--;
-            if (flag >= 0) return keys[flag];
+            if (flag >= 0) return vals[flag];
             flag = null;
-            return null; 
+            return null;
         }
         
     </ui:box>

Added: trunk/widgets/org.vexi.widgets/src_vunit/test/util/orderedlist_simple.t
===================================================================
--- trunk/widgets/org.vexi.widgets/src_vunit/test/util/orderedlist_simple.t     
                        (rev 0)
+++ trunk/widgets/org.vexi.widgets/src_vunit/test/util/orderedlist_simple.t     
2007-09-14 21:57:20 UTC (rev 2194)
@@ -0,0 +1,27 @@
+<vexi xmlns:meta="vexi://meta" xmlns:ui="vexi://ui" xmlns="vexi">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+
+    static.testInsert = function() {
+           var list = .util.orderedlist(vexi.box);
+           var asserteq = .test.vunit..assertEquals;
+           
+           // create ordered list a,b,c
+           list.insert("a", 0);
+        list.insert("c", 2);
+           list.insert("b", 1);
+           
+           list.mark();
+           asserteq("a",list.current());
+           asserteq("b",list.next());
+           asserteq("c",list.next());
+           asserteq(null,list.next());
+       }
+       
+    static.test = function(){ return 
.test.vunit..newTestCase("orderedlist_simple",testInsert);}
+    
+    <ui:box>
+        static.test().run();
+    </ui:box>
+</vexi>
\ No newline at end of file


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to