summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2009-01-13 01:15:19 +0000
committerCarl Hetherington <carl@carlh.net>2009-01-13 01:15:19 +0000
commit954e1a6e795a5a53865f9278105579f00143cdb1 (patch)
tree14e6d690c227fdab1506b37573df680ae240bb12 /gtk2_ardour
parent3b96ad2a9759feaf2d3b2c676630c12bbbdfbaae (diff)
Improvements to the port matrix (I think). Sizing of the cairo section should be better. Clicking on nodes performs port connects / disconnects.
git-svn-id: svn://localhost/ardour2/branches/3.0@4402 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/SConscript1
-rw-r--r--gtk2_ardour/bundle_manager.cc6
-rw-r--r--gtk2_ardour/io_selector.cc36
-rw-r--r--gtk2_ardour/matrix.cc264
-rw-r--r--gtk2_ardour/matrix.h20
-rw-r--r--gtk2_ardour/port_group.h34
-rw-r--r--gtk2_ardour/port_matrix.cc251
-rw-r--r--gtk2_ardour/port_matrix.h18
-rw-r--r--gtk2_ardour/route_params_ui.cc4
9 files changed, 240 insertions, 394 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index 111722fd30..c6fb356cd9 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -217,6 +217,7 @@ playlist_selector.cc
plugin_selector.cc
plugin_ui.cc
port_matrix.cc
+port_group.cc
processor_box.cc
prompter.cc
public_editor.cc
diff --git a/gtk2_ardour/bundle_manager.cc b/gtk2_ardour/bundle_manager.cc
index 63c348decc..916413d835 100644
--- a/gtk2_ardour/bundle_manager.cc
+++ b/gtk2_ardour/bundle_manager.cc
@@ -89,14 +89,14 @@ void
BundleEditorMatrix::add_row ()
{
_bundle->add_channel ();
- redisplay ();
+ setup ();
}
void
BundleEditorMatrix::remove_row (int r)
{
_bundle->remove_channel (r);
- redisplay ();
+ setup ();
}
std::string
@@ -205,7 +205,7 @@ BundleEditor::type_changed ()
void
BundleEditor::on_map ()
{
- _matrix.redisplay ();
+ _matrix.setup ();
Window::on_map ();
}
diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc
index 954ddb6b9a..0e40aa6ad3 100644
--- a/gtk2_ardour/io_selector.cc
+++ b/gtk2_ardour/io_selector.cc
@@ -55,7 +55,7 @@ IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO>
const PortSet& ps (_io->outputs());
for (PortSet::const_iterator i = ps.begin(); i != ps.end(); ++i) {
- our_ports.push_back ((*i).name());
+ our_ports.push_back (i->name());
}
} else {
@@ -64,12 +64,14 @@ IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO>
const PortSet& ps (_io->inputs());
for (PortSet::const_iterator i = ps.begin(); i != ps.end(); ++i) {
- our_ports.push_back ((*i).name());
+ our_ports.push_back (i->name());
}
}
set_ports (our_ports);
+
+ setup ();
}
void
@@ -77,7 +79,7 @@ IOSelector::ports_changed (ARDOUR::IOChange change, void *src)
{
ENSURE_GUI_THREAD (bind (mem_fun (*this, &IOSelector::ports_changed), change, src));
- redisplay ();
+ setup ();
}
void
@@ -109,17 +111,7 @@ IOSelector::get_state (int r, std::string const & p) const
_io->input(r)->get_connections (connections);
}
- int k = 0;
- for (vector<string>::iterator i = connections.begin(); i != connections.end(); ++i) {
-
- if ((*i)== p) {
- return true;
- }
-
- ++k;
- }
-
- return false;
+ return (std::find (connections.begin (), connections.end (), p) != connections.end ());
}
uint32_t
@@ -160,9 +152,9 @@ IOSelector::row_name (int r) const
string::size_type pos;
if (!_offer_inputs) {
- n = _io->input(r)->short_name();
+ n = _io->input(r)->name();
} else {
- n = _io->output(r)->short_name();
+ n = _io->output(r)->name();
}
if ((pos = n.find ('/')) != string::npos) {
@@ -270,11 +262,11 @@ IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<
get_action_area()->pack_start (ok_button, false, false);
get_vbox()->set_spacing (8);
- get_vbox()->pack_start (_selector);
+ get_vbox()->pack_start (_selector, true, true);
suggestion.set_alignment (0.5, 0.5);
suggestion_box.pack_start (suggestion, true, true);
- get_vbox()->pack_start (suggestion_box);
+ get_vbox()->pack_start (suggestion_box, false, false);
ok_button.signal_clicked().connect (mem_fun(*this, &IOSelectorWindow::accept));
cancel_button.signal_clicked().connect (mem_fun(*this, &IOSelectorWindow::cancel));
@@ -329,7 +321,7 @@ IOSelectorWindow::ports_changed (ARDOUR::IOChange change, void *src)
void
IOSelectorWindow::rescan ()
{
- _selector.redisplay ();
+ _selector.setup ();
}
void
@@ -349,7 +341,7 @@ IOSelectorWindow::accept ()
void
IOSelectorWindow::on_map ()
{
- _selector.redisplay ();
+ _selector.setup ();
Window::on_map ();
}
@@ -382,8 +374,8 @@ PortInsertUI::PortInsertUI (ARDOUR::Session& sess, boost::shared_ptr<ARDOUR::Por
void
PortInsertUI::redisplay ()
{
- input_selector.redisplay();
- output_selector.redisplay();
+ input_selector.setup ();
+ output_selector.setup ();
}
void
diff --git a/gtk2_ardour/matrix.cc b/gtk2_ardour/matrix.cc
index c1436a1f74..b67081711a 100644
--- a/gtk2_ardour/matrix.cc
+++ b/gtk2_ardour/matrix.cc
@@ -9,12 +9,13 @@
#include <vector>
#include "matrix.h"
+#include "port_matrix.h"
using namespace std;
using namespace Gtk;
using namespace ARDOUR;
-Matrix::Matrix ()
+Matrix::Matrix (PortMatrix* p) : _port_matrix (p)
{
alloc_width = 0;
alloc_height = 0;
@@ -27,10 +28,12 @@ Matrix::Matrix ()
ystep = 0;
pixmap = 0;
drawn = false;
- angle_radians = M_PI/4.0;
+ angle_radians = M_PI / 4.0;
motion_x = -1;
motion_y = -1;
+ border = 10;
+
add_events (Gdk::POINTER_MOTION_MASK|Gdk::LEAVE_NOTIFY_MASK);
}
@@ -47,7 +50,10 @@ Matrix::add_group (PortGroup& pg)
for (vector<string>::const_iterator s = pg.ports.begin(); s != pg.ports.end(); ++s) {
others.push_back (OtherPort (*s, pg));
}
- reset_size ();
+
+ if (pg.visible) {
+ reset_size ();
+ }
}
@@ -68,7 +74,10 @@ Matrix::remove_group (PortGroup& pg)
++o;
}
}
- reset_size ();
+
+ if (pg.visible) {
+ reset_size ();
+ }
}
void
@@ -86,29 +95,23 @@ Matrix::show_group (PortGroup& pg)
void
Matrix::setup_nodes ()
{
- int n, x, y;
- list<string>::iterator m;
- list<OtherPort>::iterator s;
-
for (vector<MatrixNode*>::iterator p = nodes.begin(); p != nodes.end(); ++p) {
delete *p;
}
+
nodes.clear ();
- list<OtherPort>::size_type visible_others = 0;
-
- for (list<OtherPort>::iterator s = others.begin(); s != others.end(); ++s) {
- if ((*s).visible()) {
- ++visible_others;
- }
- }
-
- nodes.assign (ours.size() * visible_others, 0);
+ nodes.assign (ours.size() * get_visible_others (), 0);
+ int n, x, y;
+ list<string>::iterator m;
+ list<OtherPort>::iterator s;
+
for (n = 0, y = 0, m = ours.begin(); m != ours.end(); ++m, ++y) {
for (x = 0, s = others.begin(); s != others.end(); ++s) {
- if ((*s).visible()) {
- nodes[n] = new MatrixNode (*m, *s, x, y);
+ if (s->visible ()) {
+ bool const c = _port_matrix->get_state (y, s->name());
+ nodes[n] = new MatrixNode (*m, *s, c, x, y);
n++;
x++;
}
@@ -116,42 +119,99 @@ Matrix::setup_nodes ()
}
}
+
void
-Matrix::reset_size ()
+Matrix::other_name_size_information (double* rotated_width, double* rotated_height, double* typical_height) const
{
- list<OtherPort>::size_type visible_others = 0;
-
- for (list<OtherPort>::iterator s = others.begin(); s != others.end(); ++s) {
- if ((*s).visible()) {
- ++visible_others;
+ double w = 0;
+ double h = 0;
+
+ GdkPixmap* pm = gdk_pixmap_new (NULL, 1, 1, 24);
+ gdk_drawable_set_colormap (pm, gdk_colormap_get_system());
+ cairo_t* cr = gdk_cairo_create (pm);
+
+ for (list<OtherPort>::const_iterator s = others.begin(); s != others.end(); ++s) {
+ if (s->visible()) {
+
+ cairo_text_extents_t extents;
+ cairo_text_extents (cr, s->short_name().c_str(), &extents);
+
+ if (extents.width > w) {
+ w = extents.width;
+ h = extents.height;
+ }
}
}
+ cairo_destroy (cr);
+ gdk_pixmap_unref (pm);
+
+ /* transform */
+
+ *rotated_width = fabs (w * cos (angle_radians) + h * sin (angle_radians));
+ *rotated_height = fabs (w * sin (angle_radians) + h * cos (angle_radians));
+ *typical_height = h;
+}
+
+
+std::pair<int, int>
+Matrix::ideal_size () const
+{
+ double rw;
+ double rh;
+ double th;
+
+ other_name_size_information (&rw, &rh, &th);
+
+ double const ideal_xstep = th * 2;
+ double const ideal_ystep = 16;
+
+ uint32_t const visible_others = get_visible_others ();
+
+ return std::make_pair (
+ int (rw + (2 * border) + ideal_xstep * visible_others),
+ int (rh + (2 * border) + ideal_ystep * ours.size ())
+ );
+}
+
+
+void
+Matrix::reset_size ()
+{
+ double rw;
+ double rh;
+ double th;
+
+ other_name_size_information (&rw, &rh, &th);
+
+ /* y shift is the largest transformed text height plus a bit for luck */
+ labels_y_shift = int (ceil (rh) + 10);
+ /* x shift is the width of the leftmost label */
+ labels_x_shift = int (ceil (rw));
+
+ uint32_t const visible_others = get_visible_others ();
+
if (!visible_others) {
- cerr << "There are no visible others!\n";
xstep = 1;
ystep = 1;
line_width = 1;
line_height = 1;
- border = 10;
arc_radius = 3;
- labels_x_shift = 0;
- labels_y_shift = 0;
return;
}
- border = 10;
-
- if (alloc_width > line_width) {
+ if (ours.size () > 1) {
- xstep = (alloc_width - labels_x_shift - (2 * border) - (2 * arc_radius)) / visible_others;
- line_width = xstep * (others.size() - 1);
+ xstep = (alloc_width - labels_x_shift - (2 * border)) / visible_others;
+ line_width = xstep * (visible_others - 1);
- ystep = (alloc_height - labels_y_shift - (2 * border) - (2 * arc_radius)) / (ours.size() - 1);
+ ystep = (alloc_height - labels_y_shift - (2 * border)) / (ours.size() - 1);
line_height = ystep * (ours.size() - 1);
} else {
+ /* we have <= 1 of our ports, so steps don't matter */
+
xstep = 20;
ystep = 20;
@@ -159,7 +219,7 @@ Matrix::reset_size ()
line_width = visible_others * xstep;
}
- int half_step = min (ystep/2,xstep/2);
+ int half_step = min (ystep / 2, xstep / 2);
if (half_step > 3) {
arc_radius = half_step - 5;
} else {
@@ -168,53 +228,19 @@ Matrix::reset_size ()
arc_radius = min (arc_radius, 10);
- /* scan all the port names that will be rotated, and compute
- how much space we need for them
- */
-
- float w = 0;
- float h = 0;
- cairo_text_extents_t extents;
- cairo_t* cr;
- GdkPixmap* pm;
-
- pm = gdk_pixmap_new (NULL, 1, 1, 24);
- gdk_drawable_set_colormap (pm, gdk_colormap_get_system());
-
- cr = gdk_cairo_create (pm);
-
- for (list<OtherPort>::iterator s = others.begin(); s != others.end(); ++s) {
- if ((*s).visible()) {
- cairo_text_extents (cr, (*s).name().c_str(), &extents);
- w = max ((float) extents.width, w);
- h = max ((float) extents.height, h);
- }
- }
-
- cairo_destroy (cr);
- gdk_pixmap_unref (pm);
-
- /* transform */
-
- w = fabs (w * cos (angle_radians) + h * sin (angle_radians));
- h = fabs (w * sin (angle_radians) + h * cos (angle_radians));
-
- labels_y_shift = (int) ceil (h) + 10;
- labels_x_shift = (int) ceil (w);
setup_nodes ();
-
- cerr << "Based on ours = " << ours.size() << " others = " << others.size()
- << " dimens = "
- << " xstep " << xstep << endl
- << " ystep " << ystep << endl
- << " line_width " << line_width << endl
- << " line_height " << line_height << endl
- << " border " << border << endl
- << " arc_radius " << arc_radius << endl
- << " labels_x_shift " << labels_x_shift << endl
- << " labels_y_shift " << labels_y_shift << endl;
+ // cerr << "Based on ours = " << ours.size() << " others = " << others.size()
+ // << " dimens = "
+ // << " xstep " << xstep << endl
+ // << " ystep " << ystep << endl
+ // << " line_width " << line_width << endl
+ // << " line_height " << line_height << endl
+ // << " border " << border << endl
+ // << " arc_radius " << arc_radius << endl
+ // << " labels_x_shift " << labels_x_shift << endl
+ // << " labels_y_shift " << labels_y_shift << endl;
}
bool
@@ -238,32 +264,33 @@ Matrix::on_leave_notify_event (GdkEventCrossing *ev)
void
Matrix::on_size_request (Requisition* req)
{
- req->width = labels_x_shift + line_width + (2*border) + (2*arc_radius);
- req->height = labels_y_shift + line_height + (2*border) + (2*arc_radius);
+ std::pair<int, int> const is = ideal_size ();
+ req->width = is.first;
+ req->height = is.second;
}
MatrixNode*
Matrix::get_node (int32_t x, int32_t y)
{
- int half_xstep = xstep / 2;
- int half_ystep = ystep / 2;
+ int const half_xstep = xstep / 2;
+ int const half_ystep = ystep / 2;
- x -= labels_x_shift - border;
- if (x < half_xstep) {
+ x -= labels_x_shift + border;
+ if (x < -half_xstep) {
return 0;
}
- y -= labels_y_shift - border;
- if (y < half_ystep) {
+ y -= labels_y_shift + border;
+ if (y < -half_ystep) {
return 0;
}
- x = (x - half_xstep) / xstep;
- y = (y - half_ystep) / ystep;
+ x = (x + half_xstep) / xstep;
+ y = (y + half_ystep) / ystep;
- x = y*ours.size() + x;
+ x = y * get_visible_others () + x;
- if (x >= nodes.size()) {
+ if (x >= int32_t (nodes.size())) {
return 0;
}
@@ -276,11 +303,14 @@ Matrix::on_button_press_event (GdkEventButton* ev)
MatrixNode* node;
if ((node = get_node (ev->x, ev->y)) != 0) {
- cerr << "Event in node " << node->our_name() << " x " << node->their_name () << endl;
node->set_connected (!node->connected());
+ _port_matrix->set_state (node->y (), node->their_name (), node->connected (), 0);
drawn = false;
queue_draw();
- }
+ return true;
+ }
+
+ return false;
}
void
@@ -328,10 +358,8 @@ Matrix::redraw (GdkDrawable* drawable, GdkRectangle* rect)
list<string>::iterator o;
list<OtherPort>::iterator t;
int x, y;
- uint32_t top_shift, bottom_shift, left_shift, right_shift;
- cairo_t* cr;
- cr = gdk_cairo_create (drawable);
+ cairo_t* cr = gdk_cairo_create (drawable);
cairo_set_source_rgb (cr, 0.83, 0.83, 0.83);
cairo_rectangle (cr, rect->x, rect->y, rect->width, rect->height);
@@ -339,10 +367,8 @@ Matrix::redraw (GdkDrawable* drawable, GdkRectangle* rect)
cairo_set_line_width (cr, 0.5);
- top_shift = labels_y_shift + border;
- left_shift = labels_x_shift + border;
- bottom_shift = 0;
- right_shift = 0;
+ int32_t const top_shift = labels_y_shift + border;
+ int32_t const left_shift = labels_x_shift + border;
/* horizontal grid lines and side labels */
@@ -376,7 +402,7 @@ Matrix::redraw (GdkDrawable* drawable, GdkRectangle* rect)
cairo_save (cr);
cairo_rotate (cr, angle_radians);
- cairo_show_text (cr, (*t).name().c_str());
+ cairo_show_text (cr, t->short_name().c_str());
cairo_restore (cr);
}
@@ -394,10 +420,10 @@ Matrix::redraw (GdkDrawable* drawable, GdkRectangle* rect)
cairo_arc (cr, left_shift+x, top_shift+y, arc_radius, 0, 2.0 * M_PI);
if ((*n)->connected()) {
cairo_set_source_rgba (cr, 1.0, 0, 0, 1.0);
- cairo_stroke (cr);
+ cairo_fill (cr);
} else {
cairo_set_source_rgba (cr, 1.0, 0, 0, 0.7);
- cairo_fill (cr);
+ cairo_stroke (cr);
}
}
}
@@ -406,8 +432,8 @@ Matrix::redraw (GdkDrawable* drawable, GdkRectangle* rect)
if (motion_x >= left_shift && motion_y >= top_shift) {
- int col_left = left_shift + ((motion_x - left_shift) / xstep) * xstep;
- int row_top = top_shift + ((motion_y - top_shift) / ystep) * ystep;
+ int col_left = left_shift + ((motion_x + (xstep / 2) + - left_shift) / xstep) * xstep;
+ int row_top = top_shift + ((motion_y + (ystep / 2) - top_shift) / ystep) * ystep;
cairo_set_line_width (cr, 5);
cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.3);
@@ -457,3 +483,29 @@ Matrix::on_expose_event (GdkEventExpose* event)
return true;
}
+
+uint32_t
+Matrix::get_visible_others () const
+{
+ uint32_t v = 0;
+
+ for (list<OtherPort>::const_iterator s = others.begin(); s != others.end(); ++s) {
+ if (s->visible()) {
+ ++v;
+ }
+ }
+
+ return v;
+}
+
+MatrixNode::MatrixNode (std::string a, OtherPort o, bool c, int32_t x, int32_t y)
+ : _name (a), them (o), _connected (c), _x(x), _y(y)
+{
+
+}
+
+std::string
+OtherPort::name () const
+{
+ return _group.prefix + _short_name;
+}
diff --git a/gtk2_ardour/matrix.h b/gtk2_ardour/matrix.h
index cbd34823d1..a02f2fb397 100644
--- a/gtk2_ardour/matrix.h
+++ b/gtk2_ardour/matrix.h
@@ -11,24 +11,26 @@
#include "port_group.h"
+/// One of the other ports that we're connecting ours to
class OtherPort {
public:
OtherPort (const std::string& n, PortGroup& g)
- : _name (n), _group (g) {}
+ : _short_name (n), _group (g) {}
- std::string name() const { return _name; }
+ std::string name () const;
+ std::string short_name () const { return _short_name; }
PortGroup& group() const { return _group; }
bool visible() const { return _group.visible; }
public:
- std::string _name;
+ std::string _short_name;
PortGroup& _group;
};
+/// A node on the matrix
class MatrixNode {
public:
- MatrixNode (std::string a, OtherPort o, int32_t x, int32_t y)
- : _name (a), them (o), _connected (random()%3), _x(x), _y(y) {}
+ MatrixNode (std::string, OtherPort, bool, int32_t, int32_t);
~MatrixNode() {}
PortGroup& get_group() const { return them.group(); }
@@ -52,7 +54,7 @@ class MatrixNode {
class Matrix : public Gtk::EventBox
{
public:
- Matrix();
+ Matrix (PortMatrix*);
void set_ports (const std::list<std::string>&);
void add_group (PortGroup&);
@@ -74,7 +76,8 @@ class Matrix : public Gtk::EventBox
MatrixNode* get_node (int32_t x, int32_t y);
-private:
+private:
+ PortMatrix* _port_matrix; ///< the PortMatrix that we're working for
int height;
int width;
int alloc_width;
@@ -100,6 +103,9 @@ private:
void redraw (GdkDrawable*, GdkRectangle*);
void alloc_pixmap ();
void setup_nodes ();
+ uint32_t get_visible_others () const;
+ void other_name_size_information (double *, double *, double *) const;
+ std::pair<int, int> ideal_size () const;
GdkPixmap* pixmap;
};
diff --git a/gtk2_ardour/port_group.h b/gtk2_ardour/port_group.h
index d5334640b1..9a38bfc39a 100644
--- a/gtk2_ardour/port_group.h
+++ b/gtk2_ardour/port_group.h
@@ -1,3 +1,22 @@
+/*
+ Copyright (C) 2002-2009 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
#ifndef __gtk_ardour_port_group_h__
#define __gtk_ardour_port_group_h__
@@ -23,15 +42,16 @@ class PortGroup
public:
/** PortGroup constructor.
* @param n Name.
- * @param p Port name prefix.
+ * @param p Port name prefix (including trailing :)
* @param v true if group should be visible in the UI, otherwise false.
*/
- PortGroup (std::string const & n, std::string const & p, bool v) : name (n), prefix (p), visible (v) {}
+ PortGroup (std::string const & n, std::string const & p, bool v)
+ : name (n), prefix (p), visible (v) {}
void add (std::string const & p);
std::string name; ///< name for the group
- std::string prefix; ///< prefix (before colon) e.g. "ardour:"
+ std::string prefix; ///< prefix e.g. "ardour:"
std::vector<std::string> ports; ///< port names
bool visible; ///< true if the group is visible in the UI
};
@@ -81,10 +101,10 @@ class PortGroupList : public std::list<PortGroup*>
ARDOUR::DataType _type;
bool _offer_inputs;
- PortGroup buss;
- PortGroup track;
- PortGroup system;
- PortGroup other;
+ PortGroup _buss;
+ PortGroup _track;
+ PortGroup _system;
+ PortGroup _other;
};
#endif /* __gtk_ardour_port_group_h__ */
diff --git a/gtk2_ardour/port_matrix.cc b/gtk2_ardour/port_matrix.cc
index f3bcce8105..e04dd3b252 100644
--- a/gtk2_ardour/port_matrix.cc
+++ b/gtk2_ardour/port_matrix.cc
@@ -19,96 +19,20 @@
#include <gtkmm/label.h>
#include <gtkmm/enums.h>
-#include <gtkmm/image.h>
-#include <gtkmm/stock.h>
-#include <gtkmm/messagedialog.h>
#include <gtkmm/menu.h>
#include <gtkmm/menu_elems.h>
#include <gtkmm/menuitem.h>
#include <gtkmm/menushell.h>
#include <glibmm/objectbase.h>
#include <gtkmm2ext/doi.h>
-#include <ardour/port_insert.h>
-#include "ardour/session.h"
-#include "ardour/io.h"
-#include "ardour/audioengine.h"
-#include "ardour/track.h"
-#include "ardour/audio_track.h"
-#include "ardour/midi_track.h"
#include "ardour/data_type.h"
-#include "io_selector.h"
-#include "keyboard.h"
-#include "utils.h"
-#include "gui_thread.h"
#include "i18n.h"
+#include "port_matrix.h"
using namespace Gtk;
-/** Add a port to a group.
- * @param p Port name, with or without prefix.
- */
-
-void
-PortGroup::add (std::string const & p)
-{
- if (prefix.empty() == false && p.substr (0, prefix.length()) == prefix) {
- ports.push_back (p.substr (prefix.length()));
- } else {
- ports.push_back (p);
- }
-}
-
-/** PortGroupUI constructor.
- * @param m PortMatrix to work for.
- * @Param g PortGroup to represent.
- */
-
-PortGroupUI::PortGroupUI (PortMatrix& m, PortGroup& g)
- : _port_matrix (m)
- , _port_group (g)
- , _ignore_check_button_toggle (false)
- , _visibility_checkbutton (g.name)
-{
- _port_group.visible = true;
- _ignore_check_button_toggle = false;
- _visibility_checkbutton.signal_toggled().connect (sigc::mem_fun (*this, &PortGroupUI::visibility_checkbutton_toggled));
-}
-
-/** The visibility of a PortGroupUI has been toggled */
-void
-PortGroupUI::visibility_checkbutton_toggled ()
-{
- _port_group.visible = _visibility_checkbutton.get_active ();
-}
-
-/** @return Checkbutton used to toggle visibility */
-Widget&
-PortGroupUI::get_visibility_checkbutton ()
-{
- return _visibility_checkbutton;
-}
-
-
-/** Handle a toggle of a port check button */
-void
-PortGroupUI::port_checkbutton_toggled (CheckButton* b, int r, int c)
-{
- if (_ignore_check_button_toggle == false) {
- // _port_matrix.hide_group (_port_group);
- }
-}
-
-/** Set up visibility of the port group according to PortGroup::visible */
-void
-PortGroupUI::setup_visibility ()
-{
- if (_visibility_checkbutton.get_active () != _port_group.visible) {
- _visibility_checkbutton.set_active (_port_group.visible);
- }
-}
-
PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type, bool offer_inputs, PortGroupList::Mask mask)
- : _offer_inputs (offer_inputs), _port_group_list (session, type, offer_inputs, mask), _type (type)
+ : _offer_inputs (offer_inputs), _port_group_list (session, type, offer_inputs, mask), _type (type), matrix (this)
{
_side_vbox_pad = 0;
@@ -165,6 +89,9 @@ PortMatrix::clear ()
void
PortMatrix::setup ()
{
+ /* sort out the ports that we'll offer to connect to */
+ _port_group_list.refresh ();
+
clear ();
_side_vbox_pad = new Label (""); /* unmanaged, explicitly deleted */
@@ -174,7 +101,7 @@ PortMatrix::setup ()
matrix.clear ();
- /* Checkbutton tables and visibility checkbuttons */
+ /* Matrix and visibility checkbuttons */
for (PortGroupList::iterator i = _port_group_list.begin(); i != _port_group_list.end(); ++i) {
PortGroupUI* t = new PortGroupUI (*this, **i);
@@ -212,13 +139,6 @@ PortMatrix::reset_visibility ()
}
}
-void
-PortMatrix::redisplay ()
-{
- _port_group_list.refresh ();
- setup ();
-}
-
/** Handle a button press on a row label */
bool
@@ -258,7 +178,7 @@ PortMatrix::set_type (ARDOUR::DataType t)
{
_type = t;
_port_group_list.set_type (t);
- redisplay ();
+ setup ();
}
void
@@ -266,161 +186,6 @@ PortMatrix::set_offer_inputs (bool i)
{
_offer_inputs = i;
_port_group_list.set_offer_inputs (i);
- redisplay ();
-}
-
-/** PortGroupList constructor.
- * @param session Session to get ports from.
- * @param type Type of ports to offer (audio or MIDI)
- * @param offer_inputs true to offer output ports, otherwise false.
- * @param mask Mask of groups to make visible by default.
- */
-
-PortGroupList::PortGroupList (ARDOUR::Session & session, ARDOUR::DataType type, bool offer_inputs, Mask mask)
- : _session (session), _type (type), _offer_inputs (offer_inputs),
- buss (_("Bus"), "ardour:", mask & BUSS),
- track (_("Track"), "ardour:", mask & TRACK),
- system (_("System"), "system:", mask & SYSTEM),
- other (_("Other"), "", mask & OTHER)
-{
- refresh ();
-}
-
-void
-PortGroupList::refresh ()
-{
- clear ();
-
- buss.ports.clear ();
- track.ports.clear ();
- system.ports.clear ();
- other.ports.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 ();
-
- cerr << "Looking for arour routes\n";
-
- for (ARDOUR::Session::RouteList::const_iterator i = routes->begin(); i != routes->end(); ++i) {
-
- PortGroup* g = 0;
-
- if (_type == ARDOUR::DataType::AUDIO) {
-
- if (boost::dynamic_pointer_cast<ARDOUR::AudioTrack> (*i)) {
- g = &track;
- } else if (!boost::dynamic_pointer_cast<ARDOUR::MidiTrack>(*i)) {
- g = &buss;
- }
-
-
- } else if (_type == ARDOUR::DataType::MIDI) {
-
- if (boost::dynamic_pointer_cast<ARDOUR::MidiTrack> (*i)) {
- g = &track;
- }
-
- /* No MIDI busses yet */
- }
-
- if (g) {
- ARDOUR::PortSet const & p = _offer_inputs ? ((*i)->inputs()) : ((*i)->outputs());
- for (uint32_t j = 0; j < p.num_ports(); ++j) {
- g->add (p.port(j)->name ());
- }
-
- 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 ("", _type.to_jack_type(), _offer_inputs ?
- JackPortIsInput : JackPortIsOutput);
- if (ports) {
-
- int n = 0;
- string client_matching_string;
-
- client_matching_string = _session.engine().client_name();
- client_matching_string += ':';
-
- while (ports[n]) {
- std::string const p = ports[n];
-
- if (p.substr(0, strlen ("system:")) == "system:") {
- /* system: prefix */
- system.add (p);
- } else {
- if (p.substr(0, client_matching_string.length()) != client_matching_string) {
- /* other (non-ardour) prefix */
- other.add (p);
- }
- }
-
- ++n;
- }
-
- free (ports);
- }
-
- push_back (&system);
- push_back (&buss);
- push_back (&track);
- push_back (&other);
-}
-
-int
-PortGroupList::n_visible_ports () const
-{
- int n = 0;
-
- for (const_iterator i = begin(); i != end(); ++i) {
- if ((*i)->visible) {
- n += (*i)->ports.size();
- }
- }
-
- return n;
-}
-
-std::string
-PortGroupList::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 "";
-}
-
-void
-PortGroupList::set_type (ARDOUR::DataType t)
-{
- _type = t;
-}
-
-void
-PortGroupList::set_offer_inputs (bool i)
-{
- _offer_inputs = i;
+ setup ();
}
diff --git a/gtk2_ardour/port_matrix.h b/gtk2_ardour/port_matrix.h
index f20c88055f..27f295b89d 100644
--- a/gtk2_ardour/port_matrix.h
+++ b/gtk2_ardour/port_matrix.h
@@ -42,7 +42,7 @@ class PortMatrix : public Gtk::VBox {
PortMatrix (ARDOUR::Session&, ARDOUR::DataType, bool, PortGroupList::Mask);
~PortMatrix ();
- void redisplay ();
+ void setup ();
enum Result {
Cancelled,
@@ -55,8 +55,19 @@ class PortMatrix : public Gtk::VBox {
void set_offer_inputs (bool);
bool offering_input() const { return _offer_inputs; }
- virtual void set_state (int, std::string const &, bool, uint32_t) = 0;
- virtual bool get_state (int, std::string const &) const = 0;
+ /** @param r Our row index.
+ * @param p Other port.
+ * @param s New state.
+ * @param k XXX
+ */
+ virtual void set_state (int r, std::string const & p, bool s, uint32_t k) = 0;
+
+ /** @param r Our row index.
+ * @param p Other port.
+ * @return true if r is connected to p, otherwise false.
+ */
+ virtual bool get_state (int r, std::string const &p) const = 0;
+
virtual uint32_t n_rows () const = 0;
virtual uint32_t maximum_rows () const = 0;
virtual uint32_t minimum_rows () const = 0;
@@ -86,7 +97,6 @@ class PortMatrix : public Gtk::VBox {
Gtk::Label* _side_vbox_pad;
Gtk::HBox _visibility_checkbutton_box;
- void setup ();
void clear ();
bool row_label_button_pressed (GdkEventButton*, int);
void reset_visibility ();
diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc
index 00a4858c42..670635fb4d 100644
--- a/gtk2_ardour/route_params_ui.cc
+++ b/gtk2_ardour/route_params_ui.cc
@@ -321,13 +321,13 @@ RouteParams_UI::setup_io_frames()
// input
_input_iosel = new IOSelector (*session, _route, true);
- _input_iosel->redisplay ();
+ _input_iosel->setup ();
input_frame.add (*_input_iosel);
input_frame.show_all();
// output
_output_iosel = new IOSelector (*session, _route, false);
- _output_iosel->redisplay ();
+ _output_iosel->setup ();
output_frame.add (*_output_iosel);
output_frame.show_all();
}