make ARDOUR2_UI_RC work again
[ardour.git] / gtk2_ardour / theme_manager.cc
1 /*
2     Copyright (C) 2000-2007 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <cmath>
21 #include <iostream>
22 #include <fstream>
23 #include <errno.h>
24
25 #include <gtkmm/stock.h>
26 #include <gtkmm2ext/gtk_ui.h>
27 #include <gtkmm/settings.h>
28
29 #include <ardour/configuration.h>
30
31 #include "theme_manager.h"
32 #include "rgb_macros.h"
33 #include "ardour_ui.h"
34
35 #include "i18n.h"
36
37 using namespace std;
38 using namespace Gtk;
39 using namespace PBD;
40 using namespace ARDOUR;
41
42 /* the global color map */
43
44 ColorMap color_map;
45
46 /* lookup table of color IDs as strings */
47
48 #undef COLORID
49 #define COLORID(s) #s,
50 static const char *color_id_strs[] = {
51         #include "colors.h"
52 };
53 #undef COLORID
54
55 /* global color change signals */
56
57 sigc::signal<void> ColorsChanged;
58 sigc::signal<void,ColorID,uint32_t> ColorChanged;
59
60 ThemeManager::ThemeManager()
61         : ArdourDialog ("ThemeManager"),
62         dark_button ("Dark Theme"),
63         light_button ("Light Theme")
64 {
65         color_list = ListStore::create (columns);
66         color_display.set_model (color_list);
67         color_display.append_column (_("Object"), columns.name);
68         color_display.append_column (_("Color"), columns.color);
69         color_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));     
70         color_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));     
71         color_display.set_reorderable (false);
72         color_display.get_selection()->set_mode (SELECTION_NONE);
73         color_display.set_headers_visible (true);
74
75         CellRenderer* color_cell = color_display.get_column_cell_renderer (1);
76         TreeViewColumn* color_column = color_display.get_column (1);
77         color_column->add_attribute (color_cell->property_cell_background_gdk(), columns.gdkcolor);
78         
79         scroller.add (color_display);
80         scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
81         
82         RadioButton::Group group = dark_button.get_group();
83         light_button.set_group(group);
84         theme_selection_hbox.set_homogeneous(false);
85         theme_selection_hbox.pack_start (dark_button);
86         theme_selection_hbox.pack_start (light_button);
87
88         get_vbox()->set_homogeneous(false);
89         get_vbox()->pack_start (theme_selection_hbox, PACK_SHRINK);
90         get_vbox()->pack_start (scroller);
91
92         color_display.signal_button_press_event().connect (mem_fun (*this, &ThemeManager::button_press_event), false);
93
94         color_dialog.get_colorsel()->set_has_opacity_control (true);
95         color_dialog.get_colorsel()->set_has_palette (true);
96
97         color_dialog.get_ok_button()->signal_clicked().connect (bind (mem_fun (color_dialog, &Gtk::Dialog::response), RESPONSE_ACCEPT));
98         color_dialog.get_cancel_button()->signal_clicked().connect (bind (mem_fun (color_dialog, &Gtk::Dialog::response), RESPONSE_CANCEL));
99         dark_button.signal_clicked().connect (bind (mem_fun (*this, &ThemeManager::load_rc), 1));
100         light_button.signal_clicked().connect (bind (mem_fun (*this, &ThemeManager::load_rc), 2));
101
102         set_size_request (-1, 400);
103 }
104
105 ThemeManager::~ThemeManager()
106 {
107 }
108
109 int
110 ThemeManager::load (string path)
111 {
112         ifstream in (path.c_str());
113
114         if (!in) {
115                 error << string_compose (_("cannot open color definition file %1: %2"), path, strerror(errno)) << endmsg;
116                 return -1;
117         }
118
119         cerr << "Loading color definition file " << path << endl;
120
121         while (in) {
122                 string name;
123                 double r, g, b, a;
124
125                 in >> name; if (!in) break;
126                 in >> r; if (!in) break;
127                 in >> g; if (!in) break;
128                 in >> b; if (!in) break;
129                 in >> a; if (!in) break;
130
131                 for (uint32_t i = 0; i < sizeof (color_id_strs)/sizeof(color_id_strs[0]); ++i) {
132                         if (name == color_id_strs[i]) {
133
134                                 /* set color map */
135
136                                 int ir,ig,ib,ia;
137                                 int rgba;
138
139                                 ir = (int) floor (r * 255.0);
140                                 ig = (int) floor (g * 255.0);
141                                 ib = (int) floor (b * 255.0);
142                                 ia = (int) floor (a * 255.0);
143                                 rgba = RGBA_TO_UINT (ir, ig, ib, ia);
144
145                                 color_map[(ColorID)i] = rgba;
146
147                                 /* set up list entry */
148
149                                 Gdk::Color col;
150                                 col.set_rgb_p (r,g,b);
151
152                                 TreeModel::Row row = *(color_list->append());
153
154                                 /* all the color names are prefixed by 'c' to avoid
155                                    naming collisions when used as enums. trim
156                                    this leading character from the displayed
157                                    value.
158                                 */
159
160                                 row[columns.name] = name.substr (1);
161                                 row[columns.color] = "";
162                                 row[columns.id] = (ColorID) i;
163                                 row[columns.gdkcolor] = col;
164                                 row[columns.rgba] = rgba;
165
166                                 break;
167                         }
168                 }
169         }
170         
171         ColorsChanged(); /* emit signal */
172
173         return 0;
174 }
175
176 int
177 ThemeManager::save (string path)
178 {
179         return 0;
180 }
181
182 bool
183 ThemeManager::button_press_event (GdkEventButton* ev)
184 {
185         TreeIter iter;
186         TreeModel::Path path;
187         TreeViewColumn* column;
188         int cellx;
189         int celly;
190         
191         if (!color_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
192                 return false;
193         }
194
195         switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
196         case 0:
197                 /* allow normal processing to occur */
198                 return false;
199
200         case 1: /* color */
201                 if ((iter = color_list->get_iter (path))) {
202
203                         ColorID edit_color_id = (*iter)[columns.id];
204                         int r,g, b, a;
205                         uint32_t rgba;
206                         Gdk::Color color;
207
208                         ResponseType result = (ResponseType) color_dialog.run();
209
210                         switch (result) {
211                         case RESPONSE_CANCEL:
212                                 break;
213                         case RESPONSE_ACCEPT:
214                                 color = color_dialog.get_colorsel()->get_current_color(); 
215                                 a = color_dialog.get_colorsel()->get_current_alpha();
216                                 r = (int) floor (color.get_red_p() * 255.0);
217                                 g = (int) floor (color.get_green_p() * 255.0);
218                                 b = (int) floor (color.get_blue_p() * 255.0);
219
220                                 rgba = RGBA_TO_UINT(r,g,b,a);
221                                 
222                                 (*iter)[columns.rgba] = rgba;
223                                 (*iter)[columns.gdkcolor] = color;
224
225                                 color_map[edit_color_id] = rgba;
226
227                                 ColorChanged (edit_color_id, rgba);
228                                 break;
229
230                         default:
231                                 break;
232
233                         }
234
235                         color_dialog.hide ();
236                 }
237                 return true;
238
239         default:
240                 break;
241         }
242
243         return false;
244 }
245
246
247 void
248 ThemeManager::load_rc(int which)
249 {
250                 
251         if (which == 1) {
252                 Config->set_ui_rc_file("ardour2_ui_dark.rc");
253                 cerr << "dark theme selected" << endl;
254                 
255         } else {
256                 Config->set_ui_rc_file("ardour2_ui_light.rc");
257                 cerr << "light theme selected" << endl;
258         }
259
260         ThemeChanged(find_config_file(Config->get_ui_rc_file())); //EMIT SIGNAL
261         
262         cerr << "load_rc() called " << find_config_file(Config->get_ui_rc_file()) << endl;
263 }
264
265 void
266 ThemeManager::setup_theme_buttons ()
267 {
268
269         if (getenv ("ARDOUR2_UI_RC")) {
270                 return;
271         }
272
273         if (Config->get_ui_rc_file() == "ardour2_ui_dark.rc") {
274                 dark_button.set_active();
275         } else if (Config->get_ui_rc_file() == "ardour2_ui_light.rc") {
276                 light_button.set_active();
277         }
278 }
279