Give route groups their own colour, settable from the route

group dialogue.  Americanise spelling of color in a few
places to avoid confusion.  Fixes #4224.  Addresses parts
of #2650 and #4064.


git-svn-id: svn://localhost/ardour2/branches/3.0@10030 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2011-08-30 09:48:53 +00:00
parent 9b7ae4cccc
commit 7d32cf3813
10 changed files with 148 additions and 45 deletions

View File

@ -38,6 +38,7 @@
#include "ardour_ui.h"
#include "gui_object.h"
#include "axis_view.h"
#include "utils.h"
#include "i18n.h"
using namespace std;
@ -60,41 +61,7 @@ AxisView::~AxisView()
Gdk::Color
AxisView::unique_random_color()
{
Gdk::Color newcolor;
while (1) {
/* avoid neon/glowing tones by limiting them to the
"inner section" (paler) of a color wheel/circle.
*/
const int32_t max_saturation = 48000; // 65535 would open up the whole color wheel
newcolor.set_red (random() % max_saturation);
newcolor.set_blue (random() % max_saturation);
newcolor.set_green (random() % max_saturation);
if (used_colors.size() == 0) {
used_colors.push_back (newcolor);
return newcolor;
}
for (list<Gdk::Color>::iterator i = used_colors.begin(); i != used_colors.end(); ++i) {
Gdk::Color c = *i;
float rdelta, bdelta, gdelta;
rdelta = newcolor.get_red() - c.get_red();
bdelta = newcolor.get_blue() - c.get_blue();
gdelta = newcolor.get_green() - c.get_green();
if (sqrt (rdelta*rdelta + bdelta*bdelta + gdelta*gdelta) > 25.0) {
used_colors.push_back (newcolor);
return newcolor;
}
}
/* XXX need throttle here to make sure we don't spin for ever */
}
return ::unique_random_color (used_colors);
}
string

View File

@ -61,7 +61,9 @@ EditorGroupTabs::compute_tabs () const
tab.from = y;
tab.group = g;
tab.colour = (*i)->color ();
if (g) {
tab.color = group_color (g);
}
}
y += (*i)->effective_height ();
@ -81,7 +83,7 @@ EditorGroupTabs::draw_tab (cairo_t* cr, Tab const & tab) const
double const arc_radius = _width;
if (tab.group && tab.group->is_active()) {
cairo_set_source_rgba (cr, tab.colour.get_red_p (), tab.colour.get_green_p (), tab.colour.get_blue_p (), 1);
cairo_set_source_rgba (cr, tab.color.get_red_p (), tab.color.get_green_p (), tab.color.get_blue_p (), 1);
} else {
cairo_set_source_rgba (cr, 1, 1, 1, 0.2);
}

View File

@ -27,12 +27,16 @@
#include "group_tabs.h"
#include "keyboard.h"
#include "i18n.h"
#include "ardour_ui.h"
#include "utils.h"
using namespace std;
using namespace Gtk;
using namespace ARDOUR;
using Gtkmm2ext::Keyboard;
list<Gdk::Color> GroupTabs::_used_colors;
GroupTabs::GroupTabs ()
: _menu (0)
, _dragging (0)
@ -501,3 +505,61 @@ GroupTabs::remove_group (RouteGroup* g)
{
_session->remove_route_group (*g);
}
/** Set the color of the tab of a route group */
void
GroupTabs::set_group_color (RouteGroup* group, Gdk::Color color)
{
assert (group);
GUIObjectState& gui_state = *ARDOUR_UI::instance()->gui_object_state;
char buf[64];
snprintf (buf, sizeof (buf), "%d:%d:%d", color.get_red(), color.get_green(), color.get_blue());
gui_state.set (group_gui_id (group), "color", buf);
}
/** @return the ID string to use for the GUI state of a route group */
string
GroupTabs::group_gui_id (RouteGroup* group)
{
assert (group);
char buf[64];
snprintf (buf, sizeof (buf), "route_group %s", group->id().to_s().c_str ());
return buf;
}
/** @return the color to use for a route group tab */
Gdk::Color
GroupTabs::group_color (RouteGroup* group)
{
assert (group);
GUIObjectState& gui_state = *ARDOUR_UI::instance()->gui_object_state;
string const gui_id = group_gui_id (group);
bool empty;
string const color = gui_state.get_string (gui_id, "color", &empty);
if (empty) {
/* no color has yet been set, so use a random one */
Gdk::Color const color = unique_random_color (_used_colors);
set_group_color (group, color);
return color;
}
Gdk::Color c;
int r, g, b;
sscanf (color.c_str(), "%d:%d:%d", &r, &g, &b);
c.set_red (r);
c.set_green (g);
c.set_blue (b);
return c;
}

View File

@ -28,7 +28,7 @@ namespace ARDOUR {
class Editor;
/** Parent class for tabs which represent route groups as coloured tabs;
/** Parent class for tabs which represent route groups as colored tabs;
* Currently used on the left-hand side of the editor and at the top of the mixer.
*/
class GroupTabs : public CairoWidget, public ARDOUR::SessionHandlePtr
@ -46,6 +46,10 @@ public:
void run_new_group_dialog (ARDOUR::RouteList const &);
static void set_group_color (ARDOUR::RouteGroup *, Gdk::Color);
static std::string group_gui_id (ARDOUR::RouteGroup *);
static Gdk::Color group_color (ARDOUR::RouteGroup *);
protected:
struct Tab {
@ -53,7 +57,7 @@ protected:
double from;
double to;
Gdk::Color colour; ///< colour
Gdk::Color color; ///< color
ARDOUR::RouteGroup* group; ///< route group
};
@ -117,4 +121,7 @@ private:
double _drag_min; ///< minimum position for drag
double _drag_max; ///< maximum position for drag
double _drag_first; ///< first mouse pointer position during drag
/** colors that have been used for new route group tabs */
static std::list<Gdk::Color> _used_colors;
};

View File

@ -67,7 +67,10 @@ MixerGroupTabs::compute_tabs () const
tab.from = x;
tab.group = g;
tab.colour = s->color ();
if (g) {
tab.color = group_color (g);
}
}
x += s->get_width ();
@ -87,7 +90,7 @@ MixerGroupTabs::draw_tab (cairo_t* cr, Tab const & tab) const
double const arc_radius = _height;
if (tab.group && tab.group->is_active()) {
cairo_set_source_rgba (cr, tab.colour.get_red_p (), tab.colour.get_green_p (), tab.colour.get_blue_p (), 1);
cairo_set_source_rgba (cr, tab.color.get_red_p (), tab.color.get_green_p (), tab.color.get_blue_p (), 1);
} else {
cairo_set_source_rgba (cr, 1, 1, 1, 0.2);
}

View File

@ -23,6 +23,7 @@
#include "ardour/route_group.h"
#include "ardour/session.h"
#include "route_group_dialog.h"
#include "group_tabs.h"
#include "i18n.h"
#include <iostream>
@ -94,6 +95,7 @@ RouteGroupDialog::RouteGroupDialog (RouteGroup* g, bool creating_new)
_select.set_active (_group->is_select());
_edit.set_active (_group->is_edit());
_route_active.set_active (_group->is_route_active());
_color.set_color (GroupTabs::group_color (_group));
_name.signal_changed().connect (sigc::mem_fun (*this, &RouteGroupDialog::update));
_active.signal_toggled().connect (sigc::mem_fun (*this, &RouteGroupDialog::update));
@ -105,10 +107,11 @@ RouteGroupDialog::RouteGroupDialog (RouteGroup* g, bool creating_new)
_select.signal_toggled().connect (sigc::mem_fun (*this, &RouteGroupDialog::update));
_edit.signal_toggled().connect (sigc::mem_fun (*this, &RouteGroupDialog::update));
_route_active.signal_toggled().connect (sigc::mem_fun (*this, &RouteGroupDialog::update));
_color.signal_color_set().connect (sigc::mem_fun (*this, &RouteGroupDialog::update));
gain_toggled ();
Table* table = manage (new Table (8, 3, false));
Table* table = manage (new Table (11, 4, false));
table->set_row_spacings (6);
l = manage (new Label ("", Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
@ -129,6 +132,12 @@ RouteGroupDialog::RouteGroupDialog (RouteGroup* g, bool creating_new)
table->attach (_edit, 1, 3, 7, 8, Gtk::FILL, Gtk::FILL, 0, 0);
table->attach (_route_active, 1, 3, 8, 9, Gtk::FILL, Gtk::FILL, 0, 0);
HBox* b = manage (new HBox);
l = manage (new Label (_("Color"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
b->pack_start (*l, Gtk::SHRINK, Gtk::SHRINK);
b->pack_start (_color, Gtk::FILL, Gtk::FILL);
table->attach (*b, 1, 3, 10, 11, Gtk::FILL, Gtk::FILL, 0, 0);
options_box->pack_start (*table, false, true);
main_vbox->pack_start (*options_box, false, true);
@ -196,6 +205,8 @@ RouteGroupDialog::update ()
plist.add (Properties::active, _active.get_active());
plist.add (Properties::name, string (_name.get_text()));
GroupTabs::set_group_color (_group, _color.get_color ());
_group->apply_changes (plist);
}

View File

@ -23,6 +23,7 @@
#include <gtkmm/dialog.h>
#include <gtkmm/entry.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/colorbutton.h>
#include "ardour_dialog.h"
@ -48,6 +49,7 @@ private:
Gtk::CheckButton _edit;
Gtk::CheckButton _route_active;
Gtk::Button* _ok;
Gtk::ColorButton _color;
void gain_toggled ();
void update ();

View File

@ -27,6 +27,7 @@
#include <cstdlib>
#include <cctype>
#include <fstream>
#include <list>
#include <sys/stat.h>
#include <libart_lgpl/art_misc.h>
#include <gtkmm/rc.h>
@ -938,4 +939,42 @@ escape_underscores (string const & s)
return o;
}
Gdk::Color
unique_random_color (list<Gdk::Color>& used_colors)
{
Gdk::Color newcolor;
while (1) {
/* avoid neon/glowing tones by limiting them to the
"inner section" (paler) of a color wheel/circle.
*/
const int32_t max_saturation = 48000; // 65535 would open up the whole color wheel
newcolor.set_red (random() % max_saturation);
newcolor.set_blue (random() % max_saturation);
newcolor.set_green (random() % max_saturation);
if (used_colors.size() == 0) {
used_colors.push_back (newcolor);
return newcolor;
}
for (list<Gdk::Color>::iterator i = used_colors.begin(); i != used_colors.end(); ++i) {
Gdk::Color c = *i;
float rdelta, bdelta, gdelta;
rdelta = newcolor.get_red() - c.get_red();
bdelta = newcolor.get_blue() - c.get_blue();
gdelta = newcolor.get_green() - c.get_green();
if (sqrt (rdelta*rdelta + bdelta*bdelta + gdelta*gdelta) > 25.0) {
used_colors.push_back (newcolor);
return newcolor;
}
}
/* XXX need throttle here to make sure we don't spin for ever */
}
}

View File

@ -91,4 +91,6 @@ void resize_window_to_proportion_of_monitor (Gtk::Window*, int, int);
std::string escape_underscores (std::string const &);
Gdk::Color unique_random_color (std::list<Gdk::Color> &);
#endif /* __ardour_gtk_utils_h__ */

View File

@ -213,10 +213,14 @@ RouteGroup::get_max_factor(gain_t factor)
}
XMLNode&
RouteGroup::get_state (void)
RouteGroup::get_state ()
{
XMLNode *node = new XMLNode ("RouteGroup");
char buf[64];
id().print (buf, sizeof (buf));
node->add_property ("id", buf);
add_properties (*node);
if (!routes->empty()) {
@ -239,10 +243,14 @@ RouteGroup::set_state (const XMLNode& node, int version)
return set_state_2X (node, version);
}
set_values (node);
const XMLProperty *prop;
if ((prop = node.property ("id")) != 0) {
_id = prop->value();
}
set_values (node);
if ((prop = node.property ("routes")) != 0) {
stringstream str (prop->value());
vector<string> ids;