+ dark_button.set_active(true);
+ }
+
+ /* there is no need to block signal handlers, here,
+ * all elements check if the value has changed and ignore NOOPs
+ */
+ all_dialogs.set_active (UIConfiguration::instance().get_all_floating_windows_are_dialogs());
+ transients_follow_front.set_active (UIConfiguration::instance().get_transients_follow_front());
+ flat_buttons.set_active (UIConfiguration::instance().get_flat_buttons());
+ blink_rec_button.set_active (UIConfiguration::instance().get_blink_rec_arm());
+ region_color_button.set_active (UIConfiguration::instance().get_color_regions_using_track_color());
+ show_clipping_button.set_active (UIConfiguration::instance().get_show_waveform_clipping());
+ waveform_gradient_depth.set_value(UIConfiguration::instance().get_waveform_gradient_depth());
+ timeline_item_gradient_depth.set_value(UIConfiguration::instance().get_timeline_item_gradient_depth());
+}
+
+void
+ThemeManager::reset_canvas_colors()
+{
+ string cfile;
+ string basename;
+
+ basename = "my-";
+ basename += UIConfiguration::instance().get_color_file();
+ basename += ".colors";
+
+ if (find_file (ardour_config_search_path(), basename, cfile)) {
+ string backup = cfile + string (X_(".old"));
+ g_rename (cfile.c_str(), backup.c_str());
+ /* don't really care if it fails */
+ }
+
+ UIConfiguration::instance().load_defaults();
+ UIConfiguration::instance().save_state ();
+ set_ui_to_state();
+}
+
+ArdourCanvas::Container*
+ThemeManager::initialize_palette_canvas (ArdourCanvas::Canvas& canvas)
+{
+ using namespace ArdourCanvas;
+
+ /* hide background */
+ canvas.set_background_color (rgba_to_color (0.0, 0.0, 1.0, 0.0));
+
+ /* bi-directional scroll group */
+
+ ScrollGroup* scroll_group = new ScrollGroup (canvas.root(), ScrollGroup::ScrollSensitivity (ScrollGroup::ScrollsVertically|ScrollGroup::ScrollsHorizontally));
+ canvas.add_scroller (*scroll_group);
+
+ /* new container to hold everything */
+
+ return new ArdourCanvas::Container (scroll_group);
+}
+
+void
+ThemeManager::palette_canvas_allocated (Gtk::Allocation& alloc, ArdourCanvas::Container* group, ArdourCanvas::Canvas* canvas, sigc::slot<bool,GdkEvent*,std::string> event_handler)
+{
+ build_palette_canvas (*canvas, *group, event_handler);
+}
+
+struct NamedColor {
+ string name;
+ ArdourCanvas::HSV color;
+ NamedColor (string s, ArdourCanvas::HSV c) : name (s), color (c) {}
+};
+
+struct SortByHue {
+ bool operator() (NamedColor const & a, NamedColor const & b) {
+ using namespace ArdourCanvas;
+ const HSV black (0, 0, 0);
+ if (a.color.is_gray() || b.color.is_gray()) {
+ return black.distance (a.color) < black.distance (b.color);
+ } else {
+ return a.color.h < b.color.h;
+ // const HSV red (rgba_to_color (1.0, 0.0, 0.0, 1.0));
+ // return red.distance (a.color) < red.distance (b.color);
+ }
+ }
+};
+
+
+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 (UIConfiguration::instance().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 = 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;