1 /*
2 * Copyright (C) 2020-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 "audio/engine.h"
21 #include "audio/port.h"
22 #include "audio/track.h"
23 #include "gui/backend/event.h"
24 #include "gui/backend/event_manager.h"
25 #include "gui/widgets/editable_label.h"
26 #include "gui/widgets/inspector_port.h"
27 #include "gui/widgets/main_window.h"
28 #include "gui/widgets/plugin_properties_expander.h"
29 #include "plugins/carla_native_plugin.h"
30 #include "plugins/lv2/lv2_state.h"
31 #include "plugins/plugin.h"
32 #include "plugins/plugin_gtk.h"
33 #include "project.h"
34 #include "utils/error.h"
35 #include "utils/gtk.h"
36 #include "zrythm_app.h"
37
G_DEFINE_TYPE(PianoRollKeysWidget,piano_roll_keys_widget,GTK_TYPE_DRAWING_AREA)38 #include <glib/gi18n.h>
39
40 G_DEFINE_TYPE (
41 PluginPropertiesExpanderWidget,
42 plugin_properties_expander_widget,
43 TWO_COL_EXPANDER_BOX_WIDGET_TYPE)
44
45 static void
46 on_bank_changed (
47 GtkComboBox * cb,
48 PluginPropertiesExpanderWidget * self)
49 {
50 if (!self->plugin)
51 return;
52
53 plugin_set_selected_bank_from_index (
54 self->plugin, gtk_combo_box_get_active (cb));
55
56 g_signal_handler_block (
57 self->presets, self->pset_changed_handler);
58 plugin_gtk_setup_plugin_presets_list_box (
59 self->presets, self->plugin);
60 g_signal_handler_unblock (
61 self->presets, self->pset_changed_handler);
62 }
63
64 static void
65 on_preset_changed (
66 GtkListBox * box,
67 PluginPropertiesExpanderWidget * self)
68 {
69 if (!self->plugin)
70 return;
71
72 GtkListBoxRow * row =
73 gtk_list_box_get_selected_row (box);
74 plugin_set_selected_preset_from_index (
75 self->plugin,
76 gtk_list_box_row_get_index (row));
77 }
78
79 static void
80 on_save_preset_clicked (
81 GtkButton * btn,
82 PluginPropertiesExpanderWidget * self)
83 {
84 if (!self->plugin || !self->plugin->instantiated)
85 return;
86
87 plugin_gtk_on_save_preset_activate (
88 GTK_WIDGET (self), self->plugin);
89 }
90
91 static void
92 on_load_preset_clicked (
93 GtkButton * btn,
94 PluginPropertiesExpanderWidget * self)
95 {
96 if (!self->plugin || !self->plugin->instantiated)
97 return;
98
99 const PluginSetting * setting =
100 self->plugin->setting;
101
102 GtkWidget* dialog =
103 gtk_file_chooser_dialog_new (
104 _("Load Preset"),
105 self->plugin->window ?
106 self->plugin->window :
107 GTK_WINDOW (MAIN_WINDOW),
108 GTK_FILE_CHOOSER_ACTION_OPEN,
109 _("_Cancel"), GTK_RESPONSE_REJECT,
110 _("_Load"), GTK_RESPONSE_ACCEPT,
111 NULL);
112 gtk_file_chooser_set_current_folder (
113 GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
114 gtk_widget_show_all (GTK_WIDGET (dialog));
115 gtk_dialog_set_default_response (
116 GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
117 if (gtk_dialog_run (GTK_DIALOG(dialog)) !=
118 GTK_RESPONSE_ACCEPT)
119 {
120 gtk_widget_destroy (GTK_WIDGET (dialog));
121 return;
122 }
123
124 const char* path =
125 gtk_file_chooser_get_filename (
126 GTK_FILE_CHOOSER (dialog));
127
128 GError * err = NULL;
129 bool applied = false;
130 if (setting->open_with_carla)
131 {
132 #ifdef HAVE_CARLA
133 applied =
134 carla_native_plugin_load_state (
135 self->plugin->carla, path, &err);
136 #else
137 g_return_if_reached ();
138 #endif
139 }
140 else if (setting->descr->protocol == PROT_LV2)
141 {
142 applied =
143 lv2_state_apply_preset (
144 self->plugin->lv2, NULL, path, &err);
145 }
146
147 if (applied)
148 {
149 EVENTS_PUSH (
150 ET_PLUGIN_PRESET_LOADED, self->plugin);
151 }
152 else
153 {
154 HANDLE_ERROR (
155 err, "%s", _("Failed to apply preset"));
156 }
157
158 gtk_widget_destroy (GTK_WIDGET (dialog));
159 }
160
161 /**
162 * Refreshes each field.
163 */
164 void
165 plugin_properties_expander_widget_refresh (
166 PluginPropertiesExpanderWidget * self,
167 Plugin * pl)
168 {
169 if (self->plugin == pl)
170 return;
171
172 self->plugin = pl;
173
174 if (pl)
175 {
176 gtk_label_set_text (
177 self->name, pl->setting->descr->name);
178 gtk_label_set_text (
179 self->type,
180 pl->setting->descr->category_str);
181 }
182 else
183 {
184 gtk_label_set_text (
185 self->name, _("None"));
186 gtk_label_set_text (
187 self->type, _("None"));
188 }
189
190 g_signal_handler_block (
191 self->banks, self->bank_changed_handler);
192 plugin_gtk_setup_plugin_banks_combo_box (
193 self->banks, pl);
194 g_signal_handler_unblock (
195 self->banks, self->bank_changed_handler);
196 g_signal_handler_block (
197 self->presets, self->pset_changed_handler);
198 plugin_gtk_setup_plugin_presets_list_box (
199 self->presets, pl);
200 g_signal_handler_unblock (
201 self->presets, self->pset_changed_handler);
202 }
203
204 /**
205 * Sets up the PluginPropertiesExpanderWidget for a Plugin.
206 */
207 void
208 plugin_properties_expander_widget_setup (
209 PluginPropertiesExpanderWidget * self,
210 Plugin * pl)
211 {
212 self->plugin = pl;
213
214 /* set name and icon */
215 expander_box_widget_set_label (
216 Z_EXPANDER_BOX_WIDGET (self),
217 _("Plugin Properties"));
218
219 GtkWidget * lbl;
220
221 #define CREATE_LABEL(x) \
222 lbl = \
223 plugin_gtk_new_label ( \
224 x, true, false, 0.f, 0.5f); \
225 z_gtk_widget_add_style_class ( \
226 lbl, "inspector_label"); \
227 gtk_widget_set_margin_start (lbl, 2); \
228 gtk_widget_set_visible (lbl, 1)
229
230 CREATE_LABEL (_("Name"));
231 gtk_widget_set_visible (lbl, TRUE);
232 two_col_expander_box_widget_add_single (
233 Z_TWO_COL_EXPANDER_BOX_WIDGET (self), lbl);
234 self->name =
235 GTK_LABEL (gtk_label_new ("dist"));
236 gtk_widget_set_visible (
237 GTK_WIDGET (self->name), TRUE);
238 gtk_label_set_xalign (
239 self->name, 0);
240 gtk_widget_set_margin_start (
241 GTK_WIDGET (self->name), 4);
242 two_col_expander_box_widget_add_single (
243 Z_TWO_COL_EXPANDER_BOX_WIDGET (self),
244 GTK_WIDGET (self->name));
245
246 CREATE_LABEL (_("Type"));
247 gtk_widget_set_visible (lbl, TRUE);
248 two_col_expander_box_widget_add_single (
249 Z_TWO_COL_EXPANDER_BOX_WIDGET (self), lbl);
250 self->type =
251 GTK_LABEL (gtk_label_new ("Instrument"));
252 gtk_widget_set_visible (
253 GTK_WIDGET (self->type), TRUE);
254 gtk_label_set_xalign (
255 self->type, 0);
256 gtk_widget_set_margin_start (
257 GTK_WIDGET (self->type), 4);
258 two_col_expander_box_widget_add_single (
259 Z_TWO_COL_EXPANDER_BOX_WIDGET (self),
260 GTK_WIDGET (self->type));
261
262 CREATE_LABEL (_("Banks"));
263 gtk_widget_set_visible (lbl, true);
264 two_col_expander_box_widget_add_single (
265 Z_TWO_COL_EXPANDER_BOX_WIDGET (self), lbl);
266 self->banks =
267 GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new ());
268 gtk_widget_set_visible (
269 GTK_WIDGET (self->banks), true);
270 two_col_expander_box_widget_add_single (
271 Z_TWO_COL_EXPANDER_BOX_WIDGET (self),
272 GTK_WIDGET (self->banks));
273 self->bank_changed_handler =
274 g_signal_connect (
275 G_OBJECT (self->banks), "changed",
276 G_CALLBACK (on_bank_changed), self);
277
278 CREATE_LABEL (_("Presets"));
279 gtk_widget_set_visible (lbl, true);
280 two_col_expander_box_widget_add_single (
281 Z_TWO_COL_EXPANDER_BOX_WIDGET (self), lbl);
282 self->presets =
283 GTK_LIST_BOX (gtk_list_box_new ());
284 gtk_widget_set_visible (
285 GTK_WIDGET (self->presets), true);
286 GtkScrolledWindow * scroll =
287 GTK_SCROLLED_WINDOW (
288 gtk_scrolled_window_new (NULL, NULL));
289 gtk_scrolled_window_set_min_content_height (
290 scroll, 86);
291 gtk_scrolled_window_set_policy (
292 scroll, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
293 gtk_widget_set_visible (
294 GTK_WIDGET (scroll), true);
295 gtk_container_add (
296 GTK_CONTAINER (scroll),
297 GTK_WIDGET (self->presets));
298 two_col_expander_box_widget_add_single (
299 Z_TWO_COL_EXPANDER_BOX_WIDGET (self),
300 GTK_WIDGET (scroll));
301 self->pset_changed_handler =
302 g_signal_connect (
303 G_OBJECT (self->presets),
304 "selected-rows-changed",
305 G_CALLBACK (on_preset_changed), self);
306
307 self->save_preset_btn =
308 z_gtk_button_new_with_icon_and_text (
309 "document-save-as", _("Save"), true,
310 GTK_ORIENTATION_HORIZONTAL, 2);
311 gtk_widget_set_tooltip_text (
312 GTK_WIDGET (self->save_preset_btn),
313 _("Save preset"));
314 self->load_preset_btn =
piano_roll_keys_widget_get_key_from_y(PianoRollKeysWidget * self,double y)315 z_gtk_button_new_with_icon_and_text (
316 "document-open", _("Load"), true,
317 GTK_ORIENTATION_HORIZONTAL, 2);
318 gtk_widget_set_tooltip_text (
319 GTK_WIDGET (self->load_preset_btn),
320 _("Load preset"));
321 GtkWidget * box =
322 gtk_button_box_new (
323 GTK_ORIENTATION_HORIZONTAL);
324 gtk_widget_set_visible (box, true);
325 gtk_container_add (
326 GTK_CONTAINER (box),
327 GTK_WIDGET (self->save_preset_btn));
328 gtk_container_add (
329 GTK_CONTAINER (box),
piano_roll_keys_widget_get_font_size(PianoRollKeysWidget * self)330 GTK_WIDGET (self->load_preset_btn));
331 z_gtk_widget_add_style_class (box, "linked");
332 two_col_expander_box_widget_add_single (
333 Z_TWO_COL_EXPANDER_BOX_WIDGET (self), box);
334 g_signal_connect (
335 G_OBJECT (self->save_preset_btn), "clicked",
336 G_CALLBACK (on_save_preset_clicked), self);
337 g_signal_connect (
338 G_OBJECT (self->load_preset_btn), "clicked",
339 G_CALLBACK (on_load_preset_clicked), self);
340
341 plugin_properties_expander_widget_refresh (
342 self, pl);
343 }
344
345 static void
346 plugin_properties_expander_widget_class_init (
send_note_event(PianoRollKeysWidget * self,int note,int on)347 PluginPropertiesExpanderWidgetClass * klass)
348 {
349 }
350
351 static void
352 plugin_properties_expander_widget_init (
353 PluginPropertiesExpanderWidget * self)
354 {
355 /*two_col_expander_box_widget_add_single (*/
356 /*Z_TWO_COL_EXPANDER_BOX_WIDGET (self),*/
357 /*GTK_WIDGET (self->name));*/
358 }
359