1 | /* bonobo-ui-state-cache.h: Image state cache for the Bonobo UI engine |
---|
2 | * |
---|
3 | * Copyright (C) 2001 Ximian, Inc. |
---|
4 | * |
---|
5 | * Author: Federico Mena-Quintero <federico@ximian.com> |
---|
6 | * |
---|
7 | * This library is free software; you can redistribute it and/or |
---|
8 | * modify it under the terms of the GNU Library General Public |
---|
9 | * License as published by the Free Software Foundation; either |
---|
10 | * version 2 of the License, or (at your option) any later version. |
---|
11 | * |
---|
12 | * This library is distributed in the hope that it will be useful, |
---|
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
15 | * Library General Public License for more details. |
---|
16 | * |
---|
17 | * You should have received a copy of the GNU Library General Public |
---|
18 | * License along with this library; if not, write to the |
---|
19 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
20 | * Boston, MA 02111-1307, USA. |
---|
21 | */ |
---|
22 | |
---|
23 | #ifdef HAVE_CONFIG_H |
---|
24 | #include <config.h> |
---|
25 | #endif |
---|
26 | |
---|
27 | #include "bonobo-ui-state-cache.h" |
---|
28 | #include "bonobo-ui-icon-modify.h" |
---|
29 | |
---|
30 | |
---|
31 | |
---|
32 | /* Structure to hold image modification parameters for the different widget states */ |
---|
33 | typedef struct { |
---|
34 | double saturation; |
---|
35 | gboolean pixelate; |
---|
36 | double pixelate_dark_factor; |
---|
37 | } Modifiers; |
---|
38 | |
---|
39 | /* A provided pixbuf and its modifiers; used as keys in the cache hash table */ |
---|
40 | typedef struct { |
---|
41 | GdkPixbuf *pixbuf; |
---|
42 | Modifiers mods; |
---|
43 | } PixbufModifiers; |
---|
44 | |
---|
45 | /* Defaults for icon desaturation/pixelation */ |
---|
46 | const static Modifiers defaults[] = { |
---|
47 | { 1.0, FALSE, 1.0 }, /* GTK_STATE_NORMAL */ |
---|
48 | { 1.0, FALSE, 1.0 }, /* GTK_STATE_ACTIVE */ |
---|
49 | { 1.0, FALSE, 1.0 }, /* GTK_STATE_PRELIGHT */ |
---|
50 | { 1.0, FALSE, 1.0 }, /* GTK_STATE_SELECTED */ |
---|
51 | { 0.8, TRUE, 0.7 }, /* GTK_STATE_INSENSITIVE */ |
---|
52 | }; |
---|
53 | |
---|
54 | |
---|
55 | |
---|
56 | /* Number of GdkStateType values */ |
---|
57 | #define NUM_STATES 5 |
---|
58 | |
---|
59 | /* Mapping of PixbufModfier structures to modified pixbufs */ |
---|
60 | static GHashTable *pixbuf_modifier_hash = NULL; |
---|
61 | |
---|
62 | |
---|
63 | |
---|
64 | /* Hash function for a PixbufModifiers key. */ |
---|
65 | static guint |
---|
66 | pixbuf_modifier_hash_fn (gconstpointer key) |
---|
67 | { |
---|
68 | const PixbufModifiers *pm; |
---|
69 | int saturation, pixelate_dark_factor; |
---|
70 | guint hash; |
---|
71 | |
---|
72 | pm = key; |
---|
73 | |
---|
74 | /* Convert the doubles to reasonable ints for hashing */ |
---|
75 | saturation = G_MAXINT * pm->mods.saturation; |
---|
76 | pixelate_dark_factor = G_MAXINT * pm->mods.pixelate_dark_factor; |
---|
77 | |
---|
78 | hash = GPOINTER_TO_UINT (pm->pixbuf) ^ saturation ^ pixelate_dark_factor; |
---|
79 | |
---|
80 | if (pm->mods.pixelate) |
---|
81 | hash = ~hash; |
---|
82 | |
---|
83 | return hash; |
---|
84 | } |
---|
85 | |
---|
86 | /* Comparison function for the PixbufModifiers hash table */ |
---|
87 | static gint |
---|
88 | pixbuf_modifier_equal_fn (gconstpointer a, gconstpointer b) |
---|
89 | { |
---|
90 | const PixbufModifiers *pma, *pmb; |
---|
91 | |
---|
92 | pma = a; |
---|
93 | pmb = b; |
---|
94 | |
---|
95 | return (pma->pixbuf == pmb->pixbuf |
---|
96 | && pma->mods.saturation == pmb->mods.saturation |
---|
97 | && pma->mods.pixelate == pmb->mods.pixelate |
---|
98 | && pma->mods.pixelate_dark_factor == pmb->mods.pixelate_dark_factor); |
---|
99 | } |
---|
100 | |
---|
101 | /* Ensures that the pixbuf->set hash table has been created */ |
---|
102 | static void |
---|
103 | ensure_hash_table (void) |
---|
104 | { |
---|
105 | if (pixbuf_modifier_hash) |
---|
106 | return; |
---|
107 | |
---|
108 | pixbuf_modifier_hash = g_hash_table_new (pixbuf_modifier_hash_fn, pixbuf_modifier_equal_fn); |
---|
109 | } |
---|
110 | |
---|
111 | /* Generates a pixbuf out of the specified one by modifying it as appropriate |
---|
112 | * for a widget state. |
---|
113 | */ |
---|
114 | static GdkPixbuf * |
---|
115 | make_pixbuf_for_state (GdkPixbuf *source, GtkStateType state) |
---|
116 | { |
---|
117 | return bonobo_ui_icon_modify (source, |
---|
118 | defaults[state].saturation, |
---|
119 | defaults[state].pixelate, |
---|
120 | defaults[state].pixelate_dark_factor); |
---|
121 | } |
---|
122 | |
---|
123 | /** |
---|
124 | * bonobo_ui_state_cache_get: |
---|
125 | * @source: Source pixbuf. |
---|
126 | * @state: Widget state for the result. |
---|
127 | * |
---|
128 | * Takes a @source pixbuf and modifies it as appropriate for display in the |
---|
129 | * specified widget @state. For example, an image could be grayed out for |
---|
130 | * insensitive widgets. The returned pixbuf comes from a cache; you should |
---|
131 | * unref it with gdk_pixbuf_unref() when you are done with it. |
---|
132 | * |
---|
133 | * Return value: A pixbuf, or NULL if the modified image could not be created. |
---|
134 | **/ |
---|
135 | GdkPixbuf * |
---|
136 | bonobo_ui_state_cache_get (GdkPixbuf *source, GtkStateType state) |
---|
137 | { |
---|
138 | PixbufModifiers pm; |
---|
139 | GdkPixbuf *modified; |
---|
140 | |
---|
141 | g_return_val_if_fail (source != NULL, NULL); |
---|
142 | g_return_val_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE, NULL); |
---|
143 | |
---|
144 | ensure_hash_table (); |
---|
145 | |
---|
146 | pm.pixbuf = source; |
---|
147 | pm.mods = defaults[state]; |
---|
148 | |
---|
149 | modified = g_hash_table_lookup (pixbuf_modifier_hash, &pm); |
---|
150 | |
---|
151 | if (!modified) { |
---|
152 | PixbufModifiers *pm_copy; |
---|
153 | |
---|
154 | modified = make_pixbuf_for_state (source, state); |
---|
155 | if (!modified) |
---|
156 | return NULL; |
---|
157 | |
---|
158 | pm_copy = g_new (PixbufModifiers, 1); |
---|
159 | *pm_copy = pm; |
---|
160 | gdk_pixbuf_ref (source); |
---|
161 | |
---|
162 | g_hash_table_insert (pixbuf_modifier_hash, pm_copy, modified); |
---|
163 | } |
---|
164 | |
---|
165 | g_assert (modified != NULL); |
---|
166 | |
---|
167 | gdk_pixbuf_ref (modified); |
---|
168 | |
---|
169 | return modified; |
---|
170 | } |
---|