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