diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2014-12-05 09:01:49 -0500 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2014-12-05 09:01:55 -0500 |
commit | 2449fc9681ba62eda3f3a42904a3691fe022954d (patch) | |
tree | 4a407a7afba6be2e14c64d446c7556b0c158313e /gtk2_ardour/theme_manager.cc | |
parent | 207fd04587e7d354c9b98453b01cc0825b2ba556 (diff) |
several steps closer to more sane color system
Diffstat (limited to 'gtk2_ardour/theme_manager.cc')
-rw-r--r-- | gtk2_ardour/theme_manager.cc | 444 |
1 files changed, 386 insertions, 58 deletions
diff --git a/gtk2_ardour/theme_manager.cc b/gtk2_ardour/theme_manager.cc index 9fdf7b24d2..04b6761b5c 100644 --- a/gtk2_ardour/theme_manager.cc +++ b/gtk2_ardour/theme_manager.cc @@ -36,6 +36,9 @@ #include "ardour/filesystem_paths.h" +#include "canvas/container.h" +#include "canvas/rectangle.h" +#include "canvas/scroll_group.h" #include "canvas/wave_view.h" #include "ardour_button.h" @@ -73,19 +76,24 @@ ThemeManager::ThemeManager() , timeline_item_gradient_depth_label (_("Timeline item gradient depth")) , all_dialogs (_("All floating windows are dialogs")) , icon_set_label (_("Icon Set")) + , base_color_viewport (*base_color_scroller.get_hadjustment(), *base_color_scroller.get_vadjustment()) + , base_color_group (0) + , palette_window (0) { set_title (_("Theme Manager")); + /* Basic color list */ + color_list = TreeStore::create (columns); color_display.set_model (color_list); color_display.append_column (_("Object"), columns.name); - + Gtkmm2ext::CellRendererColorSelector* color_renderer = manage (new Gtkmm2ext::CellRendererColorSelector); TreeViewColumn* color_column = manage (new TreeViewColumn (_("Color"), *color_renderer)); color_column->add_attribute (color_renderer->property_color(), columns.gdkcolor); color_display.append_column (*color_column); - + color_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0)); color_display.get_column (0)->set_expand (true); color_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1)); @@ -94,9 +102,37 @@ ThemeManager::ThemeManager() color_display.get_selection()->set_mode (SELECTION_NONE); color_display.set_headers_visible (true); + color_display.signal_button_press_event().connect (sigc::mem_fun (*this, &ThemeManager::button_press_event), false); + scroller.add (color_display); scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC); + /* Now the alias list */ + + alias_list = TreeStore::create (alias_columns); + alias_display.set_model (alias_list); + alias_display.append_column (_("Object"), columns.name); + + color_renderer = manage (new Gtkmm2ext::CellRendererColorSelector); + color_column = manage (new TreeViewColumn (_("Color"), *color_renderer)); + color_column->add_attribute (color_renderer->property_color(), alias_columns.color); + + alias_display.append_column (*color_column); + + alias_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0)); + alias_display.get_column (0)->set_expand (true); + alias_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1)); + alias_display.get_column (1)->set_expand (false); + alias_display.set_reorderable (false); + alias_display.get_selection()->set_mode (SELECTION_NONE); + alias_display.set_headers_visible (true); + + alias_display.signal_button_press_event().connect (sigc::mem_fun (*this, &ThemeManager::alias_button_press_event), false); + + alias_scroller.add (alias_display); + + /* various buttons */ + RadioButton::Group group = dark_button.get_group(); light_button.set_group(group); theme_selection_hbox.set_homogeneous(false); @@ -143,7 +179,14 @@ ThemeManager::ThemeManager() hbox->pack_start (timeline_item_gradient_depth_label, false, false); vbox->pack_start (*hbox, PACK_SHRINK); - vbox->pack_start (scroller); + base_color_viewport.signal_size_allocate().connect (sigc::mem_fun (*this, &ThemeManager::base_color_viewport_allocated)); + base_color_scroller.add (base_color_viewport); + + notebook.append_page (scroller, _("Palette")); + notebook.append_page (base_color_scroller, _("Base Colors")); + notebook.append_page (alias_scroller, _("Items")); + + vbox->pack_start (notebook); vbox->show_all (); @@ -152,11 +195,9 @@ ThemeManager::ThemeManager() waveform_gradient_depth.set_update_policy (Gtk::UPDATE_DELAYED); timeline_item_gradient_depth.set_update_policy (Gtk::UPDATE_DELAYED); - color_display.signal_button_press_event().connect (sigc::mem_fun (*this, &ThemeManager::button_press_event), false); - color_dialog.get_colorsel()->set_has_opacity_control (true); color_dialog.get_colorsel()->set_has_palette (true); - + flat_buttons.set_active (ARDOUR_UI::config()->get_flat_buttons()); blink_rec_button.set_active (ARDOUR_UI::config()->get_blink_rec_arm()); region_color_button.set_active (ARDOUR_UI::config()->get_color_regions_using_track_color()); @@ -183,6 +224,7 @@ ThemeManager::ThemeManager() set_size_request (-1, 400); setup_theme (); + setup_aliases (); } ThemeManager::~ThemeManager() @@ -204,8 +246,6 @@ ThemeManager::button_press_event (GdkEventButton* ev) int cellx; int celly; - ColorVariable<uint32_t> *ccvar; - if (!color_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { return false; } @@ -223,7 +263,7 @@ ThemeManager::button_press_event (GdkEventButton* ev) /* parent row, do nothing */ return false; } - + int r,g, b, a; uint32_t rgba = (*iter)[columns.rgba]; Gdk::Color color; @@ -232,49 +272,58 @@ ThemeManager::button_press_event (GdkEventButton* ev) color.set_rgb_p (r / 255.0, g / 255.0, b / 255.0); color_dialog.get_colorsel()->set_previous_color (color); color_dialog.get_colorsel()->set_current_color (color); - color_dialog.get_colorsel()->set_previous_alpha (a * 256); - color_dialog.get_colorsel()->set_current_alpha (a * 256); - - ResponseType result = (ResponseType) color_dialog.run(); - - switch (result) { - case RESPONSE_CANCEL: - break; - case RESPONSE_ACCEPT: - color = color_dialog.get_colorsel()->get_current_color(); - a = color_dialog.get_colorsel()->get_current_alpha(); - r = (int) floor (color.get_red_p() * 255.0); - g = (int) floor (color.get_green_p() * 255.0); - b = (int) floor (color.get_blue_p() * 255.0); - - rgba = RGBA_TO_UINT(r,g,b,a>>8); - (*iter)[columns.rgba] = rgba; - (*iter)[columns.gdkcolor] = color; - - ccvar = (*iter)[columns.pVar]; - ccvar->set(rgba); - /* mark dirty ... */ - ARDOUR_UI::config()->set_dirty (); - /* but save it immediately */ - ARDOUR_UI::config()->save_state (); - - ColorsChanged(); //EMIT SIGNAL - break; - - default: - break; - - } + color_dialog.get_colorsel()->set_previous_alpha ((guint16) (a * 256)); + color_dialog.get_colorsel()->set_current_alpha ((guint16) (a * 256)); - color_dialog.hide (); + color_dialog_connection.disconnect (); + color_dialog_connection = color_dialog.signal_response().connect (sigc::mem_fun (*this, &ThemeManager::foobar_response)); + color_dialog.present (); } - return true; + } + + return true; +} +void +ThemeManager::foobar_response (int result) +{ + // ColorVariable<uint32_t> *ccvar; + int r,g, b, a; + uint32_t rgba; + Gdk::Color color; + + color_dialog_connection.disconnect (); + + switch (result) { + case RESPONSE_CANCEL: + break; + case RESPONSE_ACCEPT: + color = color_dialog.get_colorsel()->get_current_color(); + a = color_dialog.get_colorsel()->get_current_alpha(); + r = (int) floor (color.get_red_p() * 255.0); + g = (int) floor (color.get_green_p() * 255.0); + b = (int) floor (color.get_blue_p() * 255.0); + + rgba = RGBA_TO_UINT(r,g,b,a>>8); + // (*iter)[columns.rgba] = rgba; + // (*iter)[columns.gdkcolor] = color; + + // ccvar = (*iter)[columns.pVar]; + // ccvar->set(rgba); + /* mark dirty ... */ + ARDOUR_UI::config()->set_dirty (); + /* but save it immediately */ + ARDOUR_UI::config()->save_state (); + + ColorsChanged(); //EMIT SIGNAL + break; + default: break; + } - - return false; + + color_dialog.hide (); } void @@ -294,18 +343,6 @@ load_rc_file (const string& filename, bool themechange) Gtkmm2ext::UI::instance()->load_rcfile (rc_file_path, themechange); } -/* hmm, this is a problem. the profile doesn't - exist when the theme manager is constructed - and toggles buttons during "normal" GTK setup. - - a better solution will be to make all Profile - methods static or something. - - XXX FIX ME -*/ - -#define HACK_PROFILE_IS_SAE() (getenv("ARDOUR_SAE")!=0) - void ThemeManager::on_flat_buttons_toggled () { @@ -490,3 +527,294 @@ ThemeManager::reset_canvas_colors() ARDOUR_UI::config()->save_state (); } +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); + } + } +}; + +ArdourCanvas::Container* +ThemeManager::initialize_canvas (ArdourCanvas::Canvas& canvas) +{ + using namespace ArdourCanvas; + + /* hide background */ + canvas.set_background_color (rgba_to_color (0.0, 0.0, 1.0, 0.0)); + + ScrollGroup* base_color_scroll_group = new ScrollGroup (canvas.root(), ScrollGroup::ScrollSensitivity (ScrollGroup::ScrollsVertically|ScrollGroup::ScrollsHorizontally)); + canvas.add_scroller (*base_color_scroll_group); + return new ArdourCanvas::Container (base_color_scroll_group); +} + +void +ThemeManager::build_base_color_canvas (ArdourCanvas::Container& group, bool (ThemeManager::*event_handler)(GdkEvent*,std::string), double width, double height) +{ + using namespace ArdourCanvas; + + /* we want the colors sorted by hue, with their name */ + + UIConfiguration::RelativeColors& relatives (ARDOUR_UI::instance()->config()->relative_colors); + vector<NamedColor> nc; + for (UIConfiguration::RelativeColors::const_iterator x = relatives.begin(); x != relatives.end(); ++x) { + nc.push_back (NamedColor (x->first, x->second.get())); + } + SortByHue sorter; + sort (nc.begin(), nc.end(), sorter); + + const uint32_t color_limit = nc.size(); + const double box_size = 20.0; + + 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) { + Rectangle* r = new Rectangle (&group, Rect (x, y, x + box_size, y + box_size)); + + string name = nc[color_num++].name; + + UIConfiguration::RelativeColors::iterator c = relatives.find (name); + + if (c != relatives.end()) { + Color color = c->second.get().color (); + 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 (sigc::mem_fun (*this, event_handler), name)); + } + } + } +} + +void +ThemeManager::base_color_viewport_allocated (Gtk::Allocation&) +{ + if (!base_color_group) { + base_color_group = initialize_canvas (*base_color_viewport.canvas()); + } + + build_base_color_canvas (*base_color_group, &ThemeManager::base_color_event, + base_color_viewport.canvas()->width(), + base_color_viewport.canvas()->height()); + +} + +bool +ThemeManager::base_color_event (GdkEvent*ev, string name) +{ + switch (ev->type) { + case GDK_BUTTON_RELEASE: + edit_named_color (name); + break; + default: + break; + } + + return true; +} + +void +ThemeManager::edit_named_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)); + + base_color_edit_name = name; + + color_dialog_connection.disconnect (); + color_dialog_connection = color_dialog.signal_response().connect (sigc::mem_fun (*this, &ThemeManager::base_color_dialog_done)); + color_dialog.present(); +} + +void +ThemeManager::base_color_dialog_done (int result) +{ + using namespace ArdourCanvas; + + cerr << "Done, using [" << base_color_edit_name << "] res = " << result << endl; + + if (base_color_edit_name.empty()) { + color_dialog.hide (); + return; + } + + UIConfiguration* uic (ARDOUR_UI::instance()->config()); + UIConfiguration::RelativeHSV rhsv ("", HSV()); + Gdk::Color gdkcolor; + double r,g, b, a; + + switch (result) { + case RESPONSE_ACCEPT: + case RESPONSE_OK: + cerr << "Accepting\n"; + 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(); + + rhsv = uic->color_as_relative_hsv (rgba_to_color (r, g, b, a)); + uic->reset_relative (base_color_edit_name, rhsv); + + /* rebuild */ + + build_base_color_canvas (*base_color_group, &ThemeManager::base_color_event, + base_color_viewport.canvas()->width(), + base_color_viewport.canvas()->height()); + + ColorsChanged(); //EMIT SIGNAL + break; + + default: + break; + } + + color_dialog.hide (); + base_color_edit_name = ""; +} + +void +ThemeManager::palette_canvas_allocated (Gtk::Allocation& alloc, ArdourCanvas::Container* group, bool (ThemeManager::*event_handler)(GdkEvent*,std::string)) +{ + build_base_color_canvas (*group, event_handler, alloc.get_width(), alloc.get_height()); +} + +bool +ThemeManager::palette_chosen (GdkEvent* ev, string name) +{ + switch (ev->type) { + case GDK_BUTTON_RELEASE: + break; + default: + return false; + break; + } + + UIConfiguration* uic (ARDOUR_UI::instance()->config()); + uic->set_alias (palette_edit_name, name); + + (void) palette_done ((GdkEventAny*) 0); + + /* rebuild alias list with new color: inefficient but simple */ + + setup_aliases (); + + return true; +} + +bool +ThemeManager::palette_done (GdkEventAny*) +{ + palette_edit_name = ""; + palette_window->hide (); + return true; +} + +void +ThemeManager::choose_color_from_palette (string const & name) +{ + if (!palette_window) { + palette_window = new Gtk::Window (WINDOW_TOPLEVEL); + ArdourCanvas::GtkCanvas* canvas = new ArdourCanvas::GtkCanvas (); + ArdourCanvas::Container* group = initialize_canvas (*canvas); + + canvas->signal_size_allocate().connect (sigc::bind (sigc::mem_fun (*this, &ThemeManager::palette_canvas_allocated), group, &ThemeManager::palette_chosen)); + palette_window->signal_delete_event().connect (sigc::mem_fun (*this, &ThemeManager::palette_done)); + + palette_window->add (*canvas); + canvas->show (); + } + + palette_edit_name = name; + + palette_window->set_position (WIN_POS_MOUSE); + palette_window->present (); +} + +void +ThemeManager::setup_aliases () +{ + using namespace ArdourCanvas; + + UIConfiguration* uic (ARDOUR_UI::instance()->config()); + UIConfiguration::ColorAliases& aliases (uic->color_aliases); + + alias_list->clear (); + + for (UIConfiguration::ColorAliases::iterator i = aliases.begin(); i != aliases.end(); ++i) { + TreeModel::Row row; + + row = *(alias_list->append()); + row[alias_columns.name] = i->first; + row[alias_columns.alias] = i->second; + + Color c = uic->color (i->second); + + /* Gdk colors don't support alpha */ + + double r, g, b, a; + color_to_rgba (c, r, g, b, a); + Gdk::Color gcolor; + gcolor.set_rgb_p (r, g, b); + + row[alias_columns.color] = gcolor; + } +} + +bool +ThemeManager::alias_button_press_event (GdkEventButton* ev) +{ + TreeIter iter; + TreeModel::Path path; + TreeViewColumn* column; + int cellx; + int celly; + + if (!alias_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { + return false; + } + + guint32 colnum = GPOINTER_TO_UINT (column->get_data (X_("colnum"))); + + switch (colnum) { + case 0: + /* allow normal processing to occur */ + return false; + + case 1: /* color */ + if ((iter = alias_list->get_iter (path))) { + choose_color_from_palette ((*iter)[alias_columns.name]); + } + break; + } + + return true; +} |