[f-spot/icon-view-cleanup: 11/24] Factor grid drawing code out of IconView to CellGridView



commit 4147234fd32974c4de43deeb7db45b03d221cab5
Author: Mike Gemünde <mike gemuende de>
Date:   Fri Aug 13 19:24:56 2010 +0200

    Factor grid drawing code out of IconView to CellGridView

 src/Clients/MainApp/FSpot.Widgets/CellGridView.cs  |  579 +++++++++++++++++++
 src/Clients/MainApp/FSpot.Widgets/IconView.cs      |  580 +++++---------------
 .../MainApp/FSpot.Widgets/ScalingIconView.cs       |    4 +-
 src/Clients/MainApp/FSpot.Widgets/TrayView.cs      |    4 +-
 src/Clients/MainApp/MainApp.csproj                 |   19 +-
 src/Clients/MainApp/Makefile.am                    |    1 +
 src/Core/FSpot.Core/FSpot.Core.csproj              |   10 +-
 7 files changed, 752 insertions(+), 445 deletions(-)
---
diff --git a/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs b/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs
new file mode 100644
index 0000000..9805ef3
--- /dev/null
+++ b/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs
@@ -0,0 +1,579 @@
+/*
+ * CellGridView.cs
+ *
+ * Author(s)
+ *  Etore Perazzoli
+ *  Larry Ewing <lewing novell com>
+ *  Stephane Delcroix <stephane delcroix org>
+ *  Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+
+using Gtk;
+using Gdk;
+
+using Hyena;
+
+
+namespace FSpot.Widgets
+{
+    /// <summary>
+    ///    This class provides the base functionality for displaying cells in a grid. The
+    ///    paramters to set up the grid are gathered by abstract properties which must be
+    ///    implemented by a subclass.
+    /// </summary>
+    public abstract class CellGridView : Gtk.Layout
+    {
+
+#region Constructors
+
+        public CellGridView (IntPtr raw) : base (raw)
+        {
+        }
+
+        public CellGridView () : base (null, null)
+        {
+        }
+
+#endregion
+
+#region Abstract Layout Description
+
+        /// <summary>
+        ///    Must return the width which each cell should have.
+        /// </summary>
+        protected abstract int CellWidth { get; }
+
+        /// <summary>
+        ///    Must return the height which each cell should have.
+        /// </summary>
+        protected abstract int CellHeight { get; }
+
+        /// <summary>
+        ///    Must return the number of cells which should be displayed.
+        /// </summary>
+        protected abstract int CellCount { get; }
+
+        /// <summary>
+        ///    Must return the number of columns which are allowed at most, or
+        ///    -1 if all number of columns are allowed.
+        /// </summary>
+        protected abstract int MaxColumns { get; }
+
+        /// <summary>
+        ///    The size of the border. The border is skipped at left, right, top
+        ///    and bottom for drawing.
+        /// </summary>
+        protected abstract int BorderSize { get; }
+
+#endregion
+
+#region Abstract Drawing Functions
+
+        /// <summary>
+        ///   The function is called to draw a Cell.
+        /// </summary>
+        protected abstract void DrawCell (int cell_num, Gdk.Rectangle area);
+
+        /// <summary>
+        ///    The function is called to preload a cell.
+        /// </summary>
+        protected abstract void PreloadCell (int cell_num);
+
+#endregion
+
+#region Private Layout Values
+
+        /// <summary>
+        ///    The number of cells per row (columns).
+        /// </summary>
+        protected int cells_per_row;
+
+        /// <summary>
+        ///    The width of each cell. It is set, when the layout is updated. The
+        ///    property <see cref="CellWidth"/> is only used when the layout is updated.
+        /// </summary>
+        protected int cell_width;
+
+        /// <summary>
+        ///    The height of each cell. It is set, when the layout is updated. The
+        ///    property <see cref="CellHeight"/> is only used when the layout is updated.
+        /// </summary>
+        protected int cell_height;
+
+        /// <summary>
+        ///    The total number of cells the layout is computed with. It is set, when the
+        ///    layout is updated. The property <see cref="CellCount"/> is only used when
+        ///    the layout is updated.
+        /// </summary>
+        private int cell_count;
+
+        /// <summary>
+        ///    The border size the current layout is computed with. It is set, when the layout
+        ///    is updated. The property <see cref="BorderSize"/> is only used when the layout is
+        ///    updated.
+        /// </summary>
+        private int border_size;
+
+        /// <summary>
+        ///    Holds the number of rows which are displayed at once regarded to the current
+        ///    size of the widget.
+        /// </summary>
+        private int displayed_rows;
+
+        /// <summary>
+        ///    The number of rows which are needed to display all cells.
+        /// </summary>
+        private int total_rows;
+
+
+        /* preserve the scroll postion when possible */
+        private bool scroll;
+        private double scroll_value;
+        // suppress scroll is currently not used. where do we need it?
+        private bool suppress_scroll = false;
+
+#endregion
+
+#region Public Layout Properties
+
+        /// <summary>
+        ///    The number of visible rows for the current widget size.
+        /// </summary>
+        public int VisibleRows {
+            get { return displayed_rows; }
+        }
+
+        /// <summary>
+        ///    The number of visible colums for the current widget size.
+        /// </summary>
+        public int VisibleColums {
+            get { return cells_per_row; }
+        }
+
+#endregion
+
+#region Public Methods
+
+        public int CellAtPosition (int x, int y)
+        {
+            return CellAtPosition (x, y, true, false);
+        }
+
+        public int CellAtPosition (int x, int y, bool crop_visible, bool include_border)
+        {
+            //if (collection == null)
+            //    return -1;
+
+            if (crop_visible
+                && ((y < (int)Vadjustment.Value || y > (int)Vadjustment.Value + Allocation.Height)
+                || (x < (int)Hadjustment.Value || x > (int)Hadjustment.Value + Allocation.Width)))
+                return -1;
+
+            if (x < border_size || x >= border_size + cells_per_row * cell_width)
+                return -1;
+
+            if (y < border_size || y >= border_size + (cell_count / cells_per_row + 1) * cell_height)
+                return -1;
+
+            int column = (int) ((x - border_size) / cell_width);
+            int row = (int) ((y - border_size) / cell_height);
+
+            int cell_num = column + row * cells_per_row;
+            if (cell_num >= cell_count)
+                return -1;
+
+            // TODO: ignore for now
+            // -----------------
+            // check if the click is in the gap between unselected cells
+            /*if (!include_border) {
+                Gdk.Rectangle displayed = CellBounds (cell_num);
+                displayed.Inflate (-cell_border_padding, -cell_border_padding-cell_details);
+                displayed.Offset (-cell_border_padding, -cell_border_padding);
+                if (displayed.Contains (x, y))
+                    return cell_num;
+                else if (selection.Contains (cell_num))
+                    return cell_num;
+                else
+                    return -1;
+            } else
+                return cell_num;*/
+
+            return cell_num;
+        }
+
+        public int TopLeftVisibleCell ()
+        {
+            // TODO: Where does the 8 come from?
+            return CellAtPosition (border_size, (int) (Vadjustment.Value + Allocation.Height * (Vadjustment.Value / Vadjustment.Upper)) + border_size + 8);
+        }
+
+        public void CellPosition (int cell_num, out int x, out int y)
+        {
+            // TODO: compare the values with the ones in GetCellCenter.
+            if (cells_per_row == 0) {
+                x = 0;
+                y = 0;
+                return;
+            }
+
+            int col = cell_num % cells_per_row;
+            int row = cell_num / cells_per_row;
+
+            x = col * cell_width + border_size;
+            y = row * cell_height + border_size;
+        }
+
+        public void CellCenter (int cell_num, out int x, out int y)
+        {
+            // TODO: compare the values with the ones in GetCellPosition.
+            if (cell_num == -1) {
+                x = -1;
+                y = -1;
+            }
+
+            CellPosition (cell_num, out x, out y);
+
+            x += cell_width / 2;
+            y += cell_height / 2;
+        }
+
+        public Gdk.Rectangle CellBounds (int cell_num)
+        {
+            Rectangle bounds;
+
+            CellPosition (cell_num, out bounds.X, out bounds.Y);
+
+            bounds.Width = cell_width;
+            bounds.Height = cell_height;
+
+            return bounds;
+        }
+
+        public void ScrollTo (int cell_num)
+        {
+            ScrollTo (cell_num, true);
+        }
+
+        public void ScrollTo (int cell_num, bool center)
+        {
+            if (!IsRealized)
+                return;
+
+            Adjustment adjustment = Vadjustment;
+            int x;
+            int y;
+
+            CellPosition (cell_num, out x, out y);
+
+            // ????
+            if (y + cell_height > adjustment.Upper) {
+                Log.DebugFormat ("y + cell_height > adjustment.Upper ({0} + {1} > {2})", y, cell_height, adjustment.Upper);
+                UpdateLayout ();
+            }
+
+            int max = (int) (Height - Allocation.Height);
+            if (center) {
+                Log.DebugFormat ("ScrollTo (center): y = {0}, upper = {1}",y + cell_height / 2 - adjustment.PageSize / 2, max);
+                adjustment.Value = Math.Min (y + cell_height / 2 - Allocation.Height / 2, max);
+            } else {
+                Log.DebugFormat ("ScrollTo (      ): y = {0}, upper = {1}",y, max);
+                adjustment.Value = Math.Min (y, max);
+            }
+
+            adjustment.ChangeValue ();
+
+        }
+
+        public void InvalidateCell (int cell_num)
+        {
+            Rectangle cell_area = CellBounds (cell_num);
+
+            // FIXME where are we computing the bounds incorrectly
+            cell_area.Width -= 1;
+            cell_area.Height -= 1;
+
+            Gdk.Rectangle visible =
+                new Gdk.Rectangle ((int) Hadjustment.Value,
+                                   (int) Vadjustment.Value,
+                                   Allocation.Width,
+                                   Allocation.Height);
+
+            if (BinWindow != null && cell_area.Intersect (visible, out cell_area))
+                BinWindow.InvalidateRect (cell_area, false);
+        }
+
+#endregion
+
+#region Event Handlers
+
+        [GLib.ConnectBefore]
+        private void HandleAdjustmentValueChanged (object sender, EventArgs args)
+        {
+            Scroll ();
+        }
+
+#endregion
+
+#region Determine Layout
+
+        protected override void OnSizeAllocated (Gdk.Rectangle allocation)
+        {
+            scroll_value = (Vadjustment.Value)/ (Vadjustment.Upper);
+            scroll = ! suppress_scroll;
+            suppress_scroll = false;
+            UpdateLayout (allocation);
+
+            base.OnSizeAllocated (allocation);
+        }
+
+
+        protected override void OnScrollAdjustmentsSet (Adjustment hadjustment, Adjustment vadjustment)
+        {
+            base.OnScrollAdjustmentsSet (hadjustment, vadjustment);
+
+            if (vadjustment != null)
+                vadjustment.ValueChanged += new EventHandler (HandleAdjustmentValueChanged);
+        }
+
+        protected override bool OnExposeEvent (Gdk.EventExpose args)
+        {
+            foreach (Rectangle area in args.Region.GetRectangles ()) {
+                DrawAllCells (area);
+            }
+            return base.OnExposeEvent (args);
+        }
+
+        private void UpdateLayout ()
+        {
+            UpdateLayout (Allocation);
+        }
+
+        private void UpdateLayout (Gdk.Rectangle allocation)
+        {
+            // get the basic values for the layout ...
+            border_size = BorderSize;
+            cell_width = CellWidth;
+            cell_height = CellHeight;
+            cell_count = CellCount;
+
+            // ... and compute the remaining ones.
+            int available_width = allocation.Width - 2 * border_size;
+            int available_height = allocation.Height - 2 * border_size;
+
+            cells_per_row = Math.Max ((int) (available_width / cell_width), 1);
+
+            cell_width += (available_width - cells_per_row * cell_width) / cells_per_row;
+
+            displayed_rows = (int) Math.Max (available_height / cell_height, 1);
+
+            total_rows = cell_count / cells_per_row;
+            if (cell_count % cells_per_row != 0)
+                total_rows ++;
+
+            int height = total_rows * cell_height + 2 * border_size;
+
+            Vadjustment.StepIncrement = cell_height;
+            int x = (int)(Hadjustment.Value);
+            int y = (int)(height * scroll_value);
+            SetSize (x, y, (int) allocation.Width, (int) height);
+        }
+
+        private void SetSize (int x, int y, int width, int height)
+        {
+            Hadjustment.Upper = System.Math.Max (Allocation.Width, width);
+            Vadjustment.Upper = System.Math.Max (Allocation.Height, height);
+
+            bool xchange = scroll && (int)(Hadjustment.Value) != x;
+            bool ychange = scroll && (int)(Vadjustment.Value) != y;
+
+            // reset scroll
+            scroll = false;
+
+            if (IsRealized)
+                BinWindow.FreezeUpdates ();
+
+            if (xchange || ychange) {
+                if (IsRealized)
+                    BinWindow.MoveResize (-x, -y, (int)(Hadjustment.Upper), (int)(Vadjustment.Upper));
+                Vadjustment.Value = y;
+                Hadjustment.Value = x;
+            }
+
+            if (this.Width != Allocation.Width || this.Height != Allocation.Height)
+                SetSize ((uint)Allocation.Width, (uint)height);
+
+            if (xchange || ychange) {
+                Vadjustment.ChangeValue ();
+                Hadjustment.ChangeValue ();
+            }
+
+            if (IsRealized) {
+                BinWindow.ThawUpdates ();
+                BinWindow.ProcessUpdates (true);
+            }
+        }
+
+        private void DrawAllCells (Gdk.Rectangle area)
+        {
+            if (cell_width == 0 || cell_height == 0)
+                return;
+
+            int start_cell_column = Math.Max ((area.X - border_size) / cell_width, 0);
+            int start_cell_row = Math.Max ((area.Y - border_size) / cell_height, 0);
+            int start_cell_num = start_cell_column + start_cell_row * cells_per_row;
+
+            int start_cell_x, cell_y;
+            CellPosition (start_cell_num, out start_cell_x, out cell_y);
+
+            int end_cell_column = Math.Max ((area.X + area.Width - border_size) / cell_width, 0);
+            int end_cell_row = Math.Max ((area.Y + area.Height - border_size) / cell_height, 0);
+
+            int num_rows = end_cell_row - start_cell_row + 1;
+            int num_cols = Math.Min (end_cell_column - start_cell_column + 1, cells_per_row - start_cell_column);
+
+            int i, cell_num;
+
+            for (i = 0, cell_num = start_cell_num; i < num_rows && cell_num < cell_count; i ++) {
+
+                int cell_x = start_cell_x;
+
+                //Log.DebugFormat ("Drawing row {0}", start_cell_row + i);
+                for (int j = 0; j < num_cols && cell_num + j < cell_count; j ++) {
+                    DrawCell (cell_num + j, area);
+                    cell_x += cell_width;
+                }
+
+                cell_y += cell_height;
+                cell_num += cells_per_row;
+            }
+        }
+
+        // The first pixel line that is currently on the screen (i.e. in the current
+        // scroll region).  Used to compute the area that went offscreen in the "changed"
+        // signal handler for the vertical GtkAdjustment.
+        private int y_offset;
+        private int x_offset;
+        private void Scroll ()
+        {
+            int ystep = (int)(Vadjustment.Value - y_offset);
+            int xstep = (int)(Hadjustment.Value - x_offset);
+
+            if (xstep > 0)
+                xstep = Math.Max (xstep, Allocation.Width);
+            else
+                xstep = Math.Min (xstep, -Allocation.Width);
+
+            if (ystep > 0)
+                ystep = Math.Max (ystep, Allocation.Height);
+            else
+                ystep = Math.Min (ystep, -Allocation.Height);
+
+            Gdk.Rectangle area;
+
+            Gdk.Region offscreen = new Gdk.Region ();
+            /*
+            Log.Debug ("step ({0}, {1}) allocation ({2},{3},{4},{5})",
+                    xstep, ystep, Hadjustment.Value, Vadjustment.Value,
+                    Allocation.Width, Allocation.Height);
+            */
+            /*
+            area = new Gdk.Rectangle (Math.Max ((int) (Hadjustment.Value + 4 * xstep), 0),
+                    Math.Max ((int) (Vadjustment.Value + 4 * ystep), 0),
+                    Allocation.Width,
+                    Allocation.Height);
+            offscreen.UnionWithRect (area);
+            area = new Gdk.Rectangle (Math.Max ((int) (Hadjustment.Value + 3 * xstep), 0),
+                    Math.Max ((int) (Vadjustment.Value + 3 * ystep), 0),
+                    Allocation.Width,
+                    Allocation.Height);
+            offscreen.UnionWithRect (area);
+            */
+            area = new Gdk.Rectangle (Math.Max ((int) (Hadjustment.Value + 2 * xstep), 0),
+                    Math.Max ((int) (Vadjustment.Value + 2 * ystep), 0),
+                    Allocation.Width,
+                    Allocation.Height);
+            offscreen.UnionWithRect (area);
+            area = new Gdk.Rectangle (Math.Max ((int) (Hadjustment.Value + xstep), 0),
+                    Math.Max ((int) (Vadjustment.Value + ystep), 0),
+                    Allocation.Width,
+                    Allocation.Height);
+            offscreen.UnionWithRect (area);
+            area = new Gdk.Rectangle ((int) Hadjustment.Value,
+                    (int) Vadjustment.Value,
+                    Allocation.Width,
+                    Allocation.Height);
+
+            // always load the onscreen area last to make sure it
+            // is first in the loading
+            Gdk.Region onscreen = Gdk.Region.Rectangle (area);
+            offscreen.Subtract (onscreen);
+
+            PreloadRegion (offscreen, ystep);
+            Preload (area, false);
+
+            y_offset = (int) Vadjustment.Value;
+            x_offset = (int) Hadjustment.Value;
+        }
+
+        private void PreloadRegion (Gdk.Region region, int step)
+        {
+            Gdk.Rectangle [] rects = region.GetRectangles ();
+
+            if (step < 0)
+                System.Array.Reverse (rects);
+
+            foreach (Gdk.Rectangle preload in rects) {
+                Preload (preload, false);
+            }
+        }
+
+        private void Preload (Gdk.Rectangle area, bool back)
+        {
+            if (cells_per_row ==0)
+                return;
+
+            int start_cell_column = Math.Max ((area.X - border_size) / cell_width, 0);
+            int start_cell_row = Math.Max ((area.Y - border_size) / cell_height, 0);
+            int start_cell_num = start_cell_column + start_cell_row * cells_per_row;
+
+            int end_cell_column = Math.Max ((area.X + area.Width - border_size) / cell_width, 0);
+            int end_cell_row = Math.Max ((area.Y + area.Height - border_size) / cell_height, 0);
+
+            int i;
+
+            int cols = end_cell_column - start_cell_column + 1;
+            int rows = end_cell_row - start_cell_row + 1;
+            int len = rows * cols;
+            int scell = start_cell_num;
+            int ecell = scell + len;
+            if (scell > cell_count - len) {
+                ecell = cell_count;
+                scell = System.Math.Max (0, scell - len);
+            } else
+                ecell = scell + len;
+
+            int mid = (ecell - scell) / 2;
+            for (i = 0; i < mid; i++) {
+
+                // The order of Preloading is kept from the previous version, because it provides
+                // smooth appearance (alternating for begin and end of the viewport) of the cells.
+                // Maybe, this can be done better in a subclass ? (e.g. by calling a PreloadCells
+                // with an Array/Enumeration of all cells to be preloaded, or with lower and upper
+                // bound of cells to be preloaded)
+                int cell = back ? ecell - i - 1 : scell + mid + i;
+                PreloadCell (cell);
+
+                cell = back ? scell + i : scell + mid - i - 1;
+                PreloadCell (cell);
+            }
+        }
+
+#endregion
+
+    }
+}
+
diff --git a/src/Clients/MainApp/FSpot.Widgets/IconView.cs b/src/Clients/MainApp/FSpot.Widgets/IconView.cs
index fbbcce1..a5a9171 100644
--- a/src/Clients/MainApp/FSpot.Widgets/IconView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/IconView.cs
@@ -34,73 +34,141 @@ namespace FSpot.Widgets
         }
     }
 
-	public class IconView : Gtk.Layout {
+    public delegate void StartDragHandler (object o, StartDragArgs args);
+
+
+	public class IconView : CellGridView
+    {
 
 		// Public properties.
 		FSpot.PixbufCache cache;
 
-		/* preserve the scroll postion when possible */
-		private bool scroll;
-		private double scroll_value;
+#region Public Events
 
-		/* suppress it sometimes */
-		bool suppress_scroll = false;
+        // Public events.
+        public event EventHandler<BrowsableEventArgs> DoubleClicked;
+        public event EventHandler ZoomChanged;
+        public event StartDragHandler StartDrag;
 
-		// Zooming factor.
-		protected const double ZOOM_FACTOR = 1.2;
+#endregion
 
-		/* Width of the thumbnails. */
-		protected int thumbnail_width = 128;
-		protected const int MAX_THUMBNAIL_WIDTH = 256;
-		protected const int MIN_THUMBNAIL_WIDTH = 64;
-		public int ThumbnailWidth {
-			get {
-				return thumbnail_width;
-			}
-			set {
-				value = Math.Min(value, MAX_THUMBNAIL_WIDTH);
-				value = Math.Max(value, MIN_THUMBNAIL_WIDTH);
+#region Zooming and Thumbnail Size
 
-				if (thumbnail_width != value) {
-					thumbnail_width = value;
-					QueueResize ();
+        // fixed constants
+        protected const double ZOOM_FACTOR = 1.2;
+        protected const int MAX_THUMBNAIL_WIDTH = 256;
+        protected const int MIN_THUMBNAIL_WIDTH = 64;
 
-					if (ZoomChanged != null)
-						ZoomChanged (this, System.EventArgs.Empty);
-				}
-			}
-		}
+        // current with of the thumbnails. (height is calculated)
+        private int thumbnail_width = 128;
 
-		public double Zoom {
-			get {
-				return ((double)(ThumbnailWidth - MIN_THUMBNAIL_WIDTH) / (double)(MAX_THUMBNAIL_WIDTH - MIN_THUMBNAIL_WIDTH));
-			}
-			set {
-				ThumbnailWidth = (int) ((value) * (MAX_THUMBNAIL_WIDTH - MIN_THUMBNAIL_WIDTH)) + MIN_THUMBNAIL_WIDTH;
-			}
-		}
+        // current ratio of thumbnail width and height
+        private double thumbnail_ratio = 4.0 / 3.0;
 
-		protected double thumbnail_ratio = 4.0 / 3.0;
-		public double ThumbnailRatio {
-			get {
-				return thumbnail_ratio;
-			}
-			set {
-				thumbnail_ratio = value;
-				QueueResize ();
-			}
-		}
+        public int ThumbnailWidth {
+            get { return thumbnail_width; }
+            set {
+                value = Math.Min(value, MAX_THUMBNAIL_WIDTH);
+                value = Math.Max(value, MIN_THUMBNAIL_WIDTH);
+
+                if (thumbnail_width != value) {
+                    thumbnail_width = value;
+                    QueueResize ();
+
+                    if (ZoomChanged != null)
+                        ZoomChanged (this, System.EventArgs.Empty);
+                }
+            }
+        }
+
+        public double Zoom {
+            get {
+                return ((double)(ThumbnailWidth - MIN_THUMBNAIL_WIDTH) / (double)(MAX_THUMBNAIL_WIDTH - MIN_THUMBNAIL_WIDTH));
+            }
+            set {
+                ThumbnailWidth = (int) ((value) * (MAX_THUMBNAIL_WIDTH - MIN_THUMBNAIL_WIDTH)) + MIN_THUMBNAIL_WIDTH;
+            }
+        }
+
+        public double ThumbnailRatio {
+            get { return thumbnail_ratio; }
+            set {
+                thumbnail_ratio = value;
+                QueueResize ();
+            }
+        }
+
+        public int ThumbnailHeight {
+            get { return (int) Math.Round ((double) thumbnail_width / ThumbnailRatio); }
+        }
+
+
+        public void ZoomIn ()
+        {
+            ThumbnailWidth = (int) (ThumbnailWidth * ZOOM_FACTOR);
+        }
+
+        public void ZoomOut ()
+        {
+            ThumbnailWidth = (int) (ThumbnailWidth / ZOOM_FACTOR);
+        }
+
+#endregion
+
+#region Implement base class layout properties
+
+        protected override int CellCount {
+            get {
+                if (collection == null)
+                    return 0;
+
+                return collection.Count;
+            }
+        }
+
+        protected override int CellHeight {
+            get {
+                int cell_height = ThumbnailHeight + 2 * cell_border_width;
+
+                cell_details = 0;
+
+                if (DisplayTags || DisplayDates || DisplayFilenames)
+                    cell_details += tag_icon_vspacing;
+    
+                if (DisplayTags)
+                    cell_details += tag_icon_size;
+
+                if (DisplayDates && Style != null) {
+                    cell_details += Style.FontDescription.MeasureTextHeight (PangoContext);
+                }
+    
+                if (DisplayFilenames && Style != null) {
+                    cell_details += Style.FontDescription.MeasureTextHeight (PangoContext);
+                }
+
+                cell_height += cell_details;
+
+                return cell_height;
+            }
+        }
+
+        protected override int CellWidth {
+            get { return ThumbnailWidth + 2 * cell_border_width; }
+        }
+
+        protected override int MaxColumns {
+            get { return -1; }
+        }
+
+        protected override int BorderSize {
+            get { return BORDER_SIZE; }
+        }
+
+#endregion
 
-		public int ThumbnailHeight {
-			get {
-				return (int) Math.Round ((double) thumbnail_width / ThumbnailRatio);
-			}
-		}
 
 		public FSpot.PixbufCache Cache {
-			get {
-				return cache;
-			}
+			get { return cache; }
 		}
 
 		private bool display_tags = true;
@@ -118,7 +186,7 @@ namespace FSpot.Widgets
 		private bool display_dates = true;
 		public bool DisplayDates {
 			get {
-				if (cell_width > 100)
+				if (CellWidth > 100)
 					return display_dates;
 				else
 					return false;
@@ -144,7 +212,7 @@ namespace FSpot.Widgets
 		private bool display_ratings = true;
 		public bool DisplayRatings {
 			get {
-				if (cell_width > 100)
+				if (CellWidth > 100)
 					return display_ratings;
 				else
 					return false;
@@ -178,17 +246,7 @@ namespace FSpot.Widgets
 		protected int tag_icon_vspacing = 3;
 
 		// Various other layout values.
-		protected int cells_per_row;
-		protected int cell_width;
-		protected int cell_height;
 		protected int cell_details;
-		protected int displayed_rows; //for pgUp pgDn support
-
-		// The first pixel line that is currently on the screen (i.e. in the current
-		// scroll region).  Used to compute the area that went offscreen in the "changed"
-		// signal handler for the vertical GtkAdjustment.
-		private int y_offset;
-		private int x_offset;
 
 		// Focus Handling
 		private int real_focus_cell;
@@ -207,22 +265,14 @@ namespace FSpot.Widgets
 			}
 		}
 
-		// Public events.
-		public event EventHandler<BrowsableEventArgs> DoubleClicked;
-		public event EventHandler ZoomChanged;
-		public delegate void StartDragHandler (object o, StartDragArgs args);
-		public event StartDragHandler StartDrag;
-
 		// Public API.
 		public IconView (IntPtr raw) : base (raw) {}
 
-		protected IconView () : base (null, null)
+		protected IconView () : base ()
 		{
 			cache = new FSpot.PixbufCache ();
 			cache.OnPixbufLoaded += HandlePixbufLoaded;
 
-			ScrollAdjustmentsSet += new ScrollAdjustmentsSetHandler (HandleScrollAdjustmentsSet);
-
 			ButtonPressEvent += new ButtonPressEventHandler (HandleButtonPressEvent);
 			ButtonReleaseEvent += new ButtonReleaseEventHandler (HandleButtonReleaseEvent);
 			KeyPressEvent += new KeyPressEventHandler (HandleKeyPressEvent);
@@ -240,8 +290,6 @@ namespace FSpot.Widgets
 				| (int) EventMask.ButtonReleaseMask);
 
 			CanFocus = true;
-
-			//FSpot.Global.ModifyColors (this);
 		}
 
 		public IconView (IBrowsableCollection collection) : this ()
@@ -269,7 +317,7 @@ namespace FSpot.Widgets
 		{
 			// FIXME we should probably try to merge the selection forward
 			// but it needs some thought to be efficient.
-			suppress_scroll = true;
+			//suppress_scroll = true;
 			QueueResize ();
 		}
 
@@ -643,72 +691,6 @@ namespace FSpot.Widgets
 			InvalidateCell (thumbnail_num);
 		}
 
-		// Cell Geometry
-		public int CellAtPosition (int x, int y)
-		{
-			return CellAtPosition (x, y, true, false);
-		}
-
-		public int CellAtPosition (int x, int y, bool crop_visible, bool include_border)
-		{
-			if (collection == null)
-				return -1;
-
-			if (crop_visible
-			    && ((y < (int)Vadjustment.Value || y > (int)Vadjustment.Value + Allocation.Height)
-				|| (x < (int)Hadjustment.Value || x > (int)Hadjustment.Value + Allocation.Width)))
-				return -1;
-
-			if (x < BORDER_SIZE || x >= BORDER_SIZE + cells_per_row * cell_width)
-				return -1;
-			if (y < BORDER_SIZE || y >= BORDER_SIZE + (collection.Count / cells_per_row + 1) * cell_height)
-				return -1;
-
-			int column = (int) ((x - BORDER_SIZE) / cell_width);
-			int row = (int) ((y - BORDER_SIZE) / cell_height);
-			int cell_num = column + row * cells_per_row;
-			if (cell_num >= collection.Count)
-				return -1;
-
-			// check if the click is in the gap between unselected cells
-			if (!include_border) {
-				Gdk.Rectangle displayed = CellBounds (cell_num);
-				displayed.Inflate (-cell_border_padding, -cell_border_padding-cell_details);
-				displayed.Offset (-cell_border_padding, -cell_border_padding);
-				if (displayed.Contains (x, y))
-					return cell_num;
-				else if (selection.Contains (cell_num))
-					return cell_num;
-				else
-					return -1;
-			} else
-				return cell_num;
-		}
-
-		public int TopLeftVisibleCell ()
-		{
-			//return CellAtPosition(BORDER_SIZE, (int)Vadjustment.Value + BORDER_SIZE + 8);
-			return CellAtPosition(BORDER_SIZE, (int) (Vadjustment.Value + Allocation.Height * (Vadjustment.Value / Vadjustment.Upper)) + BORDER_SIZE + 8);
-		}
-
-		public void GetCellCenter (int cell_num, out int x, out int y)
-		{
-			if (cell_num == -1) {
-				x = -1;
-				y = -1;
-			}
-
-			x = BORDER_SIZE + (cell_num % cells_per_row) * cell_width + cell_width / 2;
-			y = BORDER_SIZE + (cell_num / cells_per_row) * cell_height + cell_height / 2;
-		}
-
-		public void GetCellSize (int cell_num, out int w, out int h)
-		{
-			// Trivial for now.
-			w = cell_width;
-			h = cell_height;
-		}
-
 
 		// Private utility methods.
 		public void SelectAllCells ()
@@ -717,7 +699,7 @@ namespace FSpot.Widgets
 		}
 
 		// Layout and drawing.
-		protected virtual void UpdateLayout ()
+/*		protected virtual void UpdateLayout ()
 		{
 			UpdateLayout (Allocation);
 		}
@@ -807,7 +789,7 @@ namespace FSpot.Widgets
 				BinWindow.ThawUpdates ();
 				BinWindow.ProcessUpdates (true);
 			}
-		}
+		}*/
 
 		int ThrobExpansion (int cell, bool selected)
 		{
@@ -833,7 +815,7 @@ namespace FSpot.Widgets
 
 		System.Collections.Hashtable date_layouts = new Hashtable ();
 		// FIXME Cache the GCs?
-		private void DrawCell (int thumbnail_num, Gdk.Rectangle area)
+		protected override void DrawCell (int thumbnail_num, Gdk.Rectangle area)
 		{
 			Gdk.Rectangle bounds = CellBounds (thumbnail_num);
 
@@ -969,7 +951,7 @@ namespace FSpot.Widgets
 			if (DisplayDates) {
 				string date;
 				try {
-					if (cell_width > 200) {
+					if (CellWidth > 200) {
 						date = photo.Time.ToString ();
 					} else {
 						date = photo.Time.ToShortDateString ();
@@ -1083,205 +1065,14 @@ namespace FSpot.Widgets
 
 		}
 
-		private void DrawAllCells (Gdk.Rectangle area)
-		{
-			if (cell_width == 0 || cell_height == 0)
-				return;
-
-			int start_cell_column = Math.Max ((area.X - BORDER_SIZE) / cell_width, 0);
-			int start_cell_row = Math.Max ((area.Y - BORDER_SIZE) / cell_height, 0);
-			int start_cell_num = start_cell_column + start_cell_row * cells_per_row;
+        protected override void PreloadCell (int cell_num)
+        {
+            var photo = collection [cell_num];
+            var entry = cache.Lookup (photo.DefaultVersion.Uri);
 
-			int start_cell_x, cell_y;
-			GetCellPosition (start_cell_num, out start_cell_x, out cell_y);
-
-			int end_cell_column = Math.Max ((area.X + area.Width - BORDER_SIZE) / cell_width, 0);
-			int end_cell_row = Math.Max ((area.Y + area.Height - BORDER_SIZE) / cell_height, 0);
-
-			int num_rows = end_cell_row - start_cell_row + 1;
-			int num_cols = Math.Min (end_cell_column - start_cell_column + 1,
-					cells_per_row - start_cell_column);
-
-			int i, cell_num;
-			//Preload (area, false);
-
-			if (collection == null)
-				return;
-
-			for (i = 0, cell_num = start_cell_num;
-			     i < num_rows && cell_num < collection.Count;
-			     i ++) {
-				int cell_x = start_cell_x;
-
-				//Log.Debug ("Drawing row {0}", start_cell_row + i);
-				for (int j = 0; j < num_cols && cell_num + j < collection.Count; j ++) {
-					DrawCell (cell_num + j, area);
-					cell_x += cell_width;
-				}
-
-				cell_y += cell_height;
-				cell_num += cells_per_row;
-			}
-
-			// draw dragging selection
-			if (isRectSelection) {
-				Gdk.Rectangle inter;
-				if (area.Intersect (rect_select, out inter)) {
-					Cairo.Context cairo_g = CairoHelper.Create (BinWindow);
-					Gdk.Color col = Style.Background(StateType.Selected);
-					cairo_g.Color = new Cairo.Color (col.Red/65535.0, col.Green/65535.0, col.Blue/65535.0, 0.5);
-					cairo_g.Rectangle (inter.X, inter.Y, inter.Width, inter.Height);
-					cairo_g.Fill ();
-
-					((IDisposable) cairo_g.Target).Dispose ();
-					((IDisposable) cairo_g).Dispose ();
-				}
-			}
-
-		}
-
-		private void GetCellPosition (int cell_num, out int x, out int y)
-		{
-			if (cells_per_row == 0) {
-				x = 0;
-				y = 0;
-				return;
-			}
-
-			int row = cell_num / cells_per_row;
-			int col = cell_num % cells_per_row;
-
-			x = col * cell_width + BORDER_SIZE;
-			y = row * cell_height + BORDER_SIZE;
-		}
-
-
-		// Scrolling.  We do this in an idle loop so we can catch up if the user scrolls quickly.
-
-		private void Scroll ()
-		{
-			int ystep = (int)(Vadjustment.Value - y_offset);
-			int xstep = (int)(Hadjustment.Value - x_offset);
-
-			if (xstep > 0)
-				xstep = Math.Max (xstep, Allocation.Width);
-			else
-				xstep = Math.Min (xstep, -Allocation.Width);
-
-			if (ystep > 0)
-				ystep = Math.Max (ystep, Allocation.Height);
-			else
-				ystep = Math.Min (ystep, -Allocation.Height);
-
-			Gdk.Rectangle area;
-
-			Gdk.Region offscreen = new Gdk.Region ();
-			/*
-			Log.Debug ("step ({0}, {1}) allocation ({2},{3},{4},{5})",
-					xstep, ystep, Hadjustment.Value, Vadjustment.Value,
-					Allocation.Width, Allocation.Height);
-			*/
-			/*
-			area = new Gdk.Rectangle (Math.Max ((int) (Hadjustment.Value + 4 * xstep), 0),
-					Math.Max ((int) (Vadjustment.Value + 4 * ystep), 0),
-					Allocation.Width,
-					Allocation.Height);
-			offscreen.UnionWithRect (area);
-			area = new Gdk.Rectangle (Math.Max ((int) (Hadjustment.Value + 3 * xstep), 0),
-					Math.Max ((int) (Vadjustment.Value + 3 * ystep), 0),
-					Allocation.Width,
-					Allocation.Height);
-			offscreen.UnionWithRect (area);
-			*/
-			area = new Gdk.Rectangle (Math.Max ((int) (Hadjustment.Value + 2 * xstep), 0),
-					Math.Max ((int) (Vadjustment.Value + 2 * ystep), 0),
-					Allocation.Width,
-					Allocation.Height);
-			offscreen.UnionWithRect (area);
-			area = new Gdk.Rectangle (Math.Max ((int) (Hadjustment.Value + xstep), 0),
-					Math.Max ((int) (Vadjustment.Value + ystep), 0),
-					Allocation.Width,
-					Allocation.Height);
-			offscreen.UnionWithRect (area);
-			area = new Gdk.Rectangle ((int) Hadjustment.Value,
-					(int) Vadjustment.Value,
-					Allocation.Width,
-					Allocation.Height);
-
-			// always load the onscreen area last to make sure it
-			// is first in the loading
-			Gdk.Region onscreen = Gdk.Region.Rectangle (area);
-			offscreen.Subtract (onscreen);
-
-			PreloadRegion (offscreen, ystep);
-			Preload (area, false);
-
-			y_offset = (int) Vadjustment.Value;
-			x_offset = (int) Hadjustment.Value;
-		}
-
-		private void PreloadRegion (Gdk.Region region, int step)
-		{
-			Gdk.Rectangle [] rects = region.GetRectangles ();
-
-			if (step < 0)
-				System.Array.Reverse (rects);
-
-			foreach (Gdk.Rectangle preload in rects) {
-				Preload (preload, false);
-			}
-		}
-
-		private void Preload (Gdk.Rectangle area, bool back)
-		{
-			if (cells_per_row ==0)
-				return;
-
-			int start_cell_column = Math.Max ((area.X - BORDER_SIZE) / cell_width, 0);
-			int start_cell_row = Math.Max ((area.Y - BORDER_SIZE) / cell_height, 0);
-			int start_cell_num = start_cell_column + start_cell_row * cells_per_row;
-
-			int end_cell_column = Math.Max ((area.X + area.Width - BORDER_SIZE) / cell_width, 0);
-			int end_cell_row = Math.Max ((area.Y + area.Height - BORDER_SIZE) / cell_height, 0);
-
-			int i;
-
-			IPhoto photo;
-			FSpot.PixbufCache.CacheEntry entry;
-
-			// Preload the cache with images aroud the expose area
-			// FIXME the preload need to be tuned to the Cache size but this is a resonable start
-
-			int cols = end_cell_column - start_cell_column + 1;
-			int rows = end_cell_row - start_cell_row + 1;
-			int len = rows * cols;
-			int scell = start_cell_num;
-			int ecell = scell + len;
-			if (scell > collection.Count - len) {
-				ecell = collection.Count;
-				scell = System.Math.Max (0, scell - len);
-			} else
-				ecell = scell + len;
-
-			int mid = (ecell - scell) / 2;
-			for (i = 0; i < mid; i++)
-				{
-				int cell = back ? ecell - i - 1 : scell + mid + i;
-
-				photo = collection [cell];
-
-				entry = cache.Lookup (photo.DefaultVersion.Uri);
-				if (entry == null)
-					cache.Request (photo.DefaultVersion.Uri, cell, ThumbnailWidth, ThumbnailHeight);
-
-				cell = back ? scell + i : scell + mid - i - 1;
-				photo = collection [cell];
-
-				entry = cache.Lookup (photo.DefaultVersion.Uri);
-				if (entry == null)
-					cache.Request (photo.DefaultVersion.Uri, cell, ThumbnailWidth, ThumbnailHeight);
-			}
-		}
+            if (entry == null)
+                cache.Request (photo.DefaultVersion.Uri, cell_num, ThumbnailWidth, ThumbnailHeight);
+        }
 
 		//
 		// The throb interface
@@ -1319,52 +1110,10 @@ namespace FSpot.Widgets
 			}
 		}
 
-		public void ScrollTo (int cell_num)
-		{
-			ScrollTo (cell_num, true);
-		}
 
-		public void ScrollTo (int cell_num, bool center)
-		{
-			if (!IsRealized)
-				return;
-
-			Adjustment adjustment = Vadjustment;
-			int x;
-			int y;
-
-			GetCellPosition (cell_num, out x, out y);
-
-			if (y + cell_height > adjustment.Upper)
-				UpdateLayout ();
-
-			if (center)
-				adjustment.Value = y + cell_height / 2 - adjustment.PageSize / 2;
-			else
-				adjustment.Value = y;
-
-			adjustment.ChangeValue ();
-
-		}
-
-		public void ZoomIn ()
-		{
-			ThumbnailWidth = (int) (ThumbnailWidth * ZOOM_FACTOR);
-		}
-
-		public void ZoomOut ()
-		{
-			ThumbnailWidth = (int) (ThumbnailWidth / ZOOM_FACTOR);
-		}
 
 		// Event handlers.
 
-		[GLib.ConnectBefore]
-		private void HandleAdjustmentValueChanged (object sender, EventArgs args)
-		{
-			Scroll ();
-		}
-
 		private void HandlePixbufLoaded (FSpot.PixbufCache cache, FSpot.PixbufCache.CacheEntry entry)
 		{
 			Gdk.Pixbuf result = entry.ShallowCopyPixbuf ();
@@ -1401,35 +1150,6 @@ namespace FSpot.Widgets
 			InvalidateCell (order);
 		}
 
-		public Gdk.Rectangle CellBounds (int cell)
-		{
-			Rectangle bounds;
-			GetCellPosition (cell, out bounds.X, out bounds.Y);
-			bounds.Width = cell_width;
-			bounds.Height = cell_height;
-			return bounds;
-		}
-
-		public void InvalidateCell (int order)
-		{
-			Rectangle cell_area = CellBounds (order);
-			// FIXME where are we computing the bounds incorrectly
-			cell_area.Width -= 1;
-			cell_area.Height -= 1;
-			Gdk.Rectangle visible = new Gdk.Rectangle ((int)Hadjustment.Value,
-					(int)Vadjustment.Value,
-					Allocation.Width,
-					Allocation.Height);
-
-			if (BinWindow != null && cell_area.Intersect (visible, out cell_area))
-				BinWindow.InvalidateRect (cell_area, false);
-		}
-
-		private void HandleScrollAdjustmentsSet (object sender, ScrollAdjustmentsSetArgs args)
-		{
-			if (args.Vadjustment != null)
-				args.Vadjustment.ValueChanged += new EventHandler (HandleAdjustmentValueChanged);
-		}
 
 		private void HandleScrollEvent(object sender, ScrollEventArgs args)
 		{
@@ -1472,22 +1192,14 @@ namespace FSpot.Widgets
 			SetColors ();
 		}
 
-		protected override void OnSizeAllocated (Gdk.Rectangle allocation)
+/*		protected override void OnSizeAllocated (Gdk.Rectangle allocation)
 		{
 			scroll_value = (Vadjustment.Value)/ (Vadjustment.Upper);
 			scroll = !suppress_scroll;
 			suppress_scroll = false;
 			UpdateLayout (allocation);
 			base.OnSizeAllocated (allocation);
-		}
-
-		protected override bool OnExposeEvent (Gdk.EventExpose args)
-		{
-			foreach (Rectangle area in args.Region.GetRectangles ()) {
-				DrawAllCells (area);
-			}
-			return base.OnExposeEvent (args);
-		}
+		}*/
 
 
 		private bool isRectSelection = false;
@@ -1508,7 +1220,7 @@ namespace FSpot.Widgets
 		// and current x/y (get pointer)
 		private void SelectMotion ()
 		{
-			int x2, y2;
+/*			int x2, y2;
 			Gdk.ModifierType mod;
 			Display.GetPointer (out x2, out y2, out mod);
 			GetPointer (out x2, out y2);
@@ -1579,7 +1291,7 @@ namespace FSpot.Widgets
 				rect_select = new Rectangle (start_x, start_y, end_x - start_x, end_y - start_y);
 				BinWindow.InvalidateRect (rect_select, true); // new selection
 				BinWindow.ProcessUpdates (true);
-			}
+			}*/
 		}
 
 		// if scroll is required, a timeout is fired
@@ -1759,13 +1471,13 @@ namespace FSpot.Widgets
 			case Gdk.Key.Down:
 			case Gdk.Key.J:
 			case Gdk.Key.j:
-				FocusCell += cells_per_row;
+				FocusCell += VisibleColums;
 				break;
 			case Gdk.Key.Left:
 			case Gdk.Key.H:
 			case Gdk.Key.h:
 				if (control && shift)
-					FocusCell -= FocusCell % cells_per_row;
+					FocusCell -= FocusCell % VisibleColums;
 				else
 					FocusCell--;
 				break;
@@ -1773,20 +1485,20 @@ namespace FSpot.Widgets
 			case Gdk.Key.L:
 			case Gdk.Key.l:
 				if (control && shift)
-					FocusCell += cells_per_row - (FocusCell % cells_per_row) - 1;
+					FocusCell += VisibleColums - (FocusCell % VisibleColums) - 1;
 				else
 					FocusCell++;
 				break;
 			case Gdk.Key.Up:
 			case Gdk.Key.K:
 			case Gdk.Key.k:
-				FocusCell -= cells_per_row;
+				FocusCell -= VisibleColums;
 				break;
 			case Gdk.Key.Page_Up:
-				FocusCell -= cells_per_row * displayed_rows;
+				FocusCell -= VisibleColums * VisibleRows;
 				break;
 			case Gdk.Key.Page_Down:
-				FocusCell += cells_per_row * displayed_rows;
+				FocusCell += VisibleColums * VisibleRows;
 				break;
 			case Gdk.Key.Home:
 				FocusCell = 0;
diff --git a/src/Clients/MainApp/FSpot.Widgets/ScalingIconView.cs b/src/Clients/MainApp/FSpot.Widgets/ScalingIconView.cs
index 2e43b6a..0e992e7 100644
--- a/src/Clients/MainApp/FSpot.Widgets/ScalingIconView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/ScalingIconView.cs
@@ -17,7 +17,7 @@ namespace FSpot.Widgets {
 		public ScalingIconView () : base () { }
 		public ScalingIconView (IBrowsableCollection collection) : base (collection) { }
 
-		protected override void UpdateLayout ()
+		/*protected override void UpdateLayout ()
 		{
 			int num_thumbnails = collection != null ? collection.Count : 0;
 			cells_per_row = System.Math.Max (num_thumbnails, 1);
@@ -46,6 +46,6 @@ namespace FSpot.Widgets {
 
 			Hadjustment.StepIncrement = cell_width;
 			Hadjustment.Change ();
-		}
+		}*/
 	}
 }
diff --git a/src/Clients/MainApp/FSpot.Widgets/TrayView.cs b/src/Clients/MainApp/FSpot.Widgets/TrayView.cs
index 87c299e..50411c4 100644
--- a/src/Clients/MainApp/FSpot.Widgets/TrayView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/TrayView.cs
@@ -25,7 +25,7 @@ namespace FSpot.Widgets
 			tag_icon_size = 0;
 		}
 
-		protected override void UpdateLayout ()
+/*		protected override void UpdateLayout ()
 		{
 			//DisplayDates = false;
 			//DisplayTags = false;
@@ -51,6 +51,6 @@ namespace FSpot.Widgets
 			}
 
 			//base.UpdateLayout ();
-		}
+		}*/
 	}
 }
diff --git a/src/Clients/MainApp/MainApp.csproj b/src/Clients/MainApp/MainApp.csproj
index 217de78..986c2b2 100644
--- a/src/Clients/MainApp/MainApp.csproj
+++ b/src/Clients/MainApp/MainApp.csproj
@@ -113,7 +113,6 @@
     <Compile Include="FSpot\MainWindow.cs" />
     <Compile Include="FSpot\Photo.cs" />
     <Compile Include="FSpot\PhotoEventArgs.cs" />
-    <Compile Include="FSpot\PhotoList.cs" />
     <Compile Include="FSpot\PhotoLoader.cs" />
     <Compile Include="FSpot\PhotoPopup.cs" />
     <Compile Include="FSpot\PhotoQuery.cs" />
@@ -198,6 +197,8 @@
     <Compile Include="FSpot\TagStore.cs" />
     <Compile Include="FSpot.Database\DbException.cs" />
     <Compile Include="FSpot.Database\DbStore.cs" />
+    <Compile Include="FSpot\PhotoList.cs" />
+    <Compile Include="FSpot.Widgets\CellGridView.cs" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="..\..\..\COPYING">
@@ -286,8 +287,12 @@
     </MonoDevelop>
   </ProjectExtensions>
   <ItemGroup>
-    <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
-    <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <Package>gtk-sharp-2.0</Package>
+    </Reference>
+    <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <Package>gtk-sharp-2.0</Package>
+    </Reference>
     <Reference Include="System.Data" />
     <Reference Include="Mono.Posix" />
     <Reference Include="unique-sharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=22c19d4a5344e615">
@@ -301,7 +306,9 @@
     <Reference Include="System.Xml" />
     <Reference Include="System.Core" />
     <Reference Include="System" />
-    <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <Package>glade-sharp-2.0</Package>
+    </Reference>
     <Reference Include="Mono.Addins.Setup, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
       <Package>mono-addins-setup</Package>
     </Reference>
@@ -313,7 +320,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\lib\gtk-sharp-beans\gtk-sharp-beans.dll</HintPath>
     </Reference>
-    <Reference Include="gnome-sharp, Version=2.24.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <Reference Include="gnome-sharp, Version=2.24.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <Package>gnome-sharp-2.0</Package>
+    </Reference>
     <Reference Include="Mono.Addins.Gui, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
       <Package>mono-addins-gui</Package>
     </Reference>
diff --git a/src/Clients/MainApp/Makefile.am b/src/Clients/MainApp/Makefile.am
index 8796ddd..8e6ef75 100644
--- a/src/Clients/MainApp/Makefile.am
+++ b/src/Clients/MainApp/Makefile.am
@@ -87,6 +87,7 @@ SOURCES =  \
 	FSpot.UI.Dialog/SelectionRatioDialog.cs \
 	FSpot.UI.Dialog/TagSelectionDialog.cs \
 	FSpot.UI.Dialog/ThreadProgressDialog.cs \
+	FSpot.Widgets/CellGridView.cs \
 	FSpot.Widgets/CellRendererTextProgress.cs \
 	FSpot.Widgets/EditorPage.cs \
 	FSpot.Widgets/Filmstrip.cs \
diff --git a/src/Core/FSpot.Core/FSpot.Core.csproj b/src/Core/FSpot.Core/FSpot.Core.csproj
index 7bc3c35..a2f248a 100644
--- a/src/Core/FSpot.Core/FSpot.Core.csproj
+++ b/src/Core/FSpot.Core/FSpot.Core.csproj
@@ -43,6 +43,8 @@
     <Compile Include="FSpot.Core\IPhotoVersion.cs" />
     <Compile Include="FSpot.Core\IPhotoVersionable.cs" />
     <Compile Include="FSpot.Core\FilePhoto.cs" />
+    <Compile Include="FSpot.Core\PhotoSelection.cs" />
+    <Compile Include="FSpot.Core\PhotoList.cs" />
   </ItemGroup>
   <ProjectExtensions>
     <MonoDevelop>
@@ -74,8 +76,12 @@
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
-    <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
-    <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <Package>gtk-sharp-2.0</Package>
+    </Reference>
+    <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+      <Package>gtk-sharp-2.0</Package>
+    </Reference>
     <Reference Include="System.Xml" />
     <Reference Include="Mono.Posix" />
     <Reference Include="System.Core" />



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]