c0a1bd4814b0c64d1aa6f6f96a24f8da2d56b10d
[hildon] / hildon-widgets / hildon-color-selector.c
1 /*
2  * This file is part of hildon-libs
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Luc Pionchon <luc.pionchon@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24
25 /*
26  * @file hildon-color-selector.c
27  *
28  * This file contains the implementation of Hildon Color Selector
29  * widget containing the base color and custom color palette selector 
30  * and popup for selecting different colors based on RGB values.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include <gtk/gtktable.h>
38 #include <gtk/gtkhbox.h>
39 #include <gtk/gtklabel.h>
40 #include <gtk/gtkdrawingarea.h>
41 #include <gdk/gdkkeysyms.h>
42 #include <gconf/gconf-client.h> 
43
44 #include "hildon-color-selector.h"
45 #include "hildon-color-popup.h"
46
47 #include <libintl.h>
48 #define _(String) dgettext(PACKAGE, String)
49
50 /* Color amounts */
51 #define HILDON_BASE_COLOR_NUM             16
52 #define HILDON_CUSTOM_COLOR_NUM            8
53 #define HILDON_TOTAL_COLOR_NUM \
54   (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM)
55 #define BLACKIND                           0
56 #define GREYIND                            6
57 #define WHITEIND                           9
58
59 /* Pixel sizes */
60 #define HILDON_COLOR_SELECTOR_BOX_W       27
61 #define HILDON_COLOR_SELECTOR_BOX_H       27
62 #define HILDON_COLOR_SELECTOR_BOX_BORDER   2
63 #define HILDON_COLOR_SELECTOR_COLS         8
64 #define HILDON_COLOR_SELECTOR_ROWS         3
65 #define HILDON_COLOR_PALETTE_SIZE        120
66 #define HILDON_COLOR_CONTROLBAR_MAX       31
67 #define HILDON_COLOR_CONTROLBAR_MIN        0 
68 #define HILDON_COLOR_LABELS_LEFT_PAD      35
69 #define HILDON_COLOR_PALETTE_POS_PAD      45
70 #define HILDON_COLOR_BAR_WIDTH 449
71
72 #define HILDON_MORE_BUTTON_RESPONSE     1234
73
74 /* gconf definitions */
75 #define HILDON_COLOR_GCONF_PATH  "/system/osso/af/color_selector"
76 #define HILDON_COLOR_GCONF_KEYS  "/system/osso/af/color_selector/custom_colors"
77 /*
78  * Pointer parent class 
79  */
80 static GtkDialogClass *parent_class;
81
82 struct _HildonColorSelectorPriv 
83 {
84     GConfClient *client;
85     GtkWidget *drawing_area;
86     gint index;
87     guint notify_id;
88
89     /* one extra place for the modified base color */
90     GdkColor color[HILDON_TOTAL_COLOR_NUM + 1];
91 };
92
93 /* 
94  * Private function prototype definitions 
95  */
96 static void
97 hildon_color_selector_class_init (HildonColorSelectorClass * selector_class);
98
99 static void 
100 hildon_color_selector_init (HildonColorSelector * selector);
101
102 static gboolean
103 hildon_color_selector_expose (GtkWidget * widget,
104                               GdkEventExpose * event, 
105                               gpointer data);
106
107 static void 
108 hildon_color_selector_response (GtkWidget * widget,
109                                gint response_id, 
110                                gpointer data);
111
112 static gboolean 
113 key_pressed (GtkWidget * widget, 
114              GdkEventKey * event, 
115              gpointer user_data);
116
117 static gboolean 
118 color_pressed (GtkWidget * widget, 
119                GdkEventButton * event, 
120                gpointer user_data);
121
122 static void
123 select_color (HildonColorSelector * selector, 
124               int event_x, 
125               int event_y);   
126
127 static gboolean
128 color_moved (GtkWidget * widget, 
129              GdkEventMotion * event, 
130              gpointer data);
131
132 GType 
133 hildon_color_selector_get_type(void)
134 {
135     static GType selector_type = 0;
136
137     if (!selector_type) 
138     {
139         static const GTypeInfo selector_info = 
140             {
141                 sizeof(HildonColorSelectorClass),
142                 NULL,       /* base_init */
143                 NULL,       /* base_finalize */
144                 (GClassInitFunc) hildon_color_selector_class_init,
145                 NULL,       /* class_finalize */
146                 NULL,       /* class_data */
147                 sizeof(HildonColorSelector),
148                 0,  /* n_preallocs */
149                 (GInstanceInitFunc) hildon_color_selector_init,
150             };
151         selector_type = g_type_register_static(GTK_TYPE_DIALOG,
152                                                "HildonColorSelector",
153                                                &selector_info, 0);
154     }
155     return selector_type;
156 }
157
158 static void
159 hildon_color_selector_destroy(GtkObject *obj)
160 {
161   HildonColorSelectorPriv *priv = HILDON_COLOR_SELECTOR(obj)->priv;
162
163   if (priv->client)
164   {
165     gconf_client_notify_remove(priv->client, priv->notify_id);
166     g_object_unref(priv->client);
167     priv->client = NULL;
168   }
169
170   GTK_OBJECT_CLASS(parent_class)->destroy(obj);
171 }
172
173 static void
174 hildon_color_selector_class_init(HildonColorSelectorClass * selector_class)
175 {
176     parent_class = g_type_class_peek_parent(selector_class);
177     
178     g_type_class_add_private(selector_class,
179                              sizeof(HildonColorSelectorPriv));
180
181     GTK_OBJECT_CLASS(selector_class)->destroy = hildon_color_selector_destroy;
182 }
183
184
185 /**
186  * hildon_color_selector_new:
187  * @parent:  The parent window. The X window ID of the parent window
188  *           has to be the same as the X window ID of the application.
189  * @returns: new #HildonColorSelector.
190  *
191  * Creates a new #HildonColorSelector dialog with 3x8 layout of 
192  * Windows base colors and 'OK', 'More..' and 'Cancel' buttons.
193  **/
194 GtkWidget *hildon_color_selector_new(GtkWindow * parent)
195 {
196     GtkWidget *dialog = g_object_new(HILDON_TYPE_COLOR_SELECTOR, NULL);
197
198     g_assert(dialog);
199
200     if (parent) 
201     {
202         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
203     }
204
205     return dialog;
206 }
207
208 static void
209 hildon_color_selector_set_custom_colors(
210   HildonColorSelector *selector,
211   GConfValue *value)
212 {
213   GSList *list;
214   int i;
215
216   g_assert(HILDON_IS_COLOR_SELECTOR(selector));
217
218   /* We have to be really carefull. At least gconftool's
219      stress test can generate pretty ugly value setups */
220   if (value == NULL || value->type != GCONF_VALUE_LIST ||
221     gconf_value_get_list_type(value) != GCONF_VALUE_STRING)
222     list = NULL;
223   else
224     list = gconf_value_get_list(value);
225
226   for ( i = 0; i < HILDON_CUSTOM_COLOR_NUM; ++i)
227   {
228     const gchar *color_string = NULL;
229
230     if (list) {
231       color_string = gconf_value_get_string(list->data);
232       list = list->next;
233     } else {
234       color_string = "#FFFFFF";
235     }
236
237 /*    g_print("custom_color: %s\n", color_string);  */
238
239     selector->priv->color[i].pixel = 0;
240     gdk_color_parse (color_string, 
241        &(selector->priv->color[HILDON_BASE_COLOR_NUM+i]));
242   }
243 }
244
245 static void
246 gconf_notify_func(GConfClient *client,
247                              guint cnxn_id,
248                              GConfEntry *entry,
249                              gpointer data)
250 {
251   hildon_color_selector_set_custom_colors(HILDON_COLOR_SELECTOR(data), 
252     gconf_entry_get_value(entry));
253   gtk_widget_queue_draw(GTK_WIDGET(data));
254 }
255
256 static void 
257 hildon_color_selector_init(HildonColorSelector * selector)
258 {
259     guint i;
260     GtkWidget *hbox;
261     GConfValue *value;
262
263     /* 16 standard Windows colors */
264     static char *base_colours[HILDON_BASE_COLOR_NUM] = {
265         "#000000", "#FFFFFF", "#FF0000", "#660000", "#0000FF", "#000066",
266         "#FF33FF", "#660066", "#33CC33", "#006600", "#FFCC00", "#CC9900",
267         "#999999", "#666666", "#00CCCC", "#006666"
268     };
269
270     selector->priv =
271         G_TYPE_INSTANCE_GET_PRIVATE(selector,
272                                     HILDON_TYPE_COLOR_SELECTOR,
273                                     HildonColorSelectorPriv);
274     
275     /*  ***********test GConf***********   */
276     selector->priv->client = gconf_client_get_default ();
277     gconf_client_set_error_handling (selector->priv->client, 
278       GCONF_CLIENT_HANDLE_UNRETURNED);
279     
280     /* Add our directory to the list of directories the GConfClient will
281        watch. */
282     gconf_client_add_dir (selector->priv->client, HILDON_COLOR_GCONF_PATH,
283                               GCONF_CLIENT_PRELOAD_NONE,
284                               NULL);
285     
286     value = gconf_client_get(selector->priv->client, 
287       HILDON_COLOR_GCONF_KEYS, NULL);    
288
289     hildon_color_selector_set_custom_colors(selector, value);    
290
291     if (value) {
292       gconf_value_free(value);
293     }
294     
295     /* Listen to changes to our key. */
296     selector->priv->notify_id = gconf_client_notify_add (selector->priv->client, 
297         HILDON_COLOR_GCONF_KEYS, gconf_notify_func, selector, NULL, NULL); 
298
299     /* ************************************  */
300
301     selector->priv->index = GREYIND;
302     
303     /* init base colors for color boxes */
304     for (i = 0; i < HILDON_BASE_COLOR_NUM; ++i) 
305     {
306         selector->priv->color[i].pixel = 0;
307         gdk_color_parse (base_colours[i], &(selector->priv->color[i]));
308     }
309     
310     gtk_dialog_set_has_separator(GTK_DIALOG(selector), FALSE);
311
312     /* create drawing area */
313     hbox = gtk_hbox_new(TRUE, 0);
314     selector->priv->drawing_area = gtk_drawing_area_new();
315     
316     /* receive focus from dialog buttons */
317     GTK_WIDGET_SET_FLAGS (selector->priv->drawing_area, GTK_CAN_FOCUS);
318
319     gtk_widget_add_events (selector->priv->drawing_area,
320                           GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
321
322     gtk_widget_set_size_request (selector->priv->drawing_area,
323                                  (HILDON_COLOR_SELECTOR_BOX_W *
324                                   HILDON_COLOR_SELECTOR_COLS) +
325                                  (HILDON_COLOR_SELECTOR_BOX_BORDER *
326                                   2*HILDON_COLOR_SELECTOR_COLS),
327                                  (HILDON_COLOR_SELECTOR_BOX_H *
328                                   HILDON_COLOR_SELECTOR_ROWS) +
329                                  HILDON_COLOR_SELECTOR_BOX_BORDER *
330                                  2 * HILDON_COLOR_SELECTOR_ROWS);
331
332     gtk_box_pack_start (GTK_BOX(GTK_DIALOG(selector)->vbox), 
333                        hbox, FALSE, FALSE, 0);
334     gtk_box_pack_start (GTK_BOX(hbox), selector->priv->drawing_area,
335                        FALSE, FALSE, 0);
336
337     g_signal_connect (selector->priv->drawing_area, "expose_event",
338                       G_CALLBACK(hildon_color_selector_expose), selector);
339     g_signal_connect (selector->priv->drawing_area, "button_press_event", 
340                       G_CALLBACK(color_pressed), selector);
341     g_signal_connect (selector->priv->drawing_area, "motion-notify-event", 
342                       G_CALLBACK(color_moved), selector);
343     g_signal_connect (selector, "key-press-event",
344                       G_CALLBACK(key_pressed), selector);
345
346
347     gtk_dialog_add_button (GTK_DIALOG(selector), 
348                            _("ecdg_bd_colour_selector_ok"), GTK_RESPONSE_OK);
349     gtk_dialog_add_button (GTK_DIALOG(selector),
350                            _("ecdg_ti_5bit_colour_selector"),
351                            HILDON_MORE_BUTTON_RESPONSE);
352     gtk_dialog_add_button (GTK_DIALOG(selector),
353                            _("ecdg_bd_colour_selector_cancel"),
354                            GTK_RESPONSE_CANCEL);
355
356     gtk_dialog_set_default_response (GTK_DIALOG(selector), GTK_RESPONSE_OK);
357     
358     g_signal_connect (G_OBJECT(selector), "response",
359                       G_CALLBACK(hildon_color_selector_response), selector);
360
361     gtk_window_set_title ( GTK_WINDOW(selector),  
362                           _("ecdg_ti_colour_selector") );
363     gtk_widget_show_all (GTK_DIALOG(selector)->vbox);
364 }
365
366 static gboolean 
367 hildon_color_selector_expose(GtkWidget * widget,
368                              GdkEventExpose * event,
369                              gpointer data)
370 {
371     HildonColorSelector *selector;
372     GdkColor color;
373     GdkGC *gc;
374     gint x, y;
375
376     g_return_val_if_fail (GTK_IS_WIDGET(widget), FALSE);
377     g_return_val_if_fail (event, FALSE);
378     g_return_val_if_fail (HILDON_IS_COLOR_SELECTOR(data), FALSE);
379
380     if (!GTK_WIDGET_DRAWABLE(widget))
381       return FALSE;
382
383     selector = HILDON_COLOR_SELECTOR(data);
384     gc = gdk_gc_new (widget->window); 
385
386     /* draw the color boxes and a focus for one of them */
387     for (x = 0; x < HILDON_COLOR_SELECTOR_COLS; ++x) 
388     {
389         for (y = 0; y < HILDON_COLOR_SELECTOR_ROWS; ++y) 
390         {
391             color.pixel = color.red = color.green = color.blue = 0;
392             gdk_gc_set_rgb_fg_color(gc, &color);
393
394             /* focus around the selected color box */
395             if ( (y * HILDON_COLOR_SELECTOR_COLS + x) ==
396                  selector->priv->index) 
397             {
398                 /* focus box */
399                 gdk_draw_rectangle(widget->window, gc, TRUE,
400                                    (HILDON_COLOR_SELECTOR_BOX_BORDER * 2 +
401                                     HILDON_COLOR_SELECTOR_BOX_W) * x,
402                                    (HILDON_COLOR_SELECTOR_BOX_BORDER * 2 +
403                                     HILDON_COLOR_SELECTOR_BOX_H) * y,
404                                    HILDON_COLOR_SELECTOR_BOX_W +
405                                    HILDON_COLOR_SELECTOR_BOX_BORDER * 2,
406                                    HILDON_COLOR_SELECTOR_BOX_H +
407                                    HILDON_COLOR_SELECTOR_BOX_BORDER * 2); 
408             }
409             
410             /* frames on color box */
411             gdk_draw_rectangle(widget->window, gc, FALSE,
412                                (HILDON_COLOR_SELECTOR_BOX_BORDER * 2 +
413                                 HILDON_COLOR_SELECTOR_BOX_W) * x + 1,
414                                (HILDON_COLOR_SELECTOR_BOX_BORDER * 2 +
415                                 HILDON_COLOR_SELECTOR_BOX_H) * y + 1,
416                                HILDON_COLOR_SELECTOR_BOX_W + 1,
417                                HILDON_COLOR_SELECTOR_BOX_H + 1);
418             
419             gdk_gc_set_rgb_fg_color(gc, 
420               &(selector->priv->color[y * HILDON_COLOR_SELECTOR_COLS + x]));
421
422             /* color box */
423             gdk_draw_rectangle(widget->window, gc,
424                                TRUE,    /* filled */
425                                HILDON_COLOR_SELECTOR_BOX_BORDER +
426                                (HILDON_COLOR_SELECTOR_BOX_BORDER * 2 +
427                                 HILDON_COLOR_SELECTOR_BOX_W) * x,
428                                HILDON_COLOR_SELECTOR_BOX_BORDER +
429                                (HILDON_COLOR_SELECTOR_BOX_BORDER * 2 +
430                                 HILDON_COLOR_SELECTOR_BOX_H) * y,
431                                HILDON_COLOR_SELECTOR_BOX_W,
432                                HILDON_COLOR_SELECTOR_BOX_H);
433         }
434     }
435
436     g_object_unref(gc);
437     return TRUE;
438 }
439
440 /**
441  * hildon_color_selector_get_color:
442  * @selector: a #HildonColorSelector
443  * 
444  * Gets the currently selected base color as #GdkColor.
445  * 
446  * Returns: A copy of the currently selected #GdkColor.
447  */
448 GdkColor *hildon_color_selector_get_color(HildonColorSelector * selector)
449 {
450     g_return_val_if_fail(HILDON_IS_COLOR_SELECTOR(selector), NULL);    
451     return &(selector->priv->color[selector->priv->index]);
452 }
453
454 /**
455  * hildon_color_selector_set_color:
456  * @selector: #HildonColorSelector
457  * @color: #Gdkcolor to set.
458  * 
459  * Select the color specified. Does nothing if the color does not 
460  * exists among the standard colors.
461  */
462 void hildon_color_selector_set_color(HildonColorSelector * selector,
463                                      GdkColor * color)
464 {
465     gint i;
466
467     g_return_if_fail(HILDON_IS_COLOR_SELECTOR(selector));
468     g_return_if_fail(color);
469
470     for (i = 0; 
471          i < (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM);
472          ++i) 
473     {
474         if (selector->priv->color[i].red   == color->red &&
475             selector->priv->color[i].green == color->green &&
476             selector->priv->color[i].blue  == color->blue) 
477         {
478             selector->priv->index = i;
479             gtk_widget_queue_draw(selector->priv->drawing_area);
480             break;
481         }
482     }
483 }
484
485 static gboolean
486 color_pressed(GtkWidget * widget, GdkEventButton * event,
487               gpointer user_data)
488 {
489     select_color(HILDON_COLOR_SELECTOR(user_data), event->x, event->y);
490     return TRUE;
491 }
492
493 static gboolean key_pressed(GtkWidget * widget,
494                             GdkEventKey * event, gpointer user_data)
495 {
496     HildonColorSelector *selector;
497     gint index;
498
499     g_return_val_if_fail(widget, FALSE);
500     g_return_val_if_fail(user_data, FALSE);
501
502     selector = HILDON_COLOR_SELECTOR(user_data);
503     index = selector->priv->index;
504
505     /* if dialog buttons has the focus */
506     if (GTK_WIDGET_HAS_FOCUS(selector->priv->drawing_area) == FALSE)
507         return FALSE;
508
509     /* go for if available index otherwise stop keypress handler because
510        wrapping around is not allowed. */
511     switch (event->keyval) {
512     case GDK_KP_Right:
513     case GDK_Right:
514         if (index == (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM - 1)
515             || index == (HILDON_CUSTOM_COLOR_NUM - 1)
516             || index == (2*HILDON_CUSTOM_COLOR_NUM - 1)) 
517         {
518             return TRUE;
519         }
520         index++;
521         break;
522     case GDK_KP_Left:
523     case GDK_Left:
524         if (index == 0 
525             || index == (HILDON_CUSTOM_COLOR_NUM)
526             || index == (2*HILDON_CUSTOM_COLOR_NUM)) 
527         {
528             return TRUE;
529         }
530         index--;
531         break;
532     case GDK_KP_Up:
533     case GDK_Up:
534         if (index > (HILDON_COLOR_SELECTOR_COLS - 1)) 
535         {
536             index -= HILDON_COLOR_SELECTOR_COLS;
537         } 
538         else 
539         {
540             return FALSE;
541         }
542         break;
543     case GDK_KP_Down:
544     case GDK_Down:
545         if (index < (HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM)) 
546         {
547             index += HILDON_COLOR_SELECTOR_COLS;  
548         } 
549         else 
550         {
551             return FALSE;
552         }
553         break;
554     default:
555         return FALSE;
556     }
557
558     if (index < (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM)) 
559     {
560         selector->priv->index = index;
561     } 
562     else 
563     {
564         selector->priv->index = 
565             HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM - 1;
566     }
567     
568     gtk_widget_queue_draw(selector->priv->drawing_area);
569     
570     return TRUE;
571 }
572
573 static void
574 select_color(HildonColorSelector * selector, int event_x, int event_y)
575 {
576     gint x, y;
577
578     g_return_if_fail(HILDON_IS_COLOR_SELECTOR(selector));
579
580     x = ( (event_x - HILDON_COLOR_SELECTOR_BOX_BORDER) /
581           (HILDON_COLOR_SELECTOR_BOX_BORDER * 2 +
582            HILDON_COLOR_SELECTOR_BOX_W)
583         );
584     y = ( (event_y -
585            HILDON_COLOR_SELECTOR_BOX_BORDER) /
586           (HILDON_COLOR_SELECTOR_BOX_BORDER * 2 +
587            HILDON_COLOR_SELECTOR_BOX_H)
588         );
589
590     if (x > (HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM - 1)) 
591     {
592         x = HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM - 1;
593     } 
594     else if (x < 0) 
595     {
596         x = 0;
597     }
598     if (y > (HILDON_COLOR_SELECTOR_ROWS - 1)) 
599     {
600         y = HILDON_COLOR_SELECTOR_ROWS - 1;
601     } 
602     else if (y < 0) 
603     {
604         y = 0;
605     }
606     
607     selector->priv->index = (x + y * HILDON_COLOR_SELECTOR_COLS);
608     
609     gtk_widget_queue_draw(selector->priv->drawing_area);
610 }
611
612 static gboolean
613 color_moved(GtkWidget * widget, GdkEventMotion * event, gpointer data)
614 {
615     if ( event->state &
616          (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK) ) 
617     {
618         select_color(HILDON_COLOR_SELECTOR(data), event->x, event->y);
619         return TRUE;
620     }
621     return FALSE;
622 }
623
624 static void 
625 hildon_color_selector_response(GtkWidget * widget,
626                                gint response_id, 
627                                gpointer data)
628 {
629     HildonColorSelector * colselector;
630     HildonColorPopup popupdata;
631     GtkWidget *popup;
632
633     g_return_if_fail (HILDON_IS_COLOR_SELECTOR(data));
634
635     if (response_id != HILDON_MORE_BUTTON_RESPONSE)
636         return;
637
638     g_signal_stop_emission_by_name (widget, "response");
639     colselector = HILDON_COLOR_SELECTOR(data);
640
641     popup = hildon_color_popup_new(GTK_WINDOW(GTK_WIDGET(colselector)->window), 
642                     hildon_color_selector_get_color(colselector), &popupdata);
643     
644     if ( gtk_dialog_run(GTK_DIALOG(popup) ) == GTK_RESPONSE_OK) 
645     {        
646       GdkColor *color;
647
648       /* We cannot modify a base color */
649       if (colselector->priv->index < HILDON_BASE_COLOR_NUM)
650       {
651         colselector->priv->color[HILDON_TOTAL_COLOR_NUM] = 
652           colselector->priv->color[colselector->priv->index];
653         colselector->priv->index = HILDON_TOTAL_COLOR_NUM;
654       }
655
656       color = hildon_color_selector_get_color(colselector);
657       hildon_color_popup_set_color_from_sliders(color, &popupdata);
658
659       /* If we modified a base color we just accept the dialog */      
660       if( colselector->priv->index >=  HILDON_TOTAL_COLOR_NUM)
661       {          
662         gtk_dialog_response(GTK_DIALOG(colselector), GTK_RESPONSE_OK); 
663       }
664       else /* If we mofied custom colors we have to save to gconf */
665       {
666         GConfValue *value;
667         GSList * list;
668         int i;  
669
670         value = gconf_value_new(GCONF_VALUE_LIST);
671         gconf_value_set_list_type(value, GCONF_VALUE_STRING);
672         list = NULL;
673
674         for ( i = HILDON_BASE_COLOR_NUM; i < HILDON_TOTAL_COLOR_NUM; i++) 
675         {
676             GConfValue *item;
677             char buffer[32];
678                   
679             g_snprintf(buffer, sizeof(buffer), "#%.2X%.2X%.2X",
680                             (colselector->priv->color[i].red>>8)&0xFF,
681                             (colselector->priv->color[i].green>>8)&0xFF,
682                             (colselector->priv->color[i].blue>>8)&0xFF ); 
683   
684             item = gconf_value_new(GCONF_VALUE_STRING);
685             gconf_value_set_string(item, buffer);
686             list = g_slist_append (list, item);
687         } 
688         
689         gconf_value_set_list_nocopy(value, list);
690
691         /* gconf client handles the possible error */
692         gconf_client_set(colselector->priv->client, 
693           HILDON_COLOR_GCONF_KEYS, value, NULL);
694     
695         gconf_value_free(value);
696       }  
697     }
698
699     gtk_widget_destroy (popup); 
700     gtk_window_present (GTK_WINDOW(colselector));
701 }