2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001 Hiroyuki Yamamoto & The Sylpheed Claws Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 /* (alfons) - based on a contribution by Satoshi Nagayasu; revised for colorful
21 * menu and more Sylpheed integration. The idea to put the code in a separate
22 * file is just that it make it easier to allow "user changeable" label colors.
29 #include <gtk/gtkwidget.h>
30 #include <gtk/gtkpixmap.h>
31 #include <gtk/gtkmenu.h>
32 #include <gtk/gtkcheckmenuitem.h>
33 #include <gtk/gtklabel.h>
34 #include <gtk/gtkmenuitem.h>
35 #include <gtk/gtkalignment.h>
36 #include <gtk/gtkhbox.h>
37 #include <gtk/gtkwindow.h>
40 #include "colorlabel.h"
43 static gchar
*labels
[] = {
53 typedef enum LabelColorChangeFlags_
{
56 LCCF_ALL
= LCCF_COLOR
| LCCF_LABEL
57 } LabelColorChangeFlags
;
59 /* XXX: if you add colors, make sure you also check the procmsg.h.
60 * color indices are stored as 3 bits; that explains the max. of 7 colors */
63 LabelColorChangeFlags changed
;
66 /* XXX: note that the label member is supposed to be dynamically
67 * allocated and fffreed */
71 { LCCF_ALL
, { 0, 0xffff, (0x99 << 8), 0x0 }, NULL
, NULL
},
72 { LCCF_ALL
, { 0, 0xffff, 0, 0 }, NULL
, NULL
},
73 { LCCF_ALL
, { 0, 0xffff, (0x66 << 8), 0xffff }, NULL
, NULL
},
74 { LCCF_ALL
, { 0, 0x0, (0xcc << 8), 0xffff }, NULL
, NULL
},
75 { LCCF_ALL
, { 0, 0x0, 0x0, 0xffff }, NULL
, NULL
},
76 { LCCF_ALL
, { 0, 0x0, 0x99 << 8, 0x0 }, NULL
, NULL
},
77 { LCCF_ALL
, { 0, 0x66 << 8, 0x33 << 8, 0x33 << 8 }, NULL
, NULL
}
80 #define LABEL_COLORS_ELEMS (sizeof label_colors / sizeof label_colors[0])
82 #define G_RETURN_VAL_IF_INVALID_COLOR(color, val) \
83 g_return_val_if_fail((color) >= 0 && (color) < LABEL_COLORS_ELEMS, (val))
85 static void colorlabel_recreate (gint
);
86 static void colorlabel_recreate_label (gint
);
88 gint
colorlabel_get_color_count(void)
90 return LABEL_COLORS_ELEMS
;
93 GdkColor
colorlabel_get_color(gint color_index
)
95 GdkColor invalid
= { 0 };
97 G_RETURN_VAL_IF_INVALID_COLOR(color_index
, invalid
);
99 return label_colors
[color_index
].color
;
102 gchar
*colorlabel_get_color_text(gint color_index
)
104 G_RETURN_VAL_IF_INVALID_COLOR(color_index
, NULL
);
106 colorlabel_recreate_label(color_index
);
107 return label_colors
[color_index
].label
;
110 GtkPixmap
*colorlabel_create_color_pixmap(GdkColor color
)
112 const gchar
*FMT
= "+ c #%2.2X%2.2X%2.2X";
115 /* black frame of 1 pixel */
116 gchar
*dummy_xpm
[] = {
143 /* put correct color in xpm data */
144 sprintf(buf
, FMT
, color
.red
>> 8, color
.green
>> 8, color
.blue
>> 8);
147 /* XXX: passing NULL as GdkWindow* seems to be possible */
148 xpm
= gdk_pixmap_create_from_xpm_d
149 (GDK_ROOT_PARENT(), &xpmmask
, NULL
, (gchar
**) &dummy_xpm
);
151 debug_print("*** NO XPM\n");
152 pixmap
= GTK_PIXMAP(gtk_pixmap_new(xpm
, xpmmask
));
154 g_return_val_if_fail(pixmap
, NULL
);
156 gdk_pixmap_unref(xpm
);
157 gdk_bitmap_unref(xpmmask
);
162 /* XXX: this function to check if menus with colors and labels should
164 gboolean
colorlabel_changed(void)
168 for (n
= 0; n
< LABEL_COLORS_ELEMS
; n
++) {
169 if (label_colors
[n
].changed
)
176 /* XXX: colorlabel_recreate_XXX are there to make sure everything
177 * is initialized ok, without having to call a global _xxx_init_
179 static void colorlabel_recreate_color(gint color
)
183 if (!(label_colors
[color
].changed
& LCCF_COLOR
))
186 pixmap
= GTK_PIXMAP(colorlabel_create_color_pixmap(label_colors
[color
].color
));
187 g_return_if_fail(pixmap
);
189 if (label_colors
[color
].pixmap
)
190 gtk_widget_destroy(GTK_WIDGET(label_colors
[color
].pixmap
));
192 label_colors
[color
].pixmap
= pixmap
;
193 label_colors
[color
].changed
&= ~LCCF_COLOR
;
196 static void colorlabel_recreate_label(gint color
)
198 if (!label_colors
[color
].changed
& LCCF_LABEL
)
201 if (label_colors
[color
].label
== NULL
)
202 label_colors
[color
].label
= g_strdup(gettext(labels
[color
]));
204 label_colors
[color
].changed
&= ~LCCF_LABEL
;
207 /* XXX: call this function everytime when you're doing important
208 * stuff with the label_colors[] array */
209 static void colorlabel_recreate(gint color
)
211 colorlabel_recreate_label(color
);
212 colorlabel_recreate_color(color
);
215 static void colorlabel_recreate_all(void)
219 for ( n
= 0; n
< LABEL_COLORS_ELEMS
; n
++)
220 colorlabel_recreate(n
);
223 /* colorlabel_create_check_color_menu_item() - creates a color
224 * menu item with a check box */
225 GtkWidget
*colorlabel_create_check_color_menu_item(gint color_index
)
232 G_RETURN_VAL_IF_INVALID_COLOR(color_index
, NULL
);
234 item
= gtk_check_menu_item_new();
236 colorlabel_recreate(color_index
);
238 /* XXX: gnome-core::panel::menu.c is a great example of
239 * how to create pixmap menus */
240 label
= gtk_label_new(label_colors
[color_index
].label
);
242 gtk_misc_set_alignment(GTK_MISC(label
), 0.0, 0.5);
243 gtk_widget_show(label
);
244 hbox
= gtk_hbox_new(FALSE
, 0);
245 gtk_widget_show(hbox
);
246 gtk_container_add(GTK_CONTAINER(item
), hbox
);
248 align
= gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
249 gtk_widget_show(align
);
250 gtk_container_set_border_width(GTK_CONTAINER(align
), 1);
252 gtk_container_add(GTK_CONTAINER(align
),
253 GTK_WIDGET(label_colors
[color_index
].pixmap
));
254 gtk_widget_show(GTK_WIDGET(label_colors
[color_index
].pixmap
));
255 gtk_widget_set_usize(align
, 16, 16);
257 gtk_box_pack_start(GTK_BOX(hbox
), align
, FALSE
, FALSE
, 0);
258 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 4);
263 /* colorlabel_create_color_menu() - creates a color menu without
264 * checkitems, probably for use in combo items */
265 GtkWidget
*colorlabel_create_color_menu(void)
274 colorlabel_recreate_all();
276 /* create the menu items. each item has its color code attached */
277 menu
= gtk_menu_new();
278 gtk_object_set_data(GTK_OBJECT(menu
), "label_color_menu", menu
);
280 item
= gtk_menu_item_new_with_label(_("None"));
281 gtk_menu_append(GTK_MENU(menu
), item
);
282 gtk_object_set_data(GTK_OBJECT(item
), "color", GUINT_TO_POINTER(0));
283 gtk_widget_show(item
);
285 /* and the color items */
286 for (i
= 0; i
< LABEL_COLORS_ELEMS
; i
++) {
287 GtkPixmap
*pixmap
= colorlabel_create_color_pixmap(label_colors
[i
].color
);
289 item
= gtk_menu_item_new();
290 gtk_object_set_data(GTK_OBJECT(item
), "color", GUINT_TO_POINTER(i
+ 1));
292 label
= gtk_label_new(label_colors
[i
].label
);
294 gtk_misc_set_alignment(GTK_MISC(label
), 0.0, 0.5);
295 gtk_widget_show(label
);
296 hbox
= gtk_hbox_new(FALSE
, 0);
297 gtk_widget_show(hbox
);
298 gtk_container_add(GTK_CONTAINER(item
), hbox
);
300 align
= gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
301 gtk_widget_show(align
);
302 gtk_container_set_border_width(GTK_CONTAINER(align
), 1);
304 gtk_container_add(GTK_CONTAINER(align
), GTK_WIDGET(pixmap
));
305 gtk_widget_show(GTK_WIDGET(pixmap
));
306 gtk_widget_set_usize(align
, 16, 16);
308 gtk_box_pack_start(GTK_BOX(hbox
), align
, FALSE
, FALSE
, 0);
309 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 4);
311 gtk_menu_append(GTK_MENU(menu
), item
);
312 gtk_widget_show(item
);
315 gtk_widget_show(menu
);
320 guint
colorlabel_get_color_menu_active_item(GtkWidget
*menu
)
326 (gtk_object_get_data(GTK_OBJECT(menu
), "label_color_menu"), 0);
327 menuitem
= gtk_menu_get_active(GTK_MENU(menu
));
328 color
= GPOINTER_TO_UINT
329 (gtk_object_get_data(GTK_OBJECT(menuitem
), "color"));