From d1fd4d0a3234789102b6b46869a1bfc9906f336f Mon Sep 17 00:00:00 2001 From: Enrico Zini Date: Wed, 9 Dec 2009 23:53:40 +0000 Subject: [PATCH] Simplified calculations a bit --- src/fisheye.vala | 115 +++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 64 deletions(-) diff --git a/src/fisheye.vala b/src/fisheye.vala index e8a660a..c40c8a7 100644 --- a/src/fisheye.vala +++ b/src/fisheye.vala @@ -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 - * http://citeseer.ist.psu.edu/sarkar92graphical.html. - */ - - /* - * 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 + * http://citeseer.ist.psu.edu/sarkar92graphical.html. + */ + + /* + * 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 -- 2.30.2