mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
Group destination ports by track / buss / system etc.
git-svn-id: svn://localhost/ardour2/trunk@2545 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
40d8d96785
commit
a57a62b925
2 changed files with 214 additions and 91 deletions
|
|
@ -28,13 +28,14 @@
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
#include "ardour/io.h"
|
#include "ardour/io.h"
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
|
#include "ardour/track.h"
|
||||||
#include "io_selector.h"
|
#include "io_selector.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
RotatedLabelSet::RotatedLabelSet ()
|
RotatedLabelSet::RotatedLabelSet (GroupedPortList& g)
|
||||||
: Glib::ObjectBase ("RotatedLabelSet"), Gtk::Widget (), _base_start (64), _base_width (128)
|
: Glib::ObjectBase ("RotatedLabelSet"), Gtk::Widget (), _port_list (g), _base_start (64), _base_width (128)
|
||||||
{
|
{
|
||||||
set_flags (Gtk::NO_WINDOW);
|
set_flags (Gtk::NO_WINDOW);
|
||||||
set_angle (30);
|
set_angle (30);
|
||||||
|
|
@ -45,6 +46,11 @@ RotatedLabelSet::~RotatedLabelSet ()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Set the angle that the labels are drawn at.
|
||||||
|
* @param degrees New angle in degrees.
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
RotatedLabelSet::set_angle (int degrees)
|
RotatedLabelSet::set_angle (int degrees)
|
||||||
{
|
{
|
||||||
|
|
@ -65,17 +71,20 @@ RotatedLabelSet::on_size_request (Gtk::Requisition* requisition)
|
||||||
|
|
||||||
/* Our height is the highest label */
|
/* Our height is the highest label */
|
||||||
requisition->height = 0;
|
requisition->height = 0;
|
||||||
for (std::vector<std::string>::const_iterator i = _labels.begin(); i != _labels.end(); ++i) {
|
for (GroupedPortList::const_iterator i = _port_list.begin(); i != _port_list.end(); ++i) {
|
||||||
std::pair<int, int> const d = setup_layout (*i);
|
for (std::vector<std::string>::const_iterator j = i->ports.begin(); j != i->ports.end(); ++j) {
|
||||||
if (d.second > requisition->height) {
|
std::pair<int, int> const d = setup_layout (*j);
|
||||||
requisition->height = d.second;
|
if (d.second > requisition->height) {
|
||||||
|
requisition->height = d.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And our width is the base plus the width of the last label */
|
/* And our width is the base plus the width of the last label */
|
||||||
requisition->width = _base_start + _base_width;
|
requisition->width = _base_start + _base_width;
|
||||||
if (_labels.empty() == false) {
|
int const n = _port_list.n_ports ();
|
||||||
std::pair<int, int> const d = setup_layout (_labels.back());
|
if (n > 0) {
|
||||||
|
std::pair<int, int> const d = setup_layout (_port_list.get_port_by_index (n - 1, false));
|
||||||
requisition->width += d.first;
|
requisition->width += d.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -169,44 +178,29 @@ RotatedLabelSet::setup_layout (std::string const & s)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RotatedLabelSet::on_expose_event (GdkEventExpose* event)
|
bool
|
||||||
|
RotatedLabelSet::on_expose_event (GdkEventExpose* event)
|
||||||
{
|
{
|
||||||
if (!_gdk_window) {
|
if (!_gdk_window) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int const height = get_allocation().get_height ();
|
int const height = get_allocation().get_height ();
|
||||||
double const spacing = double (_base_width) / _labels.size();
|
double const spacing = double (_base_width) / _port_list.n_ports();
|
||||||
|
|
||||||
/* Plot all the labels; really we should clip for efficiency */
|
/* Plot all the labels; really we should clip for efficiency */
|
||||||
for (uint32_t i = 0; i < _labels.size(); ++i) {
|
int n = 0;
|
||||||
std::pair<int, int> const d = setup_layout (_labels[i]);
|
for (GroupedPortList::const_iterator i = _port_list.begin(); i != _port_list.end(); ++i) {
|
||||||
get_window()->draw_layout (_gc, _base_start + int ((i + 0.25) * spacing), height - d.second, _pango_layout, _fg_colour, _bg_colour);
|
for (uint32_t j = 0; j < i->ports.size(); ++j) {
|
||||||
|
std::pair<int, int> const d = setup_layout (i->ports[j]);
|
||||||
|
get_window()->draw_layout (_gc, _base_start + int ((n + 0.25) * spacing), height - d.second, _pango_layout, _fg_colour, _bg_colour);
|
||||||
|
++n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
RotatedLabelSet::set_n_labels (int n)
|
|
||||||
{
|
|
||||||
_labels.resize (n);
|
|
||||||
queue_resize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RotatedLabelSet::set_label (int n, std::string const & l)
|
|
||||||
{
|
|
||||||
_labels[n] = l;
|
|
||||||
queue_resize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
RotatedLabelSet::get_label (int n) const
|
|
||||||
{
|
|
||||||
return _labels[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the `base dimensions'. These are the dimensions of the area at which the labels start, and
|
* Set the `base dimensions'. These are the dimensions of the area at which the labels start, and
|
||||||
* have to be set up to match whatever they are labelling.
|
* have to be set up to match whatever they are labelling.
|
||||||
|
|
@ -238,7 +232,8 @@ RotatedLabelSet::set_base_dimensions (int s, int w)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool for_input)
|
IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool for_input)
|
||||||
: _session (session), _io (io), _for_input (for_input), _width (0), _height (0),
|
: _session (session), _port_list (session, io, for_input), _io (io), _for_input (for_input),
|
||||||
|
_width (0), _height (0), _column_labels (_port_list),
|
||||||
_ignore_check_button_toggle (false), _add_remove_box_added (false)
|
_ignore_check_button_toggle (false), _add_remove_box_added (false)
|
||||||
{
|
{
|
||||||
/* Column labels */
|
/* Column labels */
|
||||||
|
|
@ -257,9 +252,9 @@ IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO>
|
||||||
|
|
||||||
/* Table. We need to put in a HBox, with a dummy label to its right,
|
/* Table. We need to put in a HBox, with a dummy label to its right,
|
||||||
so that the rotated column labels can overhang the right hand side of the table. */
|
so that the rotated column labels can overhang the right hand side of the table. */
|
||||||
setup_table_size ();
|
|
||||||
|
setup_table ();
|
||||||
setup_row_labels ();
|
setup_row_labels ();
|
||||||
setup_column_labels ();
|
|
||||||
setup_check_button_states ();
|
setup_check_button_states ();
|
||||||
_table_hbox.pack_start (_table, false, false);
|
_table_hbox.pack_start (_table, false, false);
|
||||||
_table_hbox.pack_start (_dummy);
|
_table_hbox.pack_start (_dummy);
|
||||||
|
|
@ -313,26 +308,23 @@ IOSelector::update_column_label_dimensions ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IOSelector::setup_table_size ()
|
IOSelector::setup_table ()
|
||||||
{
|
{
|
||||||
if (_add_remove_box_added) {
|
if (_add_remove_box_added) {
|
||||||
_table.remove (_add_remove_box);
|
_table.remove (_add_remove_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::vector<Gtk::EventBox*>::iterator i = _group_labels.begin(); i != _group_labels.end(); ++i) {
|
||||||
|
_table.remove (**i);
|
||||||
|
delete *i;
|
||||||
|
}
|
||||||
|
|
||||||
|
_group_labels.clear ();
|
||||||
|
|
||||||
/* New width */
|
/* New width */
|
||||||
|
|
||||||
int const old_width = _width;
|
int const old_width = _width;
|
||||||
_width = 0;
|
_width = _port_list.n_ports ();
|
||||||
|
|
||||||
const char **ports = _session.engine().get_ports (
|
|
||||||
"", _io->default_type().to_jack_type(), _for_input ? JackPortIsOutput : JackPortIsInput
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ports) {
|
|
||||||
while (ports[_width]) {
|
|
||||||
++_width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New height */
|
/* New height */
|
||||||
|
|
||||||
|
|
@ -348,7 +340,7 @@ IOSelector::setup_table_size ()
|
||||||
|
|
||||||
_table.resize (_width + 1, _height + 1);
|
_table.resize (_width + 1, _height + 1);
|
||||||
|
|
||||||
/* Add checkboxes where required, and remove those that aren't */
|
/* Add checkbuttons where required, and remove those that aren't */
|
||||||
for (int x = _width; x < old_width; ++x) {
|
for (int x = _width; x < old_width; ++x) {
|
||||||
for (int y = 0; y < old_height; ++y) {
|
for (int y = 0; y < old_height; ++y) {
|
||||||
delete _check_buttons[x][y];
|
delete _check_buttons[x][y];
|
||||||
|
|
@ -390,6 +382,29 @@ IOSelector::setup_table_size ()
|
||||||
_table.attach (_add_remove_box, 0, 1, _height, _height + 1);
|
_table.attach (_add_remove_box, 0, 1, _height, _height + 1);
|
||||||
_add_remove_box_added = true;
|
_add_remove_box_added = true;
|
||||||
|
|
||||||
|
/* Add group labels */
|
||||||
|
int n = 1;
|
||||||
|
int m = 0;
|
||||||
|
|
||||||
|
/* XXX: this is a bit of a hack; should probably use a configurable colour here */
|
||||||
|
Gdk::Color alt_bg = get_style()->get_bg (Gtk::STATE_NORMAL);
|
||||||
|
alt_bg.set_rgb (alt_bg.get_red() + 4096, alt_bg.get_green() + 4096, alt_bg.get_blue () + 4096);
|
||||||
|
for (GroupedPortList::iterator i = _port_list.begin(); i != _port_list.end(); ++i) {
|
||||||
|
if (i->ports.empty() == false) {
|
||||||
|
Gtk::Label* label = new Gtk::Label ("<b>" + i->name + "</b>");
|
||||||
|
label->set_use_markup (true);
|
||||||
|
Gtk::EventBox* box = new Gtk::EventBox ();
|
||||||
|
box->add (*Gtk::manage (label));
|
||||||
|
if (m % 2 == 0) {
|
||||||
|
box->modify_bg (Gtk::STATE_NORMAL, alt_bg);
|
||||||
|
}
|
||||||
|
_group_labels.push_back (box);
|
||||||
|
_table.attach (*box, n, n + i->ports.size(), _height, _height + 1);
|
||||||
|
n += i->ports.size();
|
||||||
|
++m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
show_all ();
|
show_all ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -406,34 +421,6 @@ IOSelector::setup_row_labels ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the correct text to the column labels.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
IOSelector::setup_column_labels ()
|
|
||||||
{
|
|
||||||
/* Find the ports that we can connect to */
|
|
||||||
const char **ports = _session.engine().get_ports (
|
|
||||||
"", _io->default_type().to_jack_type(), _for_input ? JackPortIsOutput : JackPortIsInput
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ports == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
while (ports[n]) {
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
|
|
||||||
_column_labels.set_n_labels (n);
|
|
||||||
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
_column_labels.set_label (i, ports[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the state of each check button according to what connections are made.
|
* Set up the state of each check button according to what connections are made.
|
||||||
|
|
@ -449,7 +436,7 @@ IOSelector::setup_check_button_states ()
|
||||||
const char **connections = _for_input ? _io->input(i)->get_connections() : _io->output(i)->get_connections();
|
const char **connections = _for_input ? _io->input(i)->get_connections() : _io->output(i)->get_connections();
|
||||||
for (int j = 0; j < _width; ++j) {
|
for (int j = 0; j < _width; ++j) {
|
||||||
|
|
||||||
std::string const t = _column_labels.get_label (j);
|
std::string const t = _port_list.get_port_by_index (j);
|
||||||
int k = 0;
|
int k = 0;
|
||||||
bool required_state = false;
|
bool required_state = false;
|
||||||
|
|
||||||
|
|
@ -481,7 +468,7 @@ IOSelector::check_button_toggled (int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool const new_state = _check_buttons[x][y]->get_active ();
|
bool const new_state = _check_buttons[x][y]->get_active ();
|
||||||
std::string const port = _column_labels.get_label (x);
|
std::string const port = _port_list.get_port_by_index (x);
|
||||||
|
|
||||||
if (new_state) {
|
if (new_state) {
|
||||||
if (_for_input) {
|
if (_for_input) {
|
||||||
|
|
@ -599,8 +586,8 @@ IOSelector::ports_changed (ARDOUR::IOChange change, void *src)
|
||||||
void
|
void
|
||||||
IOSelector::redisplay ()
|
IOSelector::redisplay ()
|
||||||
{
|
{
|
||||||
setup_table_size ();
|
_port_list.refresh ();
|
||||||
setup_column_labels ();
|
setup_table ();
|
||||||
setup_row_labels ();
|
setup_row_labels ();
|
||||||
setup_check_button_states ();
|
setup_check_button_states ();
|
||||||
update_column_label_dimensions ();
|
update_column_label_dimensions ();
|
||||||
|
|
@ -608,6 +595,116 @@ IOSelector::redisplay ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupedPortList::GroupedPortList (ARDOUR::Session & session, boost::shared_ptr<ARDOUR::IO> io, bool for_input)
|
||||||
|
: _session (session), _io (io), _for_input (for_input)
|
||||||
|
{
|
||||||
|
refresh ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GroupedPortList::refresh ()
|
||||||
|
{
|
||||||
|
clear ();
|
||||||
|
|
||||||
|
/* Find the ports provided by ardour; we can't derive their type just from their
|
||||||
|
names, so we'll have to be more devious. */
|
||||||
|
|
||||||
|
boost::shared_ptr<ARDOUR::Session::RouteList> routes = _session.get_routes ();
|
||||||
|
|
||||||
|
PortGroup buss (_("Buss"), "ardour:");
|
||||||
|
PortGroup track (_("Track"), "ardour:");
|
||||||
|
|
||||||
|
for (ARDOUR::Session::RouteList::const_iterator i = routes->begin(); i != routes->end(); ++i) {
|
||||||
|
|
||||||
|
PortGroup& g = dynamic_cast<ARDOUR::Track*> ((*i).get()) == 0 ? buss : track;
|
||||||
|
|
||||||
|
ARDOUR::PortSet const & p = _for_input ? ((*i)->outputs()) : ((*i)->inputs());
|
||||||
|
for (uint32_t j = 0; j < p.num_ports(); ++j) {
|
||||||
|
std::string const n = p.port(j)->name ();
|
||||||
|
g.ports.push_back (n.substr(strlen ("ardour:")));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort (g.ports.begin(), g.ports.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* XXX: inserts, sends, plugin inserts? */
|
||||||
|
|
||||||
|
/* Now we need to find the non-ardour ports; we do this by first
|
||||||
|
finding all the ports that we can connect to. */
|
||||||
|
const char **ports = _session.engine().get_ports (
|
||||||
|
"", _io->default_type().to_jack_type(), _for_input ? JackPortIsOutput : JackPortIsInput
|
||||||
|
);
|
||||||
|
|
||||||
|
PortGroup system (_("System"), "system:");
|
||||||
|
PortGroup other (_("Other"), "");
|
||||||
|
|
||||||
|
if (ports) {
|
||||||
|
|
||||||
|
/* Count them */
|
||||||
|
int n = 0;
|
||||||
|
while (ports[n]) {
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
std::string const p = ports[i];
|
||||||
|
|
||||||
|
if (p.substr(0, strlen ("system:")) == "system:") {
|
||||||
|
/* system: prefix */
|
||||||
|
system.ports.push_back (p.substr (strlen ("system:")));
|
||||||
|
} else {
|
||||||
|
if (p.substr(0, strlen("ardour:")) != "ardour:") {
|
||||||
|
/* other (non-ardour) prefix */
|
||||||
|
other.ports.push_back (p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
push_back (buss);
|
||||||
|
push_back (track);
|
||||||
|
push_back (system);
|
||||||
|
push_back (other);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
GroupedPortList::n_ports () const
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
for (const_iterator i = begin(); i != end(); ++i) {
|
||||||
|
for (std::vector<std::string>::const_iterator j = i->ports.begin(); j != i->ports.end(); ++j) {
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GroupedPortList::get_port_by_index (int n, bool with_prefix) const
|
||||||
|
{
|
||||||
|
/* XXX: slightly inefficient algorithm */
|
||||||
|
|
||||||
|
for (const_iterator i = begin(); i != end(); ++i) {
|
||||||
|
for (std::vector<std::string>::const_iterator j = i->ports.begin(); j != i->ports.end(); ++j) {
|
||||||
|
if (n == 0) {
|
||||||
|
if (with_prefix) {
|
||||||
|
return i->prefix + *j;
|
||||||
|
} else {
|
||||||
|
return *j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IOSelectorWindow::IOSelectorWindow (
|
IOSelectorWindow::IOSelectorWindow (
|
||||||
ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool for_input, bool can_cancel
|
ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool for_input, bool can_cancel
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,38 @@ namespace ARDOUR {
|
||||||
class PortInsert;
|
class PortInsert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PortGroup
|
||||||
|
{
|
||||||
|
PortGroup (std::string const & n, std::string const & p) : name (n), prefix (p) {}
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::string prefix;
|
||||||
|
std::vector<std::string> ports;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GroupedPortList : public std::list<PortGroup>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GroupedPortList (ARDOUR::Session &, boost::shared_ptr<ARDOUR::IO>, bool);
|
||||||
|
|
||||||
|
void refresh ();
|
||||||
|
int n_ports () const;
|
||||||
|
std::string get_port_by_index (int, bool with_prefix = true) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ARDOUR::Session& _session;
|
||||||
|
boost::shared_ptr<ARDOUR::IO> _io;
|
||||||
|
bool _for_input;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// A widget which provides a set of rotated text labels
|
||||||
class RotatedLabelSet : public Gtk::Widget {
|
class RotatedLabelSet : public Gtk::Widget {
|
||||||
public:
|
public:
|
||||||
RotatedLabelSet ();
|
RotatedLabelSet (GroupedPortList&);
|
||||||
virtual ~RotatedLabelSet ();
|
virtual ~RotatedLabelSet ();
|
||||||
|
|
||||||
void set_angle (int);
|
void set_angle (int);
|
||||||
void set_n_labels (int);
|
|
||||||
void set_label (int, std::string const &);
|
|
||||||
std::string get_label (int) const;
|
|
||||||
void set_base_dimensions (int, int);
|
void set_base_dimensions (int, int);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -55,8 +78,8 @@ class RotatedLabelSet : public Gtk::Widget {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<int, int> setup_layout (std::string const &);
|
std::pair<int, int> setup_layout (std::string const &);
|
||||||
|
|
||||||
std::vector<std::string> _labels; ///< text for our labels
|
GroupedPortList& _port_list; ///< list of ports to display
|
||||||
int _angle_degrees; ///< label rotation angle in degrees
|
int _angle_degrees; ///< label rotation angle in degrees
|
||||||
double _angle_radians; ///< label rotation angle in radians
|
double _angle_radians; ///< label rotation angle in radians
|
||||||
int _base_start; ///< offset to start of labels; see set_base_dimensions() for more details
|
int _base_start; ///< offset to start of labels; see set_base_dimensions() for more details
|
||||||
|
|
@ -68,6 +91,9 @@ class RotatedLabelSet : public Gtk::Widget {
|
||||||
Gdk::Color _bg_colour;
|
Gdk::Color _bg_colour;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Widget for selecting what an IO is connected to
|
||||||
class IOSelector : public Gtk::VBox {
|
class IOSelector : public Gtk::VBox {
|
||||||
public:
|
public:
|
||||||
IOSelector (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool);
|
IOSelector (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool);
|
||||||
|
|
@ -86,9 +112,8 @@ class IOSelector : public Gtk::VBox {
|
||||||
ARDOUR::Session& _session;
|
ARDOUR::Session& _session;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup_table_size ();
|
void setup_table ();
|
||||||
void setup_row_labels ();
|
void setup_row_labels ();
|
||||||
void setup_column_labels ();
|
|
||||||
void setup_check_button_states ();
|
void setup_check_button_states ();
|
||||||
void check_button_toggled (int, int);
|
void check_button_toggled (int, int);
|
||||||
void add_port_button_clicked ();
|
void add_port_button_clicked ();
|
||||||
|
|
@ -96,12 +121,14 @@ class IOSelector : public Gtk::VBox {
|
||||||
void set_button_sensitivity ();
|
void set_button_sensitivity ();
|
||||||
void ports_changed (ARDOUR::IOChange, void *);
|
void ports_changed (ARDOUR::IOChange, void *);
|
||||||
void update_column_label_dimensions ();
|
void update_column_label_dimensions ();
|
||||||
|
|
||||||
|
GroupedPortList _port_list;
|
||||||
boost::shared_ptr<ARDOUR::IO> _io;
|
boost::shared_ptr<ARDOUR::IO> _io;
|
||||||
bool _for_input;
|
bool _for_input;
|
||||||
int _width;
|
int _width;
|
||||||
int _height;
|
int _height;
|
||||||
std::vector<Gtk::Label*> _row_labels;
|
std::vector<Gtk::Label*> _row_labels;
|
||||||
|
std::vector<Gtk::EventBox*> _group_labels;
|
||||||
RotatedLabelSet _column_labels;
|
RotatedLabelSet _column_labels;
|
||||||
std::vector<std::vector<Gtk::CheckButton*> > _check_buttons;
|
std::vector<std::vector<Gtk::CheckButton*> > _check_buttons;
|
||||||
bool _ignore_check_button_toggle; ///< check button toggle events are ignored when this is true
|
bool _ignore_check_button_toggle; ///< check button toggle events are ignored when this is true
|
||||||
|
|
@ -111,7 +138,6 @@ class IOSelector : public Gtk::VBox {
|
||||||
Gtk::HBox _table_hbox;
|
Gtk::HBox _table_hbox;
|
||||||
Gtk::Label _dummy;
|
Gtk::Label _dummy;
|
||||||
bool _add_remove_box_added;
|
bool _add_remove_box_added;
|
||||||
|
|
||||||
Gtk::Table _table;
|
Gtk::Table _table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue