1 /*
2  * Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
3  * Copyright (C) 2009-2011 David Robillard <d@drobilla.net>
4  * Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com>
5  * Copyright (C) 2014-2019 Robin Gareus <robin@gareus.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #ifndef __ardour_gtk_editor_route_h__
23 #define __ardour_gtk_editor_route_h__
24 
25 #include <gtkmm/liststore.h>
26 #include <gtkmm/scrolledwindow.h>
27 #include <gtkmm/treemodel.h>
28 #include <gtkmm/treestore.h>
29 
30 #include "pbd/signals.h"
31 #include "gtkmm2ext/widget_state.h"
32 
33 #include "editor_component.h"
34 
35 class VCATimeAxisView;
36 
37 class EditorRoutes : public EditorComponent, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr
38 {
39 public:
40 	EditorRoutes (Editor *);
41 	~EditorRoutes ();
42 
43 	void set_session (ARDOUR::Session *);
44 
widget()45 	Gtk::Widget& widget () {
46 		return _scroller;
47 	}
48 
49 	void move_selected_tracks (bool);
50 	void show_track_in_display (TimeAxisView &);
51 
52 
suspend_redisplay()53 	void suspend_redisplay () {
54 		if (!_no_redisplay) {
55 			_no_redisplay = true;
56 			_redisplay_on_resume = false;
57 		}
58 	}
59 
resume_redisplay()60 	void resume_redisplay () {
61 		_no_redisplay = false;
62 		if (_redisplay_on_resume) {
63 			redisplay ();
64 		}
65 	}
66 
67 	void redisplay ();
68 	void update_visibility ();
69 	void time_axis_views_added (std::list<TimeAxisView*>);
70 	void route_removed (TimeAxisView *);
71 	void hide_track_in_display (TimeAxisView &);
72 	std::list<TimeAxisView*> views () const;
73 	void hide_all_tracks (bool);
74 	void clear ();
75 	void sync_presentation_info_from_treeview ();
76 	void sync_treeview_from_presentation_info (PBD::PropertyChange const &);
77 
78 private:
79 	void initial_display ();
80 	void redisplay_real ();
81 	void on_input_active_changed (std::string const &);
82 	void on_tv_rec_enable_changed (std::string const &);
83 	void on_tv_rec_safe_toggled (std::string const &);
84 	void on_tv_mute_enable_toggled (std::string const &);
85 	void on_tv_solo_enable_toggled (std::string const &);
86 	void on_tv_solo_isolate_toggled (std::string const &);
87 	void on_tv_solo_safe_toggled (std::string const &);
88 	void build_menu ();
89 	void presentation_info_changed (PBD::PropertyChange const &);
90 	void row_deleted (Gtk::TreeModel::Path const &);
91 	void visible_changed (std::string const &);
92 	void active_changed (std::string const &);
93 	void reordered (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int *);
94 	bool button_press (GdkEventButton *);
95 	bool button_release (GdkEventButton *);
96 	void route_property_changed (const PBD::PropertyChange&, boost::weak_ptr<ARDOUR::Stripable>);
97 	void handle_gui_changes (std::string const &, void *);
98 	bool idle_update_mute_rec_solo_etc ();
99 	void update_rec_display ();
100 	void update_mute_display ();
101 	void update_solo_display ();
102 	void update_solo_isolate_display ();
103 	void update_solo_safe_display ();
104 	void update_input_active_display ();
105 	void update_active_display ();
106 	void set_all_tracks_visibility (bool);
107 	void set_all_audio_midi_visibility (int, bool);
108 	void show_all_routes ();
109 	void hide_all_routes ();
110 	void show_all_audiotracks ();
111 	void hide_all_audiotracks ();
112 	void show_all_audiobus ();
113 	void hide_all_audiobus ();
114 	void show_all_miditracks ();
115 	void hide_all_miditracks ();
116 	void show_tracks_with_regions_at_playhead ();
117 	void selection_changed ();
118 
119 	int plugin_setup (boost::shared_ptr<ARDOUR::Route>, boost::shared_ptr<ARDOUR::PluginInsert>, ARDOUR::Route::PluginSetupOptions);
120 
121 	void name_edit (std::string const &, std::string const &);
122 	void solo_changed_so_update_mute ();
123 
124 	struct ModelColumns : public Gtk::TreeModel::ColumnRecord {
ModelColumnsModelColumns125 		ModelColumns() {
126 			add (text);
127 			add (visible);
128 			add (rec_state);
129 			add (rec_safe);
130 			add (mute_state);
131 			add (solo_state);
132 			add (solo_visible);
133 			add (solo_lock_iso_visible);
134 			add (solo_isolate_state);
135 			add (solo_safe_state);
136 			add (is_track);
137 			add (tv);
138 			add (stripable);
139 			add (name_editable);
140 			add (is_input_active);
141 			add (is_midi);
142 			add (no_vca);
143 			add (active);
144 		}
145 
146 		Gtk::TreeModelColumn<std::string>    text;
147 		Gtk::TreeModelColumn<bool>           visible;
148 		Gtk::TreeModelColumn<uint32_t>       rec_state;
149 		Gtk::TreeModelColumn<uint32_t>       rec_safe;
150 		Gtk::TreeModelColumn<uint32_t>       mute_state;
151 		Gtk::TreeModelColumn<uint32_t>       solo_state;
152 		/** true if the solo buttons are visible for this route, otherwise false */
153 		Gtk::TreeModelColumn<bool>           solo_visible;
154 		Gtk::TreeModelColumn<bool>           solo_lock_iso_visible;
155 		Gtk::TreeModelColumn<uint32_t>       solo_isolate_state;
156 		Gtk::TreeModelColumn<uint32_t>       solo_safe_state;
157 		Gtk::TreeModelColumn<bool>           is_track;
158 		Gtk::TreeModelColumn<TimeAxisView*>  tv;
159 		Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Stripable> >  stripable;
160 		Gtk::TreeModelColumn<bool>           name_editable;
161 		Gtk::TreeModelColumn<bool>           is_input_active;
162 		Gtk::TreeModelColumn<bool>           is_midi;
163 		Gtk::TreeModelColumn<bool>           no_vca; // activatable
164 		Gtk::TreeModelColumn<bool>           active;
165 	};
166 
167 	Gtk::TreeViewColumn* rec_state_column;
168 	Gtk::TreeViewColumn* rec_safe_column;
169 	Gtk::TreeViewColumn* input_active_column;
170 	Gtk::TreeViewColumn* mute_state_column;
171 	Gtk::TreeViewColumn* solo_state_column;
172 	Gtk::TreeViewColumn* solo_safe_state_column;
173 	Gtk::TreeViewColumn* solo_isolate_state_column;
174 	Gtk::TreeViewColumn* name_column;
175 	Gtk::TreeViewColumn* visible_column;
176 	Gtk::TreeViewColumn* active_column;
177 
178 	Gtk::ScrolledWindow _scroller;
179 	Gtk::TreeView _display;
180 	Glib::RefPtr<Gtk::ListStore> _model;
181 	ModelColumns _columns;
182 	int _name_column;
183 	int _visible_column;
184 	int _active_column;
185 
186 	bool _ignore_reorder;
187 	bool _ignore_selection_change;
188 	bool column_does_not_select;
189 	bool _no_redisplay;
190 	bool _adding_routes;
191 	bool _route_deletion_in_progress;
192 	bool _redisplay_on_resume;
193 	bool _idle_update_queued;
194 
195 	volatile int _redisplay_active;
196 
197 	Gtk::Menu* _menu;
198 	Gtk::Widget* old_focus;
199 	Gtk::CellEditable* name_editable;
200 
201 	bool select_function (const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::Path& path, bool);
202 
203 	bool key_press (GdkEventKey* ev);
204 	bool focus_in (GdkEventFocus*);
205 	bool focus_out (GdkEventFocus*);
206 	bool enter_notify (GdkEventCrossing*);
207 	bool leave_notify (GdkEventCrossing*);
208 	void name_edit_started (Gtk::CellEditable*, const Glib::ustring&);
209 
210 	bool get_relevant_routes (boost::shared_ptr<ARDOUR::RouteList> rl);
211 };
212 
213 #endif /* __ardour_gtk_editor_route_h__ */
214