diff options
Diffstat (limited to 'src/gui/iconSelectWindow.vala')
-rw-r--r-- | src/gui/iconSelectWindow.vala | 216 |
1 files changed, 103 insertions, 113 deletions
diff --git a/src/gui/iconSelectWindow.vala b/src/gui/iconSelectWindow.vala index 9159f15..2560811 100644 --- a/src/gui/iconSelectWindow.vala +++ b/src/gui/iconSelectWindow.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,29 +12,29 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program. If not, see <http://www.gnu.org/licenses/>. +this program. If not, see <http://www.gnu.org/licenses/>. */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// -/// A window which allows selection of an Icon of the user's current icon +///////////////////////////////////////////////////////////////////////// +/// A window which allows selection of an Icon of the user's current icon /// theme. Custom icons/images can be selested as well. Loading of icons /// happens in an extra thread and a spinner is displayed while loading. ///////////////////////////////////////////////////////////////////////// public class IconSelectWindow : GLib.Object { - + ///////////////////////////////////////////////////////////////////// /// This signal gets emitted when the user selects a new icon. ///////////////////////////////////////////////////////////////////// - + public signal void on_ok(string icon_name); - + ///////////////////////////////////////////////////////////////////// /// Stores the currently selected icon. ///////////////////////////////////////////////////////////////////// - + private string active_icon = ""; ///////////////////////////////////////////////////////////////////// @@ -42,64 +42,64 @@ public class IconSelectWindow : GLib.Object { ///////////////////////////////////////////////////////////////////// private static Gtk.ListStore icon_list = null; - + ///////////////////////////////////////////////////////////////////// /// True, if the icon theme is currently reloaded. ///////////////////////////////////////////////////////////////////// - + private static bool loading = false; - + ///////////////////////////////////////////////////////////////////// /// If set to true, the icon list will be reloaded next time the /// window opens. ///////////////////////////////////////////////////////////////////// - + private static bool need_reload = true; - + ///////////////////////////////////////////////////////////////////// /// Icons of these contexts won't appear in the list. ///////////////////////////////////////////////////////////////////// - + private const string disabled_contexts = "Animations, FileSystems"; - + ///////////////////////////////////////////////////////////////////// /// The list of icons, filtered according to the chosen type and /// filter string. ///////////////////////////////////////////////////////////////////// - + private Gtk.TreeModelFilter icon_list_filtered = null; - + ///////////////////////////////////////////////////////////////////// /// The Gtk widget displaying the icons. ///////////////////////////////////////////////////////////////////// - + private Gtk.IconView icon_view = null; - + ///////////////////////////////////////////////////////////////////// /// This spinner is displayed when the icons are loaded. ///////////////////////////////////////////////////////////////////// - + private Gtk.Spinner spinner = null; - + ///////////////////////////////////////////////////////////////////// /// A Gtk widget used for custom icon/image selection. ///////////////////////////////////////////////////////////////////// - + private Gtk.FileChooserWidget file_chooser = null; - + ///////////////////////////////////////////////////////////////////// /// The notebook containing the different icon choice possibilities: /// from the theme or custom. ///////////////////////////////////////////////////////////////////// - + private Gtk.Notebook tabs = null; - + ///////////////////////////////////////////////////////////////////// /// The main window. ///////////////////////////////////////////////////////////////////// - + private Gtk.Window window = null; - + ///////////////////////////////////////////////////////////////////// /// A little structure containing data for one icon in the icon_view. ///////////////////////////////////////////////////////////////////// @@ -109,19 +109,19 @@ public class IconSelectWindow : GLib.Object { public IconContext context; public Gdk.Pixbuf pixbuf; } - + ///////////////////////////////////////////////////////////////////// /// This queue is used for icon loading. A loading thread pushes /// icons into it --- the main thread updates the icon_view /// accordingly. ///////////////////////////////////////////////////////////////////// - + private GLib.AsyncQueue<ListEntry?> load_queue; - + ///////////////////////////////////////////////////////////////////// /// Possible icon types. ///////////////////////////////////////////////////////////////////// - + private enum IconContext { ALL, APPS, @@ -131,20 +131,20 @@ public class IconSelectWindow : GLib.Object { EMOTES, OTHER } - + ///////////////////////////////////////////////////////////////////// /// C'tor, creates a new IconSelectWindow. ///////////////////////////////////////////////////////////////////// - + public IconSelectWindow(Gtk.Window parent) { try { this.load_queue = new GLib.AsyncQueue<ListEntry?>(); - + if (IconSelectWindow.icon_list == null) { IconSelectWindow.icon_list = new Gtk.ListStore(3, typeof(string), // icon name typeof(IconContext), // icon type typeof(Gdk.Pixbuf)); // the icon itself - + // disable sorting until all icons are loaded // else loading becomes horribly slow IconSelectWindow.icon_list.set_default_sort_func(() => {return 0;}); @@ -155,10 +155,10 @@ public class IconSelectWindow : GLib.Object { else IconSelectWindow.need_reload = true; }); } - + // make the icon_view filterable this.icon_list_filtered = new Gtk.TreeModelFilter(IconSelectWindow.icon_list, null); - + Gtk.Builder builder = new Gtk.Builder(); builder.add_from_file (Paths.ui_files + "/icon_select.ui"); @@ -166,42 +166,38 @@ public class IconSelectWindow : GLib.Object { this.window = builder.get_object("window") as Gtk.Window; this.window.set_transient_for(parent); this.window.set_modal(true); - + this.tabs = builder.get_object("tabs") as Gtk.Notebook; - + this.spinner = builder.get_object("spinner") as Gtk.Spinner; this.spinner.start(); - + (builder.get_object("ok-button") as Gtk.Button).clicked.connect(on_ok_button_clicked); (builder.get_object("cancel-button") as Gtk.Button).clicked.connect(on_cancel_button_clicked); - - var combo_box = builder.get_object("combo-box") as Gtk.VBox; - + + var combo_box = builder.get_object("combo-box") as Gtk.Box; + // context combo - #if HAVE_GTK_3 - var context_combo = new Gtk.ComboBoxText(); - #else - var context_combo = new Gtk.ComboBox.text(); - #endif - context_combo.append_text(_("All icons")); - context_combo.append_text(_("Applications")); - context_combo.append_text(_("Actions")); - context_combo.append_text(_("Places")); - context_combo.append_text(_("File types")); - context_combo.append_text(_("Emotes")); - context_combo.append_text(_("Miscellaneous")); - - context_combo.set_active(0); - - context_combo.changed.connect(() => { - this.icon_list_filtered.refilter(); - }); - + var context_combo = new Gtk.ComboBoxText(); + context_combo.append_text(_("All icons")); + context_combo.append_text(_("Applications")); + context_combo.append_text(_("Actions")); + context_combo.append_text(_("Places")); + context_combo.append_text(_("File types")); + context_combo.append_text(_("Emotes")); + context_combo.append_text(_("Miscellaneous")); + + context_combo.set_active(0); + + context_combo.changed.connect(() => { + this.icon_list_filtered.refilter(); + }); + combo_box.pack_start(context_combo, false, false); - + // string filter entry var filter = builder.get_object("filter-entry") as Gtk.Entry; - + // only display items which have the selected type // and whose name contains the text entered in the entry this.icon_list_filtered.set_visible_func((model, iter) => { @@ -209,25 +205,25 @@ public class IconSelectWindow : GLib.Object { IconContext context = IconContext.ALL; model.get(iter, 0, out name); model.get(iter, 1, out context); - + if (name == null) return false; - + return (context_combo.get_active() == context || context_combo.get_active() == IconContext.ALL) && name.down().contains(filter.text.down()); }); - + // clear when the users clicks on the "clear" icon filter.icon_release.connect((pos, event) => { if (pos == Gtk.EntryIconPosition.SECONDARY) filter.text = ""; }); - + // refilter on input filter.notify["text"].connect(() => { this.icon_list_filtered.refilter(); }); - + // container for the icon_view var scroll = builder.get_object("icon-scrolledwindow") as Gtk.ScrolledWindow; @@ -237,7 +233,7 @@ public class IconSelectWindow : GLib.Object { this.icon_view.item_padding = 2; this.icon_view.pixbuf_column = 2; this.icon_view.tooltip_column = 0; - + // set active_icon if selection changes this.icon_view.selection_changed.connect(() => { foreach (var path in this.icon_view.get_selected_items()) { @@ -246,7 +242,7 @@ public class IconSelectWindow : GLib.Object { this.icon_list_filtered.get(iter, 0, out this.active_icon); } }); - + // hide this window when the user activates an icon this.icon_view.item_activated.connect((path) => { Gtk.TreeIter iter; @@ -255,46 +251,40 @@ public class IconSelectWindow : GLib.Object { this.on_ok(this.active_icon); this.window.hide(); }); - + scroll.add(this.icon_view); - + // file chooser widget this.file_chooser = builder.get_object("filechooser") as Gtk.FileChooserWidget; var file_filter = new Gtk.FileFilter(); file_filter.add_pixbuf_formats(); - - #if HAVE_GTK_3 - file_filter.set_filter_name(_("All supported image formats")); - #else - file_filter.set_name(_("All supported image formats")); - #endif - + file_filter.set_filter_name(_("All supported image formats")); file_chooser.add_filter(file_filter); - + // set active_icon if the user selected a file file_chooser.selection_changed.connect(() => { if (file_chooser.get_filename() != null && GLib.FileUtils.test(file_chooser.get_filename(), GLib.FileTest.IS_REGULAR)) - + this.active_icon = file_chooser.get_filename(); }); - + // hide this window when the user activates a file file_chooser.file_activated.connect(() => { this.active_icon = file_chooser.get_filename(); this.on_ok(this.active_icon); this.window.hide(); }); - + this.window.set_focus(this.icon_view); this.window.delete_event.connect(this.window.hide_on_delete); - + } catch (GLib.Error e) { error("Could not load UI: %s\n", e.message); } } - + ///////////////////////////////////////////////////////////////////// /// Displays the window. The icons are reloaded if neccessary. ///////////////////////////////////////////////////////////////////// @@ -302,27 +292,27 @@ public class IconSelectWindow : GLib.Object { public void show() { this.window.show_all(); this.spinner.hide(); - + if (IconSelectWindow.need_reload) { IconSelectWindow.need_reload = false; this.load_icons(); } - } - + } + public static void clear_icons() { if (IconSelectWindow.icon_list != null) { IconSelectWindow.need_reload = true; IconSelectWindow.icon_list.clear(); } } - + ///////////////////////////////////////////////////////////////////// /// Makes the window select the icon of the given Pie. ///////////////////////////////////////////////////////////////////// - + public void set_icon(string icon) { this.active_icon = icon; - + if (icon.contains("/")) { this.file_chooser.set_filename(icon); this.tabs.set_current_page(1); @@ -330,7 +320,7 @@ public class IconSelectWindow : GLib.Object { this.icon_list_filtered.foreach((model, path, iter) => { string name = ""; model.get(iter, 0, out name); - + if (name == icon) { this.icon_view.select_path(path); this.icon_view.scroll_to_path(path, true, 0.5f, 0.0f); @@ -338,38 +328,38 @@ public class IconSelectWindow : GLib.Object { } return (name == icon); }); - + this.tabs.set_current_page(0); } - } - + } + ///////////////////////////////////////////////////////////////////// /// Called when the user clicks the ok button. ///////////////////////////////////////////////////////////////////// - + private void on_ok_button_clicked() { this.on_ok(this.active_icon); this.window.hide(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the user clicks the cancel button. ///////////////////////////////////////////////////////////////////// - + private void on_cancel_button_clicked() { this.window.hide(); } - + ///////////////////////////////////////////////////////////////////// /// (Re)load all icons. ///////////////////////////////////////////////////////////////////// - + private void load_icons() { // only if it's not loading currently if (!IconSelectWindow.loading) { IconSelectWindow.loading = true; IconSelectWindow.icon_list.clear(); - + // display the spinner if (spinner != null) this.spinner.visible = true; @@ -389,7 +379,7 @@ public class IconSelectWindow : GLib.Object { 1, new_entry.context, 2, new_entry.pixbuf); } - + // enable sorting of the icon_view if loading finished if (!IconSelectWindow.loading) { IconSelectWindow.icon_list.set_sort_column_id(0, Gtk.SortType.ASCENDING); @@ -399,19 +389,19 @@ public class IconSelectWindow : GLib.Object { }); } } - + ///////////////////////////////////////////////////////////////////// /// Loads all icons of an icon theme and pushes them into the /// load_queue. ///////////////////////////////////////////////////////////////////// - + private async void load_all() { var icon_theme = Gtk.IconTheme.get_default(); - + foreach (var context in icon_theme.list_contexts()) { if (!disabled_contexts.contains(context)) { foreach (var icon in icon_theme.list_icons(context)) { - + IconContext icon_context = IconContext.OTHER; switch(context) { case "Apps": case "Applications": @@ -426,31 +416,31 @@ public class IconSelectWindow : GLib.Object { icon_context = IconContext.ACTIONS; break; default: break; } - + Idle.add(load_all.callback); yield; - + try { // create a new entry for the queue var new_entry = new ListEntry(); new_entry.name = icon; new_entry.context = icon_context; new_entry.pixbuf = icon_theme.load_icon(icon, 32, 0); - + // some icons have only weird sizes... do not include them if (new_entry.pixbuf.width == 32) this.load_queue.push(new_entry); - + } catch (GLib.Error e) { warning("Failed to load image " + icon); } } } } - + // finished loading IconSelectWindow.loading = false; - + // hide the spinner if (spinner != null) spinner.visible = false; |