Tweak group tabs class hierarchy and offer the same menu in both editor and mixer. Fixes #3336.
git-svn-id: svn://localhost/ardour2/branches/3.0@7441 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -20,13 +20,9 @@
|
||||
#ifndef __ardour_gtk_editor_component_h__
|
||||
#define __ardour_gtk_editor_component_h__
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "ardour/session_handle.h"
|
||||
|
||||
class Editor;
|
||||
|
||||
class EditorComponent : public ARDOUR::SessionHandlePtr
|
||||
class EditorComponent
|
||||
{
|
||||
public:
|
||||
EditorComponent (Editor *);
|
||||
|
||||
@@ -23,12 +23,13 @@
|
||||
#include "route_time_axis.h"
|
||||
#include "utils.h"
|
||||
#include "editor_route_groups.h"
|
||||
#include "editor_routes.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
|
||||
EditorGroupTabs::EditorGroupTabs (Editor* e)
|
||||
: GroupTabs (e)
|
||||
: EditorComponent (e)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -146,14 +147,54 @@ EditorGroupTabs::routes_for_tab (Tab const * t) const
|
||||
}
|
||||
|
||||
|
||||
Gtk::Menu*
|
||||
EditorGroupTabs::get_menu (RouteGroup *g)
|
||||
void
|
||||
EditorGroupTabs::add_menu_items (Gtk::Menu* m, RouteGroup* g)
|
||||
{
|
||||
return _editor->_route_groups->menu (g);
|
||||
using namespace Gtk::Menu_Helpers;
|
||||
|
||||
if (g) {
|
||||
MenuList& items = m->items ();
|
||||
items.push_back (MenuElem (_("Fit to Window"), sigc::bind (sigc::mem_fun (*_editor, &Editor::fit_route_group), g)));
|
||||
}
|
||||
}
|
||||
|
||||
RouteGroup *
|
||||
EditorGroupTabs::new_route_group () const
|
||||
PBD::PropertyList
|
||||
EditorGroupTabs::default_properties () const
|
||||
{
|
||||
return _editor->_route_groups->new_route_group ();
|
||||
PBD::PropertyList plist;
|
||||
|
||||
plist.add (Properties::active, true);
|
||||
plist.add (Properties::mute, true);
|
||||
plist.add (Properties::solo, true);
|
||||
plist.add (Properties::recenable, true);
|
||||
plist.add (Properties::edit, true);
|
||||
|
||||
return plist;
|
||||
}
|
||||
|
||||
string
|
||||
EditorGroupTabs::order_key () const
|
||||
{
|
||||
return X_("editor");
|
||||
}
|
||||
|
||||
RouteList
|
||||
EditorGroupTabs::selected_routes () const
|
||||
{
|
||||
RouteList rl;
|
||||
|
||||
for (TrackSelection::iterator i = _editor->get_selection().tracks.begin(); i != _editor->get_selection().tracks.end(); ++i) {
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
|
||||
if (rtv) {
|
||||
rl.push_back (rtv->route());
|
||||
}
|
||||
}
|
||||
|
||||
return rl;
|
||||
}
|
||||
|
||||
void
|
||||
EditorGroupTabs::sync_order_keys ()
|
||||
{
|
||||
_editor->_routes->sync_order_keys ("");
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
class Editor;
|
||||
|
||||
class EditorGroupTabs : public GroupTabs
|
||||
class EditorGroupTabs : public GroupTabs, public EditorComponent
|
||||
{
|
||||
public:
|
||||
EditorGroupTabs (Editor *);
|
||||
@@ -35,6 +35,9 @@ private:
|
||||
double extent () const {
|
||||
return _height;
|
||||
}
|
||||
Gtk::Menu* get_menu (ARDOUR::RouteGroup* g);
|
||||
ARDOUR::RouteGroup* new_route_group () const;
|
||||
void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *);
|
||||
PBD::PropertyList default_properties () const;
|
||||
std::string order_key () const;
|
||||
ARDOUR::RouteList selected_routes () const;
|
||||
void sync_order_keys ();
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@ EditorLocations::EditorLocations (Editor* e)
|
||||
void
|
||||
EditorLocations::set_session (ARDOUR::Session* s)
|
||||
{
|
||||
EditorComponent::set_session (s);
|
||||
SessionHandlePtr::set_session (s);
|
||||
locations->set_session (s);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef __gtk_ardour_editor_locations_h__
|
||||
#define __gtk_ardour_editor_locations_h__
|
||||
|
||||
#include "ardour/session_handle.h"
|
||||
#include "editor_component.h"
|
||||
|
||||
class LocationUI;
|
||||
@@ -28,7 +29,7 @@ namespace Gtk {
|
||||
class Widget;
|
||||
}
|
||||
|
||||
class EditorLocations : public EditorComponent
|
||||
class EditorLocations : public EditorComponent, public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
EditorLocations (Editor *);
|
||||
|
||||
@@ -157,7 +157,7 @@ EditorRegions::EditorRegions (Editor* e)
|
||||
void
|
||||
EditorRegions::set_session (ARDOUR::Session* s)
|
||||
{
|
||||
EditorComponent::set_session (s);
|
||||
SessionHandlePtr::set_session (s);
|
||||
redisplay ();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "editor_component.h"
|
||||
|
||||
class EditorRegions : public EditorComponent
|
||||
class EditorRegions : public EditorComponent, public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
EditorRegions (Editor *);
|
||||
|
||||
@@ -48,7 +48,6 @@ using Gtkmm2ext::Keyboard;
|
||||
|
||||
EditorRouteGroups::EditorRouteGroups (Editor* e)
|
||||
: EditorComponent (e),
|
||||
_menu (0),
|
||||
_in_row_change (false)
|
||||
|
||||
{
|
||||
@@ -153,7 +152,7 @@ EditorRouteGroups::EditorRouteGroups (Editor* e)
|
||||
w->show();
|
||||
remove_button->add (*w);
|
||||
|
||||
add_button->signal_clicked().connect (hide_return (sigc::mem_fun (*this, &EditorRouteGroups::new_route_group)));
|
||||
add_button->signal_clicked().connect (sigc::hide_return (sigc::mem_fun (*this, &EditorRouteGroups::run_new_group_dialog)));
|
||||
remove_button->signal_clicked().connect (sigc::mem_fun (*this, &EditorRouteGroups::remove_selected));
|
||||
|
||||
button_box->pack_start (*add_button);
|
||||
@@ -163,196 +162,6 @@ EditorRouteGroups::EditorRouteGroups (Editor* e)
|
||||
_display_packer->pack_start (*button_box, false, false);
|
||||
}
|
||||
|
||||
|
||||
Gtk::Menu*
|
||||
EditorRouteGroups::menu (RouteGroup* g)
|
||||
{
|
||||
using namespace Gtk::Menu_Helpers;
|
||||
|
||||
delete _menu;
|
||||
|
||||
Menu* new_from = new Menu;
|
||||
MenuList& f = new_from->items ();
|
||||
f.push_back (MenuElem (_("Selection..."), sigc::mem_fun (*this, &EditorRouteGroups::new_from_selection)));
|
||||
f.push_back (MenuElem (_("Record Enabled..."), sigc::mem_fun (*this, &EditorRouteGroups::new_from_rec_enabled)));
|
||||
f.push_back (MenuElem (_("Soloed..."), sigc::mem_fun (*this, &EditorRouteGroups::new_from_soloed)));
|
||||
|
||||
_menu = new Menu;
|
||||
_menu->set_name ("ArdourContextMenu");
|
||||
MenuList& items = _menu->items();
|
||||
|
||||
items.push_back (MenuElem (_("New..."), hide_return (sigc::mem_fun(*this, &EditorRouteGroups::new_route_group))));
|
||||
items.push_back (MenuElem (_("New From"), *new_from));
|
||||
if (g) {
|
||||
items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &EditorRouteGroups::edit), g)));
|
||||
items.push_back (MenuElem (_("Fit to Window"), sigc::bind (sigc::mem_fun (*_editor, &Editor::fit_route_group), g)));
|
||||
items.push_back (MenuElem (_("Subgroup"), sigc::bind (sigc::mem_fun (*this, &EditorRouteGroups::subgroup), g)));
|
||||
items.push_back (MenuElem (_("Collect"), sigc::bind (sigc::mem_fun (*this, &EditorRouteGroups::collect), g)));
|
||||
}
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Activate All"), sigc::mem_fun(*this, &EditorRouteGroups::activate_all)));
|
||||
items.push_back (MenuElem (_("Disable All"), sigc::mem_fun(*this, &EditorRouteGroups::disable_all)));
|
||||
|
||||
return _menu;
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::subgroup (RouteGroup* g)
|
||||
{
|
||||
g->make_subgroup ();
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::unsubgroup (RouteGroup* g)
|
||||
{
|
||||
g->destroy_subgroup ();
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::activate_all ()
|
||||
{
|
||||
_session->foreach_route_group (
|
||||
sigc::bind (sigc::mem_fun (*this, &EditorRouteGroups::set_activation), true)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::disable_all ()
|
||||
{
|
||||
_session->foreach_route_group (
|
||||
sigc::bind (sigc::mem_fun (*this, &EditorRouteGroups::set_activation), false)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::set_activation (RouteGroup* g, bool a)
|
||||
{
|
||||
g->set_active (a, this);
|
||||
}
|
||||
|
||||
ARDOUR::RouteGroup *
|
||||
EditorRouteGroups::new_route_group () const
|
||||
{
|
||||
PropertyList plist;
|
||||
|
||||
plist.add (Properties::active, true);
|
||||
plist.add (Properties::mute, true);
|
||||
plist.add (Properties::solo, true);
|
||||
plist.add (Properties::edit, true);
|
||||
|
||||
RouteGroup* g = new RouteGroup (*_session, "");
|
||||
|
||||
g->set_properties (plist);
|
||||
|
||||
RouteGroupDialog d (g, Gtk::Stock::NEW);
|
||||
int const r = d.do_run ();
|
||||
|
||||
if (r != Gtk::RESPONSE_OK) {
|
||||
delete g;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_session->add_route_group (g);
|
||||
return g;
|
||||
}
|
||||
void
|
||||
EditorRouteGroups::run_new_group_dialog (const RouteList& rl)
|
||||
{
|
||||
PropertyList plist;
|
||||
|
||||
plist.add (Properties::active, true);
|
||||
plist.add (Properties::mute, true);
|
||||
plist.add (Properties::solo, true);
|
||||
plist.add (Properties::recenable, true);
|
||||
plist.add (Properties::edit, true);
|
||||
|
||||
RouteGroup* g = new RouteGroup (*_session, "");
|
||||
g->set_properties (plist);
|
||||
|
||||
RouteGroupDialog d (g, Gtk::Stock::NEW);
|
||||
int const r = d.do_run ();
|
||||
|
||||
switch (r) {
|
||||
case Gtk::RESPONSE_OK:
|
||||
case Gtk::RESPONSE_ACCEPT:
|
||||
_session->add_route_group (g);
|
||||
for (RouteList::const_iterator i = rl.begin(); i != rl.end(); ++i) {
|
||||
g->add (*i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
delete g;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::new_from_selection ()
|
||||
{
|
||||
if (_editor->get_selection().tracks.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RouteList rl;
|
||||
|
||||
for (TrackSelection::iterator i = _editor->get_selection().tracks.begin(); i != _editor->get_selection().tracks.end(); ++i) {
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
|
||||
if (rtv) {
|
||||
rl.push_back (rtv->route());
|
||||
}
|
||||
}
|
||||
|
||||
if (rl.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
run_new_group_dialog (rl);
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::new_from_rec_enabled ()
|
||||
{
|
||||
RouteList rl;
|
||||
|
||||
for (TrackViewList::const_iterator i = _editor->get_track_views().begin(); i != _editor->get_track_views().end(); ++i) {
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
|
||||
if (rtv && rtv->route()->record_enabled()) {
|
||||
rl.push_back (rtv->route());
|
||||
}
|
||||
}
|
||||
|
||||
if (rl.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
run_new_group_dialog (rl);
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::new_from_soloed ()
|
||||
{
|
||||
RouteList rl;
|
||||
|
||||
for (TrackViewList::const_iterator i = _editor->get_track_views().begin(); i != _editor->get_track_views().end(); ++i) {
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
|
||||
if (rtv && !rtv->route()->is_master() && rtv->route()->soloed()) {
|
||||
rl.push_back (rtv->route());
|
||||
}
|
||||
}
|
||||
|
||||
if (rl.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
run_new_group_dialog (rl);
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::edit (RouteGroup* g)
|
||||
{
|
||||
RouteGroupDialog d (g, Gtk::Stock::APPLY);
|
||||
d.do_run ();
|
||||
}
|
||||
|
||||
void
|
||||
EditorRouteGroups::remove_selected ()
|
||||
{
|
||||
@@ -381,7 +190,7 @@ EditorRouteGroups::remove_selected ()
|
||||
void
|
||||
EditorRouteGroups::button_clicked ()
|
||||
{
|
||||
new_route_group ();
|
||||
run_new_group_dialog ();
|
||||
}
|
||||
|
||||
gint
|
||||
@@ -405,7 +214,7 @@ EditorRouteGroups::button_press_event (GdkEventButton* ev)
|
||||
}
|
||||
|
||||
if (Keyboard::is_context_menu_event (ev)) {
|
||||
menu(group)->popup (1, ev->time);
|
||||
_editor->_group_tabs->get_menu(group)->popup (1, ev->time);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -678,7 +487,7 @@ EditorRouteGroups::clear ()
|
||||
void
|
||||
EditorRouteGroups::set_session (Session* s)
|
||||
{
|
||||
EditorComponent::set_session (s);
|
||||
SessionHandlePtr::set_session (s);
|
||||
|
||||
if (_session) {
|
||||
_session->route_group_added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&EditorRouteGroups::add, this, _1), gui_context());
|
||||
@@ -688,58 +497,10 @@ EditorRouteGroups::set_session (Session* s)
|
||||
groups_changed ();
|
||||
}
|
||||
|
||||
struct CollectSorter {
|
||||
bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
|
||||
return a->order_key (N_ ("editor")) < b->order_key (N_ ("editor"));
|
||||
}
|
||||
};
|
||||
|
||||
/** Collect all members of a RouteGroup so that they are together in the Editor.
|
||||
* @param g Group to collect.
|
||||
*/
|
||||
void
|
||||
EditorRouteGroups::collect (RouteGroup* g)
|
||||
EditorRouteGroups::run_new_group_dialog ()
|
||||
{
|
||||
boost::shared_ptr<RouteList> routes = g->route_list ();
|
||||
routes->sort (CollectSorter ());
|
||||
int const N = routes->size ();
|
||||
|
||||
RouteList::iterator i = routes->begin ();
|
||||
TrackViewList::const_iterator j = _editor->get_track_views().begin();
|
||||
|
||||
int diff = 0;
|
||||
int coll = -1;
|
||||
while (i != routes->end() && j != _editor->get_track_views().end()) {
|
||||
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*j);
|
||||
if (rtv) {
|
||||
|
||||
boost::shared_ptr<Route> r = rtv->route ();
|
||||
int const k = r->order_key (N_ ("editor"));
|
||||
|
||||
if (*i == r) {
|
||||
|
||||
if (coll == -1) {
|
||||
coll = k;
|
||||
diff = N - 1;
|
||||
} else {
|
||||
--diff;
|
||||
}
|
||||
|
||||
r->set_order_key (N_ ("editor"), coll);
|
||||
|
||||
++coll;
|
||||
++i;
|
||||
|
||||
} else {
|
||||
|
||||
r->set_order_key (N_ ("editor"), k + diff);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
_editor->_routes->sync_order_keys ("");
|
||||
RouteList rl;
|
||||
|
||||
return _editor->_group_tabs->run_new_group_dialog (rl);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "editor_component.h"
|
||||
|
||||
class EditorRouteGroups : public EditorComponent
|
||||
class EditorRouteGroups : public EditorComponent, public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
EditorRouteGroups (Editor *);
|
||||
@@ -30,10 +30,7 @@ public:
|
||||
return *_display_packer;
|
||||
}
|
||||
|
||||
Gtk::Menu* menu (ARDOUR::RouteGroup *);
|
||||
|
||||
void clear ();
|
||||
ARDOUR::RouteGroup* new_route_group () const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -64,29 +61,16 @@ private:
|
||||
|
||||
Columns _columns;
|
||||
|
||||
void activate_all ();
|
||||
void disable_all ();
|
||||
void subgroup (ARDOUR::RouteGroup *);
|
||||
void unsubgroup (ARDOUR::RouteGroup *);
|
||||
void collect (ARDOUR::RouteGroup *);
|
||||
|
||||
void add (ARDOUR::RouteGroup *);
|
||||
void row_change (const Gtk::TreeModel::Path&,const Gtk::TreeModel::iterator&);
|
||||
void name_edit (const Glib::ustring&, const Glib::ustring&);
|
||||
void new_from_selection ();
|
||||
void new_from_rec_enabled ();
|
||||
void new_from_soloed ();
|
||||
void edit (ARDOUR::RouteGroup *);
|
||||
void button_clicked ();
|
||||
gint button_press_event (GdkEventButton* ev);
|
||||
void add (ARDOUR::RouteGroup* group);
|
||||
void remove_route_group ();
|
||||
void groups_changed ();
|
||||
void property_changed (ARDOUR::RouteGroup*, const PBD::PropertyChange &);
|
||||
void set_activation (ARDOUR::RouteGroup *, bool);
|
||||
void remove_selected ();
|
||||
void run_new_group_dialog (const ARDOUR::RouteList&);
|
||||
void run_new_group_dialog ();
|
||||
|
||||
Gtk::Menu* _menu;
|
||||
Glib::RefPtr<Gtk::ListStore> _model;
|
||||
Glib::RefPtr<Gtk::TreeSelection> _selection;
|
||||
Gtk::TreeView _display;
|
||||
|
||||
@@ -201,7 +201,7 @@ EditorRoutes::EditorRoutes (Editor* e)
|
||||
void
|
||||
EditorRoutes::set_session (Session* s)
|
||||
{
|
||||
EditorComponent::set_session (s);
|
||||
SessionHandlePtr::set_session (s);
|
||||
|
||||
initial_display ();
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "pbd/signals.h"
|
||||
#include "editor_component.h"
|
||||
|
||||
class EditorRoutes : public EditorComponent, public PBD::ScopedConnectionList
|
||||
class EditorRoutes : public EditorComponent, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
EditorRoutes (Editor *);
|
||||
|
||||
@@ -54,7 +54,7 @@ EditorSnapshots::EditorSnapshots (Editor* e)
|
||||
void
|
||||
EditorSnapshots::set_session (Session* s)
|
||||
{
|
||||
EditorComponent::set_session (s);
|
||||
SessionHandlePtr::set_session (s);
|
||||
|
||||
redisplay ();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <gtkmm/treeview.h>
|
||||
#include "editor_component.h"
|
||||
|
||||
class EditorSnapshots : public EditorComponent
|
||||
class EditorSnapshots : public EditorComponent, public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
EditorSnapshots (Editor *);
|
||||
|
||||
@@ -60,7 +60,7 @@ EditorSummary::EditorSummary (Editor* e)
|
||||
void
|
||||
EditorSummary::set_session (Session* s)
|
||||
{
|
||||
EditorComponent::set_session (s);
|
||||
SessionHandlePtr::set_session (s);
|
||||
|
||||
set_dirty ();
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class Editor;
|
||||
/** Class to provide a visual summary of the contents of an editor window; represents
|
||||
* the whole session as a set of lines, one per region view.
|
||||
*/
|
||||
class EditorSummary : public CairoWidget, public EditorComponent
|
||||
class EditorSummary : public CairoWidget, public EditorComponent, public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
EditorSummary (Editor *);
|
||||
|
||||
@@ -33,18 +33,23 @@ using namespace Gtk;
|
||||
using namespace ARDOUR;
|
||||
using Gtkmm2ext::Keyboard;
|
||||
|
||||
GroupTabs::GroupTabs (Editor* e)
|
||||
: EditorComponent (e),
|
||||
_dragging (0),
|
||||
_dragging_new_tab (0)
|
||||
GroupTabs::GroupTabs ()
|
||||
: _menu (0)
|
||||
, _dragging (0)
|
||||
, _dragging_new_tab (0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GroupTabs::~GroupTabs ()
|
||||
{
|
||||
delete _menu;
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::set_session (Session* s)
|
||||
{
|
||||
EditorComponent::set_session (s);
|
||||
SessionHandlePtr::set_session (s);
|
||||
|
||||
if (_session) {
|
||||
_session->RouteGroupChanged.connect (_session_connections, invalidator (*this), boost::bind (&GroupTabs::set_dirty, this), gui_context());
|
||||
@@ -184,7 +189,7 @@ GroupTabs::on_button_release_event (GdkEventButton* ev)
|
||||
|
||||
if (!routes.empty()) {
|
||||
if (_dragging_new_tab) {
|
||||
RouteGroup* g = new_route_group ();
|
||||
RouteGroup* g = create_and_add_group ();
|
||||
if (g) {
|
||||
for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
g->add (*i);
|
||||
@@ -280,3 +285,223 @@ GroupTabs::click_to_tab (double c, list<Tab>::iterator* prev, list<Tab>::iterato
|
||||
return under;
|
||||
}
|
||||
|
||||
Gtk::Menu*
|
||||
GroupTabs::get_menu (RouteGroup* g)
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
delete _menu;
|
||||
|
||||
Menu* new_from = new Menu;
|
||||
MenuList& f = new_from->items ();
|
||||
f.push_back (MenuElem (_("Selection..."), sigc::mem_fun (*this, &GroupTabs::new_from_selection)));
|
||||
f.push_back (MenuElem (_("Record Enabled..."), sigc::mem_fun (*this, &GroupTabs::new_from_rec_enabled)));
|
||||
f.push_back (MenuElem (_("Soloed..."), sigc::mem_fun (*this, &GroupTabs::new_from_soloed)));
|
||||
|
||||
_menu = new Menu;
|
||||
_menu->set_name ("ArdourContextMenu");
|
||||
MenuList& items = _menu->items();
|
||||
|
||||
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 (_("Collect"), sigc::bind (sigc::mem_fun (*this, &GroupTabs::collect), 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
|
||||
GroupTabs::new_from_selection ()
|
||||
{
|
||||
RouteList rl = selected_routes ();
|
||||
if (rl.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
run_new_group_dialog (rl);
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::new_from_rec_enabled ()
|
||||
{
|
||||
boost::shared_ptr<RouteList> rl = _session->get_routes ();
|
||||
|
||||
RouteList rec_enabled;
|
||||
|
||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||
if ((*i)->record_enabled()) {
|
||||
rec_enabled.push_back (*i);
|
||||
}
|
||||
}
|
||||
|
||||
if (rec_enabled.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
run_new_group_dialog (rec_enabled);
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::new_from_soloed ()
|
||||
{
|
||||
boost::shared_ptr<RouteList> rl = _session->get_routes ();
|
||||
|
||||
RouteList soloed;
|
||||
|
||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||
if (!(*i)->is_master() && (*i)->soloed()) {
|
||||
soloed.push_back (*i);
|
||||
}
|
||||
}
|
||||
|
||||
if (soloed.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
run_new_group_dialog (soloed);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::run_new_group_dialog (RouteList const & rl)
|
||||
{
|
||||
RouteGroup* g = new RouteGroup (*_session, "");
|
||||
g->set_properties (default_properties ());
|
||||
|
||||
RouteGroupDialog d (g, Gtk::Stock::NEW);
|
||||
int const r = d.do_run ();
|
||||
|
||||
switch (r) {
|
||||
case Gtk::RESPONSE_OK:
|
||||
case Gtk::RESPONSE_ACCEPT:
|
||||
_session->add_route_group (g);
|
||||
for (RouteList::const_iterator i = rl.begin(); i != rl.end(); ++i) {
|
||||
g->add (*i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
delete g;
|
||||
}
|
||||
}
|
||||
|
||||
RouteGroup *
|
||||
GroupTabs::create_and_add_group () const
|
||||
{
|
||||
RouteGroup* g = new RouteGroup (*_session, "");
|
||||
|
||||
g->set_properties (default_properties ());
|
||||
|
||||
RouteGroupDialog d (g, Gtk::Stock::NEW);
|
||||
int const r = d.do_run ();
|
||||
|
||||
if (r != Gtk::RESPONSE_OK) {
|
||||
delete g;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_session->add_route_group (g);
|
||||
return g;
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::edit_group (RouteGroup* g)
|
||||
{
|
||||
RouteGroupDialog d (g, Gtk::Stock::APPLY);
|
||||
d.do_run ();
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::subgroup (RouteGroup* g)
|
||||
{
|
||||
g->make_subgroup ();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
std::string _key;
|
||||
};
|
||||
|
||||
/** Collect all members of a RouteGroup so that they are together in the Editor or Mixer.
|
||||
* @param g Group to collect.
|
||||
*/
|
||||
void
|
||||
GroupTabs::collect (RouteGroup* g)
|
||||
{
|
||||
boost::shared_ptr<RouteList> group_routes = g->route_list ();
|
||||
group_routes->sort (CollectSorter (order_key ()));
|
||||
int const N = group_routes->size ();
|
||||
|
||||
RouteList::iterator i = group_routes->begin ();
|
||||
boost::shared_ptr<RouteList> routes = _session->get_routes ();
|
||||
RouteList::const_iterator j = routes->begin ();
|
||||
|
||||
int diff = 0;
|
||||
int coll = -1;
|
||||
while (i != group_routes->end() && j != routes->end()) {
|
||||
|
||||
int const k = (*j)->order_key (order_key ());
|
||||
|
||||
if (*i == *j) {
|
||||
|
||||
if (coll == -1) {
|
||||
coll = k;
|
||||
diff = N - 1;
|
||||
} else {
|
||||
--diff;
|
||||
}
|
||||
|
||||
(*j)->set_order_key (order_key (), coll);
|
||||
|
||||
++coll;
|
||||
++i;
|
||||
|
||||
} else {
|
||||
|
||||
(*j)->set_order_key (order_key (), k + diff);
|
||||
|
||||
}
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
sync_order_keys ();
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::activate_all ()
|
||||
{
|
||||
_session->foreach_route_group (
|
||||
sigc::bind (sigc::mem_fun (*this, &GroupTabs::set_activation), true)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::disable_all ()
|
||||
{
|
||||
_session->foreach_route_group (
|
||||
sigc::bind (sigc::mem_fun (*this, &GroupTabs::set_activation), false)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
GroupTabs::set_activation (RouteGroup* g, bool a)
|
||||
{
|
||||
g->set_active (a, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,13 +31,21 @@ class Editor;
|
||||
/** Parent class for tabs which represent route groups as coloured tabs;
|
||||
* Currently used on the left-hand side of the editor and at the top of the mixer.
|
||||
*/
|
||||
class GroupTabs : public CairoWidget, public EditorComponent
|
||||
class GroupTabs : public CairoWidget, public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
GroupTabs (Editor *);
|
||||
GroupTabs ();
|
||||
virtual ~GroupTabs ();
|
||||
|
||||
void set_session (ARDOUR::Session *);
|
||||
|
||||
/** @param g Route group, or 0.
|
||||
* @return Menu to be popped up on right-click over the given route group.
|
||||
*/
|
||||
Gtk::Menu* get_menu (ARDOUR::RouteGroup* g);
|
||||
|
||||
void run_new_group_dialog (ARDOUR::RouteList const &);
|
||||
|
||||
protected:
|
||||
|
||||
struct Tab {
|
||||
@@ -72,13 +80,23 @@ private:
|
||||
/** @return Size of the widget along the primary axis */
|
||||
virtual double extent () const = 0;
|
||||
|
||||
/** @param g Route group, or 0.
|
||||
* @return Menu to be popped up on right-click over the given route group.
|
||||
*/
|
||||
virtual Gtk::Menu* get_menu (ARDOUR::RouteGroup* g) = 0;
|
||||
|
||||
virtual ARDOUR::RouteGroup* new_route_group () const = 0;
|
||||
virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {}
|
||||
virtual PBD::PropertyList default_properties () const = 0;
|
||||
virtual std::string order_key () const = 0;
|
||||
virtual ARDOUR::RouteList selected_routes () const = 0;
|
||||
virtual void sync_order_keys () = 0;
|
||||
|
||||
void new_from_selection ();
|
||||
void new_from_rec_enabled ();
|
||||
void new_from_soloed ();
|
||||
ARDOUR::RouteGroup* create_and_add_group () const;
|
||||
void collect (ARDOUR::RouteGroup *);
|
||||
void set_activation (ARDOUR::RouteGroup *, bool);
|
||||
void edit_group (ARDOUR::RouteGroup *);
|
||||
void subgroup (ARDOUR::RouteGroup *);
|
||||
void activate_all ();
|
||||
void disable_all ();
|
||||
|
||||
void render (cairo_t *);
|
||||
void on_size_request (Gtk::Requisition *);
|
||||
bool on_button_press_event (GdkEventButton *);
|
||||
@@ -87,6 +105,7 @@ private:
|
||||
|
||||
Tab * click_to_tab (double, std::list<Tab>::iterator *, std::list<Tab>::iterator *);
|
||||
|
||||
Gtk::Menu* _menu;
|
||||
std::list<Tab> _tabs; ///< current list of tabs
|
||||
Tab* _dragging; ///< tab being dragged, or 0
|
||||
bool _dragging_new_tab; ///< true if we're dragging a new tab
|
||||
|
||||
@@ -32,9 +32,7 @@ using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
MixerGroupTabs::MixerGroupTabs (Mixer_UI* m)
|
||||
: GroupTabs (0),
|
||||
_mixer (m),
|
||||
_menu (0)
|
||||
: _mixer (m)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -152,54 +150,8 @@ MixerGroupTabs::routes_for_tab (Tab const * t) const
|
||||
return routes;
|
||||
}
|
||||
|
||||
Gtk::Menu*
|
||||
MixerGroupTabs::get_menu (RouteGroup* g)
|
||||
{
|
||||
if (g == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
delete _menu;
|
||||
_menu = new Menu;
|
||||
|
||||
MenuList& items = _menu->items ();
|
||||
items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &MixerGroupTabs::edit_group), g)));
|
||||
items.push_back (MenuElem (_("Subgroup"), sigc::bind (sigc::mem_fun (*this, &MixerGroupTabs::make_subgroup), g)));
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Remove"), sigc::bind (sigc::mem_fun (*this, &MixerGroupTabs::remove_group), g)));
|
||||
|
||||
return _menu;
|
||||
}
|
||||
|
||||
void
|
||||
MixerGroupTabs::edit_group (RouteGroup* g)
|
||||
{
|
||||
RouteGroupDialog d (g, Gtk::Stock::APPLY);
|
||||
d.do_run ();
|
||||
}
|
||||
|
||||
void
|
||||
MixerGroupTabs::remove_group (RouteGroup *g)
|
||||
{
|
||||
_session->remove_route_group (*g);
|
||||
}
|
||||
|
||||
void
|
||||
MixerGroupTabs::make_subgroup (RouteGroup* g)
|
||||
{
|
||||
g->make_subgroup ();
|
||||
}
|
||||
|
||||
void
|
||||
MixerGroupTabs::destroy_subgroup (RouteGroup* g)
|
||||
{
|
||||
g->destroy_subgroup ();
|
||||
}
|
||||
|
||||
ARDOUR::RouteGroup *
|
||||
MixerGroupTabs::new_route_group () const
|
||||
PropertyList
|
||||
MixerGroupTabs::default_properties () const
|
||||
{
|
||||
PropertyList plist;
|
||||
|
||||
@@ -209,17 +161,23 @@ MixerGroupTabs::new_route_group () const
|
||||
plist.add (Properties::gain, true);
|
||||
plist.add (Properties::recenable, true);
|
||||
|
||||
RouteGroup* g = new RouteGroup (*_session, "");
|
||||
g->set_properties (plist);
|
||||
|
||||
RouteGroupDialog d (g, Gtk::Stock::NEW);
|
||||
int const r = d.do_run ();
|
||||
|
||||
if (r != Gtk::RESPONSE_OK) {
|
||||
delete g;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_session->add_route_group (g);
|
||||
return g;
|
||||
return plist;
|
||||
}
|
||||
|
||||
string
|
||||
MixerGroupTabs::order_key () const
|
||||
{
|
||||
return X_("signal");
|
||||
}
|
||||
|
||||
RouteList
|
||||
MixerGroupTabs::selected_routes () const
|
||||
{
|
||||
return _mixer->selection().routes;
|
||||
}
|
||||
|
||||
void
|
||||
MixerGroupTabs::sync_order_keys ()
|
||||
{
|
||||
_mixer->sync_order_keys ("");
|
||||
}
|
||||
|
||||
@@ -34,14 +34,11 @@ private:
|
||||
double extent () const {
|
||||
return _width;
|
||||
}
|
||||
Gtk::Menu* get_menu (ARDOUR::RouteGroup* g);
|
||||
ARDOUR::RouteGroup* new_route_group () const;
|
||||
|
||||
void edit_group (ARDOUR::RouteGroup *);
|
||||
void remove_group (ARDOUR::RouteGroup *);
|
||||
void make_subgroup (ARDOUR::RouteGroup *);
|
||||
void destroy_subgroup (ARDOUR::RouteGroup *);
|
||||
PBD::PropertyList default_properties () const;
|
||||
std::string order_key () const;
|
||||
ARDOUR::RouteList selected_routes () const;
|
||||
void sync_order_keys ();
|
||||
|
||||
Mixer_UI* _mixer;
|
||||
Gtk::Menu* _menu;
|
||||
};
|
||||
|
||||
@@ -1320,6 +1320,8 @@ Mixer_UI::add_route_group (RouteGroup* group)
|
||||
group_display.set_cursor (group_model->get_path (row), *col, *name_cell, true);
|
||||
}
|
||||
|
||||
_group_tabs->set_dirty ();
|
||||
|
||||
in_group_row_change = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user