summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/global_port_matrix.cc34
-rw-r--r--gtk2_ardour/global_port_matrix.h2
-rw-r--r--gtk2_ardour/io_selector.cc107
-rw-r--r--gtk2_ardour/io_selector.h17
-rw-r--r--gtk2_ardour/port_matrix.cc352
-rw-r--r--gtk2_ardour/port_matrix.h26
-rw-r--r--gtk2_ardour/port_matrix_body.cc116
-rw-r--r--gtk2_ardour/port_matrix_body.h3
-rw-r--r--gtk2_ardour/port_matrix_column_labels.cc202
-rw-r--r--gtk2_ardour/port_matrix_column_labels.h8
-rw-r--r--gtk2_ardour/port_matrix_component.cc98
-rw-r--r--gtk2_ardour/port_matrix_component.h9
-rw-r--r--gtk2_ardour/port_matrix_grid.cc304
-rw-r--r--gtk2_ardour/port_matrix_grid.h5
-rw-r--r--gtk2_ardour/port_matrix_row_labels.cc131
-rw-r--r--gtk2_ardour/port_matrix_row_labels.h1
16 files changed, 768 insertions, 647 deletions
diff --git a/gtk2_ardour/global_port_matrix.cc b/gtk2_ardour/global_port_matrix.cc
index 2b3b9c2131..b19c383565 100644
--- a/gtk2_ardour/global_port_matrix.cc
+++ b/gtk2_ardour/global_port_matrix.cc
@@ -28,6 +28,8 @@
#include "i18n.h"
+using namespace std;
+
GlobalPortMatrix::GlobalPortMatrix (ARDOUR::Session& s, ARDOUR::DataType t)
: PortMatrix (s, t)
{
@@ -119,27 +121,25 @@ GlobalPortMatrixWindow::GlobalPortMatrixWindow (ARDOUR::Session& s, ARDOUR::Data
break;
}
- Gtk::HBox* buttons_hbox = Gtk::manage (new Gtk::HBox);
-
- _rescan_button.set_label (_("Rescan"));
- _rescan_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::REFRESH, Gtk::ICON_SIZE_BUTTON)));
- _rescan_button.signal_clicked().connect (sigc::mem_fun (_port_matrix, &GlobalPortMatrix::setup_all_ports));
- buttons_hbox->pack_start (_rescan_button, Gtk::PACK_SHRINK);
+ add (_port_matrix);
+ show_all ();
- _show_ports_button.set_label (_("Show individual ports"));
- _show_ports_button.set_active (true);
- _show_ports_button.signal_toggled().connect (sigc::mem_fun (*this, &GlobalPortMatrixWindow::show_ports_toggled));
- buttons_hbox->pack_start (_show_ports_button, Gtk::PACK_SHRINK);
+ /* XXX: hack to make the window full-size on opening. This may not work for
+ people with very large monitors */
- Gtk::VBox* vbox = Gtk::manage (new Gtk::VBox);
- vbox->pack_start (_port_matrix);
- vbox->pack_start (*buttons_hbox, Gtk::PACK_SHRINK);
- add (*vbox);
- show_all ();
+ resize (32768, 32768);
}
void
-GlobalPortMatrixWindow::show_ports_toggled ()
+GlobalPortMatrixWindow::on_realize ()
{
- _port_matrix.set_show_only_bundles (!_show_ports_button.get_active());
+ Window::on_realize ();
+
+ pair<uint32_t, uint32_t> const m = _port_matrix.max_size ();
+
+ GdkGeometry g;
+ g.max_width = m.first;
+ g.max_height = m.second;
+
+ set_geometry_hints (*this, g, Gdk::HINT_MAX_SIZE);
}
diff --git a/gtk2_ardour/global_port_matrix.h b/gtk2_ardour/global_port_matrix.h
index 98b898f8aa..1e383a094a 100644
--- a/gtk2_ardour/global_port_matrix.h
+++ b/gtk2_ardour/global_port_matrix.h
@@ -63,7 +63,7 @@ public:
GlobalPortMatrixWindow (ARDOUR::Session&, ARDOUR::DataType);
private:
- void show_ports_toggled ();
+ void on_realize ();
GlobalPortMatrix _port_matrix;
Gtk::Button _rescan_button;
diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc
index 4333efd8ea..3c1e4c91ed 100644
--- a/gtk2_ardour/io_selector.cc
+++ b/gtk2_ardour/io_selector.cc
@@ -181,100 +181,22 @@ IOSelector::list_is_global (int dim) const
}
IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool can_cancel)
- : ArdourDialog ("I/O selector")
- , _selector (session, io)
- , add_button (_("Add Port"))
- , disconnect_button (_("Disconnect All"))
- , ok_button (can_cancel ? _("OK"): _("Close"))
- , cancel_button (_("Cancel"))
- , rescan_button (_("Rescan"))
-
+ : _selector (session, io)
{
- /* XXX: what's this for? */
- add_events (Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
-
set_name ("IOSelectorWindow2");
+ set_title (_("I/O selector"));
- /* Disconnect All button */
- disconnect_button.set_name ("IOSelectorButton");
- disconnect_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_BUTTON)));
- disconnect_button.signal_clicked().connect (sigc::mem_fun (_selector, &IOSelector::disassociate_all));
- get_action_area()->pack_start (disconnect_button, false, false);
-
- /* Add Port button */
- add_button.set_name ("IOSelectorButton");
- add_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::ADD, Gtk::ICON_SIZE_BUTTON)));
- get_action_area()->pack_start (add_button, false, false);
- add_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (_selector, &IOSelector::add_channel), boost::shared_ptr<Bundle> ()));
-
- /* Rescan button */
- rescan_button.set_name ("IOSelectorButton");
- rescan_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::REFRESH, Gtk::ICON_SIZE_BUTTON)));
- rescan_button.signal_clicked().connect (sigc::mem_fun (*this, &IOSelectorWindow::rescan));
- get_action_area()->pack_start (rescan_button, false, false);
-
- io->PortCountChanged.connect (sigc::hide (mem_fun (*this, &IOSelectorWindow::ports_changed)));
-
- /* Cancel button */
- if (can_cancel) {
- cancel_button.set_name ("IOSelectorButton");
- cancel_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::CANCEL, Gtk::ICON_SIZE_BUTTON)));
- get_action_area()->pack_start (cancel_button, false, false);
- } else {
- cancel_button.hide();
- }
- cancel_button.signal_clicked().connect (mem_fun(*this, &IOSelectorWindow::cancel));
-
- /* OK button */
- ok_button.set_name ("IOSelectorButton");
- if (!can_cancel) {
- ok_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::CLOSE, Gtk::ICON_SIZE_BUTTON)));
- }
- ok_button.signal_clicked().connect (mem_fun(*this, &IOSelectorWindow::accept));
- get_action_area()->pack_start (ok_button, false, false);
-
- get_vbox()->set_spacing (8);
-
- get_vbox()->pack_start (_selector, true, true);
+ add (_selector);
set_position (Gtk::WIN_POS_MOUSE);
io_name_changed (this);
- ports_changed ();
show_all ();
signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), this));
-}
-
-void
-IOSelectorWindow::ports_changed ()
-{
- /* XXX make this insensitive based on port connectivity, not
- port counts.
- */
-
- add_button.set_sensitive (true);
-}
-
-void
-IOSelectorWindow::rescan ()
-{
- _selector.setup_ports (_selector.other());
-}
-void
-IOSelectorWindow::cancel ()
-{
- _selector.Finished (IOSelector::Cancelled);
- hide ();
-}
-
-void
-IOSelectorWindow::accept ()
-{
- _selector.Finished (IOSelector::Accepted);
- hide ();
+ resize (32768, 32768);
}
void
@@ -300,6 +222,21 @@ IOSelectorWindow::io_name_changed (void* src)
set_title (title);
}
+void
+IOSelectorWindow::on_realize ()
+{
+ Window::on_realize ();
+
+ pair<uint32_t, uint32_t> const m = _selector.max_size ();
+
+ GdkGeometry g;
+ g.max_width = m.first;
+ g.max_height = m.second;
+
+ set_geometry_hints (*this, g, Gdk::HINT_MAX_SIZE);
+}
+
+
PortInsertUI::PortInsertUI (ARDOUR::Session& sess, boost::shared_ptr<ARDOUR::PortInsert> pi)
: input_selector (sess, pi->input())
, output_selector (sess, pi->output())
@@ -330,8 +267,7 @@ PortInsertWindow::PortInsertWindow (ARDOUR::Session& sess, boost::shared_ptr<ARD
: ArdourDialog ("port insert dialog"),
_portinsertui (sess, pi),
ok_button (can_cancel ? _("OK"): _("Close")),
- cancel_button (_("Cancel")),
- rescan_button (_("Rescan"))
+ cancel_button (_("Cancel"))
{
set_name ("IOSelectorWindow");
@@ -344,10 +280,7 @@ PortInsertWindow::PortInsertWindow (ARDOUR::Session& sess, boost::shared_ptr<ARD
ok_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::CLOSE, Gtk::ICON_SIZE_BUTTON)));
}
cancel_button.set_name ("IOSelectorButton");
- rescan_button.set_name ("IOSelectorButton");
- rescan_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::REFRESH, Gtk::ICON_SIZE_BUTTON)));
- get_action_area()->pack_start (rescan_button, false, false);
if (can_cancel) {
cancel_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::CANCEL, Gtk::ICON_SIZE_BUTTON)));
get_action_area()->pack_start (cancel_button, false, false);
diff --git a/gtk2_ardour/io_selector.h b/gtk2_ardour/io_selector.h
index d6b00254be..24e99e27ec 100644
--- a/gtk2_ardour/io_selector.h
+++ b/gtk2_ardour/io_selector.h
@@ -71,7 +71,7 @@ class IOSelector : public PortMatrix
bool _find_inputs_for_io_outputs;
};
-class IOSelectorWindow : public ArdourDialog
+class IOSelectorWindow : public Gtk::Window
{
public:
IOSelectorWindow (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool can_cancel = false);
@@ -80,23 +80,11 @@ class IOSelectorWindow : public ArdourDialog
protected:
void on_map ();
+ void on_realize ();
private:
IOSelector _selector;
-
- /* overall operation buttons */
-
- Gtk::Button add_button;
- Gtk::Button disconnect_button;
- Gtk::Button ok_button;
- Gtk::Button cancel_button;
- Gtk::Button rescan_button;
-
- void cancel ();
- void accept ();
- void rescan ();
- void ports_changed ();
void io_name_changed (void *src);
};
@@ -128,7 +116,6 @@ class PortInsertWindow : public ArdourDialog
Gtk::Button ok_button;
Gtk::Button cancel_button;
- Gtk::Button rescan_button;
Gtk::Frame button_frame;
void cancel ();
diff --git a/gtk2_ardour/port_matrix.cc b/gtk2_ardour/port_matrix.cc
index b2c43ad35a..820920ed14 100644
--- a/gtk2_ardour/port_matrix.cc
+++ b/gtk2_ardour/port_matrix.cc
@@ -32,23 +32,26 @@
#include "port_matrix_body.h"
#include "i18n.h"
+using namespace std;
+using namespace sigc;
+using namespace Gtk;
+
/** PortMatrix constructor.
* @param session Our session.
* @param type Port type that we are handling.
*/
PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type)
- : Gtk::Table (2, 2),
+ : Table (2, 2),
_session (session),
_type (type),
- _column_visibility_box_added (false),
- _row_visibility_box_added (false),
_menu (0),
- _setup_once (false),
_arrangement (TOP_TO_RIGHT),
_row_index (0),
_column_index (1),
_min_height_divisor (1),
- _show_only_bundles (false)
+ _show_only_bundles (false),
+ _inhibit_toggle_show_only_bundles (false),
+ _first_setup (true)
{
_body = new PortMatrixBody (this);
@@ -56,38 +59,30 @@ PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type)
_ports[i].set_type (type);
/* watch for the content of _ports[] changing */
- _ports[i].Changed.connect (sigc::mem_fun (*this, &PortMatrix::setup));
+ _ports[i].Changed.connect (mem_fun (*this, &PortMatrix::setup));
}
- _row_visibility_box.pack_start (_row_visibility_label, Gtk::PACK_SHRINK);
- _column_visibility_box.pack_start (_column_visibility_label, Gtk::PACK_SHRINK);
-
- _hscroll.signal_value_changed().connect (sigc::mem_fun (*this, &PortMatrix::hscroll_changed));
- _vscroll.signal_value_changed().connect (sigc::mem_fun (*this, &PortMatrix::vscroll_changed));
+ _hscroll.signal_value_changed().connect (mem_fun (*this, &PortMatrix::hscroll_changed));
+ _vscroll.signal_value_changed().connect (mem_fun (*this, &PortMatrix::vscroll_changed));
/* watch for routes being added or removed */
- _session.RouteAdded.connect (sigc::hide (sigc::mem_fun (*this, &PortMatrix::routes_changed)));
+ _session.RouteAdded.connect (sigc::hide (mem_fun (*this, &PortMatrix::routes_changed)));
/* and also bundles */
- _session.BundleAdded.connect (sigc::hide (sigc::mem_fun (*this, &PortMatrix::setup_global_ports)));
+ _session.BundleAdded.connect (sigc::hide (mem_fun (*this, &PortMatrix::setup_global_ports)));
reconnect_to_routes ();
+ attach (*_body, 0, 1, 0, 1);
+ attach (_vscroll, 1, 2, 0, 1, SHRINK);
+ attach (_hscroll, 0, 1, 1, 2, FILL | EXPAND, SHRINK);
+
show_all ();
}
PortMatrix::~PortMatrix ()
{
delete _body;
-
- for (std::vector<Gtk::CheckButton*>::iterator i = _column_visibility_buttons.begin(); i != _column_visibility_buttons.end(); ++i) {
- delete *i;
- }
-
- for (std::vector<Gtk::CheckButton*>::iterator i = _row_visibility_buttons.begin(); i != _row_visibility_buttons.end(); ++i) {
- delete *i;
- }
-
delete _menu;
}
@@ -95,7 +90,7 @@ PortMatrix::~PortMatrix ()
void
PortMatrix::reconnect_to_routes ()
{
- for (std::vector<sigc::connection>::iterator i = _route_connections.begin(); i != _route_connections.end(); ++i) {
+ for (vector<connection>::iterator i = _route_connections.begin(); i != _route_connections.end(); ++i) {
i->disconnect ();
}
_route_connections.clear ();
@@ -103,7 +98,7 @@ PortMatrix::reconnect_to_routes ()
boost::shared_ptr<ARDOUR::RouteList> routes = _session.get_routes ();
for (ARDOUR::RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
_route_connections.push_back (
- (*i)->processors_changed.connect (sigc::mem_fun (*this, &PortMatrix::setup_global_ports))
+ (*i)->processors_changed.connect (mem_fun (*this, &PortMatrix::setup_global_ports))
);
}
}
@@ -120,117 +115,16 @@ PortMatrix::routes_changed ()
void
PortMatrix::setup ()
{
- select_arrangement ();
+ if (_first_setup) {
+ select_arrangement ();
+ }
+
_body->setup ();
setup_scrollbars ();
queue_draw ();
- if (_setup_once) {
-
- /* we've set up before, so we need to clean up before re-setting-up */
- /* XXX: we ought to be able to do this by just getting a list of children
- from each container widget, but I couldn't make that work */
-
- for (std::vector<Gtk::CheckButton*>::iterator i = _column_visibility_buttons.begin(); i != _column_visibility_buttons.end(); ++i) {
- _column_visibility_box.remove (**i);
- delete *i;
- }
-
- _column_visibility_buttons.clear ();
-
- for (std::vector<Gtk::CheckButton*>::iterator i = _row_visibility_buttons.begin(); i != _row_visibility_buttons.end(); ++i) {
- _row_visibility_box.remove (**i);
- delete *i;
- }
-
- _row_visibility_buttons.clear ();
-
- _scroller_table.remove (_vscroll);
- _scroller_table.remove (*_body);
- _scroller_table.remove (_hscroll);
-
- remove (_scroller_table);
- if (_row_visibility_box_added) {
- remove (_row_visibility_box);
- }
-
- if (_column_visibility_box_added) {
- remove (_column_visibility_box);
- }
- }
-
- if (_column_index == 0) {
- _column_visibility_label.set_text (_("Show Outputs"));
- _row_visibility_label.set_text (_("Show Inputs"));
- } else {
- _column_visibility_label.set_text (_("Show Inputs"));
- _row_visibility_label.set_text (_("Show Outputs"));
- }
-
- for (PortGroupList::List::const_iterator i = columns()->begin(); i != columns()->end(); ++i) {
- Gtk::CheckButton* b = new Gtk::CheckButton ((*i)->name);
- b->set_active ((*i)->visible());
- boost::weak_ptr<PortGroup> w (*i);
- b->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &PortMatrix::visibility_toggled), w, b));
- _column_visibility_buttons.push_back (b);
- _column_visibility_box.pack_start (*b, Gtk::PACK_SHRINK);
- }
-
- for (PortGroupList::List::const_iterator i = rows()->begin(); i != rows()->end(); ++i) {
- Gtk::CheckButton* b = new Gtk::CheckButton ((*i)->name);
- b->set_active ((*i)->visible());
- boost::weak_ptr<PortGroup> w (*i);
- b->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &PortMatrix::visibility_toggled), w, b));
- _row_visibility_buttons.push_back (b);
- _row_visibility_box.pack_start (*b, Gtk::PACK_SHRINK);
- }
-
- if (_arrangement == TOP_TO_RIGHT) {
-
- _scroller_table.attach (_hscroll, 0, 1, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
- _scroller_table.attach (*_body, 0, 1, 1, 2);
- _scroller_table.attach (_vscroll, 1, 2, 1, 2, Gtk::SHRINK);
-
- attach (_scroller_table, 0, 1, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL | Gtk::EXPAND);
-
- if (rows()->size() > 1) {
- attach (_row_visibility_box, 1, 2, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
- _row_visibility_box_added = true;
- } else {
- _row_visibility_box_added = false;
- }
-
- if (columns()->size() > 1) {
- attach (_column_visibility_box, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
- _column_visibility_box_added = true;
- } else {
- _column_visibility_box_added = false;
- }
-
- } else {
- _scroller_table.attach (_vscroll, 0, 1, 0, 1, Gtk::SHRINK);
- _scroller_table.attach (*_body, 1, 2, 0, 1);
- _scroller_table.attach (_hscroll, 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
-
- if (rows()->size() > 1) {
- attach (_row_visibility_box, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
- _row_visibility_box_added = true;
- } else {
- _row_visibility_box_added = false;
- }
-
- attach (_scroller_table, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL | Gtk::EXPAND);
-
- if (columns()->size() > 1) {
- attach (_column_visibility_box, 1, 2, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
- _column_visibility_box_added = true;
- } else {
- _column_visibility_box_added = false;
- }
- }
-
- _setup_once = true;
-
+ _first_setup = false;
+
show_all ();
}
@@ -259,7 +153,7 @@ PortMatrix::vscroll_changed ()
void
PortMatrix::setup_scrollbars ()
{
- Gtk::Adjustment* a = _hscroll.get_adjustment ();
+ Adjustment* a = _hscroll.get_adjustment ();
a->set_lower (0);
a->set_upper (_body->full_scroll_width());
a->set_page_size (_body->alloc_scroll_width());
@@ -346,90 +240,113 @@ PortMatrix::rows () const
return &_ports[_row_index];
}
-/** A group visibility checkbutton has been toggled.
- * @param w Group.
- * @param b Button.
- */
void
-PortMatrix::visibility_toggled (boost::weak_ptr<PortGroup> w, Gtk::CheckButton* b)
+PortMatrix::popup_menu (
+ pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> column,
+ pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> row,
+ uint32_t t
+ )
{
- boost::shared_ptr<PortGroup> g = w.lock ();
- if (!g) {
- return;
- }
+ using namespace Menu_Helpers;
- g->set_visible (b->get_active());
- _body->setup ();
- setup_scrollbars ();
- queue_draw ();
-}
-
-void
-PortMatrix::popup_channel_context_menu (int dim, uint32_t N, uint32_t t)
-{
delete _menu;
- _menu = new Gtk::Menu;
+ _menu = new Menu;
_menu->set_name ("ArdourContextMenu");
- Gtk::Menu_Helpers::MenuList& items = _menu->items ();
+ MenuList& items = _menu->items ();
- ARDOUR::BundleChannel bc;
+ boost::shared_ptr<PortGroup> pg[2];
+ pg[_column_index] = column.first;
+ pg[_row_index] = row.first;
- PortGroup::BundleList const r = _ports[dim].bundles();
- for (PortGroup::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
- if (N < i->bundle->nchannels ()) {
- bc = ARDOUR::BundleChannel (i->bundle, N);
- break;
- } else {
- N -= i->bundle->nchannels ();
- }
- }
+ ARDOUR::BundleChannel bc[2];
+ bc[_column_index] = column.second;
+ bc[_row_index] = row.second;
- if (bc.bundle) {
- char buf [64];
- bool have_one = false;
+ char buf [64];
- if (can_rename_channels (dim)) {
- snprintf (buf, sizeof (buf), _("Rename '%s'..."), bc.bundle->channel_name (bc.channel).c_str());
- boost::weak_ptr<ARDOUR::Bundle> w (bc.bundle);
- items.push_back (
- Gtk::Menu_Helpers::MenuElem (
- buf,
- sigc::bind (sigc::mem_fun (*this, &PortMatrix::rename_channel_proxy), w, bc.channel)
- )
- );
+ for (int dim = 0; dim < 2; ++dim) {
- have_one = true;
- }
+ if (pg[dim]) {
- if (can_remove_channels (dim)) {
- snprintf (buf, sizeof (buf), _("Remove '%s'"), bc.bundle->channel_name (bc.channel).c_str());
- boost::weak_ptr<ARDOUR::Bundle> w (bc.bundle);
- items.push_back (
- Gtk::Menu_Helpers::MenuElem (
- buf,
- sigc::bind (sigc::mem_fun (*this, &PortMatrix::remove_channel_proxy), w, bc.channel)
- )
- );
+ boost::weak_ptr<PortGroup> wp (pg[dim]);
+
+ if (pg[dim]->visible()) {
+ if (dim == 0) {
+ snprintf (buf, sizeof (buf), _("Hide '%s' sources"), pg[dim]->name.c_str());
+ } else {
+ snprintf (buf, sizeof (buf), _("Hide '%s' destinations"), pg[dim]->name.c_str());
+ }
- have_one = true;
+ items.push_back (MenuElem (buf, bind (mem_fun (*this, &PortMatrix::hide_group), wp)));
+ } else {
+ if (dim == 0) {
+ snprintf (buf, sizeof (buf), _("Show '%s' sources"), pg[dim]->name.c_str());
+ } else {
+ snprintf (buf, sizeof (buf), _("Show '%s' destinations"), pg[dim]->name.c_str());
+ }
+ items.push_back (MenuElem (buf, bind (mem_fun (*this, &PortMatrix::show_group), wp)));
+ }
}
- if (have_one) {
- items.push_back (Gtk::Menu_Helpers::SeparatorElem ());
- }
-
- boost::weak_ptr<ARDOUR::Bundle> w (bc.bundle);
- items.push_back (Gtk::Menu_Helpers::MenuElem (
- _("Disassociate all"),
- sigc::bind (sigc::mem_fun (*this, &PortMatrix::disassociate_all_on_channel), w, bc.channel, dim)
- )
- );
+ if (bc[dim].bundle) {
+ bool have_one = false;
+
+ if (can_rename_channels (dim)) {
+ snprintf (buf, sizeof (buf), _("Rename '%s'..."), bc[dim].bundle->channel_name (bc[dim].channel).c_str());
+ boost::weak_ptr<ARDOUR::Bundle> w (bc[dim].bundle);
+ items.push_back (
+ MenuElem (
+ buf,
+ bind (mem_fun (*this, &PortMatrix::rename_channel_proxy), w, bc[dim].channel)
+ )
+ );
+
+ have_one = true;
+ }
- _menu->popup (1, t);
+ if (can_remove_channels (dim)) {
+ snprintf (buf, sizeof (buf), _("Remove '%s'"), bc[dim].bundle->channel_name (bc[dim].channel).c_str());
+ boost::weak_ptr<ARDOUR::Bundle> w (bc[dim].bundle);
+ items.push_back (
+ MenuElem (
+ buf,
+ bind (mem_fun (*this, &PortMatrix::remove_channel_proxy), w, bc[dim].channel)
+ )
+ );
+
+ have_one = true;
+ }
+
+ boost::weak_ptr<ARDOUR::Bundle> w (bc[dim].bundle);
+
+ if (_show_only_bundles) {
+ snprintf (buf, sizeof (buf), _("Disassociate all from '%s'"), bc[dim].bundle->name().c_str());
+ } else {
+ snprintf (
+ buf, sizeof (buf), _("Disassociate all from '%s/%s'"),
+ bc[dim].bundle->name().c_str(), bc[dim].bundle->channel_name (bc[dim].channel).c_str()
+ );
+ }
+
+ items.push_back (
+ MenuElem (buf, bind (mem_fun (*this, &PortMatrix::disassociate_all_on_channel), w, bc[dim].channel, dim))
+ );
+
+ }
}
+
+ items.push_back (SeparatorElem ());
+
+ items.push_back (MenuElem (_("Rescan"), mem_fun (*this, &PortMatrix::setup_all_ports)));
+ items.push_back (CheckMenuElem (_("Show individual ports"), mem_fun (*this, &PortMatrix::toggle_show_only_bundles)));
+ CheckMenuItem* i = dynamic_cast<CheckMenuItem*> (&items.back());
+ _inhibit_toggle_show_only_bundles = true;
+ i->set_active (!_show_only_bundles);
+ _inhibit_toggle_show_only_bundles = false;
+ _menu->popup (1, t);
}
@@ -500,10 +417,47 @@ PortMatrix::setup_all_ports ()
}
void
-PortMatrix::set_show_only_bundles (bool s)
+PortMatrix::toggle_show_only_bundles ()
{
- _show_only_bundles = s;
+ if (_inhibit_toggle_show_only_bundles) {
+ return;
+ }
+
+ _show_only_bundles = !_show_only_bundles;
_body->setup ();
setup_scrollbars ();
queue_draw ();
}
+
+void
+PortMatrix::hide_group (boost::weak_ptr<PortGroup> w)
+{
+ boost::shared_ptr<PortGroup> g = w.lock ();
+ if (!g) {
+ return;
+ }
+
+ g->set_visible (false);
+}
+
+void
+PortMatrix::show_group (boost::weak_ptr<PortGroup> w)
+{
+ boost::shared_ptr<PortGroup> g = w.lock ();
+ if (!g) {
+ return;
+ }
+
+ g->set_visible (true);
+}
+
+pair<uint32_t, uint32_t>
+PortMatrix::max_size () const
+{
+ pair<uint32_t, uint32_t> m = _body->max_size ();
+
+ m.first += _vscroll.get_width ();
+ m.second += _hscroll.get_height ();
+
+ return m;
+}
diff --git a/gtk2_ardour/port_matrix.h b/gtk2_ardour/port_matrix.h
index 531fdf6978..76f6d09a6a 100644
--- a/gtk2_ardour/port_matrix.h
+++ b/gtk2_ardour/port_matrix.h
@@ -60,7 +60,11 @@ public:
void disassociate_all ();
void setup_scrollbars ();
- void popup_channel_context_menu (int, uint32_t, uint32_t);
+ void popup_menu (
+ std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>,
+ std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>,
+ uint32_t
+ );
int min_height_divisor () const {
return _min_height_divisor;
@@ -83,8 +87,6 @@ public:
return _show_only_bundles;
}
- void set_show_only_bundles (bool);
-
PortGroupList const * columns () const;
/** @return index into the _ports array for the list which is displayed as columns */
@@ -107,6 +109,8 @@ public:
virtual void setup_ports (int) = 0;
void setup_all_ports ();
+ std::pair<uint32_t, uint32_t> max_size () const;
+
/** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
* @param s New state.
*/
@@ -148,12 +152,14 @@ private:
void vscroll_changed ();
void routes_changed ();
void reconnect_to_routes ();
- void visibility_toggled (boost::weak_ptr<PortGroup>, Gtk::CheckButton *);
void select_arrangement ();
void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
void setup_global_ports ();
+ void hide_group (boost::weak_ptr<PortGroup>);
+ void show_group (boost::weak_ptr<PortGroup>);
+ void toggle_show_only_bundles ();
/// port type that we are working with
ARDOUR::DataType _type;
@@ -162,22 +168,14 @@ private:
PortMatrixBody* _body;
Gtk::HScrollbar _hscroll;
Gtk::VScrollbar _vscroll;
- Gtk::HBox _column_visibility_box;
- bool _column_visibility_box_added;
- Gtk::Label _column_visibility_label;
- std::vector<Gtk::CheckButton*> _column_visibility_buttons;
- Gtk::VBox _row_visibility_box;
- bool _row_visibility_box_added;
- Gtk::Label _row_visibility_label;
- std::vector<Gtk::CheckButton*> _row_visibility_buttons;
- Gtk::Table _scroller_table;
Gtk::Menu* _menu;
- bool _setup_once;
Arrangement _arrangement;
int _row_index;
int _column_index;
int _min_height_divisor;
bool _show_only_bundles;
+ bool _inhibit_toggle_show_only_bundles;
+ bool _first_setup;
};
#endif
diff --git a/gtk2_ardour/port_matrix_body.cc b/gtk2_ardour/port_matrix_body.cc
index bad39b3f3f..593c365d3c 100644
--- a/gtk2_ardour/port_matrix_body.cc
+++ b/gtk2_ardour/port_matrix_body.cc
@@ -26,6 +26,8 @@
#include "port_matrix_row_labels.h"
#include "port_matrix_grid.h"
+using namespace std;
+
PortMatrixBody::PortMatrixBody (PortMatrix* p)
: _matrix (p),
_xoffset (0),
@@ -138,9 +140,9 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
void
PortMatrixBody::on_size_request (Gtk::Requisition *req)
{
- std::pair<int, int> const col = _column_labels->dimensions ();
- std::pair<int, int> const row = _row_labels->dimensions ();
- std::pair<int, int> const grid = _grid->dimensions ();
+ pair<int, int> const col = _column_labels->dimensions ();
+ pair<int, int> const row = _row_labels->dimensions ();
+ pair<int, int> const grid = _grid->dimensions ();
/* don't ask for the maximum size of our contents, otherwise GTK won't
let the containing window shrink below this size */
@@ -149,8 +151,8 @@ PortMatrixBody::on_size_request (Gtk::Requisition *req)
int const min_width = 512;
int const min_height = 512;
- req->width = std::min (min_width, std::max (col.first, grid.first + row.first));
- req->height = std::min (min_height / _matrix->min_height_divisor(), col.second + grid.second);
+ req->width = min (min_width, max (col.first, grid.first + row.first));
+ req->height = min (min_height / _matrix->min_height_divisor(), col.second + grid.second);
}
void
@@ -169,9 +171,10 @@ void
PortMatrixBody::compute_rectangles ()
{
/* full sizes of components */
- std::pair<uint32_t, uint32_t> const col = _column_labels->dimensions ();
- std::pair<uint32_t, uint32_t> const row = _row_labels->dimensions ();
- std::pair<uint32_t, uint32_t> const grid = _grid->dimensions ();
+ pair<uint32_t, uint32_t> const col = _column_labels->dimensions ();
+ uint32_t col_overhang = _column_labels->overhang ();
+ pair<uint32_t, uint32_t> const row = _row_labels->dimensions ();
+ pair<uint32_t, uint32_t> const grid = _grid->dimensions ();
Gdk::Rectangle col_rect;
Gdk::Rectangle row_rect;
@@ -179,35 +182,19 @@ PortMatrixBody::compute_rectangles ()
if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
- /* build from top left */
-
col_rect.set_x (0);
col_rect.set_y (0);
grid_rect.set_x (0);
- if (_alloc_width > col.first) {
- col_rect.set_width (col.first);
- } else {
- col_rect.set_width (_alloc_width);
- }
-
- /* move down to y division */
-
- uint32_t y = 0;
- if (_alloc_height > col.second) {
- y = col.second;
- } else {
- y = _alloc_height;
- }
+ col_rect.set_width (min (col.first, _alloc_width));
+ uint32_t const y = min (_alloc_height, col.second);
col_rect.set_height (y);
row_rect.set_y (y);
row_rect.set_height (_alloc_height - y);
grid_rect.set_y (y);
grid_rect.set_height (_alloc_height - y);
- /* move right to x division */
-
uint32_t x = 0;
if (_alloc_width > (grid.first + row.first)) {
x = grid.first;
@@ -222,42 +209,22 @@ PortMatrixBody::compute_rectangles ()
} else if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
- /* build from bottom right */
-
- /* move left to x division */
-
- uint32_t x = 0;
- if (_alloc_width > (grid.first + row.first)) {
- x = grid.first;
- } else if (_alloc_width > row.first) {
- x = _alloc_width - row.first;
- }
-
- grid_rect.set_x (_alloc_width - x);
- grid_rect.set_width (x);
- col_rect.set_width (col.first - grid.first + x);
- col_rect.set_x (_alloc_width - col_rect.get_width());
-
- row_rect.set_width (std::min (_alloc_width - x, row.first));
- row_rect.set_x (_alloc_width - x - row_rect.get_width());
-
- /* move up to the y division */
+ col_rect.set_height (min (_alloc_height, col.second));
+
+ row_rect.set_x (0);
+ row_rect.set_y (0);
+ row_rect.set_width (min (_alloc_width, row.first));
+ row_rect.set_height (std::min (_alloc_height - col_rect.get_height(), row.second));
+
+ grid_rect.set_x (row_rect.get_width());
+ grid_rect.set_y (0);
+ grid_rect.set_width (std::min (_alloc_width - row_rect.get_width(), grid.first));
+ grid_rect.set_height (row_rect.get_height ());
+
+ col_rect.set_width (grid_rect.get_width () + col_overhang);
+ col_rect.set_x (row_rect.get_width() + grid_rect.get_width() - col_rect.get_width());
+ col_rect.set_y (row_rect.get_height());
- uint32_t y = 0;
- if (_alloc_height > col.second) {
- y = col.second;
- } else {
- y = _alloc_height;
- }
-
- col_rect.set_y (_alloc_height - y);
- col_rect.set_height (y);
-
- grid_rect.set_height (std::min (grid.second, _alloc_height - y));
- grid_rect.set_y (_alloc_height - y - grid_rect.get_height());
-
- row_rect.set_height (grid_rect.get_height());
- row_rect.set_y (grid_rect.get_y());
}
_row_labels->set_parent_rectangle (row_rect);
@@ -270,7 +237,7 @@ PortMatrixBody::setup ()
{
/* Discard any old connections to bundles */
- for (std::list<sigc::connection>::iterator i = _bundle_connections.begin(); i != _bundle_connections.end(); ++i) {
+ for (list<sigc::connection>::iterator i = _bundle_connections.begin(); i != _bundle_connections.end(); ++i) {
i->disconnect ();
}
_bundle_connections.clear ();
@@ -348,7 +315,7 @@ PortMatrixBody::on_button_press_event (GdkEventButton* ev)
_grid->button_press (
_grid->parent_to_component_x (ev->x),
_grid->parent_to_component_y (ev->y),
- ev->button
+ ev->button, ev->time
);
} else if (Gdk::Region (_row_labels->parent_rectangle()).point_in (ev->x, ev->y)) {
@@ -453,19 +420,10 @@ PortMatrixBody::set_mouseover (PortMatrixNode const & n)
void
-PortMatrixBody::highlight_associated_channels (int dim, uint32_t N)
+PortMatrixBody::highlight_associated_channels (int dim, ARDOUR::BundleChannel h)
{
ARDOUR::BundleChannel bc[2];
-
- PortGroup::BundleList const a = _matrix->ports(dim)->bundles ();
- for (PortGroup::BundleList::const_iterator i = a.begin(); i != a.end(); ++i) {
- if (N < i->bundle->nchannels ()) {
- bc[dim] = ARDOUR::BundleChannel (i->bundle, N);
- break;
- } else {
- N -= i->bundle->nchannels ();
- }
- }
+ bc[dim] = h;
if (!bc[dim].bundle) {
return;
@@ -507,4 +465,12 @@ PortMatrixBody::component_size_changed ()
_matrix->setup_scrollbars ();
}
-
+pair<uint32_t, uint32_t>
+PortMatrixBody::max_size () const
+{
+ pair<uint32_t, uint32_t> const col = _column_labels->dimensions ();
+ pair<uint32_t, uint32_t> const row = _row_labels->dimensions ();
+ pair<uint32_t, uint32_t> const grid = _grid->dimensions ();
+
+ return make_pair (std::max (row.first, _column_labels->overhang()) + grid.first, col.second + grid.second);
+}
diff --git a/gtk2_ardour/port_matrix_body.h b/gtk2_ardour/port_matrix_body.h
index c905a98dc4..bbc72ddc7e 100644
--- a/gtk2_ardour/port_matrix_body.h
+++ b/gtk2_ardour/port_matrix_body.h
@@ -61,8 +61,9 @@ public:
return _mouseover;
}
- void highlight_associated_channels (int, uint32_t);
+ void highlight_associated_channels (int, ARDOUR::BundleChannel);
void component_size_changed ();
+ std::pair<uint32_t, uint32_t> max_size () const;
protected:
bool on_expose_event (GdkEventExpose *);
diff --git a/gtk2_ardour/port_matrix_column_labels.cc b/gtk2_ardour/port_matrix_column_labels.cc
index 92affb1f31..adef4c6eb7 100644
--- a/gtk2_ardour/port_matrix_column_labels.cc
+++ b/gtk2_ardour/port_matrix_column_labels.cc
@@ -28,7 +28,8 @@
using namespace std;
PortMatrixColumnLabels::PortMatrixColumnLabels (PortMatrix* m, PortMatrixBody* b)
- : PortMatrixLabels (m, b)
+ : PortMatrixLabels (m, b),
+ _overhang (0)
{
}
@@ -92,6 +93,8 @@ PortMatrixColumnLabels::compute_dimensions ()
if (ext.height > _highest_group_name) {
_highest_group_name = ext.height;
}
+ } else {
+ _width += column_width ();
}
}
@@ -109,7 +112,8 @@ PortMatrixColumnLabels::compute_dimensions ()
_height = parallelogram_height + _highest_group_name + 2 * name_pad();
- _width += parallelogram_height / tan (angle ());
+ _overhang = parallelogram_height / tan (angle ());
+ _width += _overhang;
}
double
@@ -144,18 +148,18 @@ PortMatrixColumnLabels::render (cairo_t* cr)
int g = 0;
for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
- if (!(*i)->visible() || (*i)->bundles().empty()) {
- continue;
- }
-
/* compute width of this group */
uint32_t w = 0;
- if (_matrix->show_only_bundles()) {
- w = (*i)->bundles().size() * column_width();
+ if (!(*i)->visible() || (*i)->bundles().empty()) {
+ w = column_width ();
} else {
- w = (*i)->total_channels() * column_width();
- }
-
+ if (_matrix->show_only_bundles()) {
+ w = (*i)->bundles().size() * column_width();
+ } else {
+ w = (*i)->total_channels() * column_width();
+ }
+ }
+
/* rectangle */
set_source_rgb (cr, get_a_group_colour (g));
double const rh = _highest_group_name + 2 * name_pad();
@@ -165,36 +169,49 @@ PortMatrixColumnLabels::render (cairo_t* cr)
cairo_rectangle (cr, x, _height - rh, w, rh);
}
cairo_fill (cr);
-
+
string const upper = Glib::ustring ((*i)->name).uppercase ();
pair<string, double> const display = fit_to_pixels (cr, upper, w);
-
+
/* plot it */
set_source_rgb (cr, text_colour());
cairo_move_to (cr, x + (w - display.second) / 2, y);
cairo_show_text (cr, display.first.c_str());
-
+
x += w;
++g;
+
}
/* BUNDLE PARALLELOGRAM-TYPE-THING AND NAME */
x = 0;
int N = 0;
- PortGroup::BundleList const bundles = _matrix->columns()->bundles();
- for (PortGroup::BundleList::const_iterator i = bundles.begin (); i != bundles.end(); ++i) {
- Gdk::Color c = i->has_colour ? i->colour : get_a_bundle_colour (N);
- render_bundle_name (cr, c, x, 0, i->bundle);
+ for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
+
+ if ((*i)->visible ()) {
+
+ PortGroup::BundleList const & bundles = (*i)->bundles ();
+ for (PortGroup::BundleList::const_iterator j = bundles.begin (); j != bundles.end(); ++j) {
+
+ Gdk::Color c = j->has_colour ? j->colour : get_a_bundle_colour (N);
+ render_bundle_name (cr, c, x, 0, j->bundle);
+
+ if (_matrix->show_only_bundles()) {
+ x += column_width();
+ } else {
+ x += j->bundle->nchannels () * column_width();
+ }
+
+ ++N;
+ }
- if (_matrix->show_only_bundles()) {
- x += column_width();
} else {
- x += i->bundle->nchannels () * column_width();
- }
- ++N;
+ x += column_width ();
+
+ }
}
@@ -203,15 +220,27 @@ PortMatrixColumnLabels::render (cairo_t* cr)
if (!_matrix->show_only_bundles()) {
x = 0;
N = 0;
- for (PortGroup::BundleList::const_iterator i = bundles.begin (); i != bundles.end(); ++i) {
+ for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
+
+ if ((*i)->visible ()) {
- for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {
- Gdk::Color c = i->has_colour ? i->colour : get_a_bundle_colour (N);
- render_channel_name (cr, c, x, 0, ARDOUR::BundleChannel (i->bundle, j));
- x += column_width();
- }
+ PortGroup::BundleList const & bundles = (*i)->bundles ();
+ for (PortGroup::BundleList::const_iterator j = bundles.begin (); j != bundles.end(); ++j) {
+
+ for (uint32_t k = 0; k < j->bundle->nchannels(); ++k) {
+ Gdk::Color c = j->has_colour ? j->colour : get_a_bundle_colour (N);
+ render_channel_name (cr, c, x, 0, ARDOUR::BundleChannel (j->bundle, k));
+ x += column_width();
+ }
+
+ ++N;
+ }
+
+ } else {
- ++N;
+ x += column_width ();
+
+ }
}
}
}
@@ -484,43 +513,102 @@ PortMatrixColumnLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
}
}
-void
-PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
+pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
+PortMatrixColumnLabels::x_position_to_group_and_channel (double x, double y) const
{
- uint32_t N = _matrix->columns()->total_visible_channels ();
- uint32_t i = 0;
- for (; i < N; ++i) {
-
- vector<pair<double, double> > const shape = port_name_shape (i * column_width(), 0);
+ uint32_t cx = 0;
+ uint32_t const gh = _highest_group_name + 2 * name_pad();
+
+ bool group_name = false;
+ if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
+ if (y > (_height - gh)) {
+ group_name = true;
+ cx = x;
+ } else {
+ cx = x - (_height - gh - y) * tan (angle ());
+ }
+ } else {
+ if (y < gh) {
+ group_name = true;
+ cx = x - _overhang;
+ } else {
+ cx = x - (_height - y) * tan (angle ());
+ }
+ }
+
+ uint32_t px = 0;
- uint32_t j = 0;
- for (; j < 4; ++j) {
- uint32_t k = (j + 1) % 4;
+ pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> gc;
+
+ for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
- double const P = (y - shape[j].second) * (shape[k].first - shape[j].first) -
- (x - shape[j].first) * (shape[k].second - shape[j].second);
+ if (!(*i)->visible()) {
- if (P > 0) {
- break;
+ uint32_t const gw = group_width (*i);
+
+ if (px <= cx && cx < (px + gw)) {
+ return make_pair (*i, ARDOUR::BundleChannel ());
+ } else {
+ px += gw;
}
- }
- if (j == 4) {
- break;
+ } else {
+
+ PortGroup::BundleList bundles = (*i)->bundles ();
+ for (PortGroup::BundleList::iterator j = bundles.begin(); j != bundles.end(); ++j) {
+
+ if (_matrix->show_only_bundles()) {
+
+ if (px <= cx && cx < (px + column_width())) {
+ return make_pair (*i, ARDOUR::BundleChannel (j->bundle, 0));
+ } else {
+ px += column_width ();
+ }
+
+ } else {
+
+ for (uint32_t k = 0; k < j->bundle->nchannels(); ++k) {
+
+ if (px <= cx && cx < (px + column_width())) {
+ if (group_name) {
+ return make_pair (*i, ARDOUR::BundleChannel ());
+ } else {
+ return make_pair (*i, ARDOUR::BundleChannel (j->bundle, k));
+ }
+ }
+
+ px += column_width ();
+ }
+ }
+
+ }
}
+
}
- if (i == N) {
- return;
- }
+ return make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ());
+}
+
+void
+PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
+{
+ pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> gc = x_position_to_group_and_channel (x, y);
- switch (b) {
- case 1:
- _body->highlight_associated_channels (_matrix->column_index(), i);
- break;
- case 3:
- _matrix->popup_channel_context_menu (_matrix->column_index(), i, t);
- break;
+ if (b == 1) {
+
+ if (gc.second.bundle) {
+ _body->highlight_associated_channels (_matrix->column_index(), gc.second);
+ } else if (gc.first) {
+ gc.first->set_visible (!gc.first->visible ());
+ }
+
+ } else if (b == 3) {
+
+ _matrix->popup_menu (
+ gc,
+ make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
+ t
+ );
}
}
diff --git a/gtk2_ardour/port_matrix_column_labels.h b/gtk2_ardour/port_matrix_column_labels.h
index f91a5be204..7ff3bc9138 100644
--- a/gtk2_ardour/port_matrix_column_labels.h
+++ b/gtk2_ardour/port_matrix_column_labels.h
@@ -44,6 +44,10 @@ public:
double parent_to_component_y (double y) const;
void mouseover_changed (PortMatrixNode const &);
+ uint32_t overhang () const {
+ return _overhang;
+ }
+
private:
void render_bundle_name (cairo_t *, Gdk::Color, double, double, boost::shared_ptr<ARDOUR::Bundle>);
void render_channel_name (cairo_t *, Gdk::Color, double, double, ARDOUR::BundleChannel const &);
@@ -60,11 +64,13 @@ private:
return _height - _highest_group_name - 2 * name_pad();
}
-// PortGroup::BundleList _bundles;
+ std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> x_position_to_group_and_channel (double, double) const;
+
double _longest_bundle_name;
double _longest_channel_name;
double _highest_text;
double _highest_group_name;
+ uint32_t _overhang;
};
#endif
diff --git a/gtk2_ardour/port_matrix_component.cc b/gtk2_ardour/port_matrix_component.cc
index c6a26d41de..6a60110f3e 100644
--- a/gtk2_ardour/port_matrix_component.cc
+++ b/gtk2_ardour/port_matrix_component.cc
@@ -21,6 +21,8 @@
#include "port_matrix.h"
#include "port_matrix_body.h"
+using namespace std;
+
/** Constructor.
* @param p Port matrix that we're in.
*/
@@ -98,7 +100,7 @@ PortMatrixComponent::set_source_rgba (cairo_t *cr, Gdk::Color const & c, double
cairo_set_source_rgba (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p(), a);
}
-std::pair<uint32_t, uint32_t>
+pair<uint32_t, uint32_t>
PortMatrixComponent::dimensions ()
{
if (_dimension_computation_required) {
@@ -107,7 +109,7 @@ PortMatrixComponent::dimensions ()
_body->component_size_changed ();
}
- return std::make_pair (_width, _height);
+ return make_pair (_width, _height);
}
Gdk::Color
@@ -115,3 +117,95 @@ PortMatrixComponent::background_colour ()
{
return _matrix->get_style()->get_bg (Gtk::STATE_NORMAL);
}
+
+uint32_t
+PortMatrixComponent::group_width (boost::shared_ptr<const PortGroup> g) const
+{
+ uint32_t width = 0;
+
+ if (g->visible()) {
+ PortGroup::BundleList const & bundles = g->bundles ();
+ if (_matrix->show_only_bundles()) {
+ width = bundles.size() * column_width ();
+ } else {
+ for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
+ width += i->bundle->nchannels() * column_width ();
+ }
+ }
+ } else {
+ width = column_width ();
+ }
+
+ return width;
+}
+
+uint32_t
+PortMatrixComponent::group_height (boost::shared_ptr<const PortGroup> g) const
+{
+ uint32_t height = 0;
+
+ if (g->visible ()) {
+ PortGroup::BundleList const & bundles = g->bundles ();
+ if (_matrix->show_only_bundles()) {
+ height = bundles.size() * row_height ();
+ } else {
+ for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
+ height += i->bundle->nchannels() * row_height ();
+ }
+ }
+ } else {
+ height = row_height ();
+ }
+
+ return height;
+}
+
+
+pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
+PortMatrixComponent::y_position_to_group_and_channel (double y) const
+{
+ PortGroupList::List::const_iterator i = _matrix->rows()->begin();
+
+ while (i != _matrix->rows()->end()) {
+
+ uint32_t const gh = group_height (*i);
+
+ if (y < gh) {
+
+ /* it's in this group */
+
+ PortGroup::BundleList const & bundles = (*i)->bundles ();
+ for (PortGroup::BundleList::const_iterator j = bundles.begin(); j != bundles.end(); ++j) {
+
+ if (_matrix->show_only_bundles()) {
+
+ if (y < row_height()) {
+ return make_pair (*i, ARDOUR::BundleChannel (j->bundle, 0));
+ } else {
+ y -= row_height ();
+ }
+
+ } else {
+
+ uint32_t const h = j->bundle->nchannels () * row_height ();
+ if (y < h) {
+ return make_pair (*i, ARDOUR::BundleChannel (j->bundle, y / row_height()));
+ } else {
+ y -= h;
+ }
+
+ }
+
+ }
+
+ } else {
+
+ y -= gh;
+
+ }
+
+ ++i;
+ }
+
+ return make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel (boost::shared_ptr<ARDOUR::Bundle> (), 0));
+}
diff --git a/gtk2_ardour/port_matrix_component.h b/gtk2_ardour/port_matrix_component.h
index d28299b8ef..34dc18e932 100644
--- a/gtk2_ardour/port_matrix_component.h
+++ b/gtk2_ardour/port_matrix_component.h
@@ -22,10 +22,16 @@
#include <stdint.h>
#include <gtkmm/eventbox.h>
+#include <boost/shared_ptr.hpp>
class PortMatrix;
class PortMatrixBody;
class PortMatrixNode;
+class PortGroup;
+
+namespace ARDOUR {
+ class BundleChannel;
+}
/** One component of the PortMatrix. This is a cairo-rendered
* Pixmap.
@@ -166,6 +172,9 @@ protected:
void set_source_rgb (cairo_t *, Gdk::Color const &);
void set_source_rgba (cairo_t *, Gdk::Color const &, double);
+ uint32_t group_width (boost::shared_ptr<const PortGroup>) const;
+ uint32_t group_height (boost::shared_ptr<const PortGroup>) const;
+ std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> y_position_to_group_and_channel (double) const;
/** Render the complete component to a cairo context. */
virtual void render (cairo_t *) = 0;
diff --git a/gtk2_ardour/port_matrix_grid.cc b/gtk2_ardour/port_matrix_grid.cc
index cb08abb460..3ad9f66cbb 100644
--- a/gtk2_ardour/port_matrix_grid.cc
+++ b/gtk2_ardour/port_matrix_grid.cc
@@ -25,6 +25,8 @@
#include "port_matrix.h"
#include "port_matrix_body.h"
+using namespace std;
+
PortMatrixGrid::PortMatrixGrid (PortMatrix* m, PortMatrixBody* b)
: PortMatrixComponent (m, b)
{
@@ -35,23 +37,13 @@ void
PortMatrixGrid::compute_dimensions ()
{
_width = 0;
- PortGroup::BundleList const c = _matrix->columns()->bundles();
- if (_matrix->show_only_bundles()) {
- _width = c.size() * column_width();
- } else {
- for (PortGroup::BundleList::const_iterator i = c.begin(); i != c.end(); ++i) {
- _width += i->bundle->nchannels() * column_width();
- }
+ for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
+ _width += group_width (*i);
}
_height = 0;
- PortGroup::BundleList const r = _matrix->rows()->bundles();
- if (_matrix->show_only_bundles()) {
- _height = r.size() * column_width();
- } else {
- for (PortGroup::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
- _height += i->bundle->nchannels() * row_height();
- }
+ for (PortGroupList::List::const_iterator i = _matrix->rows()->begin(); i != _matrix->rows()->end(); ++i) {
+ _height += group_height (*i);
}
}
@@ -59,83 +51,112 @@ PortMatrixGrid::compute_dimensions ()
void
PortMatrixGrid::render (cairo_t* cr)
{
- /* BACKGROUND */
-
set_source_rgb (cr, background_colour());
cairo_rectangle (cr, 0, 0, _width, _height);
cairo_fill (cr);
+ uint32_t x = 0;
+ for (PortGroupList::List::const_iterator c = _matrix->columns()->begin(); c != _matrix->columns()->end(); ++c) {
+
+ uint32_t y = 0;
+ for (PortGroupList::List::const_iterator r = _matrix->rows()->begin(); r != _matrix->rows()->end(); ++r) {
+
+ if ((*c)->visible() && (*r)->visible()) {
+ render_group_pair (cr, *r, *c, x, y);
+ }
+
+ y += group_height (*r);
+ }
+
+ x += group_width (*c);
+ }
+}
+
+void
+PortMatrixGrid::render_group_pair (cairo_t* cr, boost::shared_ptr<const PortGroup> row, boost::shared_ptr<const PortGroup> column, uint32_t const x, uint32_t const y)
+{
+ PortGroup::BundleList const & row_bundles = row->bundles();
+ PortGroup::BundleList const & column_bundles = column->bundles();
+
+ /* unfortunately we need to compute the height of the row group here */
+ uint32_t height = group_height (row);
+
+ uint32_t tx = x;
+
/* VERTICAL GRID LINES */
set_source_rgb (cr, grid_colour());
- uint32_t x = 0;
- PortGroup::BundleList const c = _matrix->columns()->bundles();
uint32_t N = 0;
- for (PortGroup::BundleList::const_iterator i = c.begin(); i != c.end(); ++i) {
+
+ for (PortGroup::BundleList::const_iterator i = column_bundles.begin(); i != column_bundles.end(); ++i) {
+ cairo_set_line_width (cr, thick_grid_line_width());
+ cairo_move_to (cr, tx, y);
+ cairo_line_to (cr, tx, y + height);
+ cairo_stroke (cr);
+
if (!_matrix->show_only_bundles()) {
cairo_set_line_width (cr, thin_grid_line_width());
- for (uint32_t j = 1; j < i->bundle->nchannels(); ++j) {
- x += column_width();
- cairo_move_to (cr, x, 0);
- cairo_line_to (cr, x, _height);
+ for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {
+ tx += column_width ();
+ cairo_move_to (cr, tx, y);
+ cairo_line_to (cr, tx, y + height);
cairo_stroke (cr);
}
+
+ } else {
+
+ tx += column_width ();
+
}
-
- if (N < (c.size() - 1)) {
- x += column_width();
- cairo_set_line_width (cr, thick_grid_line_width());
- cairo_move_to (cr, x, 0);
- cairo_line_to (cr, x, _height);
- cairo_stroke (cr);
- }
-
- ++N;
- }
- uint32_t grid_width = x + column_width();
+ ++N;
+ }
+
+ uint32_t const width = tx - x;
+ uint32_t ty = y;
+
/* HORIZONTAL GRID LINES */
- uint32_t y = 0;
N = 0;
- PortGroup::BundleList const r = _matrix->rows()->bundles();
- for (PortGroup::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
-
+ for (PortGroup::BundleList::const_iterator i = row_bundles.begin(); i != row_bundles.end(); ++i) {
+
+ cairo_set_line_width (cr, thick_grid_line_width());
+ cairo_move_to (cr, x, ty);
+ cairo_line_to (cr, x + width, ty);
+ cairo_stroke (cr);
+
if (!_matrix->show_only_bundles()) {
cairo_set_line_width (cr, thin_grid_line_width());
- for (uint32_t j = 1; j < i->bundle->nchannels(); ++j) {
- y += row_height();
- cairo_move_to (cr, 0, y);
- cairo_line_to (cr, grid_width, y);
+ for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {
+ ty += row_height ();
+ cairo_move_to (cr, x, ty);
+ cairo_line_to (cr, x + width, ty);
cairo_stroke (cr);
}
- }
- if (N < (r.size() - 1)) {
- y += row_height();
- cairo_set_line_width (cr, thick_grid_line_width());
- cairo_move_to (cr, 0, y);
- cairo_line_to (cr, grid_width, y);
- cairo_stroke (cr);
- }
+ } else {
+
+ ty += row_height ();
+ }
+
++N;
}
-
- /* ASSOCIATION INDICATORS */
- uint32_t bx = 0;
- uint32_t by = 0;
+ /* ASSOCIATION INDICATORS */
+
+ uint32_t bx = x;
+ uint32_t by = y;
if (_matrix->show_only_bundles()) {
- for (PortGroup::BundleList::const_iterator i = c.begin(); i != c.end(); ++i) {
- by = 0;
+ for (PortGroup::BundleList::const_iterator i = column_bundles.begin(); i != column_bundles.end(); ++i) {
+ by = y;
- for (PortGroup::BundleList::const_iterator j = r.begin(); j != r.end(); ++j) {
-
+ for (PortGroup::BundleList::const_iterator j = row_bundles.begin(); j != row_bundles.end(); ++j) {
+
PortMatrixNode::State s = bundle_to_bundle_state (i->bundle, j->bundle);
switch (s) {
case PortMatrixNode::UNKNOWN:
@@ -155,19 +176,20 @@ PortMatrixGrid::render (cairo_t* cr)
}
bx += column_width();
+
}
} else {
- for (PortGroup::BundleList::const_iterator i = c.begin(); i != c.end(); ++i) {
- by = 0;
+ for (PortGroup::BundleList::const_iterator i = column_bundles.begin(); i != column_bundles.end(); ++i) {
+ by = y;
- for (PortGroup::BundleList::const_iterator j = r.begin(); j != r.end(); ++j) {
+ for (PortGroup::BundleList::const_iterator j = row_bundles.begin(); j != row_bundles.end(); ++j) {
- x = bx;
+ tx = bx;
for (uint32_t k = 0; k < i->bundle->nchannels (); ++k) {
- y = by;
+ ty = by;
for (uint32_t l = 0; l < j->bundle->nchannels (); ++l) {
ARDOUR::BundleChannel c[2];
@@ -178,24 +200,24 @@ PortMatrixGrid::render (cairo_t* cr)
switch (s) {
case PortMatrixNode::ASSOCIATED:
- draw_association_indicator (cr, x, y);
+ draw_association_indicator (cr, tx, ty);
break;
case PortMatrixNode::UNKNOWN:
- draw_unknown_indicator (cr, x, y);
+ draw_unknown_indicator (cr, tx, ty);
break;
case PortMatrixNode::NOT_ASSOCIATED:
break;
-
+
default:
break;
}
- y += row_height();
+ ty += row_height();
}
- x += column_width();
+ tx += column_width();
}
by += j->bundle->nchannels () * row_height();
@@ -240,43 +262,63 @@ PortMatrixNode
PortMatrixGrid::position_to_node (double x, double y) const
{
return PortMatrixNode (
- position_to_channel (y, _matrix->rows()->bundles(), row_height()),
- position_to_channel (x, _matrix->columns()->bundles(), column_width())
+ y_position_to_group_and_channel (y).second,
+ x_position_to_group_and_channel (x).second
);
}
-ARDOUR::BundleChannel
-PortMatrixGrid::position_to_channel (double p, PortGroup::BundleList const & bundles, double inc) const
+pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
+PortMatrixGrid::x_position_to_group_and_channel (double x) const
{
- uint32_t pos = p / inc;
+ PortGroupList::List::const_iterator i = _matrix->columns()->begin();
- if (_matrix->show_only_bundles()) {
-
- for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
- if (pos == 0) {
- return ARDOUR::BundleChannel (i->bundle, 0);
- } else {
- pos--;
- }
- }
+ while (i != _matrix->columns()->end()) {
- } else {
+ uint32_t const gw = group_width (*i);
+
+ if (x < gw) {
+
+ /* it's in this group */
+
+ PortGroup::BundleList const & bundles = (*i)->bundles ();
+ for (PortGroup::BundleList::const_iterator j = bundles.begin(); j != bundles.end(); ++j) {
+
+ if (_matrix->show_only_bundles()) {
+
+ if (x < column_width()) {
+ return make_pair (*i, ARDOUR::BundleChannel (j->bundle, 0));
+ } else {
+ x -= column_width ();
+ }
+
+ } else {
+
+ uint32_t const w = j->bundle->nchannels () * column_width ();
+ if (x < w) {
+ return make_pair (*i, ARDOUR::BundleChannel (j->bundle, x / column_width()));
+ } else {
+ x -= w;
+ }
+
+ }
- for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
- if (pos < i->bundle->nchannels()) {
- return ARDOUR::BundleChannel (i->bundle, pos);
- } else {
- pos -= i->bundle->nchannels();
}
+
+ } else {
+
+ x -= gw;
+
}
-
+
+ ++i;
}
-
- return ARDOUR::BundleChannel (boost::shared_ptr<ARDOUR::Bundle> (), 0);
+
+ return make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel (boost::shared_ptr<ARDOUR::Bundle> (), 0));
}
+
double
PortMatrixGrid::channel_position (
ARDOUR::BundleChannel bc,
@@ -307,54 +349,62 @@ PortMatrixGrid::channel_position (
}
void
-PortMatrixGrid::button_press (double x, double y, int b)
+PortMatrixGrid::button_press (double x, double y, int b, uint32_t t)
{
- PortMatrixNode const node = position_to_node (x, y);
-
- if (_matrix->show_only_bundles()) {
-
- PortMatrixNode::State const s = bundle_to_bundle_state (node.column.bundle, node.row.bundle);
-
- for (uint32_t i = 0; i < node.column.bundle->nchannels(); ++i) {
- for (uint32_t j = 0; j < node.row.bundle->nchannels(); ++j) {
-
- ARDOUR::BundleChannel c[2];
- c[_matrix->column_index()] = ARDOUR::BundleChannel (node.column.bundle, i);
- c[_matrix->row_index()] = ARDOUR::BundleChannel (node.row.bundle, j);
- if (s == PortMatrixNode::NOT_ASSOCIATED || s == PortMatrixNode::PARTIAL) {
- _matrix->set_state (c, i == j);
- } else {
- _matrix->set_state (c, false);
- }
- }
- }
+ if (b == 1) {
- } else {
-
- if (node.row.bundle && node.column.bundle) {
+ PortMatrixNode const node = position_to_node (x, y);
+
+ if (_matrix->show_only_bundles()) {
- ARDOUR::BundleChannel c[2];
- c[_matrix->row_index()] = node.row;
- c[_matrix->column_index()] = node.column;
+ PortMatrixNode::State const s = bundle_to_bundle_state (node.column.bundle, node.row.bundle);
- PortMatrixNode::State const s = _matrix->get_state (c);
+ for (uint32_t i = 0; i < node.column.bundle->nchannels(); ++i) {
+ for (uint32_t j = 0; j < node.row.bundle->nchannels(); ++j) {
+
+ ARDOUR::BundleChannel c[2];
+ c[_matrix->column_index()] = ARDOUR::BundleChannel (node.column.bundle, i);
+ c[_matrix->row_index()] = ARDOUR::BundleChannel (node.row.bundle, j);
+ if (s == PortMatrixNode::NOT_ASSOCIATED || s == PortMatrixNode::PARTIAL) {
+ _matrix->set_state (c, i == j);
+ } else {
+ _matrix->set_state (c, false);
+ }
+ }
+ }
- if (s == PortMatrixNode::ASSOCIATED || s == PortMatrixNode::NOT_ASSOCIATED) {
-
- bool const n = !(s == PortMatrixNode::ASSOCIATED);
+ } else {
+
+ if (node.row.bundle && node.column.bundle) {
ARDOUR::BundleChannel c[2];
c[_matrix->row_index()] = node.row;
c[_matrix->column_index()] = node.column;
- _matrix->set_state (c, n);
+ PortMatrixNode::State const s = _matrix->get_state (c);
+
+ if (s == PortMatrixNode::ASSOCIATED || s == PortMatrixNode::NOT_ASSOCIATED) {
+
+ bool const n = !(s == PortMatrixNode::ASSOCIATED);
+
+ ARDOUR::BundleChannel c[2];
+ c[_matrix->row_index()] = node.row;
+ c[_matrix->column_index()] = node.column;
+
+ _matrix->set_state (c, n);
+ }
+
}
-
}
- }
+
+ require_render ();
+ _body->queue_draw ();
- require_render ();
- _body->queue_draw ();
+ } else if (b == 3) {
+
+ _matrix->popup_menu (x_position_to_group_and_channel (x), y_position_to_group_and_channel (y), t);
+
+ }
}
void
diff --git a/gtk2_ardour/port_matrix_grid.h b/gtk2_ardour/port_matrix_grid.h
index 5d2e528e60..543ea8533f 100644
--- a/gtk2_ardour/port_matrix_grid.h
+++ b/gtk2_ardour/port_matrix_grid.h
@@ -41,7 +41,7 @@ class PortMatrixGrid : public PortMatrixComponent
public:
PortMatrixGrid (PortMatrix *, PortMatrixBody *);
- void button_press (double, double, int);
+ void button_press (double, double, int, uint32_t);
void mouseover_event (double, double);
double component_to_parent_x (double x) const;
@@ -55,10 +55,11 @@ private:
void compute_dimensions ();
void render (cairo_t *);
+ void render_group_pair (cairo_t *, boost::shared_ptr<const PortGroup>, boost::shared_ptr<const PortGroup>, uint32_t, uint32_t);
double channel_position (ARDOUR::BundleChannel, PortGroup::BundleList const &, double) const;
PortMatrixNode position_to_node (double, double) const;
- ARDOUR::BundleChannel position_to_channel (double, PortGroup::BundleList const &, double) const;
+ std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> x_position_to_group_and_channel (double) const;
void queue_draw_for (PortMatrixNode const &);
void draw_association_indicator (cairo_t *, uint32_t, uint32_t, double p = 1);
void draw_unknown_indicator (cairo_t *, uint32_t, uint32_t);
diff --git a/gtk2_ardour/port_matrix_row_labels.cc b/gtk2_ardour/port_matrix_row_labels.cc
index 4802d4ca33..880f3adc3a 100644
--- a/gtk2_ardour/port_matrix_row_labels.cc
+++ b/gtk2_ardour/port_matrix_row_labels.cc
@@ -27,6 +27,8 @@
#include "i18n.h"
#include "utils.h"
+using namespace std;
+
PortMatrixRowLabels::PortMatrixRowLabels (PortMatrix* m, PortMatrixBody* b)
: PortMatrixLabels (m, b)
{
@@ -43,6 +45,7 @@ PortMatrixRowLabels::compute_dimensions ()
_longest_port_name = 0;
_longest_bundle_name = 0;
_height = 0;
+
PortGroup::BundleList const r = _matrix->rows()->bundles();
for (PortGroup::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {
@@ -74,6 +77,9 @@ PortMatrixRowLabels::compute_dimensions ()
if (ext.height > _highest_group_name) {
_highest_group_name = ext.height;
}
+ } else {
+ /* add another row_height for a tab for this hidden group */
+ _height += row_height ();
}
}
@@ -113,28 +119,28 @@ PortMatrixRowLabels::render (cairo_t* cr)
int g = 0;
for (PortGroupList::List::const_iterator i = _matrix->rows()->begin(); i != _matrix->rows()->end(); ++i) {
- if (!(*i)->visible() || (*i)->bundles().empty()) {
- continue;
- }
-
/* compute height of this group */
double h = 0;
- if (_matrix->show_only_bundles()) {
- h = (*i)->bundles().size() * row_height();
+ if (!(*i)->visible() || (*i)->bundles().empty()) {
+ h = row_height ();
} else {
- h = (*i)->total_channels () * row_height();
+ if (_matrix->show_only_bundles()) {
+ h = (*i)->bundles().size() * row_height();
+ } else {
+ h = (*i)->total_channels () * row_height();
+ }
}
-
+
/* rectangle */
set_source_rgb (cr, get_a_group_colour (g));
double const rw = _highest_group_name + 2 * name_pad();
cairo_rectangle (cr, x, y, rw, h);
cairo_fill (cr);
-
+
/* hence what abbreviation (or not) we need for the group name */
- std::string const upper = Glib::ustring ((*i)->name).uppercase ();
- std::pair<std::string, double> display = fit_to_pixels (cr, upper, h);
-
+ string const upper = Glib::ustring ((*i)->name).uppercase ();
+ pair<string, double> display = fit_to_pixels (cr, upper, h);
+
/* plot it */
set_source_rgb (cr, text_colour());
cairo_move_to (cr, x + rw - name_pad(), y + (h + display.second) / 2);
@@ -142,35 +148,41 @@ PortMatrixRowLabels::render (cairo_t* cr)
cairo_rotate (cr, - M_PI / 2);
cairo_show_text (cr, display.first.c_str());
cairo_restore (cr);
-
+
y += h;
++g;
}
- /* BUNDLE NAMES */
+ /* BUNDLE AND PORT NAMES */
y = 0;
int N = 0;
- PortGroup::BundleList const r = _matrix->rows()->bundles();
- for (PortGroup::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
- render_bundle_name (cr, i->has_colour ? i->colour : get_a_bundle_colour (N), 0, y, i->bundle);
- int const n = _matrix->show_only_bundles() ? 1 : i->bundle->nchannels();
- y += row_height() * n;
- ++N;
- }
-
-
- /* PORT NAMES */
+ int M = 0;
+ for (PortGroupList::List::const_iterator i = _matrix->rows()->begin(); i != _matrix->rows()->end(); ++i) {
- if (!_matrix->show_only_bundles()) {
- y = 0;
- N = 0;
- for (PortGroup::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
- for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {
- render_channel_name (cr, i->has_colour ? i->colour : get_a_bundle_colour (N), 0, y, ARDOUR::BundleChannel (i->bundle, j));
- y += row_height();
+ if ((*i)->visible ()) {
+
+ PortGroup::BundleList const & bundles = (*i)->bundles ();
+ for (PortGroup::BundleList::const_iterator j = bundles.begin(); j != bundles.end(); ++j) {
+ render_bundle_name (cr, j->has_colour ? j->colour : get_a_bundle_colour (N), 0, y, j->bundle);
+
+ if (!_matrix->show_only_bundles()) {
+ for (uint32_t k = 0; k < j->bundle->nchannels(); ++k) {
+ Gdk::Color c = j->has_colour ? j->colour : get_a_bundle_colour (M);
+ render_channel_name (cr, c, 0, y, ARDOUR::BundleChannel (j->bundle, k));
+ y += row_height();
+ ++M;
+ }
+ } else {
+ y += row_height();
+ }
+
+ ++N;
}
- ++N;
+
+ } else {
+
+ y += row_height ();
}
}
}
@@ -178,25 +190,48 @@ PortMatrixRowLabels::render (cairo_t* cr)
void
PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
{
- switch (b) {
- case 1:
- _body->highlight_associated_channels (_matrix->row_index(), y / row_height ());
- break;
- case 3:
- maybe_popup_context_menu (x, y, t);
- break;
- }
-}
+ uint32_t const gw = (_highest_group_name + 2 * name_pad());
-void
-PortMatrixRowLabels::maybe_popup_context_menu (double x, double y, uint32_t t)
-{
- if ( (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x > (_longest_bundle_name + name_pad() * 2)) ||
- (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x < (_longest_port_name + name_pad() * 2))
+ pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = y_position_to_group_and_channel (y);
+
+ if (
+ (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x < gw) ||
+ (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x > (_width - gw))
) {
- _matrix->popup_channel_context_menu (_matrix->row_index(), y / row_height(), t);
-
+ w.second.bundle.reset ();
+ }
+
+ if (b == 1) {
+
+ if (w.second.bundle) {
+ _body->highlight_associated_channels (_matrix->row_index(), w.second);
+ } else {
+ if (w.first) {
+ w.first->set_visible (!w.first->visible());
+ }
+ }
+
+ } else if (b == 3) {
+
+ if (
+ (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x < (_longest_port_name + name_pad() * 2)) ||
+ (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x > (_longest_port_name + name_pad() * 2))
+
+ ) {
+
+ _matrix->popup_menu (
+ make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
+ make_pair (w.first, ARDOUR::BundleChannel ()),
+ t
+ );
+ } else {
+ _matrix->popup_menu (
+ make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
+ make_pair (w.first, ARDOUR::BundleChannel ()),
+ t
+ );
+ }
}
}
diff --git a/gtk2_ardour/port_matrix_row_labels.h b/gtk2_ardour/port_matrix_row_labels.h
index 130469a607..60a699f5f2 100644
--- a/gtk2_ardour/port_matrix_row_labels.h
+++ b/gtk2_ardour/port_matrix_row_labels.h
@@ -63,7 +63,6 @@ private:
void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
void queue_draw_for (ARDOUR::BundleChannel const &);
double port_name_x () const;
- void maybe_popup_context_menu (double, double, uint32_t);
double bundle_name_x () const;
double _longest_port_name;