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