+void
+ThemeManager::build_palette_canvas (ArdourCanvas::Canvas& canvas, ArdourCanvas::Container& group, sigc::slot<bool,GdkEvent*,std::string> event_handler)
+{
+ using namespace ArdourCanvas;
+
+ /* we want the colors sorted by hue, with their name */
+
+ UIConfiguration::Colors& colors (ARDOUR_UI::instance()->config()->colors);
+ vector<NamedColor> nc;
+ for (UIConfiguration::Colors::const_iterator x = colors.begin(); x != colors.end(); ++x) {
+ nc.push_back (NamedColor (x->first, HSV (x->second)));
+ }
+ SortByHue sorter;
+ sort (nc.begin(), nc.end(), sorter);
+
+ const uint32_t color_limit = nc.size();
+ const double box_size = 20.0;
+ const double width = canvas.width();
+ const double height = canvas.height();
+
+ uint32_t color_num = 0;
+
+ /* clear existing rects and delete them */
+
+ group.clear (true);
+
+ for (uint32_t y = 0; y < height - box_size && color_num < color_limit; y += box_size) {
+ for (uint32_t x = 0; x < width - box_size && color_num < color_limit; x += box_size) {
+ ArdourCanvas::Rectangle* r = new ArdourCanvas::Rectangle (&group, ArdourCanvas::Rect (x, y, x + box_size, y + box_size));
+
+ string name = nc[color_num++].name;
+
+ UIConfiguration::Colors::iterator c = colors.find (name);
+
+ if (c != colors.end()) {
+ Color color = c->second;
+ r->set_fill_color (color);
+ r->set_outline_color (rgba_to_color (0.0, 0.0, 0.0, 1.0));
+ r->set_tooltip (name);
+ r->Event.connect (sigc::bind (event_handler, name));
+ }
+ }
+ }
+}
+
+void
+ThemeManager::palette_size_request (Gtk::Requisition* req)
+{
+ uint32_t ncolors = ARDOUR_UI::instance()->config()->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 (ARDOUR_UI::instance()->config());
+ 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();