[f-spot/icon-view-cleanup: 4/4] Move render code for the thumbnail decorations to own classes
- From: Mike Gemünde <mgemuende src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/icon-view-cleanup: 4/4] Move render code for the thumbnail decorations to own classes
- Date: Mon, 16 Aug 2010 09:08:50 +0000 (UTC)
commit 0c8cff2f16f70358e192e9cda683a9c3371b6695
Author: Mike Gemünde <mike gemuende de>
Date: Sat Aug 14 19:19:35 2010 +0200
Move render code for the thumbnail decorations to own classes
src/Clients/MainApp/FSpot.Widgets/CellGridView.cs | 2 +
src/Clients/MainApp/FSpot.Widgets/IconView.cs | 555 +++++++-------------
.../FSpot.Widgets/ThumbnailCaptionRenderer.cs | 49 ++
.../FSpot.Widgets/ThumbnailDateCaptionRenderer.cs | 91 ++++
.../FSpot.Widgets/ThumbnailDecorationRenderer.cs | 47 ++
.../ThumbnailFilenameCaptionRenderer.cs | 39 ++
.../ThumbnailRatingDecorationRenderer.cs | 62 +++
.../FSpot.Widgets/ThumbnailTagsCaptionRenderer.cs | 123 +++++
.../FSpot.Widgets/ThumbnailTextCaptionRenderer.cs | 73 +++
src/Clients/MainApp/FSpot.Widgets/TrayView.cs | 3 -
src/Clients/MainApp/Makefile.am | 7 +
11 files changed, 677 insertions(+), 374 deletions(-)
---
diff --git a/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs b/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs
index 9805ef3..5e327f0 100644
--- a/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs
@@ -135,6 +135,8 @@ namespace FSpot.Widgets
private double scroll_value;
// suppress scroll is currently not used. where do we need it?
private bool suppress_scroll = false;
+ // Size of the frame that may be selected
+ protected int cell_border_padding = 3;
#endregion
diff --git a/src/Clients/MainApp/FSpot.Widgets/IconView.cs b/src/Clients/MainApp/FSpot.Widgets/IconView.cs
index 3d8eee7..37f55ce 100644
--- a/src/Clients/MainApp/FSpot.Widgets/IconView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/IconView.cs
@@ -1,39 +1,75 @@
/*
-* Widgets/IconView.cs
-*
-* Author(s):
-* Etore Perazzoli
-* Larry Ewing <lewing novell com>
-* Stephane Delcroix <stephane delcroix org>
-*
-* This is free software. See COPYING for details.
-*/
+ * IconView.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 Gtk;
-using Gdk;
using System;
-using System.Reflection;
-using System.Collections;
using System.IO;
+using Gtk;
+using Gdk;
+
using Hyena.Gui;
using FSpot.Core;
using FSpot.Utils;
using FSpot.Platform;
+
namespace FSpot.Widgets
{
- public class IconView : CollectionGridView
+ public class IconView : CollectionGridView
{
- // Public properties.
- FSpot.PixbufCache cache;
+#region Private Fields
+
+ private FSpot.PixbufCache cache;
+
+ private ThumbnailDecorationRenderer rating_renderer = new ThumbnailRatingDecorationRenderer ();
+
+ private ThumbnailCaptionRenderer tag_renderer = new ThumbnailTagsCaptionRenderer ();
+ private ThumbnailCaptionRenderer date_renderer = new ThumbnailDateCaptionRenderer ();
+ private ThumbnailCaptionRenderer filename_renderer = new ThumbnailFilenameCaptionRenderer ();
+
+#endregion
+
+#region Properties
+
+ public FSpot.PixbufCache Cache {
+ get { return cache; }
+ }
+
+#endregion
+
+#region Constructors
+
+ public IconView (IntPtr raw) : base (raw) {}
+
+ public IconView (IBrowsableCollection collection) : base (collection)
+ {
+ cache = new FSpot.PixbufCache ();
+ cache.OnPixbufLoaded += HandlePixbufLoaded;
+
+ Name = "ImageContainer";
+ Collection.ItemsChanged += HandleItemsChanged;
+
+ ScrollEvent += new ScrollEventHandler (HandleScrollEvent);
+
+ Destroyed += HandleDestroyed;
+ }
+
+#endregion
#region Public Events
- // Public events.
public event EventHandler ZoomChanged;
#endregion
@@ -44,6 +80,16 @@ namespace FSpot.Widgets
protected const double ZOOM_FACTOR = 1.2;
protected const int MAX_THUMBNAIL_WIDTH = 256;
protected const int MIN_THUMBNAIL_WIDTH = 64;
+ // size of the border of the whole pane
+ protected const int BORDER_SIZE = 6;
+ protected const int SELECTION_THICKNESS = 5;
+
+ // frame around the whole cell
+ protected const int CELL_BORDER_WIDTH = 10;
+
+ // padding between the thumbnail and the thumbnail caption
+ protected const int CAPTION_PADDING = 6;
+
// current with of the thumbnails. (height is calculated)
private int thumbnail_width = 128;
@@ -88,7 +134,6 @@ namespace FSpot.Widgets
get { return (int) Math.Round ((double) thumbnail_width / ThumbnailRatio); }
}
-
public void ZoomIn ()
{
ThumbnailWidth = (int) (ThumbnailWidth * ZOOM_FACTOR);
@@ -105,32 +150,26 @@ namespace FSpot.Widgets
protected override int CellHeight {
get {
- int cell_height = ThumbnailHeight + 2 * cell_border_width;
-
- cell_details = 0;
+ int cell_height = ThumbnailHeight + 2 * CELL_BORDER_WIDTH;
if (DisplayTags || DisplayDates || DisplayFilenames)
- cell_details += tag_icon_vspacing;
-
+ cell_height += CAPTION_PADDING;
+
if (DisplayTags)
- cell_details += tag_icon_size;
+ cell_height += tag_renderer.GetHeight (this, ThumbnailWidth);
- if (DisplayDates && Style != null) {
- cell_details += Style.FontDescription.MeasureTextHeight (PangoContext);
- }
-
- if (DisplayFilenames && Style != null) {
- cell_details += Style.FontDescription.MeasureTextHeight (PangoContext);
- }
+ if (DisplayDates && Style != null)
+ cell_height += date_renderer.GetHeight (this, ThumbnailWidth);
- cell_height += cell_details;
+ if (DisplayFilenames && Style != null)
+ cell_height += filename_renderer.GetHeight (this, ThumbnailWidth);
return cell_height;
}
}
protected override int CellWidth {
- get { return ThumbnailWidth + 2 * cell_border_width; }
+ get { return ThumbnailWidth + 2 * CELL_BORDER_WIDTH; }
}
protected override int MaxColumns {
@@ -143,11 +182,6 @@ namespace FSpot.Widgets
#endregion
-
- public FSpot.PixbufCache Cache {
- get { return cache; }
- }
-
private bool display_tags = true;
public bool DisplayTags {
get {
@@ -201,46 +235,7 @@ namespace FSpot.Widgets
}
}
- // Size of the frame around the thumbnail.
- protected int cell_border_width = 10;
-
- // Size of the frame that may be selected
- protected int cell_border_padding = 3;
-
- // Border around the scrolled area.
- protected const int BORDER_SIZE = 6;
-
- // Thickness of the outline used to indicate selected items.
- private const int SELECTION_THICKNESS = 5;
-
- // Size of the tag icon in the view.
- protected int tag_icon_size = 16;
-
- // Horizontal spacing between the tag icons
- protected int tag_icon_hspacing = 2;
-
- // Vertical spacing between the thumbnail and additional infos (tags, dates, ...).
- protected int tag_icon_vspacing = 3;
-
- // Various other layout values.
- protected int cell_details;
-
- // Public API.
- public IconView (IntPtr raw) : base (raw) {}
-
- public IconView (IBrowsableCollection collection) : base (collection)
- {
- cache = new FSpot.PixbufCache ();
- cache.OnPixbufLoaded += HandlePixbufLoaded;
-
- Name = "ImageContainer";
- Collection.ItemsChanged += HandleItemsChanged;
-
- ScrollEvent += new ScrollEventHandler(HandleScrollEvent);
-
- Destroyed += HandleDestroyed;
- }
-
+#region Event Handlers
private void HandleItemsChanged (IBrowsableCollection sender, BrowsableEventArgs args)
{
@@ -251,129 +246,76 @@ namespace FSpot.Widgets
}
}
-
- // Updating.
- public void UpdateThumbnail (int thumbnail_num)
- {
- IPhoto photo = Collection [thumbnail_num];
- cache.Remove (photo.DefaultVersion.Uri);
- InvalidateCell (thumbnail_num);
- }
-
-
- // Layout and drawing.
-/* protected virtual void UpdateLayout ()
- {
- UpdateLayout (Allocation);
- }
-
- protected virtual void UpdateLayout (Gdk.Rectangle allocation)
- {
- int available_width = allocation.Width - 2 * BORDER_SIZE;
- int available_height = allocation.Height - 2 * BORDER_SIZE;
- cell_width = ThumbnailWidth + 2 * cell_border_width;
- cell_height = ThumbnailHeight + 2 * cell_border_width;
- cells_per_row = Math.Max ((int) (available_width / cell_width), 1);
- cell_width += (available_width - cells_per_row * cell_width) / cells_per_row;
- 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);
+ private void HandlePixbufLoaded (FSpot.PixbufCache cache, FSpot.PixbufCache.CacheEntry entry)
+ {
+ Gdk.Pixbuf result = entry.ShallowCopyPixbuf ();
+ int order = (int) entry.Data;
+
+ if (result == null)
+ return;
+
+ // We have to do the scaling here rather than on load because we need to preserve the
+ // Pixbuf option iformation to verify the thumbnail validity later
+ int width, height;
+ PixbufUtils.Fit (result, ThumbnailWidth, ThumbnailHeight, false, out width, out height);
+ if (result.Width > width && result.Height > height) {
+ // Log.Debug ("scaling");
+ Gdk.Pixbuf temp = PixbufUtils.ScaleDown (result, width, height);
+ result.Dispose ();
+ result = temp;
+ } else if (result.Width < ThumbnailWidth && result.Height < ThumbnailHeight) {
+ // FIXME this is a workaround to handle images whose actual size is smaller than
+ // the thumbnail size, it needs to be fixed at a different level.
+ Gdk.Pixbuf temp = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, true, 8, ThumbnailWidth, ThumbnailHeight);
+ temp.Fill (0x00000000);
+ result.CopyArea (0, 0,
+ result.Width, result.Height,
+ temp,
+ (temp.Width - result.Width)/ 2,
+ temp.Height - result.Height);
+
+ result.Dispose ();
+ result = temp;
}
- cell_height += cell_details;
-
- displayed_rows = (int)Math.Max (available_height / cell_height, 1);
-
- int num_thumbnails;
- if (collection != null)
- num_thumbnails = collection.Count;
- else
- num_thumbnails = 0;
-
- int num_rows = num_thumbnails / cells_per_row;
- if (num_thumbnails % cells_per_row != 0)
- num_rows ++;
-
- int height = num_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);
- }
-
- void SetSize (int x, int y, int width, int height)
- {
- bool xchange = false;
- bool ychange = false;
-
- Hadjustment.Upper = System.Math.Max (Allocation.Width, width);
- Vadjustment.Upper = System.Math.Max (Allocation.Height, height);
-
- if (scroll) {
- xchange = (int)(Hadjustment.Value) != x;
- ychange = (int)(Vadjustment.Value) != y;
- 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 (scroll)
- scroll = false;
-
- if (this.Width != Allocation.Width || this.Height != Allocation.Height)
- SetSize ((uint)Allocation.Width, (uint)height);
+ cache.Update (entry, result);
+ InvalidateCell (order);
+ }
- if (xchange || ychange) {
- Vadjustment.ChangeValue ();
- Hadjustment.ChangeValue ();
- }
+ private void HandleScrollEvent(object sender, ScrollEventArgs args)
+ {
+ // Activated only by Control + ScrollWheelUp/ScrollWheelDown
+ if (ModifierType.ControlMask != (args.Event.State & ModifierType.ControlMask))
+ return;
+
+ if (args.Event.Direction == ScrollDirection.Up) {
+ ZoomIn ();
+ // stop event from propagating.
+ args.RetVal = true;
+ } else if (args.Event.Direction == ScrollDirection.Down ) {
+ ZoomOut ();
+ args.RetVal = true;
+ }
+ }
- if (IsRealized) {
- BinWindow.ThawUpdates ();
- BinWindow.ProcessUpdates (true);
- }
- }*/
+ private void HandleDestroyed (object sender, System.EventArgs args)
+ {
+ cache.OnPixbufLoaded -= HandlePixbufLoaded;
+ CancelThrob ();
+ }
- int ThrobExpansion (int cell, bool selected)
- {
- int expansion = 0;
- if (cell == throb_cell) {
- double t = throb_state / (double) (throb_state_max - 1);
- double s;
- if (selected)
- s = Math.Cos (-2 * Math.PI * t);
- else
- s = 1 - Math.Cos (-2 * Math.PI * t);
+#endregion
- expansion = (int) (SELECTION_THICKNESS * s);
- } else if (selected) {
- expansion = SELECTION_THICKNESS;
- }
+#region Drawing Methods
- return expansion;
- }
+ // Updating.
+ public void UpdateThumbnail (int thumbnail_num)
+ {
+ IPhoto photo = Collection [thumbnail_num];
+ cache.Remove (photo.DefaultVersion.Uri);
+ InvalidateCell (thumbnail_num);
+ }
- System.Collections.Hashtable date_layouts = new Hashtable ();
// FIXME Cache the GCs?
protected override void DrawPhoto (int cell_num, Rectangle cell_area, Rectangle expose_area, bool selected, bool focussed)
{
@@ -407,7 +349,7 @@ namespace FSpot.Widgets
}
Gdk.Rectangle region = Gdk.Rectangle.Zero;
- Gdk.Rectangle image_bounds = Gdk.Rectangle.Inflate (cell_area, -cell_border_width, -cell_border_width);
+ Gdk.Rectangle image_bounds = Gdk.Rectangle.Inflate (cell_area, -CELL_BORDER_WIDTH, -CELL_BORDER_WIDTH);
int expansion = ThrobExpansion (cell_num, selected);
Gdk.Pixbuf thumbnail = null;
@@ -421,7 +363,7 @@ namespace FSpot.Widgets
true, out region.Width, out region.Height);
region.X = (int) (cell_area.X + (cell_area.Width - region.Width) / 2);
- region.Y = (int) cell_area.Y + ThumbnailHeight - region.Height + cell_border_width;
+ region.Y = (int) cell_area.Y + ThumbnailHeight - region.Height + CELL_BORDER_WIDTH;
if (Math.Abs (region.Width - thumbnail.Width) > 1
&& Math.Abs (region.Height - thumbnail.Height) > 1)
@@ -497,129 +439,38 @@ namespace FSpot.Widgets
if (thumbnail != null) {
thumbnail.Dispose ();
}
- if (DisplayRatings && photo.Rating > 0 && region.X == draw.X && region.X != 0) {
- FSpot.Widgets.RatingSmall rating;
- rating = new FSpot.Widgets.RatingSmall ((int) photo.Rating, false);
- rating.DisplayPixbuf.RenderToDrawable (BinWindow, Style.WhiteGC,
- 0, 0, region.X, region.Y, -1, -1, RgbDither.None, 0, 0);
-
- }
- Gdk.Rectangle layout_bounds = Gdk.Rectangle.Zero;
- if (DisplayDates) {
- string date;
- try {
- if (CellWidth > 200) {
- date = photo.Time.ToString ();
- } else {
- date = photo.Time.ToShortDateString ();
- }
- } catch (Exception) {
- date = String.Empty;
- }
-
- Pango.Layout layout = (Pango.Layout)date_layouts [date];
- if (layout == null) {
- layout = new Pango.Layout (this.PangoContext);
- layout.SetText (date);
- date_layouts [date] = layout;
- }
-
- layout.GetPixelSize (out layout_bounds.Width, out layout_bounds.Height);
-
- layout_bounds.Y = cell_area.Y + cell_area.Height -
- cell_border_width - layout_bounds.Height + tag_icon_vspacing;
- layout_bounds.X = cell_area.X + (cell_area.Width - layout_bounds.Width) / 2;
-
- if (DisplayTags)
- layout_bounds.Y -= tag_icon_size;
-
- if (DisplayFilenames) {
- layout_bounds.Y -= Style.FontDescription.MeasureTextHeight (PangoContext);
- }
-
- if (layout_bounds.Intersect (expose_area, out region)) {
- Style.PaintLayout (Style, BinWindow, cell_state,
- true, expose_area, this, "IconView",
- layout_bounds.X, layout_bounds.Y,
- layout);
- }
- }
-
- if (DisplayFilenames) {
-
- string filename = System.IO.Path.GetFileName (photo.DefaultVersion.Uri.LocalPath);
- Pango.Layout layout = new Pango.Layout (this.PangoContext);
- layout.SetText (filename);
-
- layout.GetPixelSize (out layout_bounds.Width, out layout_bounds.Height);
-
- layout_bounds.Y = cell_area.Y + cell_area.Height - cell_border_width - layout_bounds.Height + tag_icon_vspacing;
- layout_bounds.X = cell_area.X + (cell_area.Width - layout_bounds.Width) / 2;
-
- if (DisplayTags)
- layout_bounds.Y -= tag_icon_size;
-
- if (layout_bounds.Intersect (expose_area, out region)) {
- Style.PaintLayout (Style, BinWindow, cell_state,
- true, expose_area, this, "IconView",
- layout_bounds.X, layout_bounds.Y,
- layout);
- }
-
- }
- if (DisplayTags) {
- Tag [] tags = photo.Tags;
- Gdk.Rectangle tag_bounds;
+ // Render Decorations
+ if (DisplayRatings) {
+ rating_renderer.Render (BinWindow, this, region, expose_area, cell_state, photo);
+ }
- tag_bounds.X = cell_area.X + (cell_area.Width + tag_icon_hspacing - tags.Length * (tag_icon_size + tag_icon_hspacing)) / 2;
- tag_bounds.Y = cell_area.Y + cell_area.Height - cell_border_width - tag_icon_size + tag_icon_vspacing;
- tag_bounds.Width = tag_icon_size;
- tag_bounds.Height = tag_icon_size;
+ // Render Captions
+ Rectangle caption_area = Rectangle.Zero;
+ caption_area.Y = cell_area.Y + CELL_BORDER_WIDTH + ThumbnailHeight + CAPTION_PADDING;
+ caption_area.X = cell_area.X + CELL_BORDER_WIDTH;
+ caption_area.Width = cell_area.Width - 2 * CELL_BORDER_WIDTH;
- foreach (Tag t in tags) {
- if (t == null)
- continue;
+ if (DisplayDates) {
+ caption_area.Height = date_renderer.GetHeight (this, ThumbnailWidth);
+ date_renderer.Render (BinWindow, this, caption_area, expose_area, cell_state, photo);
- Pixbuf icon = t.Icon;
+ caption_area.Y += caption_area.Height;
+ }
- Tag tag_iter = t.Category;
- while (icon == null && tag_iter != App.Instance.Database.Tags.RootCategory && tag_iter != null) {
- icon = tag_iter.Icon;
- tag_iter = tag_iter.Category;
- }
+ if (DisplayFilenames) {
+ caption_area.Height = filename_renderer.GetHeight (this, ThumbnailWidth);
+ filename_renderer.Render (BinWindow, this, caption_area, expose_area, cell_state, photo);
- if (icon == null)
- continue;
-
- if (tag_bounds.Intersect (expose_area, out region)) {
- Pixbuf scaled_icon;
- if (icon.Width == tag_bounds.Width) {
- scaled_icon = icon;
- } else {
- scaled_icon = icon.ScaleSimple (tag_bounds.Width,
- tag_bounds.Height,
- InterpType.Bilinear);
- }
+ caption_area.Y += caption_area.Height;
+ }
- Cms.Profile screen_profile;
- if (FSpot.ColorManagement.Profiles.TryGetValue (Preferences.Get<string> (Preferences.COLOR_MANAGEMENT_DISPLAY_PROFILE), out screen_profile))
- FSpot.ColorManagement.ApplyProfile (scaled_icon, screen_profile);
-
- scaled_icon.RenderToDrawable (BinWindow, Style.WhiteGC,
- region.X - tag_bounds.X,
- region.Y - tag_bounds.Y,
- region.X, region.Y,
- region.Width, region.Height,
- RgbDither.None, region.X, region.Y);
- if (scaled_icon != icon) {
- scaled_icon.Dispose ();
- }
- }
- tag_bounds.X += tag_bounds.Width + tag_icon_hspacing;
- }
- }
+ if (DisplayTags) {
+ caption_area.Height = tag_renderer.GetHeight (this, ThumbnailWidth);
+ tag_renderer.Render (BinWindow, this, caption_area, expose_area, cell_state, photo);
+ caption_area.Y += caption_area.Height;
+ }
}
protected override void PreloadCell (int cell_num)
@@ -631,9 +482,11 @@ namespace FSpot.Widgets
cache.Request (photo.DefaultVersion.Uri, cell_num, ThumbnailWidth, ThumbnailHeight);
}
- //
- // The throb interface
- //
+#endregion
+
+
+#region Throb Interface
+
private uint throb_timer_id;
private int throb_cell = -1;
private int throb_state;
@@ -668,61 +521,26 @@ namespace FSpot.Widgets
}
+ int ThrobExpansion (int cell, bool selected)
+ {
+ int expansion = 0;
+ if (cell == throb_cell) {
+ double t = throb_state / (double) (throb_state_max - 1);
+ double s;
+ if (selected)
+ s = Math.Cos (-2 * Math.PI * t);
+ else
+ s = 1 - Math.Cos (-2 * Math.PI * t);
+
+ expansion = (int) (SELECTION_THICKNESS * s);
+ } else if (selected) {
+ expansion = SELECTION_THICKNESS;
+ }
- // Event handlers.
-
- private void HandlePixbufLoaded (FSpot.PixbufCache cache, FSpot.PixbufCache.CacheEntry entry)
- {
- Gdk.Pixbuf result = entry.ShallowCopyPixbuf ();
- int order = (int) entry.Data;
-
- if (result == null)
- return;
-
- // We have to do the scaling here rather than on load because we need to preserve the
- // Pixbuf option iformation to verify the thumbnail validity later
- int width, height;
- PixbufUtils.Fit (result, ThumbnailWidth, ThumbnailHeight, false, out width, out height);
- if (result.Width > width && result.Height > height) {
- // Log.Debug ("scaling");
- Gdk.Pixbuf temp = PixbufUtils.ScaleDown (result, width, height);
- result.Dispose ();
- result = temp;
- } else if (result.Width < ThumbnailWidth && result.Height < ThumbnailHeight) {
- // FIXME this is a workaround to handle images whose actual size is smaller than
- // the thumbnail size, it needs to be fixed at a different level.
- Gdk.Pixbuf temp = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, true, 8, ThumbnailWidth, ThumbnailHeight);
- temp.Fill (0x00000000);
- result.CopyArea (0, 0,
- result.Width, result.Height,
- temp,
- (temp.Width - result.Width)/ 2,
- temp.Height - result.Height);
-
- result.Dispose ();
- result = temp;
- }
-
- cache.Update (entry, result);
- InvalidateCell (order);
- }
-
-
- private void HandleScrollEvent(object sender, ScrollEventArgs args)
- {
- // Activated only by Control + ScrollWheelUp/ScrollWheelDown
- if (ModifierType.ControlMask != (args.Event.State & ModifierType.ControlMask))
- return;
+ return expansion;
+ }
- if (args.Event.Direction == ScrollDirection.Up) {
- ZoomIn ();
- // stop event from propagating.
- args.RetVal = true;
- } else if (args.Event.Direction == ScrollDirection.Down ) {
- ZoomOut ();
- args.RetVal = true;
- }
- }
+#endregion
private void SetColors ()
{
@@ -749,10 +567,5 @@ namespace FSpot.Widgets
SetColors ();
}
- private void HandleDestroyed (object sender, System.EventArgs args)
- {
- cache.OnPixbufLoaded -= HandlePixbufLoaded;
- CancelThrob ();
- }
}
}
diff --git a/src/Clients/MainApp/FSpot.Widgets/ThumbnailCaptionRenderer.cs b/src/Clients/MainApp/FSpot.Widgets/ThumbnailCaptionRenderer.cs
new file mode 100644
index 0000000..d96e5a1
--- /dev/null
+++ b/src/Clients/MainApp/FSpot.Widgets/ThumbnailCaptionRenderer.cs
@@ -0,0 +1,49 @@
+/*
+ * ThumbnailCaptionRenderer.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+
+using Gtk;
+using Gdk;
+
+using FSpot.Core;
+
+
+namespace FSpot.Widgets
+{
+ /// <summary>
+ /// Renders a caption below a thumbnail. It must compute the height needed for
+ /// the annotation.
+ /// </summary>
+ public abstract class ThumbnailCaptionRenderer
+ {
+
+#region Constructor
+
+ public ThumbnailCaptionRenderer ()
+ {
+ }
+
+#endregion
+
+#region Drawing Methods
+
+ public abstract int GetHeight (Widget widget, int width);
+
+ public abstract void Render (Drawable window,
+ Widget widget,
+ Rectangle cell_area,
+ Rectangle expose_area,
+ StateType cell_state,
+ IPhoto photo);
+
+#endregion
+
+ }
+}
diff --git a/src/Clients/MainApp/FSpot.Widgets/ThumbnailDateCaptionRenderer.cs b/src/Clients/MainApp/FSpot.Widgets/ThumbnailDateCaptionRenderer.cs
new file mode 100644
index 0000000..a8b795d
--- /dev/null
+++ b/src/Clients/MainApp/FSpot.Widgets/ThumbnailDateCaptionRenderer.cs
@@ -0,0 +1,91 @@
+/*
+ * ThumbnailDateCaptionRenderer.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+using System.Collections.Generic;
+
+using Gtk;
+using Gdk;
+
+using Hyena.Gui;
+
+using FSpot.Core;
+
+
+namespace FSpot.Widgets
+{
+ /// <summary>
+ /// Renders a text caption with the date of the photo. This class is not based on
+ /// TextCaptionRenderer, because it uses caching of the dates.
+ /// </summary>
+ public class ThumbnailDateCaptionRenderer : ThumbnailCaptionRenderer
+ {
+
+#region Private Fields
+
+ private Dictionary <string, Pango.Layout> cache = new Dictionary <string, Pango.Layout> ();
+
+#endregion
+
+#region Constructor
+
+ public ThumbnailDateCaptionRenderer ()
+ {
+ }
+
+#endregion
+
+#region Drawing Methods
+
+ public override int GetHeight (Widget widget, int width)
+ {
+ return widget.Style.FontDescription.MeasureTextHeight (widget.PangoContext);
+ }
+
+ public override void Render (Drawable window,
+ Widget widget,
+ Rectangle cell_area,
+ Rectangle expose_area,
+ StateType cell_state,
+ IPhoto photo)
+ {
+ string date_text = null;
+
+ if (cell_area.Width > 200) {
+ date_text = photo.Time.ToString ();
+ } else {
+ date_text = photo.Time.ToShortDateString ();
+ }
+
+ Pango.Layout layout = null;
+ if ( ! cache.TryGetValue (date_text, out layout)) {
+ layout = new Pango.Layout (widget.PangoContext);
+ layout.SetText (date_text);
+
+ cache.Add (date_text, layout);
+ }
+
+ Rectangle layout_bounds;
+ layout.GetPixelSize (out layout_bounds.Width, out layout_bounds.Height);
+
+ layout_bounds.Y = cell_area.Y;
+ layout_bounds.X = cell_area.X + (cell_area.Width - layout_bounds.Width) / 2;
+
+ if (layout_bounds.IntersectsWith (expose_area)) {
+ Style.PaintLayout (widget.Style, window, cell_state,
+ true, expose_area, widget, "IconView",
+ layout_bounds.X, layout_bounds.Y,
+ layout);
+ }
+ }
+
+#endregion
+
+ }
+}
diff --git a/src/Clients/MainApp/FSpot.Widgets/ThumbnailDecorationRenderer.cs b/src/Clients/MainApp/FSpot.Widgets/ThumbnailDecorationRenderer.cs
new file mode 100644
index 0000000..7fd78d4
--- /dev/null
+++ b/src/Clients/MainApp/FSpot.Widgets/ThumbnailDecorationRenderer.cs
@@ -0,0 +1,47 @@
+/*
+ * ThumbnailDecorationRenderer.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+
+using Gtk;
+using Gdk;
+
+using FSpot.Core;
+
+
+namespace FSpot.Widgets
+{
+ /// <summary>
+ /// This is a renderer for drawing annotations to a thumbnail. The annotations
+ /// are rendered directly to the thumbnail and no previous size computation is needed.
+ /// </summary>
+ public abstract class ThumbnailDecorationRenderer
+ {
+
+#region Constructor
+
+ public ThumbnailDecorationRenderer ()
+ {
+ }
+
+#endregion
+
+#region Drawing Methods
+
+ public abstract void Render (Drawable window,
+ Widget widget,
+ Rectangle cell_area,
+ Rectangle expose_area,
+ StateType cell_state,
+ IPhoto photo);
+
+#endregion
+
+ }
+}
diff --git a/src/Clients/MainApp/FSpot.Widgets/ThumbnailFilenameCaptionRenderer.cs b/src/Clients/MainApp/FSpot.Widgets/ThumbnailFilenameCaptionRenderer.cs
new file mode 100644
index 0000000..d591d2d
--- /dev/null
+++ b/src/Clients/MainApp/FSpot.Widgets/ThumbnailFilenameCaptionRenderer.cs
@@ -0,0 +1,39 @@
+/*
+ * ThumbnailFilenameCaptionRenderer.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+using System.IO;
+
+using FSpot.Core;
+
+
+namespace FSpot.Widgets
+{
+
+ public class ThumbnailFilenameCaptionRenderer : ThumbnailTextCaptionRenderer
+ {
+#region Constructor
+
+ public ThumbnailFilenameCaptionRenderer ()
+ {
+ }
+
+#endregion
+
+#region Drawing Methods
+
+ protected override string GetRenderText (IPhoto photo)
+ {
+ return Path.GetFileName (photo.DefaultVersion.Uri.LocalPath);
+ }
+
+#endregion
+
+ }
+}
diff --git a/src/Clients/MainApp/FSpot.Widgets/ThumbnailRatingDecorationRenderer.cs b/src/Clients/MainApp/FSpot.Widgets/ThumbnailRatingDecorationRenderer.cs
new file mode 100644
index 0000000..d96e768
--- /dev/null
+++ b/src/Clients/MainApp/FSpot.Widgets/ThumbnailRatingDecorationRenderer.cs
@@ -0,0 +1,62 @@
+/*
+ * ThumbnailRatingDecorationRenderer.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+
+using Gtk;
+using Gdk;
+
+using FSpot.Core;
+
+
+namespace FSpot.Widgets
+{
+
+ /// <summary>
+ /// Renders the Rating of a photo as stars to the top left of the thumbnail.
+ /// </summary>
+ public class ThumbnailRatingDecorationRenderer : ThumbnailDecorationRenderer
+ {
+
+#region Private Fields
+
+ RatingSmall rating = new RatingSmall (false);
+
+#endregion
+
+#region Constructor
+
+ public ThumbnailRatingDecorationRenderer ()
+ {
+ }
+
+#endregion
+
+#region Drawing Methods
+
+ public override void Render (Drawable window,
+ Widget widget,
+ Rectangle cell_area,
+ Rectangle expose_area,
+ StateType cell_state,
+ IPhoto photo)
+ {
+ if (photo.Rating > 0) {
+ rating.Value = (int) photo.Rating;
+
+ rating.DisplayPixbuf.RenderToDrawable (window, widget.Style.WhiteGC,
+ 0, 0, cell_area.X, cell_area.Y,
+ -1, -1, RgbDither.None, 0, 0);
+ }
+ }
+
+#endregion
+
+ }
+}
\ No newline at end of file
diff --git a/src/Clients/MainApp/FSpot.Widgets/ThumbnailTagsCaptionRenderer.cs b/src/Clients/MainApp/FSpot.Widgets/ThumbnailTagsCaptionRenderer.cs
new file mode 100644
index 0000000..6b0e2cc
--- /dev/null
+++ b/src/Clients/MainApp/FSpot.Widgets/ThumbnailTagsCaptionRenderer.cs
@@ -0,0 +1,123 @@
+/*
+ * ThumbnailCaptionRenderer.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+
+using Gtk;
+using Gdk;
+
+using FSpot.Core;
+
+
+namespace FSpot.Widgets
+{
+ public class ThumbnailTagsCaptionRenderer : ThumbnailCaptionRenderer
+ {
+
+#region private fields
+
+ private int tag_icon_size;
+
+ private int tag_icon_hspacing;
+
+#endregion
+
+#region Constructor
+
+ public ThumbnailTagsCaptionRenderer () : this (16)
+ {
+ }
+
+ public ThumbnailTagsCaptionRenderer (int tag_icon_size) : this (tag_icon_size, 2)
+ {
+ }
+
+ public ThumbnailTagsCaptionRenderer (int tag_icon_size, int tag_icon_hspacing)
+ {
+ this.tag_icon_size = tag_icon_size;
+ this.tag_icon_hspacing = tag_icon_hspacing;
+ }
+
+#endregion
+
+#region Drawing Methods
+
+ public override int GetHeight (Widget widget, int width)
+ {
+ return tag_icon_size;
+ }
+
+ public override void Render (Drawable window,
+ Widget widget,
+ Rectangle cell_area,
+ Rectangle expose_area,
+ StateType cell_state,
+ IPhoto photo)
+ {
+ Tag [] tags = photo.Tags;
+ Rectangle tag_bounds;
+
+ tag_bounds.X = cell_area.X + (cell_area.Width + tag_icon_hspacing - tags.Length * (tag_icon_size + tag_icon_hspacing)) / 2;
+ tag_bounds.Y = cell_area.Y;// + cell_area.Height - cell_border_width - tag_icon_size + tag_icon_vspacing;
+ tag_bounds.Width = tag_icon_size;
+ tag_bounds.Height = tag_icon_size;
+
+
+ foreach (Tag t in tags) {
+
+ if (t == null)
+ continue;
+
+ Pixbuf icon = t.Icon;
+
+ Tag tag_iter = t.Category;
+ while (icon == null && tag_iter != App.Instance.Database.Tags.RootCategory && tag_iter != null) {
+ icon = tag_iter.Icon;
+ tag_iter = tag_iter.Category;
+ }
+
+ if (icon == null)
+ continue;
+
+ Rectangle region;
+ if (tag_bounds.Intersect (expose_area, out region)) {
+ Pixbuf scaled_icon;
+ if (icon.Width == tag_bounds.Width) {
+ scaled_icon = icon;
+ } else {
+ scaled_icon = icon.ScaleSimple (tag_bounds.Width,
+ tag_bounds.Height,
+ InterpType.Bilinear);
+ }
+
+ Cms.Profile screen_profile;
+ if (FSpot.ColorManagement.Profiles.TryGetValue (Preferences.Get<string> (Preferences.COLOR_MANAGEMENT_DISPLAY_PROFILE), out screen_profile))
+ FSpot.ColorManagement.ApplyProfile (scaled_icon, screen_profile);
+
+ scaled_icon.RenderToDrawable (window, widget.Style.WhiteGC,
+ region.X - tag_bounds.X,
+ region.Y - tag_bounds.Y,
+ region.X, region.Y,
+ region.Width, region.Height,
+ RgbDither.None, region.X, region.Y);
+
+ if (scaled_icon != icon) {
+ scaled_icon.Dispose ();
+ }
+ }
+
+ tag_bounds.X += tag_bounds.Width + tag_icon_hspacing;
+ }
+ }
+
+#endregion
+
+ }
+}
+
diff --git a/src/Clients/MainApp/FSpot.Widgets/ThumbnailTextCaptionRenderer.cs b/src/Clients/MainApp/FSpot.Widgets/ThumbnailTextCaptionRenderer.cs
new file mode 100644
index 0000000..67cbed0
--- /dev/null
+++ b/src/Clients/MainApp/FSpot.Widgets/ThumbnailTextCaptionRenderer.cs
@@ -0,0 +1,73 @@
+/*
+ * ThumbnailTextCaptionRenderer.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+
+using Gtk;
+using Gdk;
+
+using Hyena.Gui;
+
+using FSpot.Core;
+
+
+namespace FSpot.Widgets
+{
+ /// <summary>
+ /// Class to provide a single text line rendered as caption to a thumbnail.
+ /// </summary>
+ public abstract class ThumbnailTextCaptionRenderer : ThumbnailCaptionRenderer
+ {
+#region Constructor
+
+ public ThumbnailTextCaptionRenderer ()
+ {
+ }
+
+#endregion
+
+#region Drawing Methods
+
+ public override int GetHeight (Widget widget, int width)
+ {
+ return widget.Style.FontDescription.MeasureTextHeight (widget.PangoContext);
+ }
+
+ public override void Render (Drawable window,
+ Widget widget,
+ Rectangle cell_area,
+ Rectangle expose_area,
+ StateType cell_state,
+ IPhoto photo)
+ {
+ string text = GetRenderText (photo);
+
+ var layout = new Pango.Layout (widget.PangoContext);
+ layout.SetText (text);
+
+ Rectangle layout_bounds;
+ layout.GetPixelSize (out layout_bounds.Width, out layout_bounds.Height);
+
+ layout_bounds.Y = cell_area.Y;
+ layout_bounds.X = cell_area.X + (cell_area.Width - layout_bounds.Width) / 2;
+
+ if (layout_bounds.IntersectsWith (expose_area)) {
+ Style.PaintLayout (widget.Style, window, cell_state,
+ true, expose_area, widget, "IconView",
+ layout_bounds.X, layout_bounds.Y,
+ layout);
+ }
+ }
+
+ protected abstract string GetRenderText (IPhoto photo);
+
+#endregion
+
+ }
+}
diff --git a/src/Clients/MainApp/FSpot.Widgets/TrayView.cs b/src/Clients/MainApp/FSpot.Widgets/TrayView.cs
index 50411c4..2f422be 100644
--- a/src/Clients/MainApp/FSpot.Widgets/TrayView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/TrayView.cs
@@ -20,9 +20,6 @@ namespace FSpot.Widgets
{
DisplayDates = false;
DisplayTags = false;
- cell_border_width = 10;
- tag_icon_vspacing = 0;
- tag_icon_size = 0;
}
/* protected override void UpdateLayout ()
diff --git a/src/Clients/MainApp/Makefile.am b/src/Clients/MainApp/Makefile.am
index 6f05eb6..c8425c8 100644
--- a/src/Clients/MainApp/Makefile.am
+++ b/src/Clients/MainApp/Makefile.am
@@ -115,6 +115,13 @@ SOURCES = \
FSpot.Widgets/TagMenu.cs \
FSpot.Widgets/TagView.cs \
FSpot.Widgets/Tests/FindBarTests.cs \
+ FSpot.Widgets/ThumbnailCaptionRenderer.cs \
+ FSpot.Widgets/ThumbnailDateCaptionRenderer.cs \
+ FSpot.Widgets/ThumbnailDecorationRenderer.cs \
+ FSpot.Widgets/ThumbnailFilenameCaptionRenderer.cs \
+ FSpot.Widgets/ThumbnailRatingDecorationRenderer.cs \
+ FSpot.Widgets/ThumbnailTagsCaptionRenderer.cs \
+ FSpot.Widgets/ThumbnailTextCaptionRenderer.cs \
FSpot.Widgets/TrayView.cs \
FSpot.Widgets/ViewContext.cs \
FSpot/Accelerometer.cs \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]