changeset 16949:06f6768b6e29

Now that the docklet icon is based on the status from status selector, it isn't necessary to have a separate DockletStatus enum/typedef to track the status. This replaces usage of DockletStatus with PurpleStatusPrimitive. This requires tracking connecting and pending flags separately and passing them on to the ui_ops implementation with the status. Removed an old TODO comment that has already been implemented.
author Casey Harkins <charkins@pidgin.im>
date Tue, 08 May 2007 02:38:55 +0000
parents 2fffd9d72b8f
children 37c57a0a9686
files pidgin/gtkdocklet-x11.c pidgin/gtkdocklet.c pidgin/gtkdocklet.h pidgin/win32/gtkdocklet-win32.c
diffstat 4 files changed, 111 insertions(+), 129 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtkdocklet-x11.c	Tue May 08 00:48:20 2007 +0000
+++ b/pidgin/gtkdocklet-x11.c	Tue May 08 02:38:55 2007 +0000
@@ -42,7 +42,6 @@
 static GtkTooltips *tooltips = NULL;
 static GdkPixbuf *blank_icon = NULL;
 static int embed_timeout = 0;
-static DockletStatus icon_status = 0;
 static int docklet_height = 0;
 
 /* protos */
@@ -90,39 +89,38 @@
 }
 
 static void
-docklet_x11_update_icon(DockletStatus icon)
+docklet_x11_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending)
 {
 	const gchar *icon_name = NULL;
 
 	g_return_if_fail(image != NULL);
 
-	switch (icon) {
-		case DOCKLET_STATUS_OFFLINE:
+	switch (status) {
+		case PURPLE_STATUS_OFFLINE:
 			icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
 			break;
-		case DOCKLET_STATUS_CONNECTING:
-			icon_name = PIDGIN_STOCK_TRAY_CONNECT;
+		case PURPLE_STATUS_AWAY:
+			icon_name = PIDGIN_STOCK_TRAY_AWAY;
+			break;
+		case PURPLE_STATUS_UNAVAILABLE:
+			icon_name = PIDGIN_STOCK_TRAY_BUSY;
 			break;
-		case DOCKLET_STATUS_AVAILABLE:
+		case PURPLE_STATUS_EXTENDED_AWAY:
+			icon_name = PIDGIN_STOCK_TRAY_XA;
+			break;
+		case PURPLE_STATUS_INVISIBLE:
+			icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
+			break;
+		default:
 			icon_name = PIDGIN_STOCK_TRAY_AVAILABLE;
 			break;
-		case DOCKLET_STATUS_PENDING:
-			icon_name = PIDGIN_STOCK_TRAY_PENDING;
-			break;
-		case DOCKLET_STATUS_AWAY:
-			icon_name = PIDGIN_STOCK_TRAY_AWAY;
-			break;
-		case DOCKLET_STATUS_BUSY:
-			icon_name = PIDGIN_STOCK_TRAY_BUSY;
-			break;
-		case DOCKLET_STATUS_XA:
-			icon_name = PIDGIN_STOCK_TRAY_XA;
-			break;
-		case DOCKLET_STATUS_INVISIBLE:
-			icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
-			break;
 	}
 
+	if (pending)
+		icon_name = PIDGIN_STOCK_TRAY_PENDING;
+	if (connecting)
+		icon_name = PIDGIN_STOCK_TRAY_CONNECT;
+
 	if(icon_name) {
 		int icon_size;
 		if (docklet_height < 22)
@@ -132,7 +130,6 @@
 
 		gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, icon_size);
 	}
-	icon_status = icon;
 }
 
 static void
@@ -141,7 +138,7 @@
 	if (docklet_height == widget->allocation.height)
 		return;
 	docklet_height = widget->allocation.height;
-	docklet_x11_update_icon(icon_status);
+	pidgin_docklet_update_icon();
 }
 
 static void
--- a/pidgin/gtkdocklet.c	Tue May 08 00:48:20 2007 +0000
+++ b/pidgin/gtkdocklet.c	Tue May 08 02:38:55 2007 +0000
@@ -49,7 +49,9 @@
 
 /* globals */
 static struct docklet_ui_ops *ui_ops = NULL;
-static DockletStatus status = DOCKLET_STATUS_OFFLINE;
+static PurpleStatusPrimitive status = PURPLE_STATUS_OFFLINE;
+static gboolean pending = FALSE;
+static gboolean connecting = FALSE;
 static gboolean enable_join_chat = FALSE;
 static guint docklet_blinking_timer = 0;
 static gboolean visible = FALSE;
@@ -66,21 +68,17 @@
 
 	blinked = !blinked;
 
-	switch (status) {
-		case DOCKLET_STATUS_PENDING:
-			if (blinked) {
-				if (ui_ops && ui_ops->blank_icon)
-					ui_ops->blank_icon();
-			} else {
-				if (ui_ops && ui_ops->update_icon)
-					ui_ops->update_icon(status);
-			}
-			ret = TRUE; /* keep blinking */
-			break;
-		default:
-			docklet_blinking_timer = 0;
-			blinked = FALSE;
-			break;
+	if(pending && !connecting) {
+		if (blinked) {
+			if (ui_ops && ui_ops->blank_icon)
+				ui_ops->blank_icon();
+		} else {
+			pidgin_docklet_update_icon();
+		}
+		ret = TRUE; /* keep blinking */
+	} else {
+		docklet_blinking_timer = 0;
+		blinked = FALSE;
 	}
 
 	return ret;
@@ -114,9 +112,8 @@
 	GList *convs, *l;
 	int count;
 	PurpleSavedStatus *saved_status;
-	PurpleStatusPrimitive prim;
-	DockletStatus newstatus = DOCKLET_STATUS_OFFLINE;
-	gboolean pending = FALSE, connecting = FALSE;
+	PurpleStatusPrimitive newstatus = PURPLE_STATUS_OFFLINE;
+	gboolean newpending = FALSE, newconnecting = FALSE;
 
 	/* get the current savedstatus */
 	saved_status = purple_savedstatus_get_current();
@@ -141,7 +138,7 @@
 	}
 
 	if (convs != NULL) {
-		pending = TRUE;
+		newpending = TRUE;
 
 		/* set tooltip if messages are pending */
 		if (ui_ops->set_tooltip) {
@@ -190,38 +187,22 @@
 
 		account_status = purple_account_get_active_status(account);
 		if (purple_account_is_connecting(account))
-			connecting = TRUE;
+			newconnecting = TRUE;
 	}
 
-	prim = purple_savedstatus_get_type(saved_status);
-	if (pending)
-		newstatus = DOCKLET_STATUS_PENDING;
-	else if (connecting)
-		newstatus = DOCKLET_STATUS_CONNECTING;
-	else if (prim == PURPLE_STATUS_UNAVAILABLE)
-		newstatus = DOCKLET_STATUS_BUSY;
-	else if (prim == PURPLE_STATUS_AWAY)
-		newstatus = DOCKLET_STATUS_AWAY;
-	else if (prim == PURPLE_STATUS_EXTENDED_AWAY)
-		newstatus = DOCKLET_STATUS_XA;
-	else if (prim == PURPLE_STATUS_OFFLINE)
-		newstatus = DOCKLET_STATUS_OFFLINE;
-	else if (prim == PURPLE_STATUS_INVISIBLE)
-		newstatus = DOCKLET_STATUS_INVISIBLE;
-	else
-		newstatus = DOCKLET_STATUS_AVAILABLE;
+	newstatus = purple_savedstatus_get_type(saved_status);
 
 	/* update the icon if we changed status */
-	if (status != newstatus) {
+	if (status != newstatus || pending!=newpending || connecting!=newconnecting) {
 		status = newstatus;
+		pending = newpending;
+		connecting = newconnecting;
 
-		if (ui_ops && ui_ops->update_icon)
-			ui_ops->update_icon(status);
+		pidgin_docklet_update_icon();
 
 		/* and schedule the blinker function if messages are pending */
-		if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink") &&
-		    status == DOCKLET_STATUS_PENDING
-		    && docklet_blinking_timer == 0) {
+		if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")
+			&& pending && !connecting && docklet_blinking_timer == 0) {
 			docklet_blinking_timer = g_timeout_add(500, docklet_blink_icon, NULL);
 		}
 	}
@@ -510,7 +491,7 @@
 
 	menuitem = gtk_menu_item_new_with_label(_("Unread Messages"));
 
-	if (status == DOCKLET_STATUS_PENDING) {
+	if (pending) {
 		GtkWidget *submenu = gtk_menu_new();
 		GList *l = get_pending_list(0);
 		if (l == NULL) {
@@ -530,7 +511,7 @@
 	pidgin_separator(menu);
 
 	menuitem = pidgin_new_item_from_stock(menu, _("New Message..."), PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, G_CALLBACK(pidgin_dialogs_im), NULL, 0, 0, NULL);
-	if (status == DOCKLET_STATUS_OFFLINE)
+	if (status == PURPLE_STATUS_OFFLINE)
 		gtk_widget_set_sensitive(menuitem, FALSE);
 
 	menuitem = docklet_status_submenu();
@@ -558,10 +539,6 @@
 
 	pidgin_separator(menu);
 
-	/* TODO: need a submenu to change status, this needs to "link"
-	 * to the status in the buddy list gtkstatusbox
-	 */
-
 	pidgin_new_item_from_stock(menu, _("Quit"), GTK_STOCK_QUIT, G_CALLBACK(purple_core_quit), NULL, 0, 0, NULL);
 
 #ifdef _WIN32
@@ -578,11 +555,18 @@
  * public api for ui_ops
  **************************************************************************/
 void
+pidgin_docklet_update_icon()
+{
+	if (ui_ops && ui_ops->update_icon)
+		ui_ops->update_icon(status, connecting, pending);
+}
+
+void
 pidgin_docklet_clicked(int button_type)
 {
 	switch (button_type) {
 		case 1:
-			if (status == DOCKLET_STATUS_PENDING) {
+			if (pending) {
 				GList *l = get_pending_list(1);
 				if (l != NULL) {
 					purple_conversation_present((PurpleConversation *)l->data);
@@ -608,8 +592,7 @@
 	}
 	visible = TRUE;
 	docklet_update_status();
-	if (ui_ops && ui_ops->update_icon)
-		ui_ops->update_icon(status);
+	pidgin_docklet_update_icon();
 }
 
 void
@@ -625,7 +608,7 @@
 			docklet_blinking_timer = 0;
 		}
 		visible = FALSE;
-		status = DOCKLET_STATUS_OFFLINE;
+		status = PURPLE_STATUS_OFFLINE;
 	}
 }
 
--- a/pidgin/gtkdocklet.h	Tue May 08 00:48:20 2007 +0000
+++ b/pidgin/gtkdocklet.h	Tue May 08 02:38:55 2007 +0000
@@ -25,23 +25,13 @@
 #ifndef _GTKDOCKLET_H_
 #define _GTKDOCKLET_H_
 
-typedef enum
-{
-	DOCKLET_STATUS_OFFLINE,
-	DOCKLET_STATUS_AVAILABLE,
-	DOCKLET_STATUS_INVISIBLE,
-	DOCKLET_STATUS_PENDING,
-	DOCKLET_STATUS_AWAY,
-	DOCKLET_STATUS_BUSY,
-	DOCKLET_STATUS_XA,
-	DOCKLET_STATUS_CONNECTING
-} DockletStatus;
+#include "status.h"
 
 struct docklet_ui_ops
 {
 	void (*create)(void);
 	void (*destroy)(void);
-	void (*update_icon)(DockletStatus);
+	void (*update_icon)(PurpleStatusPrimitive, gboolean, gboolean);
 	void (*blank_icon)(void);
 	void (*set_tooltip)(gchar *);
 	GtkMenuPositionFunc position_menu;
@@ -49,6 +39,7 @@
 
 
 /* functions in gtkdocklet.c */
+void pidgin_docklet_update_icon(void);
 void pidgin_docklet_clicked(int);
 void pidgin_docklet_embedded(void);
 void pidgin_docklet_remove(void);
--- a/pidgin/win32/gtkdocklet-win32.c	Tue May 08 00:48:20 2007 +0000
+++ b/pidgin/win32/gtkdocklet-win32.c	Tue May 08 02:38:55 2007 +0000
@@ -45,7 +45,8 @@
  *  LOCALS
  */
 static HWND systray_hwnd = NULL;
-static HICON cached_icons[DOCKLET_STATUS_CONNECTING + 1];
+/* additional two cached_icons entries for pending and connecting icons */
+static HICON cached_icons[PURPLE_STATUS_NUM_PRIMITIVES + 2];
 static GtkWidget *image = NULL;
 static NOTIFYICONDATA _nicon_data;
 
@@ -466,46 +467,56 @@
 	Shell_NotifyIcon(NIM_DELETE, &_nicon_data);
 }
 
-static void winpidgin_tray_update_icon(DockletStatus icon) {
+static void winpidgin_tray_update_icon(PurpleStatusPrimitive status,
+		gboolean connecting, gboolean pending) {
+
+	int icon_index;
+	g_return_if_fail(image != NULL);
 
-	g_return_if_fail(image != NULL);
-	g_return_if_fail(icon < (sizeof(cached_icons) / sizeof(HICON)));
+	if(connecting)
+		icon_index = PURPLE_STATUS_NUM_PRIMITIVES;
+	else if(pending)
+		icon_index = PURPLE_STATUS_NUM_PRIMITIVES+1;
+	else
+		icon_index = status;
+
+	g_return_if_fail(icon_index < (sizeof(cached_icons) / sizeof(HICON)));
 
 	/* Look up and cache the HICON if we don't already have it */
-	if (cached_icons[icon] == NULL) {
+	if (cached_icons[icon_index] == NULL) {
 		const gchar *icon_name = NULL;
-		switch (icon) {
-		case DOCKLET_STATUS_OFFLINE:
-			icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
-			break;
-		case DOCKLET_STATUS_CONNECTING:
-			icon_name = PIDGIN_STOCK_TRAY_CONNECT;
-			break;
-		case DOCKLET_STATUS_AVAILABLE:
-			icon_name = PIDGIN_STOCK_TRAY_AVAILABLE;
-			break;
-		case DOCKLET_STATUS_PENDING:
-			icon_name = PIDGIN_STOCK_TRAY_PENDING;
-			break;
-		case DOCKLET_STATUS_AWAY:
-			icon_name = PIDGIN_STOCK_TRAY_AWAY;
-			break;
-		case DOCKLET_STATUS_BUSY:
-			icon_name = PIDGIN_STOCK_TRAY_BUSY;
-			break;
-		case DOCKLET_STATUS_XA:
-			icon_name = PIDGIN_STOCK_TRAY_XA;
-			break;
-		case DOCKLET_STATUS_INVISIBLE:
-			icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
+		switch (status) {
+			case PURPLE_STATUS_OFFLINE:
+				icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
+				break;
+			case PURPLE_STATUS_AWAY:
+				icon_name = PIDGIN_STOCK_TRAY_AWAY;
+				break;
+			case PURPLE_STATUS_UNAVAILABLE:
+				icon_name = PIDGIN_STOCK_TRAY_BUSY;
+				break;
+			case PURPLE_STATUS_EXTENDED_AWAY:
+				icon_name = PIDGIN_STOCK_TRAY_XA;
+				break;
+			case PURPLE_STATUS_INVISIBLE:
+				icon_name = PIDGIN_STOCK_TRAY_INVISIBLE;
+				break;
+			default:
+				icon_name = PIDGIN_STOCK_TRAY_AVAILABLE;
+				break;
 		}
 
+		if (pending)
+			icon_name = PIDGIN_STOCK_TRAY_PENDING;
+		if (connecting)
+			icon_name = PIDGIN_STOCK_TRAY_CONNECT;
+	
 		g_return_if_fail(icon_name != NULL);
 
-		cached_icons[icon] = load_hicon_from_stock(icon_name);
+		cached_icons[icon_index] = load_hicon_from_stock(icon_name);
 	}
 
-	systray_change_icon(cached_icons[icon]);
+	systray_change_icon(cached_icons[icon_index]);
 }
 
 static void winpidgin_tray_blank_icon() {
@@ -557,21 +568,21 @@
 	 * That is why we use custom 4-bit icons for pre XP Windowses */
 	if (osinfo.dwMajorVersion < 5 || (osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion == 0))
 	{
-		cached_icons[DOCKLET_STATUS_OFFLINE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
+		cached_icons[PURPLE_STATUS_OFFLINE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
 			MAKEINTRESOURCE(PIDGIN_TRAY_OFFLINE_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
-		cached_icons[DOCKLET_STATUS_AVAILABLE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
+		cached_icons[PURPLE_STATUS_AVAILABLE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
 			MAKEINTRESOURCE(PIDGIN_TRAY_AVAILABLE_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
-		cached_icons[DOCKLET_STATUS_AWAY] = (HICON) LoadImage(winpidgin_dll_hinstance(),
+		cached_icons[PURPLE_STATUS_AWAY] = (HICON) LoadImage(winpidgin_dll_hinstance(),
 			MAKEINTRESOURCE(PIDGIN_TRAY_AWAY_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
-		cached_icons[DOCKLET_STATUS_XA] = (HICON) LoadImage(winpidgin_dll_hinstance(),
+		cached_icons[PURPLE_STATUS_EXTENDED_AWAY] = (HICON) LoadImage(winpidgin_dll_hinstance(),
 			MAKEINTRESOURCE(PIDGIN_TRAY_XA_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
-		cached_icons[DOCKLET_STATUS_BUSY] = (HICON) LoadImage(winpidgin_dll_hinstance(),
+		cached_icons[PURPLE_STATUS_UNAVAILABLE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
 			MAKEINTRESOURCE(PIDGIN_TRAY_BUSY_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
-		cached_icons[DOCKLET_STATUS_CONNECTING] = (HICON) LoadImage(winpidgin_dll_hinstance(),
+		cached_icons[PURPLE_STATUS_NUM_PRIMITIVES] = (HICON) LoadImage(winpidgin_dll_hinstance(),
 			MAKEINTRESOURCE(PIDGIN_TRAY_CONNECTING_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
-		cached_icons[DOCKLET_STATUS_PENDING] = (HICON) LoadImage(winpidgin_dll_hinstance(),
+		cached_icons[PURPLE_STATUS_NUM_PRIMITIVES+1] = (HICON) LoadImage(winpidgin_dll_hinstance(),
 			MAKEINTRESOURCE(PIDGIN_TRAY_PENDING_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
-		cached_icons[DOCKLET_STATUS_INVISIBLE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
+		cached_icons[PURPLE_STATUS_INVISIBLE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
 			MAKEINTRESOURCE(PIDGIN_TRAY_INVISIBLE_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
 	}