Add eyedrop tool. The treeview will scroll to the selection.
[colorize.git] / gui / palette.c
1 #include <gtk/gtk.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include "main.h"
5 #include "../src/mark.h"
6 #include "../src/yuv.h"
7 #include "palette.h"
8 #include "timeline.h"
9 #include "image.h"
10
11 int mark_selected = 0;
12
13 #define COLOR_WIDTH 100
14 #define COLOR_HEIGHT 20
15
16 char *bc_pic[] = {
17         "     *     ",
18         " *   *   * ",
19         "  *     *  ",
20         "    ***    ",
21         "   *** *   ",
22         "** *** * **",
23         "   *** *   ",
24         "    ***    ",
25         "  *     *  ",
26         " *   *   * ",
27         "     *     ",
28 };
29 static GdkPixbuf *draw_pixpuf(int i)
30 {
31         GdkPixbuf *pixbuf;
32         guchar *data;
33         int j, k, rs;
34         int cr, cg, cb;
35         float bright, contrast;
36         double r, g, b, y, u, v;
37
38         cr = mark_palette[i].r;
39         cg = mark_palette[i].g;
40         cb = mark_palette[i].b;
41         bright = mark_palette[i].bright;
42         contrast = mark_palette[i].contrast;
43         r = cr / 255.0;
44         g = cg / 255.0;
45         b = cb / 255.0;
46         rgb2yuv_pixle(r, g, b, &y, &u, &v);
47
48         pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, COLOR_WIDTH, COLOR_HEIGHT);
49         data = gdk_pixbuf_get_pixels(pixbuf);
50         rs = gdk_pixbuf_get_rowstride(pixbuf);
51         if (cr == 255 && cg == 255 && cb == 255) {
52                 for (k = 0; k < COLOR_WIDTH; k++) {
53                         for (j = 0; j < COLOR_HEIGHT; j++) {
54                                 data[j * rs + k * 3 + 0] = 255;
55                                 data[j * rs + k * 3 + 1] = 255;
56                                 data[j * rs + k * 3 + 2] = 255;
57                         }
58                 }
59         } else {
60                 for (k = 0; k < COLOR_WIDTH; k++) {
61                         /* we use height as horizontal size of original color area */
62                         if (k >= COLOR_HEIGHT+3) {
63                                 y = (double)(k-COLOR_HEIGHT-3) / (double)((COLOR_WIDTH-COLOR_HEIGHT-3)-1);
64                                 y = (y - 0.5) * contrast + 0.5;
65                                 y += bright;
66                                 if (y < 0)
67                                         y = 0;
68                                 if (y > 1)
69                                         y = 1;
70                                 yuv2rgb_pixle(y, u, v, &r, &g, &b);
71                                 cr = r * 255.0F;
72                                 if (cr < 0)
73                                         cr = 0;
74                                 else if (cr > 255)
75                                         cr = 255;
76                                 cg = g * 255.0F;
77                                 if (cg < 0)
78                                         cg = 0;
79                                 else if (cg > 255)
80                                         cg = 255;
81                                 cb = b * 255.0F;
82                                 if (cb < 0)
83                                         cb = 0;
84                                 else if (cb > 255)
85                                         cb = 255;
86                         } else
87                         if (k >= COLOR_HEIGHT) {
88                                 cr = 255;
89                                 cg = 255;
90                                 cb = 255;
91                         }
92                         for (j = 0; j < COLOR_HEIGHT; j++) {
93                                 data[j * rs + k * 3 + 0] = cr;
94                                 data[j * rs + k * 3 + 1] = cg;
95                                 data[j * rs + k * 3 + 2] = cb;
96                         }
97                 }
98         }
99
100         /* indicate a change in brightness + contrast */
101         if (bright != 0 || contrast != 1) {
102                 for (k = 0; k < 11; k++) {
103                         for (j = 0; j < 11; j++) {
104                                 if (bc_pic[j][k] == '*') {
105                                         data[j * rs + k * 3 + 0] = 255;
106                                         data[j * rs + k * 3 + 1] = 0;
107                                         data[j * rs + k * 3 + 2] = 0;
108                                 }
109                         }
110                 }
111         }
112
113         return pixbuf;
114 }
115
116 void create_palette(void)
117 {
118         GtkListStore *palette_store;
119         GtkTreeIter   iter;
120         int i;
121         char number[10];
122         GdkPixbuf *color;
123
124         for (i = 0; i < 255; i++) {
125                 strcpy(mark_palette[i].name, "");
126                 mark_palette[i].r = 0;
127                 mark_palette[i].g = 0;
128                 mark_palette[i].b = 0;
129                 mark_palette[i].bright = 0;
130                 mark_palette[i].contrast = 1;
131         }
132
133         strcpy(mark_palette[0].name, "red");
134         mark_palette[0].r = 255;
135         mark_palette[0].g = 0;
136         mark_palette[0].b = 0;
137         strcpy(mark_palette[1].name, "green");
138         mark_palette[1].r = 0;
139         mark_palette[1].g = 255;
140         mark_palette[1].b = 0;
141         strcpy(mark_palette[2].name, "blue");
142         mark_palette[2].r = 0;
143         mark_palette[2].g = 0;
144         mark_palette[2].b = 255;
145
146         palette_store = gtk_list_store_new(3, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING);
147         gtk_tree_view_set_model(GTK_TREE_VIEW(palette_treeview), GTK_TREE_MODEL(palette_store));
148         gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(palette_treeview), FALSE);
149
150         for (i = 0; i < 255; i++) {
151                 gtk_list_store_append(palette_store, &iter);
152                 sprintf(number, "%d", i+1);
153                 color = draw_pixpuf(i);
154                 gtk_list_store_set(palette_store, &iter, 0, number, 1, color, 2, mark_palette[i].name, -1);
155                 g_object_unref(color);
156                 if (i == mark_selected) {
157                         GtkTreeSelection *selection;
158                         GtkTreePath *path;
159                         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(palette_treeview));
160                         gtk_tree_selection_select_iter(selection, &iter);
161                         path = gtk_tree_model_get_path(GTK_TREE_MODEL(palette_store), &iter);
162                         gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(palette_treeview), path, NULL, FALSE, 0,0);
163                         gtk_tree_path_free(path);
164                 }
165         }
166
167         g_object_unref(palette_store);
168
169 }
170
171 int get_iter_by_path_name(GtkTreeIter *iter, GtkTreeModel *model, int entry)
172 {
173         char path_name[10];
174
175         sprintf(path_name, "%d", entry);
176         if (gtk_tree_model_get_iter_from_string(model, iter, path_name))
177                 return 1;
178         return 0;
179 }
180
181 void update_color(int entry)
182 {
183         GdkPixbuf *color;
184         GtkTreeIter iter;
185         GtkTreeModel *model;
186
187         color = draw_pixpuf(entry);
188
189         model = gtk_tree_view_get_model(GTK_TREE_VIEW(palette_treeview));
190         if (get_iter_by_path_name(&iter, model, entry))
191                 gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, color, 2, mark_palette[entry].name, -1);
192 }
193
194 void pick_color(int x, int y)
195 {
196         GdkDrawable *draw = gtk_widget_get_window(img_drawing_area);
197         int window_width, window_height;
198         unsigned char c;
199         gdk_drawable_get_size (draw, &window_width, &window_height);
200
201         if (!img_mark_buffer)
202                 return;
203
204         /* we need to calculate an offset, since the drawing area is now larger */
205         x -= (window_width - img_width*img_scale_x/16) / 2;
206         y -= (window_height - img_height*img_scale_y/16) / 2;
207
208         x = x*16/img_scale_x;
209         y = y*16/img_scale_y;
210
211         if (x < 0 || x >= img_width || y < 0 || y >= img_height)
212                 return;
213
214         c = img_mark_buffer[img_width*y+x];
215         if (c > 0) {
216                 GtkTreeIter iter;
217                 GtkTreeModel *model;
218                 GtkTreeSelection *selection;
219                 GtkTreePath *path;
220
221                 mark_selected = c - 1;
222                 model = gtk_tree_view_get_model(GTK_TREE_VIEW(palette_treeview));
223                 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(palette_treeview));
224                 if (get_iter_by_path_name(&iter, model, mark_selected)) {
225                         gtk_tree_selection_select_iter(selection, &iter);
226                         path = gtk_tree_model_get_path(model, &iter);
227                         gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(palette_treeview), path, NULL, FALSE, 0,0);
228                         gtk_tree_path_free(path);
229                 }
230         }
231 }
232