+void
+ThemeManager::palette_size_request (Gtk::Requisition* req)
+{
+ uint32_t ncolors = UIConfiguration::instance().colors.size();
+ const int box_size = 20;
+
+ double c = sqrt ((double)ncolors);
+ req->width = (int) floor (c * box_size);
+ req->height = (int) floor (c * box_size);
+
+ /* add overflow row if necessary */
+
+ if (fmod (ncolors, c) != 0.0) {
+ req->height += box_size;
+ }
+}
+
+void
+ThemeManager::setup_palette ()
+{
+ build_palette_canvas (*palette_viewport.canvas(), *palette_group, sigc::mem_fun (*this, &ThemeManager::palette_event));
+}
+
+bool
+ThemeManager::palette_event (GdkEvent* ev, string name)
+{
+ switch (ev->type) {
+ case GDK_BUTTON_RELEASE:
+ edit_palette_color (name);
+ return true;
+ default:
+ break;
+ }
+ return true;
+}
+
+void
+ThemeManager::edit_palette_color (std::string name)
+{
+ using namespace ArdourCanvas;
+ double r,g, b, a;
+ UIConfiguration* uic (&UIConfiguration::instance());
+ ArdourCanvas::Color c = uic->color (name);
+ Gdk::Color gdkcolor;
+
+ color_to_rgba (c, r, g, b, a);
+
+ gdkcolor.set_rgb_p (r, g, b);
+ color_dialog.get_colorsel()->set_previous_color (gdkcolor);
+ color_dialog.get_colorsel()->set_current_color (gdkcolor);
+ color_dialog.get_colorsel()->set_previous_alpha ((guint16) (a * 65535));
+ color_dialog.get_colorsel()->set_current_alpha ((guint16) (a * 65535));
+
+ color_dialog_connection.disconnect ();
+ color_dialog_connection = color_dialog.signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ThemeManager::palette_color_response), name));
+ color_dialog.present();
+}
+
+void
+ThemeManager::palette_color_response (int result, std::string name)
+{
+ using namespace ArdourCanvas;
+
+ color_dialog_connection.disconnect ();
+
+ UIConfiguration* uic (&UIConfiguration::instance());
+ Gdk::Color gdkcolor;
+ double r,g, b, a;
+
+ switch (result) {
+ case RESPONSE_ACCEPT:
+ case RESPONSE_OK:
+ gdkcolor = color_dialog.get_colorsel()->get_current_color();
+ a = color_dialog.get_colorsel()->get_current_alpha() / 65535.0;
+ r = gdkcolor.get_red_p();
+ g = gdkcolor.get_green_p();
+ b = gdkcolor.get_blue_p();
+
+ uic->set_color (name, rgba_to_color (r, g, b, a));
+ break;
+
+ default:
+ break;
+ }
+
+ color_dialog.hide ();
+}
+
+bool
+ThemeManager::alias_palette_event (GdkEvent* ev, string new_alias, string target_name)
+{
+ switch (ev->type) {
+ case GDK_BUTTON_RELEASE:
+ UIConfiguration::instance().set_alias (target_name, new_alias);
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void
+ThemeManager::alias_palette_response (int response, std::string target_name, std::string old_alias)
+{
+ switch (response) {
+ case GTK_RESPONSE_OK:
+ case GTK_RESPONSE_ACCEPT:
+ /* rebuild alias list with new color: inefficient but simple */
+ setup_aliases ();
+ break;
+
+ case GTK_RESPONSE_REJECT:
+ /* revert choice */
+ UIConfiguration::instance().set_alias (target_name, old_alias);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ palette_window->hide ();
+}
+
+void
+ThemeManager::choose_color_from_palette (string const & name)
+{
+ UIConfiguration* uic (&UIConfiguration::instance());
+ UIConfiguration::ColorAliases::iterator i = uic->color_aliases.find (name);
+
+ if (i == uic->color_aliases.end()) {
+ return;
+ }
+
+ delete palette_window;
+
+ palette_window = new ArdourDialog (_("Color Palette"));
+ palette_window->add_button (Stock::CANCEL, RESPONSE_REJECT); /* using CANCEL causes confusion if dialog is closed via CloseAllDialogs */
+ palette_window->add_button (Stock::OK, RESPONSE_OK);
+
+ ArdourCanvas::GtkCanvas* canvas = new ArdourCanvas::GtkCanvas ();
+ ArdourCanvas::Container* group = initialize_palette_canvas (*canvas);
+
+ canvas->signal_size_request().connect (sigc::mem_fun (*this, &ThemeManager::palette_size_request));
+ canvas->signal_size_allocate().connect (sigc::bind (sigc::mem_fun (*this, &ThemeManager::palette_canvas_allocated), group, canvas,
+ sigc::bind (sigc::mem_fun (*this, &ThemeManager::alias_palette_event), name)));
+
+ palette_window->get_vbox()->pack_start (*canvas);
+ palette_window->show_all ();
+
+ palette_response_connection = palette_window->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ThemeManager::alias_palette_response), name, i->second));
+
+ palette_window->set_position (WIN_POS_MOUSE);
+ palette_window->present ();
+}
+
+void
+ThemeManager::setup_aliases ()
+{
+ using namespace ArdourCanvas;
+
+ UIConfiguration* uic (&UIConfiguration::instance());
+ UIConfiguration::ColorAliases& aliases (uic->color_aliases);
+
+ alias_list->clear ();
+
+ for (UIConfiguration::ColorAliases::iterator i = aliases.begin(); i != aliases.end(); ++i) {
+ TreeModel::Children rows = alias_list->children();