#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)
list<Tab>::iterator j = _tabs.insert (next, n);
t = &(*j);
}
-
+
} else {
_dragging_new_tab = false;
}
if (!_drag_moved) {
if (_dragging->group) {
-
+
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
-
+
/* edit */
- RouteGroupDialog d (_dragging->group, Gtk::Stock::APPLY);
+ RouteGroupDialog d (_dragging->group, false);
d.do_run ();
-
+
} else {
-
+
/* toggle active state */
_dragging->group->set_active (!_dragging->group->is_active (), this);
-
+
}
}
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (find (routes.begin(), routes.end(), *i) == routes.end()) {
- /* this route is not on the list of those that should be in _dragging's group */
- if ((*i)->route_group() == _dragging->group) {
+ /* this route is not contained in the tab we are dragging ... */
+ if ((*i)->route_group() != _dragging->group) {
+ /* and it's not in the dragged tab's group either */
_dragging->group->remove (*i);
}
} else {
/** Convert a click position to a tab.
* @param c Click position.
- * @param prev Filled in with the previous tab to the click, or 0.
- * @param next Filled in with the next tab after the click, or 0.
+ * @param prev Filled in with the previous tab to the click, or _tabs.end().
+ * @param next Filled in with the next tab after the click, or _tabs.end().
* @return Tab under the click, or 0.
*/
while (i != _tabs.end()) {
if (i->from > c) {
+ *next = i;
break;
}
++i;
}
- if (i != _tabs.end()) {
- *next = i;
-
- if (under) {
- *next++;
- }
- }
-
return under;
}
items.push_back (MenuElem (_("New..."), hide_return (sigc::mem_fun(*this, &GroupTabs::create_and_add_group))));
items.push_back (MenuElem (_("New From"), *new_from));
-
+
if (g) {
items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &GroupTabs::edit_group), g)));
- items.push_back (MenuElem (_("Subgroup"), sigc::bind (sigc::mem_fun (*this, &GroupTabs::subgroup), g)));
+ items.push_back (MenuElem (_("Add New Subgroup Bus"), sigc::bind (sigc::mem_fun (*this, &GroupTabs::subgroup), g, false, PreFader)));
+ items.push_back (MenuElem (_("Add New Aux Bus (pre-fader)"), sigc::bind (sigc::mem_fun (*this, &GroupTabs::subgroup), g, true, PreFader)));
+ items.push_back (MenuElem (_("Add New Aux Bus (post-fader)"), sigc::bind (sigc::mem_fun (*this, &GroupTabs::subgroup), g, true, PostFader)));
items.push_back (MenuElem (_("Collect"), sigc::bind (sigc::mem_fun (*this, &GroupTabs::collect), g)));
items.push_back (MenuElem (_("Remove"), sigc::bind (sigc::mem_fun (*this, &GroupTabs::remove_group), g)));
}
add_menu_items (_menu, g);
-
+
items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Activate All"), sigc::mem_fun(*this, &GroupTabs::activate_all)));
items.push_back (MenuElem (_("Disable All"), sigc::mem_fun(*this, &GroupTabs::disable_all)));
return _menu;
-
+
}
void
}
run_new_group_dialog (soloed);
-
}
void
RouteGroup* g = new RouteGroup (*_session, "");
g->apply_changes (default_properties ());
- RouteGroupDialog d (g, Gtk::Stock::NEW);
- int const r = d.do_run ();
+ RouteGroupDialog d (g, true);
- switch (r) {
- case Gtk::RESPONSE_OK:
- case Gtk::RESPONSE_ACCEPT:
+ if (d.do_run ()) {
+ delete g;
+ } else {
_session->add_route_group (g);
for (RouteList::const_iterator i = rl.begin(); i != rl.end(); ++i) {
g->add (*i);
}
- break;
- default:
- delete g;
}
}
g->apply_changes (default_properties ());
- RouteGroupDialog d (g, Gtk::Stock::NEW);
- int const r = d.do_run ();
+ RouteGroupDialog d (g, true);
- if (r != Gtk::RESPONSE_OK) {
+ if (d.do_run ()) {
delete g;
return 0;
}
-
+
_session->add_route_group (g);
return g;
}
void
GroupTabs::edit_group (RouteGroup* g)
{
- RouteGroupDialog d (g, Gtk::Stock::APPLY);
+ RouteGroupDialog d (g, false);
d.do_run ();
}
void
-GroupTabs::subgroup (RouteGroup* g)
+GroupTabs::subgroup (RouteGroup* g, bool aux, Placement placement)
{
- g->make_subgroup ();
+ g->make_subgroup (aux, placement);
}
struct CollectSorter {
CollectSorter (std::string const & key) : _key (key) {}
-
+
bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
return a->order_key (_key) < b->order_key (_key);
}
++i;
} else {
-
+
(*j)->set_order_key (order_key (), k + diff);
-
+
}
++j;
{
g->set_active (a, this);
}
-
+
void
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);
+
+ /* This is a bit of a hack, but this might change
+ our route's effective color, so emit gui_changed
+ for our routes.
+ */
+
+ for (RouteList::iterator i = group->route_list()->begin(); i != group->route_list()->end(); ++i) {
+ (*i)->gui_changed (X_("color"), 0);
+ }
+}
+
+/** @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;
+}
+