Simplified calculations a bit
[gregoa/zavai.git] / src / fisheye.vala
index e8a660a9fa060369fbb67e9381c03641619568fb..c40c8a73d24afc3dd400664d234f3c38572208f7 100644 (file)
@@ -40,7 +40,6 @@ public class FisheyeList : Gtk.DrawingArea
        protected int focus_end;
        protected int[] focus_starts;
        protected bool focus_locked;
-       protected int focus_centre;
        protected bool focus_layout_needed;
 
        protected int _focus_size;
@@ -54,16 +53,6 @@ public class FisheyeList : Gtk.DrawingArea
                }
        }
 
-       protected int _distortion_factor;
-       public int distortion_factor {
-               get { return _distortion_factor; }
-               set {
-                       _distortion_factor = value;
-                       focus_layout_needed = true;
-                       queue_draw();
-               }
-       }
-
        protected int _label_column;
        public int label_column {
                get { return _label_column; }
@@ -90,11 +79,9 @@ public class FisheyeList : Gtk.DrawingArea
 
                // Defaults for properties
                focus_size = 20;
-               distortion_factor = 30;
                label_column = 0;
 
                cur_el = 0;
-               focus_centre = 0;
                focus_locked = false;
 
                add_events(Gdk.EventMask.POINTER_MOTION_MASK
@@ -230,10 +217,8 @@ public class FisheyeList : Gtk.DrawingArea
 
        protected int el_y(int idx)
        {
-               // Undistorted Y
-               int undy = idx * allocation.height / label_cache.length;
                // Distorted position
-               int pos = fisheye(undy, focus_centre, _distortion_factor, 0, allocation.height);
+               int pos = fisheye(idx);
                //stderr.printf("%d %f %f\n", idx, undy, pos);
                return pos;
        }
@@ -272,29 +257,18 @@ public class FisheyeList : Gtk.DrawingArea
        {
                if (label_cache.length == 0)
                {
-                       focus_centre = 0;
                        focus_first = 0;
                        focus_end = 0;
                        focus_starts[0] = 0;
                } else {
-                       // Anchor point
-                       focus_centre = cur_el*allocation.height/label_cache.length;
-
                        focus_first = cur_el > _focus_size/2 ? cur_el-_focus_size/2 : 0;
                        focus_end = focus_first + _focus_size;
                        if (focus_end >= label_cache.length) focus_end = label_cache.length;
 
                        // Compute starting positions for all items in focus
-                       for (int idx = focus_first; idx < focus_end; ++idx)
+                       for (int idx = focus_first; idx <= focus_end; ++idx)
                        {
-                               int posprev = idx == 0 ? 0 : el_y(idx-1);
-                               int pos = el_y(idx);
-                               int posnext = idx == label_cache.length-1 ? 1 : el_y(idx+1);
-                               int y0 = (pos+posprev)/2;
-                               int y1 = (pos+posnext)/2;
-
-                               focus_starts[idx - focus_first] = y0;
-                               focus_starts[idx - focus_first + 1] = y1;
+                               focus_starts[idx - focus_first] = el_y(idx);
                        }
                }
                focus_layout_needed = false;
@@ -369,41 +343,54 @@ public class FisheyeList : Gtk.DrawingArea
                }
        }
 
-    /*
-     * The following function is adapted from Prefuse's FisheyeDistortion.java.
-     *
-     * A relevant annotation from Prefuse:
-     *
-     * For more details on this form of transformation, see Manojit Sarkar and 
-     * Marc H. Brown, "Graphical Fisheye Views of Graphs", in Proceedings of 
-     * CHI'92, Human Factors in Computing Systems, p. 83-91, 1992. Available
-     * online at <a href="http://citeseer.ist.psu.edu/sarkar92graphical.html">
-     * http://citeseer.ist.psu.edu/sarkar92graphical.html</a>. 
-     */
-
-    /*
-     * Distorts an item's coordinate.
-     * @param x the undistorted coordinate
-     * @param coordinate of the anchor or focus point
-     * @param d disortion factor
-     * @param min the beginning of the display
-     * @param max the end of the display
-     * @return the distorted coordinate
-     */
-    private int fisheye(int x, int a, int d, int min, int max)
-    {
-        if ( d != 0 ) {
-            bool left = x<a;
-            double v;
-           int m = (left ? a-min : max-a);
-            if ( m == 0 ) m = max-min;
-            v = (double)(x - a).abs() / m;
-            v = (double)(d+1)/(d+(1/v));
-            return (int)Math.round((left?-1:1)*m*v + a);
-        } else {
-            return x;
-        }
-    }
+       /*
+        * The following function is adapted from Prefuse's FisheyeDistortion.java.
+        *
+        * A relevant annotation from Prefuse:
+        *
+        * For more details on this form of transformation, see Manojit Sarkar and 
+        * Marc H. Brown, "Graphical Fisheye Views of Graphs", in Proceedings of 
+        * CHI'92, Human Factors in Computing Systems, p. 83-91, 1992. Available
+        * online at <a href="http://citeseer.ist.psu.edu/sarkar92graphical.html">
+        * http://citeseer.ist.psu.edu/sarkar92graphical.html</a>. 
+        */
+
+       /*
+        * Distorts an item's coordinate.
+        * @param x the undistorted coordinate
+        * @param coordinate of the anchor or focus point
+        * @param d disortion factor
+        * @param min the beginning of the display
+        * @param max the end of the display
+        * @return the distorted coordinate
+        */
+       private int fisheye(int idx)
+       {
+               // Autocompute distortion factor
+               // 20 is the pixel size of the item at centre of focus
+               double d = label_cache.length * 20 / allocation.height;
+               if ( d <= 1 )
+                       return idx * allocation.height / label_cache.length;
+
+               double a = (double)cur_el * allocation.height / label_cache.length;
+               double x = (double)idx * allocation.height / label_cache.length;
+               double max = (double)allocation.height;
+
+               if (idx < cur_el)
+               {
+                       double m = a;
+                       if ( m == 0 ) m = max;
+                       double v = (double)(a - x) / m;
+                       v = (double)(d+1)/(d+(1/v));
+                       return (int)Math.round(a - m*v);
+               } else {
+                       double m = max-a;
+                       if ( m == 0 ) m = max;
+                       double v = (double)(x - a) / m;
+                       v = (double)(d+1)/(d+(1/v));
+                       return (int)Math.round(a + m*v);
+               }
+       }
 }
 
 public class Fisheye : Gtk.Window