1 /*
2 * overviewcolor.c - This file is part of the Geany Overview plugin
3 *
4 * Copyright (c) 2015 Matthew Brush <mbrush@codebrainz.ca>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include "overviewcolor.h"
28 #include <string.h>
29
30 OverviewColor *
overview_color_copy(OverviewColor * color)31 overview_color_copy (OverviewColor *color)
32 {
33 OverviewColor *new_color = g_slice_new0 (OverviewColor);
34 memcpy (new_color, color, sizeof (OverviewColor));
35 return new_color;
36 }
37
38 void
overview_color_free(OverviewColor * color)39 overview_color_free (OverviewColor *color)
40 {
41 if (color != NULL)
42 g_slice_free (OverviewColor, color);
43 }
44
45 gboolean
overview_color_equal(const OverviewColor * color1,const OverviewColor * color2)46 overview_color_equal (const OverviewColor *color1,
47 const OverviewColor *color2)
48 {
49 return (color1->red == color2->red &&
50 color1->green == color2->green &&
51 color1->blue == color2->blue &&
52 color1->alpha == color2->alpha);
53 }
54
55 gboolean
overview_color_parse(OverviewColor * color,const gchar * color_str)56 overview_color_parse (OverviewColor *color,
57 const gchar *color_str)
58 {
59 g_return_val_if_fail (color != NULL, FALSE);
60 g_return_val_if_fail (color_str != NULL, FALSE);
61
62 #if GTK_CHECK_VERSION (3, 0, 0)
63 GdkRGBA gcolor;
64 if (gdk_rgba_parse (&gcolor, color_str))
65 {
66 overview_color_from_rgba (color, &gcolor);
67 return TRUE;
68 }
69 #else
70 GdkColor gcolor;
71 if (gdk_color_parse (color_str, &gcolor))
72 {
73 overview_color_from_gdk_color (color, &gcolor, 1.0);
74 return TRUE;
75 }
76 #endif
77
78 return FALSE;
79 }
80
81 gchar *
overview_color_to_string(const OverviewColor * color)82 overview_color_to_string (const OverviewColor *color)
83 {
84 g_return_val_if_fail (color != NULL, NULL);
85
86 #if GTK_CHECK_VERSION (3, 0, 0)
87 GdkRGBA gcolor;
88 overview_color_to_rgba (color, &gcolor);
89 return gdk_rgba_to_string (&gcolor);
90 #else
91 GdkColor gcolor;
92 overview_color_to_gdk_color (color, &gcolor);
93 return gdk_color_to_string (&gcolor);
94 #endif
95 }
96
97 void
overview_color_from_gdk_color(OverviewColor * color,const GdkColor * gcolor,gdouble alpha)98 overview_color_from_gdk_color (OverviewColor *color,
99 const GdkColor *gcolor,
100 gdouble alpha)
101 {
102 g_return_if_fail (color != NULL);
103 g_return_if_fail (gcolor != NULL);
104
105 color->red = (gdouble) gcolor->red / G_MAXUINT16;
106 color->green = (gdouble) gcolor->green / G_MAXUINT16;
107 color->blue = (gdouble) gcolor->blue / G_MAXUINT16;
108 color->alpha = alpha;
109 }
110
111 void
overview_color_to_gdk_color(const OverviewColor * color,GdkColor * gcolor)112 overview_color_to_gdk_color (const OverviewColor *color,
113 GdkColor *gcolor)
114 {
115 g_return_if_fail (color != NULL);
116 g_return_if_fail (gcolor != NULL);
117
118 gcolor->red = (guint16)(color->red * G_MAXUINT16);
119 gcolor->green = (guint16)(color->green * G_MAXUINT16);
120 gcolor->blue = (guint16)(color->blue * G_MAXUINT16);
121 }
122
123 #if GTK_CHECK_VERSION (3, 0, 0)
124 void
overview_color_from_rgba(OverviewColor * color,const GdkRGBA * rgba)125 overview_color_from_rgba (OverviewColor *color,
126 const GdkRGBA *rgba)
127 {
128 g_return_if_fail (color != NULL);
129 g_return_if_fail (rgba != NULL);
130
131 color->red = rgba->red;
132 color->green = rgba->green;
133 color->blue = rgba->blue;
134 color->alpha = rgba->alpha;
135 }
136
137 void
overview_color_to_rgba(const OverviewColor * color,GdkRGBA * rgba)138 overview_color_to_rgba (const OverviewColor *color,
139 GdkRGBA *rgba)
140 {
141 g_return_if_fail (color != NULL);
142 g_return_if_fail (rgba != NULL);
143
144 rgba->red = color->red;
145 rgba->green = color->green;
146 rgba->blue = color->blue;
147 rgba->alpha = color->alpha;
148 }
149 #endif
150
151 void
overview_color_from_int(OverviewColor * color,guint32 abgr,gboolean with_alpha)152 overview_color_from_int (OverviewColor *color,
153 guint32 abgr,
154 gboolean with_alpha)
155 {
156 g_return_if_fail (color != NULL);
157 guint8 r = abgr & 0xFF;
158 guint8 g = (abgr>>8) & 0xFF;
159 guint8 b = (abgr>>16) & 0xFF;
160 guint8 a = 255;
161
162 if (with_alpha)
163 a = (abgr>>24) & 0xFF;
164
165 color->red = (gdouble)r / G_MAXUINT8;
166 color->green = (gdouble)g / G_MAXUINT8;
167 color->blue = (gdouble)b / G_MAXUINT8;
168 color->alpha = (gdouble)a / G_MAXUINT8;
169 }
170
171 guint32
overview_color_to_int(const OverviewColor * color,gboolean with_alpha)172 overview_color_to_int (const OverviewColor *color,
173 gboolean with_alpha)
174 {
175 g_return_val_if_fail (color != NULL, 0);
176
177 guint32 r = (guint8)(color->red * 255.0);
178 guint32 g = (guint8)(color->green * 255.0);
179 guint32 b = (guint8)(color->blue * 255.0);
180 guint32 a = 0;
181
182 if (with_alpha)
183 a = (guint8)(color->alpha * 255.0);
184
185 return (a<<24) | (b<<16) | (g<<8) | r;
186 }
187
188 gboolean
overview_color_from_keyfile(OverviewColor * color,GKeyFile * keyfile,const gchar * section,const gchar * option,GError ** error)189 overview_color_from_keyfile (OverviewColor *color,
190 GKeyFile *keyfile,
191 const gchar *section,
192 const gchar *option,
193 GError **error)
194 {
195 gchar *color_key;
196 gchar *alpha_key;
197 gchar *clr_str;
198 gdouble alpha;
199
200 g_return_val_if_fail (color != NULL, FALSE);
201 g_return_val_if_fail (keyfile != NULL, FALSE);
202 g_return_val_if_fail (section != NULL, FALSE);
203 g_return_val_if_fail (option != NULL, FALSE);
204
205 color_key = g_strdup_printf ("%s-color", option);
206 alpha_key = g_strdup_printf ("%s-alpha", option);
207
208 clr_str = g_key_file_get_string (keyfile, section, color_key, error);
209 if (*error != NULL)
210 {
211 g_free (color_key);
212 g_free (alpha_key);
213 return FALSE;
214 }
215
216 g_free (color_key);
217
218 alpha = g_key_file_get_double (keyfile, section, alpha_key, error);
219 if (*error != NULL)
220 {
221 g_free (alpha_key);
222 g_free (clr_str);
223 return FALSE;
224 }
225
226 g_free (alpha_key);
227
228 if (alpha < 0.0 || alpha > 1.0)
229 g_warning ("alpha value '%g' from keyfile out of 0-1 range", alpha);
230
231 overview_color_parse (color, clr_str);
232 color->alpha = alpha;
233
234 g_free (clr_str);
235
236 return TRUE;
237 }
238
239 gboolean
overview_color_to_keyfile(const OverviewColor * color,GKeyFile * keyfile,const gchar * section,const gchar * option)240 overview_color_to_keyfile (const OverviewColor *color,
241 GKeyFile *keyfile,
242 const gchar *section,
243 const gchar *option)
244 {
245 gchar *color_key;
246 gchar *alpha_key;
247 gchar *clr_str;
248
249 g_return_val_if_fail (color != NULL, FALSE);
250 g_return_val_if_fail (keyfile != NULL, FALSE);
251 g_return_val_if_fail (section != NULL, FALSE);
252 g_return_val_if_fail (option != NULL, FALSE);
253
254 color_key = g_strdup_printf ("%s-color", option);
255 alpha_key = g_strdup_printf ("%s-alpha", option);
256
257 clr_str = overview_color_to_string (color);
258 g_key_file_set_string (keyfile, section, color_key, clr_str);
259 g_free (color_key);
260 g_free (clr_str);
261
262 g_key_file_set_double (keyfile, section, alpha_key, color->alpha);
263 g_free (alpha_key);
264
265 return TRUE;
266 }
267
268 void
overview_color_from_color_button(OverviewColor * color,GtkColorButton * button)269 overview_color_from_color_button (OverviewColor *color,
270 GtkColorButton *button)
271 {
272 GdkColor gcolor;
273 guint16 alpha;
274 gdouble falpha;
275 gtk_color_button_get_color (button, &gcolor);
276 alpha = gtk_color_button_get_alpha (button);
277 falpha = (gdouble) alpha / (gdouble) G_MAXUINT16;
278 overview_color_from_gdk_color (color, &gcolor, falpha);
279 }
280
281 void
overview_color_to_color_button(const OverviewColor * color,GtkColorButton * button)282 overview_color_to_color_button (const OverviewColor *color,
283 GtkColorButton *button)
284 {
285 GdkColor gcolor;
286 guint16 alpha;
287 overview_color_to_gdk_color (color, &gcolor);
288 gtk_color_button_set_color (button, &gcolor);
289 alpha = (guint16)(color->alpha * (gdouble) G_MAXUINT16);
290 gtk_color_button_set_alpha (button, alpha);
291 }
292
293 GType
overview_color_get_type(void)294 overview_color_get_type (void)
295 {
296 static GType type = 0;
297 if (type == 0)
298 {
299 type =
300 g_boxed_type_register_static ("OverviewColor",
301 (GBoxedCopyFunc) overview_color_copy,
302 (GBoxedFreeFunc) overview_color_free);
303 }
304 return type;
305 }
306