2f1a286467de7767f6e88b2485b9f3f6368fafce
[ardour.git] / gtk2_ardour / color_manager.cc
1 #include <cmath>
2 #include <iostream>
3 #include <fstream>
4 #include <errno.h>
5
6 #include <gtkmm/stock.h>
7
8 #include "color_manager.h"
9 #include "rgb_macros.h"
10
11 #include "i18n.h"
12
13 using namespace std;
14 using namespace Gtk;
15 using namespace PBD;
16
17 /* the global color map */
18
19 ColorMap color_map;
20
21 /* lookup table of color IDs as strings */
22
23 #undef COLORID
24 #define COLORID(s) #s,
25 static const char *color_id_strs[] = {
26         #include "colors.h"
27 };
28 #undef COLORID
29
30 /* global color change signals */
31
32 sigc::signal<void> ColorsChanged;
33 sigc::signal<void,ColorID,uint32_t> ColorChanged;
34
35 ColorManager::ColorManager()
36         : ArdourDialog ("ColorManager")
37 {
38         color_list = ListStore::create (columns);
39         color_display.set_model (color_list);
40         color_display.append_column (_("Object"), columns.name);
41         color_display.append_column (_("Color"), columns.color);
42         color_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));     
43         color_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));     
44         color_display.set_reorderable (false);
45         color_display.get_selection()->set_mode (SELECTION_NONE);
46         color_display.set_headers_visible (true);
47
48         CellRenderer* color_cell = color_display.get_column_cell_renderer (1);
49         TreeViewColumn* color_column = color_display.get_column (1);
50         color_column->add_attribute (color_cell->property_cell_background_gdk(), columns.gdkcolor);
51         
52         scroller.add (color_display);
53         scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
54
55         get_vbox()->pack_start (scroller);
56
57         color_display.signal_button_press_event().connect (mem_fun (*this, &ColorManager::button_press_event), false);
58
59         color_dialog.get_colorsel()->set_has_opacity_control (true);
60         color_dialog.get_colorsel()->set_has_palette (true);
61
62         color_dialog.get_ok_button()->signal_clicked().connect (bind (mem_fun (color_dialog, &Gtk::Dialog::response), RESPONSE_ACCEPT));
63         color_dialog.get_cancel_button()->signal_clicked().connect (bind (mem_fun (color_dialog, &Gtk::Dialog::response), RESPONSE_CANCEL));
64
65         set_size_request (-1, 400);
66 }
67
68 ColorManager::~ColorManager()
69 {
70 }
71
72 int
73 ColorManager::load (string path)
74 {
75         ifstream in (path.c_str());
76
77         if (!in) {
78                 error << string_compose (_("cannot open color definition file %1: %2"), path, strerror(errno)) << endmsg;
79                 return -1;
80         }
81
82         while (in) {
83                 string name;
84                 double r, g, b, a;
85
86                 in >> name; if (!in) break;
87                 in >> r; if (!in) break;
88                 in >> g; if (!in) break;
89                 in >> b; if (!in) break;
90                 in >> a; if (!in) break;
91
92                 for (uint32_t i = 0; i < sizeof (color_id_strs)/sizeof(color_id_strs[0]); ++i) {
93                         if (name == color_id_strs[i]) {
94
95                                 /* set color map */
96
97                                 int ir,ig,ib,ia;
98                                 int rgba;
99
100                                 ir = (int) floor (r * 255.0);
101                                 ig = (int) floor (g * 255.0);
102                                 ib = (int) floor (b * 255.0);
103                                 ia = (int) floor (a * 255.0);
104                                 rgba = RGBA_TO_UINT (ir, ig, ib, ia);
105
106                                 color_map[(ColorID)i] = rgba;
107
108                                 /* set up list entry */
109
110                                 Gdk::Color col;
111                                 col.set_rgb_p (r,g,b);
112
113                                 TreeModel::Row row = *(color_list->append());
114
115                                 /* all the color names are prefixed by 'c' to avoid
116                                    naming collisions when used as enums. trim
117                                    this leading character from the displayed
118                                    value.
119                                 */
120
121                                 row[columns.name] = name.substr (1);
122                                 row[columns.color] = "";
123                                 row[columns.id] = (ColorID) i;
124                                 row[columns.gdkcolor] = col;
125                                 row[columns.rgba] = rgba;
126
127                                 break;
128                         }
129                 }
130         }
131         
132         ColorsChanged(); /* emit signal */
133         return 0;
134 }
135
136 int
137 ColorManager::save (string path)
138 {
139         return 0;
140 }
141
142 bool
143 ColorManager::button_press_event (GdkEventButton* ev)
144 {
145         TreeIter iter;
146         TreeModel::Path path;
147         TreeViewColumn* column;
148         int cellx;
149         int celly;
150         
151         if (!color_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
152                 return false;
153         }
154
155         switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
156         case 0:
157                 /* allow normal processing to occur */
158                 return false;
159
160         case 1: /* color */
161                 if ((iter = color_list->get_iter (path))) {
162
163                         ColorID edit_color_id = (*iter)[columns.id];
164                         int r,g, b, a;
165                         uint32_t rgba;
166                         Gdk::Color color;
167
168                         ResponseType result = (ResponseType) color_dialog.run();
169
170                         switch (result) {
171                         case RESPONSE_CANCEL:
172                                 break;
173                         case RESPONSE_ACCEPT:
174                                 color = color_dialog.get_colorsel()->get_current_color(); 
175                                 a = color_dialog.get_colorsel()->get_current_alpha();
176                                 r = (int) floor (color.get_red_p() * 255.0);
177                                 g = (int) floor (color.get_green_p() * 255.0);
178                                 b = (int) floor (color.get_blue_p() * 255.0);
179
180                                 rgba = RGBA_TO_UINT(r,g,b,a);
181                                 
182                                 (*iter)[columns.rgba] = rgba;
183                                 (*iter)[columns.gdkcolor] = color;
184
185                                 color_map[edit_color_id] = rgba;
186
187                                 ColorChanged (edit_color_id, rgba);
188                                 break;
189
190                         default:
191                                 break;
192
193                         }
194
195                         color_dialog.hide ();
196                 }
197                 return true;
198
199         default:
200                 break;
201         }
202
203         return false;
204 }