1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2019 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU 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  * GSequencer 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 General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <ags/X/editor/ags_automation_toolbar_callbacks.h>
21 
22 #include <ags/X/ags_automation_editor.h>
23 
24 #include <math.h>
25 
26 void ags_automation_toolbar_zoom_callback_apply(GList *list,
27 						gdouble old_zoom_factor,
28 						gdouble zoom_factor, gdouble zoom);
29 
30 void
ags_automation_toolbar_machine_changed_callback(AgsAutomationEditor * automation_editor,AgsMachine * machine,AgsAutomationToolbar * toolbar)31 ags_automation_toolbar_machine_changed_callback(AgsAutomationEditor *automation_editor,
32 						AgsMachine *machine,
33 						AgsAutomationToolbar *toolbar)
34 {
35   AgsAutomation *automation;
36 
37   /* load ports */
38   ags_automation_toolbar_load_port(automation_editor->automation_toolbar);
39 }
40 
41 void
ags_automation_toolbar_position_callback(GtkToggleToolButton * toggle_button,AgsAutomationToolbar * automation_toolbar)42 ags_automation_toolbar_position_callback(GtkToggleToolButton *toggle_button, AgsAutomationToolbar *automation_toolbar)
43 {
44   AgsAutomationEditor *automation_editor;
45 
46   automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
47 								      AGS_TYPE_AUTOMATION_EDITOR);
48 
49   if(toggle_button == automation_toolbar->selected_edit_mode){
50     if(!gtk_toggle_tool_button_get_active(toggle_button)){
51       gtk_toggle_tool_button_set_active(toggle_button, TRUE);
52     }
53   }else if(gtk_toggle_tool_button_get_active(toggle_button)){
54     GtkToggleToolButton *old_selected_edit_mode;
55 
56     old_selected_edit_mode = automation_toolbar->selected_edit_mode;
57     automation_toolbar->selected_edit_mode = toggle_button;
58     gtk_toggle_tool_button_set_active(old_selected_edit_mode, FALSE);
59   }
60 }
61 
62 void
ags_automation_toolbar_edit_callback(GtkToggleToolButton * toggle_button,AgsAutomationToolbar * automation_toolbar)63 ags_automation_toolbar_edit_callback(GtkToggleToolButton *toggle_button, AgsAutomationToolbar *automation_toolbar)
64 {
65   if(toggle_button == automation_toolbar->selected_edit_mode){
66     if(!gtk_toggle_tool_button_get_active(toggle_button)){
67       gtk_toggle_tool_button_set_active(toggle_button, TRUE);
68     }
69   }else if(gtk_toggle_tool_button_get_active(toggle_button)){
70     GtkToggleToolButton *old_selected_edit_mode;
71 
72     old_selected_edit_mode = automation_toolbar->selected_edit_mode;
73     automation_toolbar->selected_edit_mode = toggle_button;
74     gtk_toggle_tool_button_set_active(old_selected_edit_mode, FALSE);
75   }
76 }
77 
78 void
ags_automation_toolbar_clear_callback(GtkToggleToolButton * toggle_button,AgsAutomationToolbar * automation_toolbar)79 ags_automation_toolbar_clear_callback(GtkToggleToolButton *toggle_button, AgsAutomationToolbar *automation_toolbar)
80 {
81   if(toggle_button == automation_toolbar->selected_edit_mode){
82     if(!gtk_toggle_tool_button_get_active(toggle_button)){
83       gtk_toggle_tool_button_set_active(toggle_button, TRUE);
84     }
85   }else if(gtk_toggle_tool_button_get_active(toggle_button)){
86     GtkToggleToolButton *old_selected_edit_mode;
87 
88     old_selected_edit_mode = automation_toolbar->selected_edit_mode;
89     automation_toolbar->selected_edit_mode = toggle_button;
90     gtk_toggle_tool_button_set_active(old_selected_edit_mode, FALSE);
91   }
92 }
93 
94 void
ags_automation_toolbar_select_callback(GtkToggleToolButton * toggle_button,AgsAutomationToolbar * automation_toolbar)95 ags_automation_toolbar_select_callback(GtkToggleToolButton *toggle_button, AgsAutomationToolbar *automation_toolbar)
96 {
97   if(toggle_button == automation_toolbar->selected_edit_mode){
98     if(!gtk_toggle_tool_button_get_active(toggle_button)){
99       gtk_toggle_tool_button_set_active(toggle_button, TRUE);
100     }
101   }else if(gtk_toggle_tool_button_get_active(toggle_button)){
102     GtkToggleToolButton *old_selected_edit_mode;
103 
104     old_selected_edit_mode = automation_toolbar->selected_edit_mode;
105     automation_toolbar->selected_edit_mode = toggle_button;
106     gtk_toggle_tool_button_set_active(old_selected_edit_mode, FALSE);
107   }
108 }
109 
110 void
ags_automation_toolbar_copy_or_cut_callback(GtkWidget * widget,AgsAutomationToolbar * automation_toolbar)111 ags_automation_toolbar_copy_or_cut_callback(GtkWidget *widget, AgsAutomationToolbar *automation_toolbar)
112 {
113   AgsAutomationEditor *automation_editor;
114 
115   automation_editor = AGS_AUTOMATION_EDITOR(gtk_widget_get_ancestor(GTK_WIDGET(automation_toolbar),
116 								    AGS_TYPE_AUTOMATION_EDITOR));
117 
118   if(widget == (GtkWidget *) automation_toolbar->copy){
119     ags_automation_editor_copy(automation_editor);
120   }else{
121     ags_automation_editor_cut(automation_editor);
122   }
123 }
124 
125 void
ags_automation_toolbar_paste_callback(GtkWidget * widget,AgsAutomationToolbar * automation_toolbar)126 ags_automation_toolbar_paste_callback(GtkWidget *widget, AgsAutomationToolbar *automation_toolbar)
127 {
128   AgsAutomationEditor *automation_editor;
129 
130   automation_editor = AGS_AUTOMATION_EDITOR(gtk_widget_get_ancestor(GTK_WIDGET(automation_toolbar),
131 								    AGS_TYPE_AUTOMATION_EDITOR));
132 
133   ags_automation_editor_paste(automation_editor);
134 }
135 
136 void
ags_automation_toolbar_match_line_callback(GtkWidget * widget,AgsAutomationToolbar * automation_toolbar)137 ags_automation_toolbar_match_line_callback(GtkWidget *widget, AgsAutomationToolbar *automation_toolbar)
138 {
139   AgsAutomationEditor *automation_editor;
140 
141   automation_editor = AGS_AUTOMATION_EDITOR(gtk_widget_get_ancestor(GTK_WIDGET(automation_toolbar),
142 								    AGS_TYPE_AUTOMATION_EDITOR));
143 
144   if(gtk_check_menu_item_get_active((GtkCheckMenuItem *) widget)){
145     automation_editor->flags |= AGS_AUTOMATION_EDITOR_PASTE_MATCH_LINE;
146   }else{
147     automation_editor->flags &= (~AGS_AUTOMATION_EDITOR_PASTE_MATCH_LINE);
148   }
149 }
150 
151 void
ags_automation_toolbar_no_duplicates_callback(GtkWidget * widget,AgsAutomationToolbar * automation_toolbar)152 ags_automation_toolbar_no_duplicates_callback(GtkWidget *widget, AgsAutomationToolbar *automation_toolbar)
153 {
154   AgsAutomationEditor *automation_editor;
155 
156   automation_editor = AGS_AUTOMATION_EDITOR(gtk_widget_get_ancestor(GTK_WIDGET(automation_toolbar),
157 								    AGS_TYPE_AUTOMATION_EDITOR));
158 
159   if(gtk_check_menu_item_get_active((GtkCheckMenuItem *) widget)){
160     automation_editor->flags |= AGS_AUTOMATION_EDITOR_PASTE_NO_DUPLICATES;
161   }else{
162     automation_editor->flags &= (~AGS_AUTOMATION_EDITOR_PASTE_NO_DUPLICATES);
163   }
164 }
165 
166 void
ags_automation_toolbar_tool_popup_select_acceleration_callback(GtkWidget * item,AgsAutomationToolbar * automation_toolbar)167 ags_automation_toolbar_tool_popup_select_acceleration_callback(GtkWidget *item, AgsAutomationToolbar *automation_toolbar)
168 {
169   gtk_widget_show_all((GtkWidget *) automation_toolbar->select_acceleration);
170 }
171 
172 void
ags_automation_toolbar_tool_popup_ramp_acceleration_callback(GtkWidget * item,AgsAutomationToolbar * automation_toolbar)173 ags_automation_toolbar_tool_popup_ramp_acceleration_callback(GtkWidget *item, AgsAutomationToolbar *automation_toolbar)
174 {
175   gtk_widget_show_all((GtkWidget *) automation_toolbar->ramp_acceleration);
176 }
177 
178 void
ags_automation_toolbar_tool_popup_position_cursor_callback(GtkWidget * item,AgsAutomationToolbar * automation_toolbar)179 ags_automation_toolbar_tool_popup_position_cursor_callback(GtkWidget *item, AgsAutomationToolbar *automation_toolbar)
180 {
181   gtk_widget_show_all((GtkWidget *) automation_toolbar->position_automation_cursor);
182 }
183 
184 void
ags_automation_toolbar_tool_popup_enable_all_lines_callback(GtkWidget * item,AgsAutomationToolbar * automation_toolbar)185 ags_automation_toolbar_tool_popup_enable_all_lines_callback(GtkWidget *item, AgsAutomationToolbar *automation_toolbar)
186 {
187   AgsAutomationEditor *automation_editor;
188   AgsNotebook *notebook;
189 
190   automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
191 								      AGS_TYPE_AUTOMATION_EDITOR);
192 
193   notebook = NULL;
194 
195   /* queue draw */
196   switch(gtk_notebook_get_current_page(automation_editor->notebook)){
197   case 1:
198     {
199       notebook = automation_editor->output_notebook;
200     }
201     break;
202   case 2:
203     {
204       notebook = automation_editor->input_notebook;
205     }
206     break;
207   }
208 
209   if(notebook != NULL){
210     GList *start_list, *list;
211 
212     list =
213       start_list = g_list_copy(notebook->tab);
214 
215     while(list != NULL){
216       gtk_toggle_button_set_active(AGS_NOTEBOOK_TAB(list->data)->toggle,
217 				   TRUE);
218 
219       list = list->next;
220     }
221 
222     g_list_free(start_list);
223   }
224 }
225 
226 void
ags_automation_toolbar_tool_popup_disable_all_lines_callback(GtkWidget * item,AgsAutomationToolbar * automation_toolbar)227 ags_automation_toolbar_tool_popup_disable_all_lines_callback(GtkWidget *item, AgsAutomationToolbar *automation_toolbar)
228 {
229   AgsAutomationEditor *automation_editor;
230   AgsNotebook *notebook;
231 
232   automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
233 								      AGS_TYPE_AUTOMATION_EDITOR);
234 
235   notebook = NULL;
236 
237   /* queue draw */
238   switch(gtk_notebook_get_current_page(automation_editor->notebook)){
239   case 1:
240     {
241       notebook = automation_editor->output_notebook;
242     }
243     break;
244   case 2:
245     {
246       notebook = automation_editor->input_notebook;
247     }
248     break;
249   }
250 
251   if(notebook != NULL){
252     GList *start_list, *list;
253 
254     list =
255       start_list = g_list_copy(notebook->tab);
256 
257     while(list != NULL){
258       gtk_toggle_button_set_active(AGS_NOTEBOOK_TAB(list->data)->toggle,
259 				   FALSE);
260 
261       list = list->next;
262     }
263 
264     g_list_free(start_list);
265   }
266 }
267 
268 void
ags_automation_toolbar_zoom_callback_apply(GList * list,gdouble old_zoom_factor,gdouble zoom_factor,gdouble zoom)269 ags_automation_toolbar_zoom_callback_apply(GList *list,
270 					   gdouble old_zoom_factor,
271 					   gdouble zoom_factor, gdouble zoom)
272 {
273   AgsAutomationEdit *automation_edit;
274 
275   while(list != NULL){
276     automation_edit = list->data;
277 
278     gtk_widget_queue_draw((GtkWidget *) automation_edit);
279 
280     /* reset ruler */
281     automation_edit->ruler->factor = zoom_factor;
282     automation_edit->ruler->precision = zoom;
283     automation_edit->ruler->scale_precision = 1.0 / zoom;
284 
285     gtk_widget_queue_draw((GtkWidget *) automation_edit->ruler);
286 
287     list = list->next;
288   }
289 }
290 
291 void
ags_automation_toolbar_zoom_callback(GtkComboBox * combo_box,AgsAutomationToolbar * automation_toolbar)292 ags_automation_toolbar_zoom_callback(GtkComboBox *combo_box, AgsAutomationToolbar *automation_toolbar)
293 {
294   AgsAutomationEditor *automation_editor;
295   GtkWidget *widget;
296 
297   GtkAdjustment *adjustment;
298 
299   GList *list_start;
300 
301   gdouble old_value;
302   gdouble old_zoom_factor;
303   gdouble zoom_factor, zoom;
304 
305   automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
306 								      AGS_TYPE_AUTOMATION_EDITOR);
307 
308   /* zoom */
309   old_zoom_factor = exp2(6.0 - (double) automation_toolbar->zoom_history);
310 
311   automation_toolbar->zoom_history = gtk_combo_box_get_active((GtkComboBox *) automation_toolbar->zoom);
312 
313   zoom_factor = exp2(6.0 - (double) automation_toolbar->zoom_history);
314   zoom = exp2((double) gtk_combo_box_get_active((GtkComboBox *) automation_toolbar->zoom) - 2.0);
315 
316   /* audio */
317   old_value = gtk_range_get_value(automation_editor->audio_hscrollbar);
318 
319   automation_editor->audio_ruler->factor = zoom_factor;
320   automation_editor->audio_ruler->precision = zoom;
321   automation_editor->audio_ruler->scale_precision = 1.0 / zoom;
322 
323   gtk_widget_queue_draw((GtkWidget *) automation_editor->audio_ruler);
324 
325   list_start = gtk_container_get_children((GtkContainer *) automation_editor->audio_scrolled_automation_edit_box->automation_edit_box);
326   ags_automation_toolbar_zoom_callback_apply(list_start,
327 					     old_zoom_factor,
328 					     zoom_factor, zoom);
329 
330   g_list_free(list_start);
331 
332   ags_automation_editor_reset_audio_scrollbar(automation_editor);
333 
334   gtk_range_set_value(automation_editor->audio_hscrollbar,
335 		      old_value * old_zoom_factor / zoom_factor);
336 
337   /* output */
338   old_value = gtk_range_get_value(automation_editor->output_hscrollbar);
339 
340   automation_editor->output_ruler->factor = zoom_factor;
341   automation_editor->output_ruler->precision = zoom;
342   automation_editor->output_ruler->scale_precision = 1.0 / zoom;
343 
344   gtk_widget_queue_draw((GtkWidget *) automation_editor->output_ruler);
345 
346   list_start = gtk_container_get_children((GtkContainer *) automation_editor->output_scrolled_automation_edit_box->automation_edit_box);
347   ags_automation_toolbar_zoom_callback_apply(list_start,
348 					     old_zoom_factor,
349 					     zoom_factor, zoom);
350 
351   g_list_free(list_start);
352 
353   ags_automation_editor_reset_output_scrollbar(automation_editor);
354 
355   gtk_range_set_value(automation_editor->output_hscrollbar,
356 		      old_value * old_zoom_factor / zoom_factor);
357 
358   /* input */
359   old_value = gtk_range_get_value(automation_editor->input_hscrollbar);
360 
361   automation_editor->input_ruler->factor = zoom_factor;
362   automation_editor->input_ruler->precision = zoom;
363   automation_editor->input_ruler->scale_precision = 1.0 / zoom;
364 
365   gtk_widget_queue_draw((GtkWidget *) automation_editor->input_ruler);
366 
367   list_start = gtk_container_get_children((GtkContainer *) automation_editor->input_scrolled_automation_edit_box->automation_edit_box);
368   ags_automation_toolbar_zoom_callback_apply(list_start,
369 					     old_zoom_factor,
370 					     zoom_factor, zoom);
371 
372   g_list_free(list_start);
373 
374   ags_automation_editor_reset_input_scrollbar(automation_editor);
375 
376   gtk_range_set_value(automation_editor->input_hscrollbar,
377 		      old_value * old_zoom_factor / zoom_factor);
378 }
379 
380 void
ags_automation_toolbar_port_callback(GtkComboBox * combo_box,AgsAutomationToolbar * automation_toolbar)381 ags_automation_toolbar_port_callback(GtkComboBox *combo_box,
382 				     AgsAutomationToolbar *automation_toolbar)
383 {
384   GtkTreeModel *model;
385   GtkTreeIter iter;
386 
387   gchar *scope;
388   gchar *control_name;
389 
390   GType channel_type;
391 
392   GValue value = {0,};
393 
394   if((AGS_AUTOMATION_TOOLBAR_RESET_PORT & (automation_toolbar->flags)) != 0){
395     return;
396   }
397 
398   automation_toolbar->flags |= AGS_AUTOMATION_TOOLBAR_RESET_PORT;
399 
400   model = gtk_combo_box_get_model(combo_box);
401   gtk_combo_box_get_active_iter(combo_box, &iter);
402 
403   gtk_tree_model_get(model,
404 		     &iter,
405 		     1, &scope,
406 		     2, &control_name,
407 		     -1);
408 
409   channel_type = G_TYPE_NONE;
410 
411   if(!g_strcmp0("audio",
412 		scope)){
413     channel_type = G_TYPE_NONE;
414   }else if(!g_strcmp0("output",
415 		      scope)){
416     channel_type = AGS_TYPE_OUTPUT;
417   }else if(!g_strcmp0("input",
418 		      scope)){
419     channel_type = AGS_TYPE_INPUT;
420   }
421 
422   if(control_name != NULL &&
423      strlen(control_name) > 0){
424     ags_automation_toolbar_apply_port(automation_toolbar,
425 				      channel_type, control_name);
426   }
427 
428   automation_toolbar->flags &= (~AGS_AUTOMATION_TOOLBAR_RESET_PORT);
429 }
430 
431 void
ags_automation_toolbar_opacity_callback(GtkSpinButton * spin_button,AgsAutomationToolbar * automation_toolbar)432 ags_automation_toolbar_opacity_callback(GtkSpinButton *spin_button, AgsAutomationToolbar *automation_toolbar)
433 {
434   AgsAutomationEditor *automation_editor;
435 
436   GList *start_list, *list;
437 
438   automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
439 								      AGS_TYPE_AUTOMATION_EDITOR);
440 
441 
442   /* queue draw */
443   switch(gtk_notebook_get_current_page(automation_editor->notebook)){
444   case 0:
445     {
446       list =
447 	start_list = gtk_container_get_children((GtkContainer *) automation_editor->audio_scrolled_automation_edit_box->automation_edit_box);
448     }
449     break;
450   case 1:
451     {
452       list =
453 	start_list = gtk_container_get_children((GtkContainer *) automation_editor->output_scrolled_automation_edit_box->automation_edit_box);
454     }
455     break;
456   case 2:
457     {
458       list =
459 	start_list = gtk_container_get_children((GtkContainer *) automation_editor->input_scrolled_automation_edit_box->automation_edit_box);
460     }
461     break;
462   default:
463     {
464       list =
465 	start_list = NULL;
466     }
467   }
468 
469 
470   while(list != NULL){
471     gtk_widget_queue_draw((GtkWidget *) list->data);
472 
473     list = list->next;
474   }
475 
476   g_list_free(start_list);
477 }
478