// // Copyright (C) 2009-2010 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 Gtk; using Gdk; using System.Collections.Generic; using System.ComponentModel; using Mistelix.Widgets; using Mistelix.DataModel; using Mistelix.Core; namespace Mistelix.Dialogs { // Button properties dialog public class ButtonPropertiesDialog : BuilderDialog { Project project; int button_id; ThumbnailCollection thumbnails; ListStore store; Pixbuf def_image; Dictionary mapping; BackgroundWorker thumbnailing; [GtkBeans.Builder.Object] Gtk.Entry element_entry; [GtkBeans.Builder.Object] Gtk.RadioButton image_radio; [GtkBeans.Builder.Object] Gtk.RadioButton text_radio; [GtkBeans.Builder.Object] Gtk.Button ok_button; [GtkBeans.Builder.Object] Gtk.IconView thumbnails_iconview; const int COL_PIXBUF = 0; const int COL_INDEX = 1; public ButtonPropertiesDialog (Project project, int button_id) : base ("ButtonPropertiesDialog.ui", "buttonproperties") { this.project = project; this.button_id = button_id; if (project.Buttons[button_id].ShowAs == ButtonShowAs.Thumbnail) { image_radio.Active = true; element_entry.Sensitive = false; } else { text_radio.Active = true; element_entry.Sensitive = true; } if (project.Buttons[button_id].Text != null) element_entry.Text = project.Buttons[button_id].Text; image_radio.Toggled += new EventHandler (OnCheckToggled); element_entry.Changed += OnChangedText; CreateDefaultImage (); thumbnails_iconview.PixbufColumn = 0; mapping = new Dictionary (); thumbnails_iconview.Model = store = CreateStore (); thumbnailing = new BackgroundWorker (); thumbnailing.WorkerSupportsCancellation = true; thumbnailing.DoWork += new DoWorkEventHandler (DoWork); LoadThumbnails (); } void CreateDefaultImage () { const int channels = 4; Cairo.ImageSurface image; int thumbnail_width, thumbnail_height; thumbnail_width = ThumbnailSizeManager.List [project.Details.ButtonThumbnailSize].Width; thumbnail_height = ThumbnailSizeManager.List [project.Details.ButtonThumbnailSize].Height; image = Utils.CreateNoPreviewImage (thumbnail_width, thumbnail_height); byte[] data = DataImageSurface.FromCairo32ToPixBuf (image.Data, thumbnail_width, thumbnail_height, channels); def_image = new Pixbuf (data, true, 8, thumbnail_width, thumbnail_height, thumbnail_width * channels, null); image.Destroy (); } ListStore CreateStore () { // Pixbuf return new ListStore (typeof (Pixbuf), typeof (int)); } void DoWork (object sender, DoWorkEventArgs e) { Task task; while (true) { if (thumbnailing.CancellationPending) break; task = thumbnails.Dispatcher.GetNextTask (); if (task == null) break; task.Do (); } } void LoadThumbnails () { VisibleProjectElement element; Resolution size; Gtk.TreeIter selected_iter = Gtk.TreeIter.Zero; size = ThumbnailSizeManager.List [project.Details.ButtonThumbnailSize]; element = project.ElementFromID (project.Buttons[button_id].LinkedId); thumbnails = element.GetThumbnailRepresentations (size.Width, size.Height); foreach (ThumbnailCollection.ItemTask task in thumbnails) { Gtk.TreeIter iter; iter = store.AppendValues (def_image, task.ThumbnailIndex); mapping.Add (task, iter); if (task.ThumbnailIndex == project.Buttons[button_id].ThumbnailIndex) selected_iter = iter; task.CompletedEventHandler += delegate (object obj, EventArgs args) { ThumbnailCollection.ItemTask itemtask = (ThumbnailCollection.ItemTask) obj; Gtk.TreeIter tree_iter; try { mapping.TryGetValue (itemtask, out tree_iter); } catch (KeyNotFoundException) { Logger.Error ("ButtonPropertiesDialog.LoadThumbnails. Cannot find key"); return; } Application.Invoke (delegate { store.SetValue (tree_iter, COL_PIXBUF, itemtask.Pixbuf); }); }; } TreePath path = store.GetPath (selected_iter); thumbnails_iconview.SelectPath (path); thumbnailing.RunWorkerAsync (store); } void OnChangedText (object sender, EventArgs args) { EnableOKButton (); } void EnableOKButton () { bool enabled; if (text_radio.Active == true) { if (element_entry.Text.Length > 0) enabled = true; else enabled = false; } else enabled = true; ok_button.Sensitive = enabled; } void OnOK (object sender, EventArgs args) { if (image_radio.Active == false) { // Text project.Buttons[button_id].ShowAs = ButtonShowAs.Text; project.Buttons[button_id].Text = element_entry.Text; return; } project.Buttons[button_id].ShowAs = ButtonShowAs.Thumbnail; TreeIter iter; int idx; TreePath[] items = thumbnails_iconview.SelectedItems; store.GetIter (out iter, items [0]); idx = (int) store.GetValue (iter, COL_INDEX); project.Buttons[button_id].ThumbnailIndex = idx; } void OnCheckToggled (object obj, EventArgs args) { element_entry.Sensitive = text_radio.Active; EnableOKButton (); } public override void Destroy () { thumbnailing.CancelAsync (); thumbnailing.Dispose (); store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter) { Gdk.Pixbuf im = (Gdk.Pixbuf) store.GetValue (iter, COL_PIXBUF); if (def_image != im) im.Dispose (); return false; }); def_image.Dispose (); base.Destroy (); } } }