// // Copyright (C) 2009 Jordi Mas i Hernandez, jmas@softcatala.org // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gdk; using Gtk; using Pango; using Mistelix.Transitions; using Mistelix.Core; using Mistelix.DataModel; using Mistelix.Widgets; namespace Mistelix.Core { // DVD Button public class Button : ButtonProjectElement // TODO: Should use Dispose pattern { PixbufImageSurface thumbnail; int imgbox_width, imgbox_height; int box_width, box_height; public Button () { } // TODO: A button belongs to a project and it should be specified in the constructor once public Button (int x, int y, int linked_id) : base (x, y, linked_id) { } public override int ThumbnailIndex { get { return base.ThumbnailIndex;} set { if (base.ThumbnailIndex == value) return; base.ThumbnailIndex = value; InvalidateThumbnail (); } } // Space needed horizontally to represent the object public int DrawingBoxWidth { get { if (ShowAs == ButtonShowAs.Thumbnail) return imgbox_width; return box_width; } } // Space needed vertically to represent the object public int DrawingBoxHeight { get { if (ShowAs == ButtonShowAs.Thumbnail) return imgbox_height; return box_height; } } // Check if a point is part of the button public bool Contains (int x, int y) { if ((x >= X && x <= X + DrawingBoxWidth) && (y >= Y && y <= Y + DrawingBoxHeight)) return true; return false; } // Indicates if the thumbnail is actually created or if the draw operation will need // to create it public bool IsThumbnailCreated { get { return thumbnail != null; } } public void Draw (Cairo.Context cr, Project project) { Draw (cr, project, X, Y); } public void Draw (Cairo.Context cr, Project project, int x, int y) { if (ShowAs == ButtonShowAs.Thumbnail) DrawThumbnail (cr, project, x, y); else DrawText (cr, project, x, y); } public void InvalidateThumbnail () { if (thumbnail == null) return; ((IDisposable)thumbnail).Dispose (); thumbnail = null; } void DrawThumbnail (Cairo.Context cr, Project project, int x, int y) { if (thumbnail == null) LoadThumbnail (project); thumbnail.Render (cr, x, y); } void DrawText (Cairo.Context cr, Project project, int x, int y) { using (Pango.Layout layout = Pango.CairoHelper.CreateLayout (cr)) { layout.FontDescription = Pango.FontDescription.FromString (project.Details.ButtonsFontName); layout.SetMarkup (Text); layout.Ellipsize = Pango.EllipsizeMode.End; layout.Alignment = Pango.Alignment.Center; layout.SingleParagraphMode = true; layout.Width = -1; layout.GetPixelSize (out box_width, out box_height); // Background cr.Color = project.Details.ButtonsBackColor; cr.Rectangle (x, y, box_width, box_height); cr.Fill (); cr.Stroke (); cr.MoveTo (x, y); cr.Color = project.Details.ButtonsForeColor; Pango.CairoHelper.ShowLayout (cr, layout); } } public void LoadThumbnail (Project project) { Gdk.Pixbuf pix = null; Resolution size; Gdk.Pixbuf im; size = ThumbnailSizeManager.List [project.Details.ButtonThumbnailSize]; try { VisibleProjectElement element; element = project.ElementFromID (LinkedId); if (element is SlideShowProjectElement == false && element is VideoProjectElement == false) throw new InvalidOperationException ("Only videos and slideshows allowed"); if (element is SlideShowProjectElement) { SlideShowProjectElement slide; string file; slide = (SlideShowProjectElement) element; file = slide.images[ThumbnailIndex].image; im = new Gdk.Pixbuf (file); } else { // VideoProjectElement VideoProjectElement video; video = (VideoProjectElement) element; im = Backends.GStreamer.Thumbnail.VideoScreenshot (video.filename, ThumbnailIndex); } int max = Math.Max (im.Width, im.Height); Gdk.Pixbuf scaled = im.ScaleSimple (size.Width * im.Width / max, size.Height * im.Height / max, InterpType.Nearest); im.Dispose (); pix = scaled; imgbox_width = pix.Width; imgbox_height = pix.Height; } catch (Exception e) { Logger.Error ("Button.LoadThumbnail. Exception {0}", e.Message); pix = Gtk.IconTheme.Default.LoadIcon ("gtk-new", size.Width, (Gtk.IconLookupFlags) 0); } finally { thumbnail = new PixbufImageSurface (pix, true); } } } }