Mercurial > pidgin
changeset 26580:0dddfdb3a24a
A status-icon theme editor.
TODO:
* Actually create the XML files for the theme laoders (I don't really
plan on writing that part of the code >:) )
* The selected icons are stored in a theme-hierarchy under "/tmp". This
needs to be fixed to use a more appropriate location (volunteers?).
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Sun, 19 Apr 2009 17:30:59 +0000 |
parents | 9b6619a28f5d |
children | 7519de6ea00f |
files | pidgin/plugins/Makefile.am pidgin/plugins/themeedit-icon.c pidgin/plugins/themeedit-icon.h pidgin/plugins/themeedit.c |
diffstat | 4 files changed, 228 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/pidgin/plugins/Makefile.am Sat Apr 18 23:27:38 2009 +0000 +++ b/pidgin/plugins/Makefile.am Sun Apr 19 17:30:59 2009 +0000 @@ -84,7 +84,7 @@ relnot_la_SOURCES = relnot.c sendbutton_la_SOURCES = sendbutton.c spellchk_la_SOURCES = spellchk.c -themeedit_la_SOURCES = themeedit.c +themeedit_la_SOURCES = themeedit.c themeedit-icon.c themeedit-icon.h timestamp_la_SOURCES = timestamp.c timestamp_format_la_SOURCES = timestamp_format.c xmppconsole_la_SOURCES = xmppconsole.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/plugins/themeedit-icon.c Sun Apr 19 17:30:59 2009 +0000 @@ -0,0 +1,215 @@ +/* Pidgin + * + * Pidgin is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ +#include "internal.h" +#include "pidgin.h" +#include "debug.h" +#include "version.h" + +#include "theme-manager.h" + +#include "gtkblist.h" +#include "gtkblist-theme.h" +#include "gtkutils.h" +#include "gtkplugin.h" + +#include "pidginstock.h" +#include "themeedit-icon.h" + +static const char *stocksizes [] = { + PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC, + PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL, + PIDGIN_ICON_SIZE_TANGO_SMALL, + PIDGIN_ICON_SIZE_TANGO_MEDIUM, + PIDGIN_ICON_SIZE_TANGO_LARGE, + PIDGIN_ICON_SIZE_TANGO_HUGE, + NULL +}; + +static const struct { + const char *stockid; + const char *text; +} statuses[] = { + {PIDGIN_STOCK_STATUS_AVAILABLE, N_("Available")}, + {PIDGIN_STOCK_STATUS_AWAY, N_("Away")}, + {PIDGIN_STOCK_STATUS_BUSY, N_("Busy")}, + {PIDGIN_STOCK_STATUS_OFFLINE, N_("Offline")}, + {NULL, NULL} +}; + +static PidginStatusIconTheme * +create_icon_theme(GtkWidget *window) +{ + int i, j; + char *dirname = "/tmp"; /* FIXME */ + PidginStatusIconTheme *theme = g_object_new(PIDGIN_TYPE_STATUS_ICON_THEME, "type", "status-icon", + "author", getlogin(), + "directory", dirname, + NULL); + + for (i = 0; statuses[i].stockid; i++) { + GtkWidget *image = g_object_get_data(G_OBJECT(window), statuses[i].stockid); + GdkPixbuf *pixbuf = g_object_get_data(G_OBJECT(image), "pixbuf"); + pidgin_icon_theme_set_icon(PIDGIN_ICON_THEME(theme), statuses[i].stockid, + statuses[i].stockid); + for (j = 0; stocksizes[j]; j++) { + int width, height; + GtkIconSize iconsize; + char size[8]; + char *name; + GdkPixbuf *scale; + GError *error = NULL; + + iconsize = gtk_icon_size_from_name(stocksizes[j]); + gtk_icon_size_lookup(iconsize, &width, &height); + g_snprintf(size, sizeof(size), "%d", width); + + if (i == 0) { + name = g_build_filename(dirname, size, NULL); + purple_build_dir(name, S_IRUSR | S_IWUSR | S_IXUSR); + g_free(name); + } + + name = g_build_filename(dirname, size, statuses[i].stockid, NULL); + scale = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR); + gdk_pixbuf_save(scale, name, "png", &error, "compression", "9", NULL); + g_free(name); + g_object_unref(G_OBJECT(scale)); + if (error) + g_error_free(error); + } + } + return theme; +} + +static void +use_icon_theme(GtkWidget *w, GtkWidget *window) +{ + PidginStatusIconTheme *theme = create_icon_theme(window); + pidgin_stock_load_status_icon_theme(PIDGIN_STATUS_ICON_THEME(theme)); + pidgin_blist_refresh(purple_get_blist()); + g_object_unref(theme); +} + +static void +save_icon_theme(GtkWidget *w, GtkWidget *window) +{ + /* TODO: SAVE! */ + gtk_widget_destroy(window); +} + +static void +stock_icon_selected(const char *filename, gpointer image) +{ + GError *error = NULL; + GdkPixbuf *scale; + int i; + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, &error); + + if (error || !pixbuf) { + purple_debug_error("theme-editor-icon", "Unable to load icon file '%s' (%s)\n", + filename, error ? error->message : "Reason unknown"); + if (error) + g_error_free(error); + return; + } + + scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(GTK_IMAGE(image), scale); + g_object_unref(G_OBJECT(scale)); + + /* Update the size previews */ + for (i = 0; stocksizes[i]; i++) { + int width, height; + GtkIconSize iconsize; + GtkWidget *prev = g_object_get_data(G_OBJECT(image), stocksizes[i]); + if (!prev) + continue; + iconsize = gtk_icon_size_from_name(stocksizes[i]); + gtk_icon_size_lookup(iconsize, &width, &height); + scale = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(GTK_IMAGE(prev), scale); + g_object_unref(G_OBJECT(scale)); + } + + /* Save the original pixbuf so we can use it for resizing later */ + g_object_set_data_full(G_OBJECT(image), "pixbuf", pixbuf, + (GDestroyNotify)g_object_unref); +} + +static gboolean +change_stock_image(GtkWidget *widget, GdkEventButton *event, GtkWidget *image) +{ + GtkWidget *win = pidgin_buddy_icon_chooser_new(GTK_WINDOW(gtk_widget_get_toplevel(widget)), + stock_icon_selected, image); + gtk_widget_show_all(win); + + return TRUE; +} + +void pidgin_icon_theme_edit(void) +{ + GtkWidget *dialog; + GtkWidget *box, *vbox; + GtkSizeGroup *sizegroup; + int i, j; + dialog = pidgin_create_dialog(_("Pidgin Icon Theme Editor"), 0, "theme-editor-icon", FALSE); + box = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(dialog), FALSE, PIDGIN_HIG_BOX_SPACE); + + vbox = pidgin_make_frame(box, _("Status Icons")); + sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + for (i = 0; statuses[i].stockid; i++) { + const char *id = statuses[i].stockid; + const char *text = _(statuses[i].text); + + GtkWidget *hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); + GtkWidget *label = gtk_label_new(text); + GtkWidget *image = gtk_image_new_from_stock(id, + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); + GtkWidget *ebox = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(ebox), image); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + + g_signal_connect(G_OBJECT(ebox), "button-press-event", G_CALLBACK(change_stock_image), image); + g_object_set_data(G_OBJECT(image), "property-name", (gpointer)id); + + gtk_size_group_add_widget(sizegroup, label); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), ebox, FALSE, FALSE, 0); + + for (j = 0; stocksizes[j]; j++) { + GtkWidget *sh = gtk_image_new_from_stock(id, gtk_icon_size_from_name(stocksizes[j])); + gtk_box_pack_start(GTK_BOX(hbox), sh, FALSE, FALSE, 0); + g_object_set_data(G_OBJECT(image), stocksizes[j], sh); + } + + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + g_object_set_data(G_OBJECT(dialog), id, image); + } + + gtk_dialog_set_has_separator(GTK_DIALOG(dialog), TRUE); + pidgin_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_SAVE, G_CALLBACK(save_icon_theme), dialog); + pidgin_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_APPLY, G_CALLBACK(use_icon_theme), dialog); + gtk_widget_show_all(dialog); + g_object_unref(sizegroup); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/plugins/themeedit-icon.h Sun Apr 19 17:30:59 2009 +0000 @@ -0,0 +1,2 @@ +void pidgin_icon_theme_edit(void); +
--- a/pidgin/plugins/themeedit.c Sat Apr 18 23:27:38 2009 +0000 +++ b/pidgin/plugins/themeedit.c Sun Apr 19 17:30:59 2009 +0000 @@ -29,7 +29,9 @@ #include "gtkutils.h" #include "gtkplugin.h" -#define PLUGIN_ID "gtk-blist-theme-editor" +#define PLUGIN_ID "gtk-theme-editor" + +#include "themeedit-icon.h" static gboolean prop_type_is_color(PidginBlistTheme *theme, const char *prop) @@ -239,7 +241,7 @@ { NULL, { } } }; - dialog = pidgin_create_dialog(_("Pidgin Buddylist Theme Editor"), 0, "theme-editor", FALSE); + dialog = pidgin_create_dialog(_("Pidgin Buddylist Theme Editor"), 0, "theme-editor-blist", FALSE); box = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(dialog), FALSE, PIDGIN_HIG_BOX_SPACE); theme = pidgin_blist_get_theme(); @@ -295,7 +297,9 @@ GList *l = NULL; PurplePluginAction *act = NULL; - act = purple_plugin_action_new(_("Edit"), pidgin_blist_theme_edit); + act = purple_plugin_action_new(_("Edit Buddylist Theme"), pidgin_blist_theme_edit); + l = g_list_append(l, act); + act = purple_plugin_action_new(_("Edit Status Icon Theme"), pidgin_icon_theme_edit); l = g_list_append(l, act); return l; @@ -313,12 +317,12 @@ PURPLE_PRIORITY_DEFAULT, /**< priority */ PLUGIN_ID, /**< id */ - N_("Pidgin Buddylist Theme Editor"), /**< name */ + N_("Pidgin Theme Editor"), /**< name */ DISPLAY_VERSION, /**< version */ /** summary */ - N_("Pidgin Buddylist Theme Editor. Enjoy, motherfucker!!"), + N_("Pidgin Theme Editor."), /** description */ - N_("Pidgin Buddylist Theme Editor"), + N_("Pidgin Theme Editor"), "Sadrul Habib Chowdhury <imadil@gmail.com>", /**< author */ PURPLE_WEBSITE, /**< homepage */