Rework port matrix to use Gtk notebook tabs to select visible groups.

git-svn-id: svn://localhost/ardour2/branches/3.0@6117 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2009-11-18 13:35:31 +00:00
parent ef92349187
commit 73a0cd56f8
16 changed files with 407 additions and 602 deletions

View file

@ -42,6 +42,9 @@ BundleEditorMatrix::BundleEditorMatrix (
{
_port_group = boost::shared_ptr<PortGroup> (new PortGroup (""));
_port_group->add_bundle (_bundle);
setup_all_ports ();
init ();
}
void

View file

@ -35,6 +35,7 @@ GlobalPortMatrix::GlobalPortMatrix (Gtk::Window* p, ARDOUR::Session& s, ARDOUR::
: PortMatrix (p, s, t)
{
setup_all_ports ();
init ();
}
void

View file

@ -57,10 +57,11 @@ IOSelector::IOSelector (Gtk::Window* p, ARDOUR::Session& session, boost::shared_
_ours = 1;
}
_port_group.reset (new PortGroup (""));
_port_group.reset (new PortGroup (io->name()));
_ports[_ours].add_group (_port_group);
setup_all_ports ();
init ();
}
void

View file

@ -45,7 +45,7 @@ using namespace ARDOUR;
* @param n Name.
*/
PortGroup::PortGroup (std::string const & n)
: name (n), _visible (true)
: name (n)
{
}
@ -242,7 +242,9 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs, bool allow_dups)
boost::shared_ptr<PortGroup> bus (new PortGroup (_("Bus")));
boost::shared_ptr<PortGroup> track (new PortGroup (_("Track")));
boost::shared_ptr<PortGroup> system (new PortGroup (_("System")));
boost::shared_ptr<PortGroup> system_mono (new PortGroup (_("System (mono)")));
boost::shared_ptr<PortGroup> system_stereo (new PortGroup (_("System (stereo)")));
boost::shared_ptr<PortGroup> system_other (new PortGroup (_("System (other)")));
boost::shared_ptr<PortGroup> ardour (new PortGroup (_("Ardour")));
boost::shared_ptr<PortGroup> other (new PortGroup (_("Other")));
@ -304,13 +306,25 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs, bool allow_dups)
for (BundleList::iterator i = b->begin(); i != b->end(); ++i) {
if (boost::dynamic_pointer_cast<UserBundle> (*i) && (*i)->ports_are_inputs() == inputs && (*i)->type() == _type) {
system->add_bundle (*i, allow_dups);
if ((*i)->nchannels() == 1) {
system_mono->add_bundle (*i, allow_dups);
} else if ((*i)->nchannels() == 2) {
system_stereo->add_bundle (*i, allow_dups);
} else {
system_other->add_bundle (*i, allow_dups);
}
}
}
for (BundleList::iterator i = b->begin(); i != b->end(); ++i) {
if (boost::dynamic_pointer_cast<UserBundle> (*i) == 0 && (*i)->ports_are_inputs() == inputs && (*i)->type() == _type) {
system->add_bundle (*i, allow_dups);
if ((*i)->nchannels() == 1) {
system_mono->add_bundle (*i, allow_dups);
} else if ((*i)->nchannels() == 2) {
system_stereo->add_bundle (*i, allow_dups);
} else {
system_other->add_bundle (*i, allow_dups);
}
}
}
@ -340,7 +354,13 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs, bool allow_dups)
std::string const p = ports[n];
if (!system->has_port(p) && !bus->has_port(p) && !track->has_port(p) && !ardour->has_port(p) && !other->has_port(p)) {
if (!system_mono->has_port(p) &&
!system_stereo->has_port(p) &&
!system_other->has_port(p) &&
!bus->has_port(p) &&
!track->has_port(p) &&
!ardour->has_port(p) &&
!other->has_port(p)) {
if (port_has_prefix (p, "system:") ||
port_has_prefix (p, "alsa_pcm") ||
@ -358,18 +378,27 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs, bool allow_dups)
}
if (!extra_system.empty()) {
system->add_bundle (make_bundle_from_ports (extra_system, inputs));
boost::shared_ptr<Bundle> b = make_bundle_from_ports (extra_system, inputs);
if (b->nchannels() == 1) {
system_mono->add_bundle (b);
} else if (b->nchannels() == 2) {
system_stereo->add_bundle (b);
} else {
system_other->add_bundle (b);
}
}
if (!extra_other.empty()) {
other->add_bundle (make_bundle_from_ports (extra_other, inputs));
}
add_group (system);
add_group (bus);
add_group (track);
add_group (ardour);
add_group (other);
add_group_if_not_empty (system_mono);
add_group_if_not_empty (system_stereo);
add_group_if_not_empty (system_other);
add_group_if_not_empty (bus);
add_group_if_not_empty (track);
add_group_if_not_empty (ardour);
add_group_if_not_empty (other);
emit_changed ();
}
@ -471,19 +500,24 @@ PortGroupList::bundles () const
}
uint32_t
PortGroupList::total_visible_channels () const
PortGroupList::total_channels () const
{
uint32_t n = 0;
for (PortGroupList::List::const_iterator i = begin(); i != end(); ++i) {
if ((*i)->visible()) {
n += (*i)->total_channels ();
}
n += (*i)->total_channels ();
}
return n;
}
void
PortGroupList::add_group_if_not_empty (boost::shared_ptr<PortGroup> g)
{
if (!g->bundles().empty ()) {
add_group (g);
}
}
void
PortGroupList::add_group (boost::shared_ptr<PortGroup> g)

View file

@ -60,15 +60,6 @@ public:
std::string name; ///< name for the group
bool visible () const {
return _visible;
}
void set_visible (bool v) {
_visible = v;
Changed ();
}
bool has_port (std::string const &) const;
sigc::signal<void> Changed;
@ -95,7 +86,6 @@ private:
void add_bundle_internal (boost::shared_ptr<ARDOUR::Bundle>, boost::shared_ptr<ARDOUR::IO>, bool, Gdk::Color, bool);
BundleList _bundles;
bool _visible; ///< true if the group is visible in the UI
};
/// A list of PortGroups
@ -107,12 +97,13 @@ class PortGroupList : public sigc::trackable
typedef std::vector<boost::shared_ptr<PortGroup> > List;
void add_group (boost::shared_ptr<PortGroup>);
void add_group_if_not_empty (boost::shared_ptr<PortGroup>);
void set_type (ARDOUR::DataType);
void gather (ARDOUR::Session &, bool, bool);
PortGroup::BundleList const & bundles () const;
void clear ();
void remove_bundle (boost::shared_ptr<ARDOUR::Bundle>);
uint32_t total_visible_channels () const;
uint32_t total_channels () const;
uint32_t size () const {
return _groups.size();
}

View file

@ -46,7 +46,7 @@ using namespace ARDOUR;
* @param type Port type that we are handling.
*/
PortMatrix::PortMatrix (Window* parent, Session& session, DataType type)
: Table (2, 2),
: Table (4, 4),
_session (session),
_parent (parent),
_type (type),
@ -56,13 +56,56 @@ PortMatrix::PortMatrix (Window* parent, Session& session, DataType type)
_column_index (1),
_min_height_divisor (1),
_show_only_bundles (false),
_inhibit_toggle_show_only_bundles (false)
_inhibit_toggle_show_only_bundles (false),
_in_setup_notebooks (false)
{
_body = new PortMatrixBody (this);
attach (*_body, 2, 3, 2, 3);
attach (_vscroll, 3, 4, 2, 3, SHRINK);
attach (_hscroll, 2, 3, 3, 4, FILL | EXPAND, SHRINK);
attach (_vlabel, 0, 1, 2, 3, SHRINK);
attach (_hlabel, 2, 3, 0, 1, FILL | EXPAND, SHRINK);
attach (_vnotebook, 1, 2, 2, 3, SHRINK);
attach (_hnotebook, 2, 3, 1, 2, FILL | EXPAND, SHRINK);
_vnotebook.signal_switch_page().connect (mem_fun (*this, &PortMatrix::v_page_selected));
_hnotebook.signal_switch_page().connect (mem_fun (*this, &PortMatrix::h_page_selected));
for (int i = 0; i < 2; ++i) {
_ports[i].set_type (type);
}
_vlabel.set_angle (90);
_hlabel.set_use_markup ();
_vlabel.set_use_markup ();
_hlabel.set_alignment (0, 0.5);
_vlabel.set_alignment (0.5, 0);
show_all ();
}
PortMatrix::~PortMatrix ()
{
delete _body;
delete _menu;
}
void
PortMatrix::init ()
{
select_arrangement ();
setup_notebooks ();
if (!_ports[0].empty()) {
_visible_ports[0] = *_ports[0].begin();
}
if (!_ports[1].empty()) {
_visible_ports[1] = *_ports[1].begin();
}
for (int i = 0; i < 2; ++i) {
/* watch for the content of _ports[] changing */
_ports[i].Changed.connect (mem_fun (*this, &PortMatrix::setup));
@ -83,18 +126,8 @@ PortMatrix::PortMatrix (Window* parent, Session& session, DataType type)
_session.engine().PortRegisteredOrUnregistered.connect (mem_fun (*this, &PortMatrix::setup_all_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;
delete _menu;
setup ();
}
/** Disconnect from and reconnect to routes' signals that we need to watch for things that affect the matrix */
@ -126,12 +159,9 @@ PortMatrix::routes_changed ()
void
PortMatrix::setup ()
{
if ((get_flags () & Gtk::REALIZED) == 0) {
select_arrangement ();
}
_body->setup ();
setup_scrollbars ();
setup_notebooks ();
queue_draw ();
show_all ();
@ -211,8 +241,8 @@ void
PortMatrix::select_arrangement ()
{
uint32_t const N[2] = {
_ports[0].total_visible_channels (),
_ports[1].total_visible_channels ()
_ports[0].total_channels (),
_ports[1].total_channels ()
};
/* The list with the most channels goes on left or right, so that the most channel
@ -226,12 +256,16 @@ PortMatrix::select_arrangement ()
_row_index = 0;
_column_index = 1;
_arrangement = LEFT_TO_BOTTOM;
_vlabel.set_label (_("<b>Sources</b>"));
_hlabel.set_label (_("<b>Destinations</b>"));
} else {
_row_index = 1;
_column_index = 0;
_arrangement = TOP_TO_RIGHT;
_hlabel.set_label (_("<b>Sources</b>"));
_vlabel.set_label (_("<b>Destinations</b>"));
}
}
@ -242,6 +276,12 @@ PortMatrix::columns () const
return &_ports[_column_index];
}
boost::shared_ptr<PortGroup>
PortMatrix::visible_columns () const
{
return _visible_ports[_column_index];
}
/* @return rows list */
PortGroupList const *
PortMatrix::rows () const
@ -249,12 +289,14 @@ PortMatrix::rows () const
return &_ports[_row_index];
}
boost::shared_ptr<PortGroup>
PortMatrix::visible_rows () const
{
return _visible_ports[_row_index];
}
void
PortMatrix::popup_menu (
pair<boost::shared_ptr<PortGroup>, BundleChannel> column,
pair<boost::shared_ptr<PortGroup>, BundleChannel> row,
uint32_t t
)
PortMatrix::popup_menu (BundleChannel column, BundleChannel row, uint32_t t)
{
using namespace Menu_Helpers;
@ -265,13 +307,9 @@ PortMatrix::popup_menu (
MenuList& items = _menu->items ();
boost::shared_ptr<PortGroup> pg[2];
pg[_column_index] = column.first;
pg[_row_index] = row.first;
BundleChannel bc[2];
bc[_column_index] = column.second;
bc[_row_index] = row.second;
bc[_column_index] = column;
bc[_row_index] = row;
char buf [64];
bool need_separator = false;
@ -343,55 +381,6 @@ PortMatrix::popup_menu (
items.push_back (SeparatorElem ());
}
need_separator = false;
for (int dim = 0; dim < 2; ++dim) {
if (pg[dim]) {
boost::weak_ptr<PortGroup> wp (pg[dim]);
if (pg[dim]->visible()) {
if (dim == 0) {
if (pg[dim]->name.empty()) {
snprintf (buf, sizeof (buf), _("Hide sources"));
} else {
snprintf (buf, sizeof (buf), _("Hide '%s' sources"), pg[dim]->name.c_str());
}
} else {
if (pg[dim]->name.empty()) {
snprintf (buf, sizeof (buf), _("Hide destinations"));
} else {
snprintf (buf, sizeof (buf), _("Hide '%s' destinations"), pg[dim]->name.c_str());
}
}
items.push_back (MenuElem (buf, bind (mem_fun (*this, &PortMatrix::hide_group), wp)));
} else {
if (dim == 0) {
if (pg[dim]->name.empty()) {
snprintf (buf, sizeof (buf), _("Show sources"));
} else {
snprintf (buf, sizeof (buf), _("Show '%s' sources"), pg[dim]->name.c_str());
}
} else {
if (pg[dim]->name.empty()) {
snprintf (buf, sizeof (buf), _("Show destinations"));
} 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)));
}
need_separator = true;
}
}
if (need_separator) {
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());
@ -483,28 +472,6 @@ PortMatrix::toggle_show_only_bundles ()
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
{
@ -606,3 +573,91 @@ PortMatrix::bundle_changed (ARDOUR::Bundle::Change c)
setup ();
}
void
PortMatrix::setup_notebooks ()
{
_in_setup_notebooks = true;
remove_notebook_pages (_hnotebook);
remove_notebook_pages (_vnotebook);
for (PortGroupList::List::const_iterator i = _ports[_row_index].begin(); i != _ports[_row_index].end(); ++i) {
HBox* dummy = manage (new HBox);
dummy->show ();
Label* label = manage (new Label ((*i)->name));
label->set_angle (90);
_vnotebook.prepend_page (*dummy, *label);
}
for (PortGroupList::List::const_iterator i = _ports[_column_index].begin(); i != _ports[_column_index].end(); ++i) {
HBox* dummy = manage (new HBox);
dummy->show ();
_hnotebook.append_page (*dummy, (*i)->name);
}
_vnotebook.set_tab_pos (POS_LEFT);
_hnotebook.set_tab_pos (POS_TOP);
_in_setup_notebooks = false;
}
void
PortMatrix::remove_notebook_pages (Notebook& n)
{
int const N = n.get_n_pages ();
for (int i = 0; i < N; ++i) {
n.remove_page ();
}
}
void
PortMatrix::v_page_selected (GtkNotebookPage *, guint n)
{
if (_in_setup_notebooks) {
return;
}
PortGroupList& p = _ports[_row_index];
n = p.size() - n - 1;
int i = 0;
PortGroupList::List::const_iterator j = p.begin();
while (i != int (n) && j != p.end()) {
++i;
++j;
}
if (j != p.end()) {
_visible_ports[_row_index] = *j;
_body->setup ();
setup_scrollbars ();
queue_draw ();
}
}
void
PortMatrix::h_page_selected (GtkNotebookPage *, guint n)
{
if (_in_setup_notebooks) {
return;
}
PortGroupList& p = _ports[_column_index];
int i = 0;
PortGroupList::List::const_iterator j = p.begin();
while (i != int (n) && j != p.end()) {
++i;
++j;
}
if (j != p.end()) {
_visible_ports[_column_index] = *j;
_body->setup ();
setup_scrollbars ();
queue_draw ();
}
}

View file

@ -26,6 +26,7 @@
#include <gtkmm/table.h>
#include <gtkmm/label.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/notebook.h>
#include <boost/shared_ptr.hpp>
#include "ardour/bundle.h"
#include "port_group.h"
@ -61,11 +62,7 @@ public:
void disassociate_all ();
void setup_scrollbars ();
void popup_menu (
std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>,
std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>,
uint32_t
);
void popup_menu (ARDOUR::BundleChannel, ARDOUR::BundleChannel, uint32_t);
int min_height_divisor () const {
return _min_height_divisor;
@ -79,6 +76,7 @@ public:
LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom
};
/** @return Arrangement in use */
Arrangement arrangement () const {
return _arrangement;
@ -89,6 +87,7 @@ public:
}
PortGroupList const * columns () const;
boost::shared_ptr<PortGroup> visible_columns () const;
/** @return index into the _ports array for the list which is displayed as columns */
int column_index () const {
@ -96,6 +95,7 @@ public:
}
PortGroupList const * rows () const;
boost::shared_ptr<PortGroup> visible_rows () const;
/** @return index into the _ports array for the list which is displayed as rows */
int row_index () const {
@ -106,6 +106,11 @@ public:
return &_ports[d];
}
boost::shared_ptr<const PortGroup> visible_ports (int d) const {
return _visible_ports[d];
}
void init ();
void setup ();
virtual void setup_ports (int) = 0;
void setup_all_ports ();
@ -150,6 +155,7 @@ protected:
from left to right as you go from list 0 to list 1. Hence subclasses which deal with
inputs and outputs should put outputs in list 0 and inputs in list 1. */
PortGroupList _ports[2];
boost::shared_ptr<PortGroup> _visible_ports[2];
ARDOUR::Session& _session;
private:
@ -164,12 +170,14 @@ private:
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 ();
bool on_scroll_event (GdkEventScroll *);
boost::shared_ptr<ARDOUR::IO> io_from_bundle (boost::shared_ptr<ARDOUR::Bundle>) const;
void bundle_changed (ARDOUR::Bundle::Change);
void setup_notebooks ();
void remove_notebook_pages (Gtk::Notebook &);
void v_page_selected (GtkNotebookPage *, guint);
void h_page_selected (GtkNotebookPage *, guint);
Gtk::Window* _parent;
@ -180,6 +188,10 @@ private:
PortMatrixBody* _body;
Gtk::HScrollbar _hscroll;
Gtk::VScrollbar _vscroll;
Gtk::Notebook _vnotebook;
Gtk::Notebook _hnotebook;
Gtk::Label _vlabel;
Gtk::Label _hlabel;
Gtk::Menu* _menu;
Arrangement _arrangement;
int _row_index;
@ -187,7 +199,7 @@ private:
int _min_height_divisor;
bool _show_only_bundles;
bool _inhibit_toggle_show_only_bundles;
bool _realized;
bool _in_setup_notebooks;
};
#endif

View file

@ -58,7 +58,7 @@ PortMatrixBody::~PortMatrixBody ()
bool
PortMatrixBody::on_expose_event (GdkEventExpose* event)
{
if (_matrix->columns()->empty() || _matrix->rows()->empty()) {
if (_matrix->visible_columns()->bundles().empty() || _matrix->visible_rows()->bundles().empty()) {
/* nothing to connect */
@ -446,7 +446,7 @@ PortMatrixBody::highlight_associated_channels (int dim, ARDOUR::BundleChannel h)
_row_labels->add_channel_highlight (bc[dim]);
}
PortGroup::BundleList const b = _matrix->ports(1 - dim)->bundles ();
PortGroup::BundleList const b = _matrix->visible_ports(1 - dim)->bundles ();
for (PortGroup::BundleList::const_iterator i = b.begin(); i != b.end(); ++i) {
for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {

View file

@ -49,7 +49,10 @@ PortMatrixColumnLabels::compute_dimensions ()
_highest_text = 0;
/* width of the whole thing */
_width = 0;
_highest_group_name = 0;
/* Compute dimensions using all port groups, so that we allow for the largest and hence
we can change between visible groups without the size of the labels jumping around.
*/
for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
PortGroup::BundleList const c = _matrix->columns()->bundles();
@ -84,12 +87,6 @@ PortMatrixColumnLabels::compute_dimensions ()
}
_width += group_size (*i) * grid_spacing ();
cairo_text_extents_t ext;
cairo_text_extents (cr, (*i)->name.c_str(), &ext);
if (ext.height > _highest_group_name) {
_highest_group_name = ext.height;
}
}
cairo_destroy (cr);
@ -102,11 +99,8 @@ PortMatrixColumnLabels::compute_dimensions ()
a += _longest_channel_name;
}
double const parallelogram_height = a * sin (angle()) + _highest_text * cos (angle());
_height = parallelogram_height + _highest_group_name + 2 * name_pad();
_overhang = parallelogram_height / tan (angle ());
_height = a * sin (angle()) + _highest_text * cos (angle());
_overhang = _height / tan (angle ());
_width += _overhang;
}
@ -131,59 +125,36 @@ PortMatrixColumnLabels::render (cairo_t* cr)
double x = 0;
int N = 0;
for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
PortGroup::BundleList const & bundles = _matrix->visible_columns()->bundles ();
for (PortGroup::BundleList::const_iterator i = bundles.begin (); i != bundles.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, background_colour (), c, x, 0, j->bundle);
if (_matrix->show_only_bundles()) {
x += grid_spacing();
} else {
x += j->bundle->nchannels () * grid_spacing();
}
++N;
}
Gdk::Color c = i->has_colour ? i->colour : get_a_bundle_colour (N);
render_bundle_name (cr, background_colour (), c, x, 0, i->bundle);
if (_matrix->show_only_bundles()) {
x += grid_spacing();
} else {
x += grid_spacing ();
x += i->bundle->nchannels () * grid_spacing();
}
++N;
}
/* PORT NAMES */
if (!_matrix->show_only_bundles()) {
x = 0;
N = 0;
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) {
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, background_colour (), c, x, 0, ARDOUR::BundleChannel (j->bundle, k));
x += grid_spacing();
}
++N;
}
} else {
x += grid_spacing ();
for (PortGroup::BundleList::const_iterator i = bundles.begin (); i != bundles.end(); ++i) {
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, background_colour (), c, x, 0, ARDOUR::BundleChannel (i->bundle, j));
x += grid_spacing();
}
++N;
}
}
}
@ -241,7 +212,7 @@ PortMatrixColumnLabels::port_name_shape (double xoff, double yoff) const
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
double x_ = xoff + slanted_height() / tan (angle()) + w;
double x_ = xoff + _height / tan (angle()) + w;
double y_ = yoff;
shape.push_back (make_pair (x_, y_));
x_ -= w;
@ -288,18 +259,14 @@ PortMatrixColumnLabels::render_bundle_name (
double x_ = xoff;
uint32_t y = yoff;
if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
y += _height;
} else {
y += slanted_height();
}
y += _height;
double y_ = y;
cairo_move_to (cr, x_, y_);
x_ += w;
cairo_line_to (cr, x_, y_);
x_ += slanted_height() / tan (angle ());
y_ -= slanted_height();
x_ += _height / tan (angle ());
y_ -= _height;
cairo_line_to (cr, x_, y_);
x_ -= w;
cairo_line_to (cr, x_, y_);
@ -330,7 +297,7 @@ PortMatrixColumnLabels::render_bundle_name (
cairo_move_to (
cr,
xoff + basic_text_x_pos (0) + name_pad() * cos (angle ()),
yoff + slanted_height() - name_pad() * sin (angle())
yoff + _height - name_pad() * sin (angle())
);
}
@ -375,7 +342,7 @@ PortMatrixColumnLabels::render_channel_name (
cairo_move_to (
cr,
xoff + basic_text_x_pos(bc.channel) + rl * cos (angle ()),
yoff + slanted_height() - rl * sin (angle())
yoff + _height - rl * sin (angle())
);
}
@ -399,7 +366,7 @@ PortMatrixColumnLabels::render_channel_name (
double
PortMatrixColumnLabels::channel_x (ARDOUR::BundleChannel const &bc) const
{
return channel_to_position (bc, _matrix->columns()) * grid_spacing ();
return channel_to_position (bc, _matrix->visible_columns()) * grid_spacing ();
}
double
@ -441,7 +408,7 @@ PortMatrixColumnLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
} else if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
double const x_ = x + slanted_height() / tan (angle()) - lc * cos (angle());
double const x_ = x + _height / tan (angle()) - lc * cos (angle());
_body->queue_draw_area (
component_to_parent_x (x_) - 1,
@ -455,129 +422,38 @@ PortMatrixColumnLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
}
}
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
PortMatrixColumnLabels::position_to_group_and_channel (double p, double o, PortGroupList const * groups) const
ARDOUR::BundleChannel
PortMatrixColumnLabels::position_to_channel (double p, double o, boost::shared_ptr<const PortGroup> group) const
{
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 (o > (_height - gh)) {
group_name = true;
cx = p;
} else {
cx = p - (_height - gh - o) * tan (angle ());
}
} else {
if (o < gh) {
group_name = true;
cx = p - _overhang;
} else {
cx = p - (_height - o) * tan (angle ());
}
}
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = PortMatrixComponent::position_to_group_and_channel (cx, o, groups);
if (group_name) {
w.second.bundle.reset ();
}
return w;
uint32_t const cx = p - (_height - o) * tan (angle ());
return PortMatrixComponent::position_to_channel (cx, o, group);
}
void
PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> gc = position_to_group_and_channel (x, y, _matrix->columns());
ARDOUR::BundleChannel const gc = position_to_channel (x, y, _matrix->visible_columns());
if (b == 3) {
_matrix->popup_menu (
gc,
make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
ARDOUR::BundleChannel (),
t
);
}
}
void
PortMatrixColumnLabels::draw_extra (cairo_t* cr)
{
PortMatrixLabels::draw_extra (cr);
/* PORT GROUP NAME */
double x = 0;
double y = 0;
if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
x = component_to_parent_x (slanted_height() / tan (angle()));
y = component_to_parent_y ( _highest_group_name + name_pad());
} else {
x = component_to_parent_x (0);
y = component_to_parent_y (_height - name_pad());
}
int g = 0;
for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
/* compute width of this group */
uint32_t w = 0;
if (!(*i)->visible()) {
w = grid_spacing ();
} else {
if (_matrix->show_only_bundles()) {
w = (*i)->bundles().size() * grid_spacing();
} else {
w = (*i)->total_channels() * grid_spacing();
}
}
if (w == 0) {
continue;
}
/* rectangle */
set_source_rgb (cr, get_a_group_colour (g));
double const rh = _highest_group_name + 2 * name_pad();
if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
cairo_rectangle (cr, x, component_to_parent_y (0), w, rh);
} else {
cairo_rectangle (cr, x, component_to_parent_y (_height - rh), w, rh);
}
cairo_fill (cr);
/* x area available to draw the label in (trying to keep it visible) */
double const lx = max (x, double (_parent_rectangle.get_x ()));
double const rx = min (x + w, double (_parent_rectangle.get_width()));
/* hence what abbreviation (or not) we need for the group name */
string const upper = Glib::ustring ((*i)->name).uppercase ();
pair<string, double> const display = fit_to_pixels (cr, upper, rx - lx);
/* plot it */
set_source_rgb (cr, text_colour());
cairo_move_to (cr, (lx + rx - display.second) / 2, y);
cairo_show_text (cr, display.first.c_str());
x += w;
++g;
}
}
void
PortMatrixColumnLabels::motion (double x, double y)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> const w = position_to_group_and_channel (x, y, _matrix->columns());
ARDOUR::BundleChannel const w = position_to_channel (x, y, _matrix->visible_columns());
if (w.second.bundle == 0) {
if (w.bundle == 0) {
_body->set_mouseover (PortMatrixNode ());
return;
}
uint32_t const bh = _highest_group_name + _longest_channel_name * sin (angle ()) + _highest_text / cos (angle ());
uint32_t const bh = _longest_channel_name * sin (angle ()) + _highest_text / cos (angle ());
if (
(_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && y > bh) ||
@ -588,8 +464,8 @@ PortMatrixColumnLabels::motion (double x, double y)
list<PortMatrixNode> n;
for (uint32_t i = 0; i < w.second.bundle->nchannels(); ++i) {
ARDOUR::BundleChannel const bc (w.second.bundle, i);
for (uint32_t i = 0; i < w.bundle->nchannels(); ++i) {
ARDOUR::BundleChannel const bc (w.bundle, i);
n.push_back (PortMatrixNode (ARDOUR::BundleChannel (), bc));
}
@ -597,6 +473,6 @@ PortMatrixColumnLabels::motion (double x, double y)
} else {
_body->set_mouseover (PortMatrixNode (ARDOUR::BundleChannel (), w.second));
_body->set_mouseover (PortMatrixNode (ARDOUR::BundleChannel (), w));
}
}

View file

@ -43,7 +43,6 @@ public:
double component_to_parent_y (double y) const;
double parent_to_component_y (double y) const;
void mouseover_changed (std::list<PortMatrixNode> const &);
void draw_extra (cairo_t *);
void motion (double, double);
uint32_t overhang () const {
@ -56,21 +55,16 @@ private:
double channel_x (ARDOUR::BundleChannel const &) const;
double channel_y (ARDOUR::BundleChannel const &) const;
void queue_draw_for (ARDOUR::BundleChannel const &);
std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
ARDOUR::BundleChannel position_to_channel (double, double, boost::shared_ptr<const PortGroup>) const;
void render (cairo_t *);
void compute_dimensions ();
double basic_text_x_pos (int) const;
std::vector<std::pair<double, double> > port_name_shape (double, double) const;
double slanted_height () const {
return _height - _highest_group_name - 2 * name_pad();
}
double _longest_bundle_name;
double _longest_channel_name;
double _highest_text;
double _highest_group_name;
uint32_t _overhang;
};

View file

@ -126,17 +126,13 @@ PortMatrixComponent::group_size (boost::shared_ptr<const PortGroup> g) const
{
uint32_t s = 0;
if (g->visible()) {
PortGroup::BundleList const & bundles = g->bundles ();
if (_matrix->show_only_bundles()) {
s = bundles.size();
} else {
for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
s += i->bundle->nchannels();
}
}
PortGroup::BundleList const & bundles = g->bundles ();
if (_matrix->show_only_bundles()) {
s = bundles.size();
} else {
s = 1;
for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
s += i->bundle->nchannels();
}
}
return s;
@ -144,46 +140,35 @@ PortMatrixComponent::group_size (boost::shared_ptr<const PortGroup> g) const
/** @param bc Channel.
* @param groups List of groups.
* @return Position of bc in groups in grid units, taking visibility and show_only_bundles into account.
* @return Position of bc in groups in grid units, taking show_only_bundles into account.
*/
uint32_t
PortMatrixComponent::channel_to_position (ARDOUR::BundleChannel bc, PortGroupList const * groups) const
PortMatrixComponent::channel_to_position (ARDOUR::BundleChannel bc, boost::shared_ptr<const PortGroup> group) const
{
uint32_t p = 0;
for (PortGroupList::List::const_iterator i = groups->begin(); i != groups->end(); ++i) {
PortGroup::BundleList const & bundles = group->bundles ();
PortGroup::BundleList const & bundles = (*i)->bundles ();
for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
for (PortGroup::BundleList::const_iterator j = bundles.begin(); j != bundles.end(); ++j) {
if (j->bundle == bc.bundle) {
/* found the bundle */
if (_matrix->show_only_bundles() || !(*i)->visible()) {
return p;
} else {
return p + bc.channel;
}
if (i->bundle == bc.bundle) {
/* found the bundle */
if (_matrix->show_only_bundles()) {
return p;
} else {
return p + bc.channel;
}
if ((*i)->visible()) {
/* move past this bundle */
if (_matrix->show_only_bundles()) {
p += 1;
} else {
p += j->bundle->nchannels ();
}
}
}
if (!(*i)->visible()) {
/* if this group isn't visible we won't have updated p, so do it now */
/* move past this bundle */
if (_matrix->show_only_bundles()) {
p += 1;
} else {
p += i->bundle->nchannels ();
}
}
@ -191,57 +176,34 @@ PortMatrixComponent::channel_to_position (ARDOUR::BundleChannel bc, PortGroupLis
}
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
PortMatrixComponent::position_to_group_and_channel (double p, double, PortGroupList const * groups) const
ARDOUR::BundleChannel
PortMatrixComponent::position_to_channel (double p, double, boost::shared_ptr<const PortGroup> group) const
{
p /= grid_spacing ();
PortGroupList::List::const_iterator i = groups->begin ();
PortGroup::BundleList const & bundles = group->bundles ();
for (PortGroup::BundleList::const_iterator j = bundles.begin(); j != bundles.end(); ++j) {
while (i != groups->end()) {
uint32_t const gs = group_size (*i);
if (p < gs) {
/* it's in this group */
if (!(*i)->visible()) {
return make_pair (*i, ARDOUR::BundleChannel (boost::shared_ptr<ARDOUR::Bundle> (), 0));
if (_matrix->show_only_bundles()) {
if (p == 0) {
return ARDOUR::BundleChannel (j->bundle, 0);
} else {
p -= 1;
}
PortGroup::BundleList const & bundles = (*i)->bundles ();
for (PortGroup::BundleList::const_iterator j = bundles.begin(); j != bundles.end(); ++j) {
if (_matrix->show_only_bundles()) {
if (p == 0) {
return make_pair (*i, ARDOUR::BundleChannel (j->bundle, 0));
} else {
p -= 1;
}
} else {
uint32_t const s = j->bundle->nchannels ();
if (p < s) {
return make_pair (*i, ARDOUR::BundleChannel (j->bundle, p));
} else {
p -= s;
}
}
}
} else {
p -= gs;
uint32_t const s = j->bundle->nchannels ();
if (p < s) {
return ARDOUR::BundleChannel (j->bundle, p);
} else {
p -= s;
}
}
++i;
}
return make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel (boost::shared_ptr<ARDOUR::Bundle> (), 0));
return ARDOUR::BundleChannel (boost::shared_ptr<ARDOUR::Bundle> (), 0);
}

View file

@ -171,8 +171,8 @@ protected:
void set_source_rgb (cairo_t *, Gdk::Color const &);
void set_source_rgba (cairo_t *, Gdk::Color const &, double);
uint32_t group_size (boost::shared_ptr<const PortGroup>) const;
uint32_t channel_to_position (ARDOUR::BundleChannel, PortGroupList const *) const;
virtual std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
uint32_t channel_to_position (ARDOUR::BundleChannel, boost::shared_ptr<const PortGroup>) const;
virtual ARDOUR::BundleChannel position_to_channel (double, double, boost::shared_ptr<const PortGroup>) const;
/** Render the complete component to a cairo context. */
virtual void render (cairo_t *) = 0;

View file

@ -39,15 +39,16 @@ PortMatrixGrid::PortMatrixGrid (PortMatrix* m, PortMatrixBody* b)
void
PortMatrixGrid::compute_dimensions ()
{
_width = 0;
for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
_width += group_size (*i) * grid_spacing ();
if (_matrix->visible_columns() == 0) {
_width = 0;
} else {
_width = group_size (_matrix->visible_columns()) * grid_spacing ();
}
_height = 0;
for (PortGroupList::List::const_iterator i = _matrix->rows()->begin(); i != _matrix->rows()->end(); ++i) {
_height += group_size (*i) * grid_spacing ();
if (_matrix->visible_rows() == 0) {
_height = 0;
} else {
_height = group_size (_matrix->visible_rows()) * grid_spacing ();
}
}
@ -59,33 +60,10 @@ PortMatrixGrid::render (cairo_t* cr)
cairo_rectangle (cr, 0, 0, _width, _height);
cairo_fill (cr);
PortGroup::BundleList const & row_bundles = _matrix->visible_rows()->bundles();
PortGroup::BundleList const & column_bundles = _matrix->visible_columns()->bundles();
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_size (*r) * grid_spacing ();
}
x += group_size (*c) * grid_spacing ();
}
}
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_size (row) * grid_spacing ();
uint32_t tx = x;
/* VERTICAL GRID LINES */
@ -95,31 +73,29 @@ PortMatrixGrid::render_group_pair (cairo_t* cr, boost::shared_ptr<const PortGrou
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_move_to (cr, x, 0);
cairo_line_to (cr, x, _height);
cairo_stroke (cr);
if (!_matrix->show_only_bundles()) {
cairo_set_line_width (cr, thin_grid_line_width());
for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {
tx += grid_spacing ();
cairo_move_to (cr, tx, y);
cairo_line_to (cr, tx, y + height);
x += grid_spacing ();
cairo_move_to (cr, x, 0);
cairo_line_to (cr, x, _height);
cairo_stroke (cr);
}
} else {
tx += grid_spacing ();
x += grid_spacing ();
}
++N;
}
uint32_t const width = tx - x;
uint32_t ty = y;
uint32_t y = 0;
/* HORIZONTAL GRID LINES */
@ -127,22 +103,22 @@ PortMatrixGrid::render_group_pair (cairo_t* cr, boost::shared_ptr<const PortGrou
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_move_to (cr, 0, y);
cairo_line_to (cr, _width, y);
cairo_stroke (cr);
if (!_matrix->show_only_bundles()) {
cairo_set_line_width (cr, thin_grid_line_width());
for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {
ty += grid_spacing ();
cairo_move_to (cr, x, ty);
cairo_line_to (cr, x + width, ty);
y += grid_spacing ();
cairo_move_to (cr, 0, y);
cairo_line_to (cr, _width, y);
cairo_stroke (cr);
}
} else {
ty += grid_spacing ();
y += grid_spacing ();
}
@ -151,13 +127,13 @@ PortMatrixGrid::render_group_pair (cairo_t* cr, boost::shared_ptr<const PortGrou
/* ASSOCIATION INDICATORS */
uint32_t bx = x;
uint32_t by = y;
uint32_t bx = 0;
uint32_t by = 0;
if (_matrix->show_only_bundles()) {
for (PortGroup::BundleList::const_iterator i = column_bundles.begin(); i != column_bundles.end(); ++i) {
by = y;
by = 0;
for (PortGroup::BundleList::const_iterator j = row_bundles.begin(); j != row_bundles.end(); ++j) {
@ -186,14 +162,14 @@ PortMatrixGrid::render_group_pair (cairo_t* cr, boost::shared_ptr<const PortGrou
} else {
for (PortGroup::BundleList::const_iterator i = column_bundles.begin(); i != column_bundles.end(); ++i) {
by = y;
by = 0;
for (PortGroup::BundleList::const_iterator j = row_bundles.begin(); j != row_bundles.end(); ++j) {
tx = bx;
x = bx;
for (uint32_t k = 0; k < i->bundle->nchannels (); ++k) {
ty = by;
y = by;
for (uint32_t l = 0; l < j->bundle->nchannels (); ++l) {
ARDOUR::BundleChannel c[2];
@ -204,7 +180,7 @@ PortMatrixGrid::render_group_pair (cairo_t* cr, boost::shared_ptr<const PortGrou
switch (s) {
case PortMatrixNode::ASSOCIATED:
draw_association_indicator (cr, tx, ty);
draw_association_indicator (cr, x, y);
break;
case PortMatrixNode::NOT_ASSOCIATED:
@ -214,10 +190,10 @@ PortMatrixGrid::render_group_pair (cairo_t* cr, boost::shared_ptr<const PortGrou
break;
}
ty += grid_spacing();
y += grid_spacing();
}
tx += grid_spacing();
x += grid_spacing();
}
by += j->bundle->nchannels () * grid_spacing();
@ -263,21 +239,21 @@ PortMatrixNode
PortMatrixGrid::position_to_node (double x, double y) const
{
return PortMatrixNode (
position_to_group_and_channel (y, x, _matrix->rows()).second,
position_to_group_and_channel (x, y, _matrix->columns()).second
position_to_channel (y, x, _matrix->visible_rows()),
position_to_channel (x, y, _matrix->visible_columns())
);
}
void
PortMatrixGrid::button_press (double x, double y, int b, uint32_t t)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> px = position_to_group_and_channel (x, y, _matrix->columns());
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> py = position_to_group_and_channel (y, x, _matrix->rows());
ARDOUR::BundleChannel const px = position_to_channel (x, y, _matrix->visible_columns());
ARDOUR::BundleChannel const py = position_to_channel (y, x, _matrix->visible_rows());
if (b == 1) {
_dragging = true;
_drag_valid = (px.second.bundle && py.second.bundle);
_drag_valid = (px.bundle && py.bundle);
_moved = false;
_drag_start_x = x / grid_spacing ();
@ -423,8 +399,8 @@ PortMatrixGrid::draw_extra (cairo_t* cr)
for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
double const x = component_to_parent_x (channel_to_position (i->column, _matrix->columns()) * grid_spacing()) + grid_spacing() / 2;
double const y = component_to_parent_y (channel_to_position (i->row, _matrix->rows()) * grid_spacing()) + grid_spacing() / 2;
double const x = component_to_parent_x (channel_to_position (i->column, _matrix->visible_columns()) * grid_spacing()) + grid_spacing() / 2;
double const y = component_to_parent_y (channel_to_position (i->row, _matrix->visible_rows()) * grid_spacing()) + grid_spacing() / 2;
if (i->row.bundle && i->column.bundle) {
@ -458,14 +434,14 @@ PortMatrixGrid::draw_extra (cairo_t* cr)
if (s) {
draw_association_indicator (
cr,
component_to_parent_x (channel_to_position (i->column, _matrix->columns()) * grid_spacing ()),
component_to_parent_y (channel_to_position (i->row, _matrix->rows()) * grid_spacing ())
component_to_parent_x (channel_to_position (i->column, _matrix->visible_columns()) * grid_spacing ()),
component_to_parent_y (channel_to_position (i->row, _matrix->visible_rows()) * grid_spacing ())
);
} else {
draw_empty_square (
cr,
component_to_parent_x (channel_to_position (i->column, _matrix->columns()) * grid_spacing ()),
component_to_parent_y (channel_to_position (i->row, _matrix->rows()) * grid_spacing ())
component_to_parent_x (channel_to_position (i->column, _matrix->visible_columns()) * grid_spacing ()),
component_to_parent_y (channel_to_position (i->row, _matrix->visible_rows()) * grid_spacing ())
);
}
}
@ -523,7 +499,7 @@ PortMatrixGrid::queue_draw_for (list<PortMatrixNode> const &n)
if (i->row.bundle) {
double const y = channel_to_position (i->row, _matrix->rows()) * grid_spacing ();
double const y = channel_to_position (i->row, _matrix->visible_rows()) * grid_spacing ();
_body->queue_draw_area (
_parent_rectangle.get_x(),
component_to_parent_y (y),
@ -534,7 +510,7 @@ PortMatrixGrid::queue_draw_for (list<PortMatrixNode> const &n)
if (i->column.bundle) {
double const x = channel_to_position (i->column, _matrix->columns()) * grid_spacing ();
double const x = channel_to_position (i->column, _matrix->visible_columns()) * grid_spacing ();
_body->queue_draw_area (
component_to_parent_x (x),

View file

@ -32,7 +32,7 @@ public:
PortMatrixLabels (PortMatrix* m, PortMatrixBody* b) : PortMatrixComponent (m, b) {}
virtual ~PortMatrixLabels () {}
virtual void draw_extra (cairo_t *);
void draw_extra (cairo_t *);
void clear_channel_highlights ();
void add_channel_highlight (ARDOUR::BundleChannel const &);

View file

@ -45,7 +45,10 @@ PortMatrixRowLabels::compute_dimensions ()
_longest_port_name = 0;
_longest_bundle_name = 0;
_height = 0;
_highest_group_name = 0;
/* Compute maximum dimensions using all port groups, so that we allow for the largest and hence
we can change between visible groups without the size of the labels jumping around.
*/
for (PortGroupList::List::const_iterator i = _matrix->rows()->begin(); i != _matrix->rows()->end(); ++i) {
@ -66,22 +69,16 @@ PortMatrixRowLabels::compute_dimensions ()
_longest_bundle_name = ext.width;
}
}
_height += group_size (*i) * grid_spacing ();
cairo_text_extents_t ext;
cairo_text_extents (cr, (*i)->name.c_str(), &ext);
if (ext.height > _highest_group_name) {
_highest_group_name = ext.height;
}
}
_height += group_size (_matrix->visible_rows()) * grid_spacing ();
cairo_destroy (cr);
gdk_pixmap_unref (pm);
_width = _highest_group_name +
_longest_bundle_name +
name_pad() * 4;
_width = _longest_bundle_name +
name_pad() * 2;
if (!_matrix->show_only_bundles()) {
_width += _longest_port_name;
@ -104,62 +101,35 @@ PortMatrixRowLabels::render (cairo_t* cr)
double y = 0;
int N = 0;
int M = 0;
for (PortGroupList::List::const_iterator i = _matrix->rows()->begin(); i != _matrix->rows()->end(); ++i) {
PortGroup::BundleList const & bundles = _matrix->visible_rows()->bundles ();
for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
render_bundle_name (cr, background_colour (), i->has_colour ? i->colour : get_a_bundle_colour (N), 0, y, i->bundle);
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, background_colour (), 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, background_colour (), c, 0, y, ARDOUR::BundleChannel (j->bundle, k));
y += grid_spacing();
++M;
}
} else {
y += grid_spacing();
}
++N;
if (!_matrix->show_only_bundles()) {
for (uint32_t j = 0; j < i->bundle->nchannels(); ++j) {
Gdk::Color c = i->has_colour ? i->colour : get_a_bundle_colour (M);
render_channel_name (cr, background_colour (), c, 0, y, ARDOUR::BundleChannel (i->bundle, j));
y += grid_spacing();
++M;
}
} else {
y += grid_spacing ();
y += grid_spacing();
}
++N;
}
}
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
PortMatrixRowLabels::position_to_group_and_channel (double p, double o, PortGroupList const * groups) const
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = PortMatrixComponent::position_to_group_and_channel (p, o, _matrix->rows());
uint32_t const gw = (_highest_group_name + 2 * name_pad());
if (
(_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && o < gw) ||
(_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && o > (_width - gw))
) {
w.second.bundle.reset ();
}
return w;
}
void
PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = position_to_group_and_channel (y, x, _matrix->rows());
ARDOUR::BundleChannel const w = position_to_channel (y, x, _matrix->visible_rows());
if (b == 3) {
_matrix->popup_menu (
make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
ARDOUR::BundleChannel (),
w,
t
);
@ -198,14 +168,8 @@ PortMatrixRowLabels::bundle_name_x () const
{
double x = 0;
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
x = _highest_group_name + 2 * name_pad();
} else {
if (_matrix->show_only_bundles()) {
x = 0;
} else {
x = _longest_port_name + name_pad() * 2;
}
if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && !_matrix->show_only_bundles ()) {
x = _longest_port_name + name_pad() * 2;
}
return x;
@ -215,7 +179,7 @@ double
PortMatrixRowLabels::port_name_x () const
{
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
return _longest_bundle_name + _highest_group_name + name_pad() * 4;
return _longest_bundle_name + name_pad() * 2;
} else {
return 0;
}
@ -283,7 +247,7 @@ PortMatrixRowLabels::channel_x (ARDOUR::BundleChannel const &) const
double
PortMatrixRowLabels::channel_y (ARDOUR::BundleChannel const& bc) const
{
return channel_to_position (bc, _matrix->rows()) * grid_spacing ();
return channel_to_position (bc, _matrix->visible_rows()) * grid_spacing ();
}
void
@ -327,79 +291,18 @@ PortMatrixRowLabels::mouseover_changed (list<PortMatrixNode> const &)
}
}
void
PortMatrixRowLabels::draw_extra (cairo_t* cr)
{
PortMatrixLabels::draw_extra (cr);
/* PORT GROUP NAMES */
double x = 0;
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
x = component_to_parent_x (0);
} else {
x = component_to_parent_x (_width - _highest_group_name - 2 * name_pad());
}
double y = component_to_parent_y (0);
int g = 0;
for (PortGroupList::List::const_iterator i = _matrix->rows()->begin(); i != _matrix->rows()->end(); ++i) {
/* compute height of this group */
double h = 0;
if (!(*i)->visible()) {
h = grid_spacing ();
} else {
if (_matrix->show_only_bundles()) {
h = (*i)->bundles().size() * grid_spacing();
} else {
h = (*i)->total_channels () * grid_spacing();
}
}
if (h == 0) {
continue;
}
/* 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);
/* y area available to draw the label in (trying to keep it visible) */
double const ty = max (y, 0.0);
double const by = min (y + h, double (_body->alloc_scroll_height ()));
/* hence what abbreviation (or not) we need for the group name */
string const upper = Glib::ustring ((*i)->name).uppercase ();
pair<string, double> display = fit_to_pixels (cr, upper, by - ty);
/* plot it */
set_source_rgb (cr, text_colour());
cairo_move_to (cr, x + rw - name_pad(), (by + ty + display.second) / 2);
cairo_save (cr);
cairo_rotate (cr, - M_PI / 2);
cairo_show_text (cr, display.first.c_str());
cairo_restore (cr);
y += h;
++g;
}
}
void
PortMatrixRowLabels::motion (double x, double y)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> const w = position_to_group_and_channel (y, x, _matrix->rows());
ARDOUR::BundleChannel const w = position_to_channel (y, x, _matrix->visible_rows());
if (w.second.bundle == 0) {
if (w.bundle == 0) {
/* not over any bundle */
_body->set_mouseover (PortMatrixNode ());
return;
}
uint32_t const bw = _highest_group_name + 2 * name_pad() + _longest_bundle_name + 2 * name_pad();
uint32_t const bw = _longest_bundle_name + 2 * name_pad();
if (
(_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x < bw) ||
@ -411,8 +314,8 @@ PortMatrixRowLabels::motion (double x, double y)
list<PortMatrixNode> n;
for (uint32_t i = 0; i < w.second.bundle->nchannels(); ++i) {
ARDOUR::BundleChannel const bc (w.second.bundle, i);
for (uint32_t i = 0; i < w.bundle->nchannels(); ++i) {
ARDOUR::BundleChannel const bc (w.bundle, i);
n.push_back (PortMatrixNode (bc, ARDOUR::BundleChannel ()));
}
@ -420,7 +323,7 @@ PortMatrixRowLabels::motion (double x, double y)
} else {
_body->set_mouseover (PortMatrixNode (w.second, ARDOUR::BundleChannel ()));
_body->set_mouseover (PortMatrixNode (w, ARDOUR::BundleChannel ()));
}
}

View file

@ -50,7 +50,6 @@ public:
double component_to_parent_y (double y) const;
double parent_to_component_y (double y) const;
void mouseover_changed (std::list<PortMatrixNode> const &);
void draw_extra (cairo_t *);
void motion (double, double);
private:
@ -58,7 +57,6 @@ private:
void render_bundle_name (cairo_t *, Gdk::Color, Gdk::Color, double, double, boost::shared_ptr<ARDOUR::Bundle>);
double channel_x (ARDOUR::BundleChannel const &) const;
double channel_y (ARDOUR::BundleChannel const &) const;
virtual std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
void render (cairo_t *);
void compute_dimensions ();
@ -70,7 +68,6 @@ private:
double _longest_port_name;
double _longest_bundle_name;
double _highest_group_name;
};
#endif