5523f1600ec30e7b10afb617cf4df41876d5ceec
[hildon] / hildon-widgets / hildon-color-popup.c
1 /*
2  * This file is part of hildon-libs
3  *
4  * Copyright (C) 2005, 2006 Nokia Corporation.
5  *
6  * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@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; version 2.1 of
11  * the License.
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  * SECTION:hildon-color-popup
27  * @short_description: A popup dialog for editing a color and showing the 
28  * edited result
29  * @see_also: #HildonColorButton, #HildonColorSelector
30  *
31  * #HildonColorPopup is only used inside #HildonColorButton. It is a
32  * popup dialog for editing a color. The color can be changed using
33  * three control bars that are used to adjust the red, green and blue
34  * color channels. The display is updated in real time when the bars are
35  * moved.
36  */
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include <gtk/gtkbox.h>
43 #include <gtk/gtktable.h>
44 #include <gtk/gtklabel.h>
45 #include <gtk/gtkdrawingarea.h>
46
47 #include "hildon-color-selector.h"
48 #include "hildon-color-popup.h"
49 #include "hildon-controlbar.h"
50
51 #include <libintl.h>
52 #define _(String) dgettext(PACKAGE, String)
53
54 /* Pixel sizes */
55 #define HILDON_COLOR_PALETTE_SIZE        120
56 #define HILDON_COLOR_CONTROLBAR_MAX       31
57 #define HILDON_COLOR_CONTROLBAR_MIN        0 
58 #define HILDON_COLOR_LABELS_LEFT_PAD      35
59 #define HILDON_COLOR_PALETTE_POS_PAD      45
60 #define HILDON_COLOR_BAR_WIDTH           449
61 #define HILDON_COLOR_COL_SPACING          18
62
63 /* 
64  * Private function prototype definitions 
65  */
66
67 static gboolean 
68 hildon_popup_palette_expose (GtkWidget * widget,
69                              GdkEventExpose * event,
70                              gpointer data);
71 /**
72  * hildon_color_popup_new:
73  * @parent: the parent window of the dialog
74  * @initial_color: a #GdkColor with the initial values to be used
75  * @popup_data: a #HildonColorPopup
76  *
77  * This function creates a new popup dialog with three controlbars
78  * (red, green, blue) and a drawing area with the current color.
79  *
80  * Used as normal GtkDialog (run with gtk_dialog_run() and read 
81  * stardard responses (GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL). 
82  *
83  * Returns: the newly created popup dialog 
84  */
85
86 GtkWidget *
87 hildon_color_popup_new(GtkWindow *parent, const GdkColor *initial_color, 
88                 HildonColorPopup *popup_data)
89 {
90   GtkWidget *popup;
91   GtkTable *layout;
92   GtkWidget *area;
93   GtkWidget *l_red, *l_green, *l_blue;
94
95   /* Create control bars for HildonColorPopup */
96   popup_data->ctrlbar_red   = hildon_controlbar_new (); 
97   popup_data->ctrlbar_green = hildon_controlbar_new ();
98   popup_data->ctrlbar_blue  = hildon_controlbar_new ();
99   area = gtk_drawing_area_new();
100   layout = GTK_TABLE(gtk_table_new(12, 2, FALSE));
101
102   /* Set widgets' size */
103   gtk_widget_set_size_request (area, 
104                                HILDON_COLOR_PALETTE_SIZE, 
105                                HILDON_COLOR_PALETTE_SIZE);
106   gtk_widget_set_size_request(popup_data->ctrlbar_red,
107                                HILDON_COLOR_BAR_WIDTH, -1); 
108   gtk_widget_set_size_request(popup_data->ctrlbar_green,
109                                HILDON_COLOR_BAR_WIDTH, -1); 
110   gtk_widget_set_size_request(popup_data->ctrlbar_blue,
111                                HILDON_COLOR_BAR_WIDTH, -1); 
112
113   /* Create labels for three kinds of color */
114   l_red   = gtk_label_new(_("ecdg_fi_5bit_colour_selector_red"));
115   l_green = gtk_label_new(_("ecdg_fi_5bit_colour_selector_green"));
116   l_blue  = gtk_label_new(_("ecdg_fi_5bit_colour_selector_blue"));
117   
118   /* Position the labels to start about the same label as the controlbars */
119   gtk_misc_set_alignment(GTK_MISC(l_red), 0.08f, 0.5f);
120   gtk_misc_set_alignment(GTK_MISC(l_green), 0.08f, 0.5f);  
121   gtk_misc_set_alignment(GTK_MISC(l_blue), 0.08f, 0.5f);
122
123   /* Add labels and control bars to the layout table */
124   gtk_table_set_col_spacing(layout, 0, HILDON_COLOR_COL_SPACING);
125   gtk_table_attach_defaults(layout, l_red, 0, 1, 0, 2);
126   gtk_table_attach_defaults(layout, popup_data->ctrlbar_red, 0, 1, 2, 4);
127   gtk_table_attach_defaults(layout, l_green, 0, 1, 4, 6);
128   gtk_table_attach_defaults(layout, popup_data->ctrlbar_green, 0, 1, 6, 8);
129   gtk_table_attach_defaults(layout, l_blue, 0, 1, 8, 10);
130   gtk_table_attach_defaults(layout, popup_data->ctrlbar_blue, 0, 1, 10, 12);
131   gtk_table_attach(layout, area, 1, 2, 3, 11, GTK_SHRINK, GTK_SHRINK, 0, 0);
132
133   /* Give the maximum and minimum limits for each control bar */
134   hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_red),
135                                  HILDON_COLOR_CONTROLBAR_MIN, 
136                                  HILDON_COLOR_CONTROLBAR_MAX);
137   hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_green), 
138                                  HILDON_COLOR_CONTROLBAR_MIN, 
139                                  HILDON_COLOR_CONTROLBAR_MAX);
140   hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_blue), 
141                                  HILDON_COLOR_CONTROLBAR_MIN, 
142                                  HILDON_COLOR_CONTROLBAR_MAX);
143
144   /* Give the initial values for each control bar */
145   hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_red),   
146                                  (initial_color->red >> 11)&0x1F);
147   hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_green),
148                                  (initial_color->green >> 11)&0x1F);
149   hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_blue),
150                                  (initial_color->blue >> 11)&0x1F);
151
152   /* Register controlbar callbacks */
153   g_signal_connect_swapped(popup_data->ctrlbar_red, "value-changed",
154                       G_CALLBACK(gtk_widget_queue_draw), area);
155   g_signal_connect_swapped(popup_data->ctrlbar_green, "value-changed",
156                       G_CALLBACK(gtk_widget_queue_draw), area);
157   g_signal_connect_swapped(popup_data->ctrlbar_blue, "value-changed",
158                       G_CALLBACK(gtk_widget_queue_draw), area);
159
160   /* Attach expose_event callback function to drawing area */
161   g_signal_connect (area,  "expose_event",
162                       G_CALLBACK(hildon_popup_palette_expose), 
163                       popup_data);
164   
165   /* Create popup dialog */
166   popup = gtk_dialog_new_with_buttons (_("ecdg_ti_5bit_colour_selector"), 
167                                        GTK_WINDOW(parent),
168                                        GTK_DIALOG_DESTROY_WITH_PARENT |
169                                        GTK_DIALOG_NO_SEPARATOR,
170                                        _("ecdg_bd_5bit_colour_selector_ok"), GTK_RESPONSE_OK,
171                                        _("ecdg_bd_5bit_colour_selector_cancel"),
172                                        GTK_RESPONSE_CANCEL,
173                                        NULL);
174
175   /* Select-key shouldn't do anything unless dialog's button is focused */
176   gtk_dialog_set_default_response(GTK_DIALOG(popup), GTK_RESPONSE_NONE);
177
178   /* Add layout table to the Vbox of the popup dialog */
179   gtk_box_pack_start (GTK_BOX(GTK_DIALOG(popup)->vbox), 
180                         GTK_WIDGET(layout), TRUE, TRUE, 0);
181
182   /* Show thw Vbox of the popup dialog */
183   gtk_widget_show_all(GTK_DIALOG(popup)->vbox);      
184
185   return popup;
186 }
187
188 /**
189  * hildon_color_popup_set_color_from_sliders:
190  * @color: a pointer to #GdkColor to which the new values will be put
191  * @popup_data: a #HildonColorPopup
192  *
193  * Sets the values in the given #GdkColor to the values of the
194  * controlbars.
195  */
196
197 void
198 hildon_color_popup_set_color_from_sliders(GdkColor *color,
199   HildonColorPopup *popup_data)
200 {
201   color->pixel = 0;
202   color->red = hildon_controlbar_get_value (
203         HILDON_CONTROLBAR(popup_data->ctrlbar_red)) <<  11;
204   color->green = hildon_controlbar_get_value (
205         HILDON_CONTROLBAR(popup_data->ctrlbar_green)) <<  11;
206   color->blue = hildon_controlbar_get_value (
207         HILDON_CONTROLBAR(popup_data->ctrlbar_blue)) <<  11;
208 }
209
210 /* expose_event callback function */
211 static gboolean 
212 hildon_popup_palette_expose (GtkWidget * widget,
213                              GdkEventExpose *event, gpointer data)
214 {
215   if (GTK_WIDGET_DRAWABLE(widget))
216   {
217     GdkColor color;
218     GdkGC * gc = gdk_gc_new (widget->window); 
219
220     /* Get the current color value */
221     hildon_color_popup_set_color_from_sliders(&color, data);
222     gdk_gc_set_rgb_fg_color(gc, &color);
223                          
224     /* draw the color area */
225     gdk_draw_rectangle( widget->window, gc, TRUE /* filled */,  
226                         1, 1, widget->allocation.width - 2, 
227                         widget->allocation.height - 2);    
228
229     color.pixel = color.red = color.green = color.blue = 0;
230     gdk_gc_set_rgb_fg_color(gc, &color);
231
232     /* Draw frames on color box */
233     gdk_draw_rectangle( widget->window, gc, FALSE, 
234                         0, 0, widget->allocation.width - 1, 
235                         widget->allocation.height - 1); 
236
237     /* Free memory used by the graphics contexts */
238     g_object_unref(gc);
239   }
240
241   return TRUE;
242 }