1 /*
2  * Copyright (C) 2018-2019 Paul Davis <paul@linuxaudiosystems.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef __ardour_gtk_transport_masters_dialog_h__
20 #define __ardour_gtk_transport_masters_dialog_h__
21 
22 #include <vector>
23 #include <string>
24 
25 #include <gtkmm/button.h>
26 #include <gtkmm/eventbox.h>
27 #include <gtkmm/radiobutton.h>
28 #include <gtkmm/label.h>
29 #include <gtkmm/table.h>
30 #include <gtkmm/entry.h>
31 #include <gtkmm/treestore.h>
32 
33 #include "widgets/ardour_button.h"
34 
35 #include "ardour_window.h"
36 
37 namespace Gtk {
38 	class Menu;
39 }
40 
41 namespace ARDOUR {
42 	class TransportMaster;
43 }
44 
45 class FloatingTextEntry;
46 
47 class TransportMastersWidget : public Gtk::VBox, public ARDOUR::SessionHandlePtr
48 {
49   public:
50 	TransportMastersWidget ();
51 	~TransportMastersWidget ();
52 
53 	void update (ARDOUR::samplepos_t);
54 	void set_transport_master (boost::shared_ptr<ARDOUR::TransportMaster>);
55 
56 	void set_session (ARDOUR::Session*);
57 
58   protected:
59 	void on_map ();
60 	void on_unmap ();
61 
62   private:
63 
64 	struct AddTransportMasterDialog : public ArdourDialog {
65 	  public:
66 		AddTransportMasterDialog ();
67 		std::string get_name () const;
68 		ARDOUR::SyncSource get_type () const;
69 
70 	  private:
71 		Gtk::Label name_label;
72 		Gtk::Label type_label;
73 		Gtk::HBox name_hbox;
74 		Gtk::HBox type_hbox;
75 		Gtk::Entry name_entry;
76 		Gtk::ComboBoxText type_combo;
77 	};
78 
79 	struct Row : sigc::trackable, PBD::ScopedConnectionList {
80 		TransportMastersWidget& parent;
81 		Gtk::EventBox label_box;
82 		Gtk::EventBox current_box;
83 		Gtk::EventBox last_box;
84 		Gtk::Label label;
85 		Gtk::Label type;
86 		Gtk::Label format;
87 		Gtk::Label current;
88 		Gtk::Label last;
89 		Gtk::RadioButton use_button;
90 		Gtk::ComboBoxText port_combo;
91 		Gtk::CheckButton sclock_synced_button;
92 		Gtk::CheckButton fr2997_button;
93 		ArdourWidgets::ArdourButton request_options;
94 		Gtk::Menu* request_option_menu;
95 		ArdourWidgets::ArdourButton remove_button;
96 		FloatingTextEntry* name_editor;
97 		samplepos_t save_when;
98 		std::string save_last;
99 
100 		void build_request_options();
101 		void mod_request_type (ARDOUR::TransportRequestType);
102 
103 		boost::shared_ptr<ARDOUR::TransportMaster> tm;
104 
105 		void update (ARDOUR::Session*, ARDOUR::samplepos_t);
106 
107 		Row (TransportMastersWidget& parent);
108 		~Row ();
109 
110 		void populate_port_combo ();
111 		void build_port_list (ARDOUR::DataType);
112 
113 		void use_button_toggled ();
114 		void collect_button_toggled ();
115 		void sync_button_toggled ();
116 		void fr2997_button_toggled ();
117 		void port_choice_changed ();
118 		void connection_handler ();
119 		bool request_option_press (GdkEventButton*);
120 		void prop_change (PBD::PropertyChange);
121 		void remove_clicked ();
122 
123 		bool name_press (GdkEventButton*);
124 		void name_edited (std::string, int);
125 
126 		PBD::ScopedConnection property_change_connection;
127 		bool ignore_active_change;
128 
129 		bool port_combo_proxy (GdkEventButton*);
130 	};
131 
132 	std::vector<Row*> rows;
133 
134 	Gtk::Table table;
135 	Gtk::Label col_title[14];
136 	float align[14];
137 	ArdourWidgets::ArdourButton add_master_button;
138 	Gtk::CheckButton lost_sync_button;
139 
140 	sigc::connection update_connection;
141 	PBD::ScopedConnection current_connection;
142 	PBD::ScopedConnection add_connection;
143 	PBD::ScopedConnection remove_connection;
144 	PBD::ScopedConnection engine_running_connection;
145 
146 	struct PortColumns : public Gtk::TreeModel::ColumnRecord {
PortColumnsPortColumns147 		PortColumns() {
148 			add (short_name);
149 			add (full_name);
150 		}
151 		Gtk::TreeModelColumn<std::string> short_name;
152 		Gtk::TreeModelColumn<std::string> full_name;
153 	};
154 
155 	PortColumns port_columns;
156 
157 	friend class Row;
158 	Glib::RefPtr<Gtk::ListStore> midi_port_store;
159 	Glib::RefPtr<Gtk::ListStore> audio_port_store;
160 
161 	PBD::ScopedConnectionList port_reg_connection;
162 	void update_ports ();
163 	bool ignore_active_change;
164 	void build_port_model (Glib::RefPtr<Gtk::ListStore>, std::vector<std::string> const &);
165 
166 	void rebuild ();
167 	void clear ();
168 	void current_changed (boost::shared_ptr<ARDOUR::TransportMaster> old_master, boost::shared_ptr<ARDOUR::TransportMaster> new_master);
169 	void add_master ();
170 	void update_usability ();
171 	void allow_master_select (bool);
172 
173 	void lost_sync_changed ();
174 	void lost_sync_button_toggled ();
175 	void param_changed (std::string const &);
176 	PBD::ScopedConnection config_connection;
177 	PBD::ScopedConnection session_config_connection;
178 
179   public:
180 	bool idle_remove (Row*);
181 };
182 
183 class TransportMastersWindow : public ArdourWindow
184 {
185   public:
186 	TransportMastersWindow ();
187 
188 	void set_session (ARDOUR::Session*);
189 
190   protected:
191 	void on_realize ();
192 
193   private:
194 	TransportMastersWidget w;
195 };
196 
197 
198 #endif /* __ardour_gtk_transport_masters_dialog_h__ */
199