sadrul.gtkblist-theme: 68a55224: A status-icon theme editor.

sadrul at pidgin.im sadrul at pidgin.im
Sun Apr 19 13:30:56 EDT 2009


-----------------------------------------------------------------
Revision: 68a55224160cd206e7a976d1f266d30bf2aa7ed8
Ancestor: e039ff6ca69e4028101db0b3b484cceca6d0a52e
Author: sadrul at pidgin.im
Date: 2009-04-19T17:30:59
Branch: im.pidgin.sadrul.gtkblist-theme
URL: http://d.pidgin.im/viewmtn/revision/info/68a55224160cd206e7a976d1f266d30bf2aa7ed8

Added files:
        pidgin/plugins/themeedit-icon.c
        pidgin/plugins/themeedit-icon.h
Modified files:
        pidgin/plugins/Makefile.am pidgin/plugins/themeedit.c

ChangeLog: 

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?).

-------------- next part --------------
============================================================
--- pidgin/plugins/themeedit-icon.c	93fa025cae324bad18c6fb1d8eca5e2870d6e1a7
+++ pidgin/plugins/themeedit-icon.c	93fa025cae324bad18c6fb1d8eca5e2870d6e1a7
@@ -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);
+}
+
============================================================
--- pidgin/plugins/themeedit-icon.h	0cf03f88d55838373d3618c143895454572c8a2e
+++ pidgin/plugins/themeedit-icon.h	0cf03f88d55838373d3618c143895454572c8a2e
@@ -0,0 +1,2 @@
+void pidgin_icon_theme_edit(void);
+
============================================================
--- pidgin/plugins/Makefile.am	30e1cb3c81c662f391de1476e40efcba015e4d22
+++ pidgin/plugins/Makefile.am	c9c4453becb1168c12720a61a651b5a6029f6388
@@ -84,7 +84,7 @@ spellchk_la_SOURCES         = spellchk.c
 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
============================================================
--- pidgin/plugins/themeedit.c	9f515c429992162f5d280bd860e26253851e1fdb
+++ pidgin/plugins/themeedit.c	5764cd3cc52a6ce9abbe8c0937323aa39b4ed2a3
@@ -29,8 +29,10 @@
 #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 @@ pidgin_blist_theme_edit(void)
 		{ 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,8 +297,10 @@ actions(PurplePlugin *plugin, gpointer c
 	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 @@ static PurplePluginInfo info =
 	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 at gmail.com>",        /**< author         */
 	PURPLE_WEBSITE,                        /**< homepage       */
 


More information about the Commits mailing list