1 /*
2 * Copyright (C) 2018-2021 Alexandros Theodotou <alex at zrythm dot org>
3 *
4 * This file is part of Zrythm
5 *
6 * Zrythm is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Zrythm is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "gui/backend/event_manager.h"
21 #include "gui/backend/tracklist_selections.h"
22 #include "gui/widgets/center_dock.h"
23 #include "gui/widgets/channel_sends_expander.h"
24 #include "gui/widgets/color_area.h"
25 #include "gui/widgets/fader_controls_expander.h"
26 #include "gui/widgets/inspector_track.h"
27 #include "gui/widgets/left_dock_edge.h"
28 #include "gui/widgets/main_window.h"
29 #include "gui/widgets/plugin_strip_expander.h"
30 #include "gui/widgets/ports_expander.h"
31 #include "gui/widgets/track_input_expander.h"
32 #include "gui/widgets/track_properties_expander.h"
33 #include "gui/widgets/text_expander.h"
34 #include "project.h"
35 #include "settings/settings.h"
36 #include "utils/gtk.h"
37 #include "utils/resources.h"
38 #include "zrythm_app.h"
39
40 #include <gtk/gtk.h>
41
42 #include <glib/gi18n.h>
43
G_DEFINE_TYPE(InspectorTrackWidget,inspector_track_widget,GTK_TYPE_BOX)44 G_DEFINE_TYPE (
45 InspectorTrackWidget,
46 inspector_track_widget,
47 GTK_TYPE_BOX)
48
49 static void
50 reveal_cb (
51 ExpanderBoxWidget * expander,
52 const bool revealed,
53 void * user_data)
54 {
55 InspectorTrackWidget * self =
56 Z_INSPECTOR_TRACK_WIDGET (user_data);
57
58 #define SET_SETTING(mem,key) \
59 if (expander == Z_EXPANDER_BOX_WIDGET (self->mem)) \
60 { \
61 g_settings_set_boolean ( \
62 S_UI_INSPECTOR, \
63 "track-" key "-expanded", revealed); \
64 }
65
66 SET_SETTING (track_info, "properties");
67 SET_SETTING (inputs, "inputs");
68 SET_SETTING (outputs, "outputs");
69 SET_SETTING (sends, "sends");
70 SET_SETTING (controls, "controls");
71 SET_SETTING (inserts, "inserts");
72 SET_SETTING (midi_fx, "midi-fx");
73 SET_SETTING (fader, "fader");
74 SET_SETTING (comment, "comment");
75
76 #undef SET_SETTING
77 }
78
79 static void
setup_color(InspectorTrackWidget * self,Track * track)80 setup_color (
81 InspectorTrackWidget * self,
82 Track * track)
83 {
84 if (track)
85 {
86 color_area_widget_setup_track (
87 self->color, track);
88 }
89 else
90 {
91 GdkRGBA color = { 1, 1, 1, 1 };
92 color_area_widget_set_color (
93 self->color, &color);
94 }
95 }
96
97 /**
98 * Shows the inspector page for the given tracklist
99 * selection.
100 *
101 * @param set_notebook_page Whether to set the
102 * current left panel tab to the track page.
103 */
104 void
inspector_track_widget_show_tracks(InspectorTrackWidget * self,TracklistSelections * tls,bool set_notebook_page)105 inspector_track_widget_show_tracks (
106 InspectorTrackWidget * self,
107 TracklistSelections * tls,
108 bool set_notebook_page)
109 {
110 g_debug ("showing %d tracks", tls->num_tracks);
111
112 if (set_notebook_page &&
113 gtk_notebook_get_current_page (
114 GTK_NOTEBOOK (
115 MW_LEFT_DOCK_EDGE->inspector_notebook)) !=
116 0)
117 {
118 gtk_notebook_set_current_page (
119 GTK_NOTEBOOK (
120 MW_LEFT_DOCK_EDGE->inspector_notebook), 0);
121 }
122
123 /* show info for first track */
124 Track * track = NULL;
125 if (tls->num_tracks > 0)
126 {
127 track = tls->tracks[0];
128 g_debug ("track %s", track->name);
129
130 setup_color (self, track);
131
132 track_properties_expander_widget_refresh (
133 self->track_info, track);
134
135 gtk_widget_set_visible (
136 GTK_WIDGET (self->sends), false);
137 gtk_widget_set_visible (
138 GTK_WIDGET (self->outputs), false);
139 gtk_widget_set_visible (
140 GTK_WIDGET (self->controls), false);
141 gtk_widget_set_visible (
142 GTK_WIDGET (self->inputs), false);
143 gtk_widget_set_visible (
144 GTK_WIDGET (self->inserts), false);
145 gtk_widget_set_visible (
146 GTK_WIDGET (self->midi_fx), false);
147 gtk_widget_set_visible (
148 GTK_WIDGET (self->fader), false);
149 gtk_widget_set_visible (
150 GTK_WIDGET (self->comment), true);
151
152 text_expander_widget_setup (
153 self->comment, true, track_get_comment,
154 track_comment_setter, track);
155 expander_box_widget_set_label (
156 Z_EXPANDER_BOX_WIDGET (self->comment),
157 _("Comment"));
158
159 if (track_type_has_channel (track->type))
160 {
161 gtk_widget_set_visible (
162 GTK_WIDGET (self->sends), true);
163 #if 0
164 gtk_widget_set_visible (
165 GTK_WIDGET (self->outputs), true);
166 gtk_widget_set_visible (
167 GTK_WIDGET (self->controls), true);
168 #endif
169 gtk_widget_set_visible (
170 GTK_WIDGET (self->fader), true);
171 gtk_widget_set_visible (
172 GTK_WIDGET (self->inserts), true);
173
174 if (track_has_inputs (track))
175 {
176 gtk_widget_set_visible (
177 GTK_WIDGET (self->inputs), true);
178 track_input_expander_widget_refresh (
179 self->inputs, track);
180 }
181 if (track->in_signal_type == TYPE_EVENT)
182 {
183 gtk_widget_set_visible (
184 GTK_WIDGET (self->midi_fx), true);
185 plugin_strip_expander_widget_setup (
186 self->midi_fx, PLUGIN_SLOT_MIDI_FX,
187 PSE_POSITION_INSPECTOR, track);
188 }
189 ports_expander_widget_setup_track (
190 self->outputs,
191 track, PE_TRACK_PORT_TYPE_SENDS);
192 ports_expander_widget_setup_track (
193 self->controls,
194 track, PE_TRACK_PORT_TYPE_CONTROLS);
195
196 plugin_strip_expander_widget_setup (
197 self->inserts, PLUGIN_SLOT_INSERT,
198 PSE_POSITION_INSPECTOR, track);
199
200 fader_controls_expander_widget_setup (
201 self->fader, track);
202
203 channel_sends_expander_widget_setup (
204 self->sends, CSE_POSITION_INSPECTOR,
205 track);
206 }
207 }
208 else /* no tracks selected */
209 {
210 track_properties_expander_widget_refresh (
211 self->track_info, NULL);
212 ports_expander_widget_setup_track (
213 self->outputs,
214 track, PE_TRACK_PORT_TYPE_SENDS);
215 ports_expander_widget_setup_track (
216 self->controls,
217 track, PE_TRACK_PORT_TYPE_CONTROLS);
218 text_expander_widget_setup (
219 self->comment, false, NULL, NULL, NULL);
220
221 setup_color (self, NULL);
222 }
223 }
224
225 /**
226 * Sets up the inspector track widget for the first
227 * time.
228 */
229 void
inspector_track_widget_setup(InspectorTrackWidget * self,TracklistSelections * tls)230 inspector_track_widget_setup (
231 InspectorTrackWidget * self,
232 TracklistSelections * tls)
233 {
234 g_return_if_fail (tls);
235 if (tls->num_tracks == 0)
236 {
237 g_critical (
238 "no tracks selected. this should never "
239 "happen");
240 return;
241 }
242
243 Track * track = tls->tracks[0];
244 g_return_if_fail (track);
245
246 track_properties_expander_widget_setup (
247 self->track_info, track);
248 }
249
250 InspectorTrackWidget *
inspector_track_widget_new(void)251 inspector_track_widget_new (void)
252 {
253 InspectorTrackWidget * self =
254 g_object_new (
255 INSPECTOR_TRACK_WIDGET_TYPE, NULL);
256
257 return self;
258 }
259
260 /**
261 * Prepare for finalization.
262 */
263 void
inspector_track_widget_tear_down(InspectorTrackWidget * self)264 inspector_track_widget_tear_down (
265 InspectorTrackWidget * self)
266 {
267 g_message ("tearing down %p...", self);
268
269 if (self->fader)
270 {
271 fader_controls_expander_widget_tear_down (
272 self->fader);
273 }
274
275 g_message ("done");
276 }
277
278 static void
inspector_track_widget_class_init(InspectorTrackWidgetClass * _klass)279 inspector_track_widget_class_init (
280 InspectorTrackWidgetClass * _klass)
281 {
282 GtkWidgetClass * klass =
283 GTK_WIDGET_CLASS (_klass);
284 resources_set_class_template (
285 klass, "inspector_track.ui");
286
287 #define BIND_CHILD(child) \
288 gtk_widget_class_bind_template_child ( \
289 GTK_WIDGET_CLASS (klass), \
290 InspectorTrackWidget, \
291 child);
292
293 BIND_CHILD (track_info);
294 BIND_CHILD (sends);
295 BIND_CHILD (outputs);
296 BIND_CHILD (controls);
297 BIND_CHILD (inputs);
298 BIND_CHILD (inserts);
299 BIND_CHILD (midi_fx);
300 BIND_CHILD (fader);
301 BIND_CHILD (comment);
302 BIND_CHILD (color);
303
304 #undef BIND_CHILD
305 }
306
307 static void
inspector_track_widget_init(InspectorTrackWidget * self)308 inspector_track_widget_init (
309 InspectorTrackWidget * self)
310 {
311 g_type_ensure (
312 TRACK_PROPERTIES_EXPANDER_WIDGET_TYPE);
313 g_type_ensure (
314 TRACK_INPUT_EXPANDER_WIDGET_TYPE);
315 g_type_ensure (
316 PORTS_EXPANDER_WIDGET_TYPE);
317 g_type_ensure (
318 PLUGIN_STRIP_EXPANDER_WIDGET_TYPE);
319 g_type_ensure (
320 CHANNEL_SENDS_EXPANDER_WIDGET_TYPE);
321 g_type_ensure (
322 FADER_CONTROLS_EXPANDER_WIDGET_TYPE);
323 g_type_ensure (
324 TEXT_EXPANDER_WIDGET_TYPE);
325 g_type_ensure (
326 COLOR_AREA_WIDGET_TYPE);
327
328 gtk_widget_init_template (GTK_WIDGET (self));
329
330 z_gtk_widget_add_style_class (
331 GTK_WIDGET (self), "inspector");
332
333 expander_box_widget_set_vexpand (
334 Z_EXPANDER_BOX_WIDGET (self->inserts), false);
335 expander_box_widget_set_vexpand (
336 Z_EXPANDER_BOX_WIDGET (self->midi_fx), false);
337 expander_box_widget_set_vexpand (
338 Z_EXPANDER_BOX_WIDGET (self->comment), false);
339
340 /* set states */
341 #define SET_STATE(mem,key) \
342 expander_box_widget_set_reveal ( \
343 Z_EXPANDER_BOX_WIDGET (self->mem), \
344 g_settings_get_boolean ( \
345 S_UI_INSPECTOR, \
346 "track-" key "-expanded")); \
347 expander_box_widget_set_reveal_callback ( \
348 Z_EXPANDER_BOX_WIDGET (self->mem), \
349 reveal_cb, self)
350
351 SET_STATE (track_info, "properties");
352 SET_STATE (inputs, "inputs");
353 SET_STATE (outputs, "outputs");
354 SET_STATE (sends, "sends");
355 SET_STATE (controls, "controls");
356 SET_STATE (inserts, "inserts");
357 SET_STATE (midi_fx, "midi-fx");
358 SET_STATE (fader, "fader");
359 SET_STATE (comment, "comment");
360
361 #undef SET_STATE
362 }
363