2007-10-19 09:30:07 -04:00
|
|
|
/*
|
2019-08-02 17:26:43 -04:00
|
|
|
* Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
|
|
|
|
* Copyright (C) 2008-2012 Paul Davis <paul@linuxaudiosystems.com>
|
|
|
|
* Copyright (C) 2009-2011 David Robillard <d@drobilla.net>
|
|
|
|
*
|
|
|
|
* 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.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
2007-10-19 09:30:07 -04:00
|
|
|
|
2024-09-25 20:38:59 -04:00
|
|
|
#pragma once
|
2007-10-19 09:30:07 -04:00
|
|
|
|
2009-01-20 09:46:00 -05:00
|
|
|
#include <list>
|
2023-02-16 12:59:41 -05:00
|
|
|
#include <memory>
|
|
|
|
|
2007-10-19 09:30:07 -04:00
|
|
|
#include <gtkmm/box.h>
|
2009-01-20 09:46:00 -05:00
|
|
|
#include <gtkmm/scrollbar.h>
|
2009-01-30 10:08:09 -05:00
|
|
|
#include <gtkmm/table.h>
|
|
|
|
#include <gtkmm/label.h>
|
|
|
|
#include <gtkmm/checkbutton.h>
|
2009-11-18 08:35:31 -05:00
|
|
|
#include <gtkmm/notebook.h>
|
2009-12-17 13:24:23 -05:00
|
|
|
|
2009-02-04 12:05:26 -05:00
|
|
|
#include "ardour/bundle.h"
|
2009-11-30 18:16:28 -05:00
|
|
|
#include "ardour/types.h"
|
2009-12-17 13:24:23 -05:00
|
|
|
#include "ardour/session_handle.h"
|
|
|
|
|
2008-12-08 11:07:28 -05:00
|
|
|
#include "port_group.h"
|
2009-05-03 10:31:42 -04:00
|
|
|
#include "port_matrix_types.h"
|
2009-01-20 09:46:00 -05:00
|
|
|
|
|
|
|
/** The `port matrix' UI. This is a widget which lets the user alter
|
|
|
|
* associations between one set of ports and another. e.g. to connect
|
|
|
|
* things together.
|
|
|
|
*
|
|
|
|
* It is made up of a body, PortMatrixBody, which is rendered using cairo,
|
2009-01-30 10:08:09 -05:00
|
|
|
* and some scrollbars and other stuff. All of this is arranged inside the
|
2009-05-03 10:31:42 -04:00
|
|
|
* Table that we inherit from.
|
2009-01-20 09:46:00 -05:00
|
|
|
*/
|
2007-10-19 09:30:07 -04:00
|
|
|
|
|
|
|
namespace ARDOUR {
|
2009-01-20 09:46:00 -05:00
|
|
|
class Bundle;
|
2007-10-19 09:30:07 -04:00
|
|
|
}
|
|
|
|
|
2009-12-14 11:44:20 -05:00
|
|
|
namespace Gtk {
|
|
|
|
namespace Menu_Helpers {
|
|
|
|
class MenuList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-04 12:05:26 -05:00
|
|
|
class PortMatrixBody;
|
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
class PortMatrix : public Gtk::Table, public ARDOUR::SessionHandlePtr
|
2009-01-20 09:46:00 -05:00
|
|
|
{
|
|
|
|
public:
|
2009-12-04 22:04:54 -05:00
|
|
|
PortMatrix (Gtk::Window*, ARDOUR::Session *, ARDOUR::DataType);
|
2007-10-19 09:30:07 -04:00
|
|
|
~PortMatrix ();
|
|
|
|
|
2009-01-20 09:46:00 -05:00
|
|
|
void set_type (ARDOUR::DataType);
|
2009-01-25 01:47:11 -05:00
|
|
|
|
|
|
|
ARDOUR::DataType type () const {
|
|
|
|
return _type;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-01-20 09:46:00 -05:00
|
|
|
void disassociate_all ();
|
2009-01-30 10:08:09 -05:00
|
|
|
void setup_scrollbars ();
|
2009-11-18 08:35:31 -05:00
|
|
|
void popup_menu (ARDOUR::BundleChannel, ARDOUR::BundleChannel, uint32_t);
|
2007-10-19 09:30:07 -04:00
|
|
|
|
2009-02-09 21:09:46 -05:00
|
|
|
int min_height_divisor () const {
|
|
|
|
return _min_height_divisor;
|
|
|
|
}
|
|
|
|
void set_min_height_divisor (int f) {
|
|
|
|
_min_height_divisor = f;
|
|
|
|
}
|
|
|
|
|
2009-01-30 10:08:09 -05:00
|
|
|
enum Arrangement {
|
|
|
|
TOP_TO_RIGHT, ///< column labels on top, row labels to the right
|
|
|
|
LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom
|
2007-10-19 09:30:07 -04:00
|
|
|
};
|
|
|
|
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-01-30 10:08:09 -05:00
|
|
|
/** @return Arrangement in use */
|
|
|
|
Arrangement arrangement () const {
|
|
|
|
return _arrangement;
|
|
|
|
}
|
2007-10-19 09:30:07 -04:00
|
|
|
|
2009-05-03 10:31:42 -04:00
|
|
|
bool show_only_bundles () const {
|
|
|
|
return _show_only_bundles;
|
|
|
|
}
|
|
|
|
|
2009-01-30 10:08:09 -05:00
|
|
|
PortGroupList const * columns () const;
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<const PortGroup> visible_columns () const;
|
2009-01-30 10:08:09 -05:00
|
|
|
|
|
|
|
/** @return index into the _ports array for the list which is displayed as columns */
|
|
|
|
int column_index () const {
|
|
|
|
return _column_index;
|
|
|
|
}
|
|
|
|
|
|
|
|
PortGroupList const * rows () const;
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<const PortGroup> visible_rows () const;
|
2009-01-30 10:08:09 -05:00
|
|
|
|
|
|
|
/** @return index into the _ports array for the list which is displayed as rows */
|
|
|
|
int row_index () const {
|
|
|
|
return _row_index;
|
|
|
|
}
|
2009-02-02 20:55:25 -05:00
|
|
|
|
|
|
|
PortGroupList const * ports (int d) const {
|
|
|
|
return &_ports[d];
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<const PortGroup> visible_ports (int d) const;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-11-18 08:35:31 -05:00
|
|
|
void init ();
|
2009-02-08 22:18:10 -05:00
|
|
|
void setup ();
|
|
|
|
virtual void setup_ports (int) = 0;
|
|
|
|
void setup_all_ports ();
|
2009-01-30 10:08:09 -05:00
|
|
|
|
2009-07-17 18:54:45 -04:00
|
|
|
std::pair<uint32_t, uint32_t> max_size () const;
|
|
|
|
|
2010-06-30 21:14:14 -04:00
|
|
|
bool should_show (ARDOUR::DataType) const;
|
|
|
|
uint32_t count_of_our_type (ARDOUR::ChanCount) const;
|
2011-08-13 16:19:39 -04:00
|
|
|
uint32_t count_of_our_type_min_1 (ARDOUR::ChanCount) const;
|
2010-06-30 21:14:14 -04:00
|
|
|
|
2010-12-10 12:27:13 -05:00
|
|
|
PortMatrixNode::State get_association (PortMatrixNode) const;
|
|
|
|
|
2012-06-20 18:01:22 -04:00
|
|
|
void flip ();
|
|
|
|
bool key_press (GdkEventKey *);
|
|
|
|
|
2009-01-30 10:08:09 -05:00
|
|
|
/** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
|
2009-01-12 20:15:19 -05:00
|
|
|
* @param s New state.
|
|
|
|
*/
|
2009-01-30 10:08:09 -05:00
|
|
|
virtual void set_state (ARDOUR::BundleChannel c[2], bool s) = 0;
|
2009-01-20 09:46:00 -05:00
|
|
|
|
2009-01-30 10:08:09 -05:00
|
|
|
/** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
|
2009-01-23 16:24:11 -05:00
|
|
|
* @return state
|
2009-01-12 20:15:19 -05:00
|
|
|
*/
|
2009-05-03 10:31:42 -04:00
|
|
|
virtual PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const = 0;
|
2009-02-08 22:18:10 -05:00
|
|
|
virtual bool list_is_global (int) const = 0;
|
2009-01-20 09:46:00 -05:00
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
virtual bool can_add_channels (std::shared_ptr<ARDOUR::Bundle>) const;
|
|
|
|
virtual void add_channel (std::shared_ptr<ARDOUR::Bundle>, ARDOUR::DataType);
|
|
|
|
virtual bool can_remove_channels (std::shared_ptr<ARDOUR::Bundle>) const;
|
2009-07-19 20:22:09 -04:00
|
|
|
virtual void remove_channel (ARDOUR::BundleChannel);
|
2023-02-16 18:33:28 -05:00
|
|
|
virtual void remove_all_channels (std::weak_ptr<ARDOUR::Bundle>);
|
|
|
|
virtual bool can_rename_channels (std::shared_ptr<ARDOUR::Bundle>) const {
|
2009-07-19 20:22:09 -04:00
|
|
|
return false;
|
|
|
|
}
|
2023-02-16 18:33:28 -05:00
|
|
|
virtual bool can_add_port (std::shared_ptr<ARDOUR::Bundle>, ARDOUR::DataType t) const;
|
2009-01-30 10:08:09 -05:00
|
|
|
virtual void rename_channel (ARDOUR::BundleChannel) {}
|
2009-07-19 15:07:31 -04:00
|
|
|
virtual std::string disassociation_verb () const = 0;
|
2010-05-07 21:20:33 -04:00
|
|
|
virtual std::string channel_noun () const;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-01-30 10:08:09 -05:00
|
|
|
enum Result {
|
|
|
|
Cancelled,
|
|
|
|
Accepted
|
|
|
|
};
|
|
|
|
|
|
|
|
sigc::signal<void, Result> Finished;
|
2008-10-01 05:18:30 -04:00
|
|
|
|
2023-02-16 18:33:28 -05:00
|
|
|
static bool bundle_with_channels (std::shared_ptr<ARDOUR::Bundle>);
|
2011-08-13 16:19:39 -04:00
|
|
|
|
2009-01-20 09:46:00 -05:00
|
|
|
protected:
|
2009-01-23 16:24:11 -05:00
|
|
|
|
2009-01-30 10:08:09 -05:00
|
|
|
/** We have two port group lists. One will be presented on the rows of the matrix,
|
|
|
|
the other on the columns. The PortMatrix chooses the arrangement based on which has
|
|
|
|
more ports in it. Subclasses must fill these two lists with the port groups that they
|
|
|
|
wish to present. The PortMatrix will arrange its layout such that signal flow is vaguely
|
|
|
|
from left to right as you go from list 0 to list 1. Hence subclasses which deal with
|
|
|
|
inputs and outputs should put outputs in list 0 and inputs in list 1. */
|
|
|
|
PortGroupList _ports[2];
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-01-20 09:46:00 -05:00
|
|
|
private:
|
2007-10-19 09:30:07 -04:00
|
|
|
|
2009-01-20 09:46:00 -05:00
|
|
|
void hscroll_changed ();
|
|
|
|
void vscroll_changed ();
|
2009-01-27 12:37:07 -05:00
|
|
|
void routes_changed ();
|
2009-01-30 10:08:09 -05:00
|
|
|
void reconnect_to_routes ();
|
|
|
|
void select_arrangement ();
|
2023-02-16 18:33:28 -05:00
|
|
|
bool can_add_port_proxy (std::weak_ptr<ARDOUR::Bundle>, ARDOUR::DataType) const;
|
|
|
|
void add_channel_proxy (std::weak_ptr<ARDOUR::Bundle>, ARDOUR::DataType);
|
|
|
|
void remove_channel_proxy (std::weak_ptr<ARDOUR::Bundle>, uint32_t);
|
|
|
|
void rename_channel_proxy (std::weak_ptr<ARDOUR::Bundle>, uint32_t);
|
|
|
|
void disassociate_all_on_channel (std::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
|
|
|
|
void disassociate_all_on_bundle (std::weak_ptr<ARDOUR::Bundle>, int);
|
2009-02-08 22:18:10 -05:00
|
|
|
void setup_global_ports ();
|
2013-10-20 09:19:43 -04:00
|
|
|
void setup_global_ports_proxy ();
|
2009-07-17 18:54:45 -04:00
|
|
|
void toggle_show_only_bundles ();
|
2009-07-19 15:07:31 -04:00
|
|
|
bool on_scroll_event (GdkEventScroll *);
|
2023-02-16 18:33:28 -05:00
|
|
|
std::shared_ptr<ARDOUR::IO> io_from_bundle (std::shared_ptr<ARDOUR::Bundle>) const;
|
2009-11-18 08:35:31 -05:00
|
|
|
void setup_notebooks ();
|
|
|
|
void remove_notebook_pages (Gtk::Notebook &);
|
2009-12-07 13:35:42 -05:00
|
|
|
void notebook_page_selected (GtkNotebookPage *, guint);
|
2009-11-30 18:16:28 -05:00
|
|
|
void route_processors_changed (ARDOUR::RouteProcessorChange);
|
2009-12-06 19:41:50 -05:00
|
|
|
void body_dimensions_changed ();
|
2009-12-04 22:04:54 -05:00
|
|
|
void session_going_away ();
|
2023-02-16 18:33:28 -05:00
|
|
|
void add_remove_option (Gtk::Menu_Helpers::MenuList &, std::weak_ptr<ARDOUR::Bundle>, int);
|
|
|
|
void add_disassociate_option (Gtk::Menu_Helpers::MenuList &, std::weak_ptr<ARDOUR::Bundle>, int, int);
|
2010-04-05 11:23:54 -04:00
|
|
|
void port_connected_or_disconnected ();
|
2012-05-21 17:50:29 -04:00
|
|
|
void update_tab_highlighting ();
|
2012-06-20 18:01:22 -04:00
|
|
|
std::pair<int, int> check_flip () const;
|
|
|
|
bool can_flip () const;
|
2020-01-10 19:15:17 -05:00
|
|
|
void parameter_changed (std::string);
|
2009-01-25 01:47:11 -05:00
|
|
|
|
2009-07-21 21:28:31 -04:00
|
|
|
Gtk::Window* _parent;
|
|
|
|
|
2012-06-20 18:01:22 -04:00
|
|
|
/** port type that we are working with, or NIL if we are working with all of them */
|
2007-10-19 09:30:07 -04:00
|
|
|
ARDOUR::DataType _type;
|
2009-12-17 13:24:23 -05:00
|
|
|
PBD::ScopedConnectionList _route_connections;
|
2009-12-19 15:26:31 -05:00
|
|
|
PBD::ScopedConnectionList _changed_connections;
|
|
|
|
PBD::ScopedConnectionList _bundle_changed_connections;
|
2009-01-20 09:46:00 -05:00
|
|
|
|
2009-02-04 12:05:26 -05:00
|
|
|
PortMatrixBody* _body;
|
2009-01-20 09:46:00 -05:00
|
|
|
Gtk::HScrollbar _hscroll;
|
|
|
|
Gtk::VScrollbar _vscroll;
|
2009-11-18 08:35:31 -05:00
|
|
|
Gtk::Notebook _vnotebook;
|
|
|
|
Gtk::Notebook _hnotebook;
|
|
|
|
Gtk::Label _vlabel;
|
|
|
|
Gtk::Label _hlabel;
|
2009-11-18 09:04:59 -05:00
|
|
|
Gtk::VBox _vbox;
|
|
|
|
Gtk::HBox _hbox;
|
2009-12-06 19:41:50 -05:00
|
|
|
Gtk::Label _hspacer;
|
|
|
|
Gtk::Label _vspacer;
|
2009-01-30 10:08:09 -05:00
|
|
|
Gtk::Menu* _menu;
|
|
|
|
Arrangement _arrangement;
|
|
|
|
int _row_index;
|
|
|
|
int _column_index;
|
2009-02-09 21:09:46 -05:00
|
|
|
int _min_height_divisor;
|
2009-05-03 10:31:42 -04:00
|
|
|
bool _show_only_bundles;
|
2009-07-17 18:54:45 -04:00
|
|
|
bool _inhibit_toggle_show_only_bundles;
|
2009-12-04 17:37:52 -05:00
|
|
|
bool _ignore_notebook_page_selected;
|
2007-10-19 09:30:07 -04:00
|
|
|
};
|
|
|
|
|