1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2021 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.h>
21 #include <ags/X/editor/ags_automation_toolbar_callbacks.h>
22
23 #include <ags/X/ags_window.h>
24 #include <ags/X/ags_automation_window.h>
25 #include <ags/X/ags_menu_bar.h>
26 #include <ags/X/ags_automation_editor.h>
27 #include <ags/X/ags_automation_editor_callbacks.h>
28 #include <ags/X/ags_pad.h>
29 #include <ags/X/ags_line.h>
30 #include <ags/X/ags_line_member.h>
31
32 #include <ags/X/editor/ags_select_acceleration_dialog.h>
33 #include <ags/X/editor/ags_ramp_acceleration_dialog.h>
34 #include <ags/X/editor/ags_position_automation_cursor_dialog.h>
35
36 #include <ags/config.h>
37 #include <ags/i18n.h>
38
39 void ags_automation_toolbar_class_init(AgsAutomationToolbarClass *automation_toolbar);
40 void ags_automation_toolbar_connectable_interface_init(AgsConnectableInterface *connectable);
41 void ags_automation_toolbar_init(AgsAutomationToolbar *automation_toolbar);
42 void ags_automation_toolbar_connect(AgsConnectable *connectable);
43 void ags_automation_toolbar_disconnect(AgsConnectable *connectable);
44
45 /**
46 * SECTION:ags_automation_toolbar
47 * @short_description: automation toolbar
48 * @title: AgsAutomationToolbar
49 * @section_id:
50 * @include: ags/X/editor/ags_automation_toolbar.h
51 *
52 * The #AgsAutomationToolbar lets you choose edit tool.
53 */
54
55 GType
ags_automation_toolbar_get_type(void)56 ags_automation_toolbar_get_type(void)
57 {
58 static volatile gsize g_define_type_id__volatile = 0;
59
60 if(g_once_init_enter (&g_define_type_id__volatile)){
61 GType ags_type_automation_toolbar = 0;
62
63 static const GTypeInfo ags_automation_toolbar_info = {
64 sizeof (AgsAutomationToolbarClass),
65 NULL, /* base_init */
66 NULL, /* base_finalize */
67 (GClassInitFunc) ags_automation_toolbar_class_init,
68 NULL, /* class_finalize */
69 NULL, /* class_data */
70 sizeof (AgsAutomationToolbar),
71 0, /* n_preallocs */
72 (GInstanceInitFunc) ags_automation_toolbar_init,
73 };
74
75 static const GInterfaceInfo ags_connectable_interface_info = {
76 (GInterfaceInitFunc) ags_automation_toolbar_connectable_interface_init,
77 NULL, /* interface_finalize */
78 NULL, /* interface_data */
79 };
80
81 ags_type_automation_toolbar = g_type_register_static(GTK_TYPE_TOOLBAR,
82 "AgsAutomationToolbar", &ags_automation_toolbar_info,
83 0);
84
85 g_type_add_interface_static(ags_type_automation_toolbar,
86 AGS_TYPE_CONNECTABLE,
87 &ags_connectable_interface_info);
88
89 g_once_init_leave(&g_define_type_id__volatile, ags_type_automation_toolbar);
90 }
91
92 return g_define_type_id__volatile;
93 }
94
95 void
ags_automation_toolbar_class_init(AgsAutomationToolbarClass * automation_toolbar)96 ags_automation_toolbar_class_init(AgsAutomationToolbarClass *automation_toolbar)
97 {
98 }
99
100 void
ags_automation_toolbar_connectable_interface_init(AgsConnectableInterface * connectable)101 ags_automation_toolbar_connectable_interface_init(AgsConnectableInterface *connectable)
102 {
103 connectable->is_ready = NULL;
104 connectable->is_connected = NULL;
105 connectable->connect = ags_automation_toolbar_connect;
106 connectable->disconnect = ags_automation_toolbar_disconnect;
107 }
108
109 void
ags_automation_toolbar_init(AgsAutomationToolbar * automation_toolbar)110 ags_automation_toolbar_init(AgsAutomationToolbar *automation_toolbar)
111 {
112 GtkToolItem *tool_item;
113 GtkMenuToolButton *menu_tool_button;
114 GtkMenu *menu;
115 GtkMenuItem *item;
116 GtkLabel *label;
117 GtkCellRenderer *cell_renderer;
118 GtkHBox *hbox;
119
120 /* position */
121 tool_item = gtk_tool_item_new();
122 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
123 (GtkWidget *) tool_item,
124 -1);
125
126 automation_toolbar->position = (GtkToggleToolButton *) g_object_new(GTK_TYPE_TOGGLE_TOOL_BUTTON,
127 "label", i18n("Position"),
128 "icon-name", "go-jump",
129 NULL);
130 gtk_container_add((GtkContainer *) tool_item,
131 (GtkWidget *) automation_toolbar->position);
132
133 /* edit */
134 tool_item = gtk_tool_item_new();
135 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
136 (GtkWidget *) tool_item,
137 -1);
138
139 automation_toolbar->edit = (GtkToggleToolButton *) g_object_new(GTK_TYPE_TOGGLE_TOOL_BUTTON,
140 "label", i18n("Edit"),
141 "icon-name", "format-text-direction-ltr",
142 "active", TRUE,
143 NULL);
144 automation_toolbar->selected_edit_mode = automation_toolbar->edit;
145 gtk_container_add((GtkContainer *) tool_item,
146 (GtkWidget *) automation_toolbar->edit);
147
148 /* clear */
149 tool_item = gtk_tool_item_new();
150 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
151 (GtkWidget *) tool_item,
152 -1);
153
154 automation_toolbar->clear = (GtkToggleToolButton *) g_object_new(GTK_TYPE_TOGGLE_TOOL_BUTTON,
155 "label", i18n("Clear"),
156 "icon-name", "edit-clear",
157 NULL);
158 gtk_container_add((GtkContainer *) tool_item,
159 (GtkWidget *) automation_toolbar->clear);
160
161 /* select */
162 tool_item = gtk_tool_item_new();
163 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
164 (GtkWidget *) tool_item,
165 -1);
166
167 automation_toolbar->select = (GtkToggleToolButton *) g_object_new(GTK_TYPE_TOGGLE_TOOL_BUTTON,
168 "label", i18n("Select"),
169 "icon-name", "edit-select-all",
170 NULL);
171 gtk_container_add((GtkContainer *) tool_item,
172 (GtkWidget *) automation_toolbar->select);
173
174 /* copy */
175 tool_item = gtk_tool_item_new();
176 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
177 (GtkWidget *) tool_item,
178 -1);
179
180 automation_toolbar->copy = (GtkToolButton *) g_object_new(GTK_TYPE_TOOL_BUTTON,
181 "label", i18n("Copy"),
182 "icon-name", "edit-copy",
183 NULL);
184 gtk_container_add((GtkContainer *) tool_item,
185 (GtkWidget *) automation_toolbar->copy);
186
187 /* cut */
188 tool_item = gtk_tool_item_new();
189 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
190 (GtkWidget *) tool_item,
191 -1);
192
193 automation_toolbar->cut = (GtkToolButton *) g_object_new(GTK_TYPE_TOOL_BUTTON,
194 "label", i18n("Cut"),
195 "icon-name", "edit-cut",
196 NULL);
197 gtk_container_add((GtkContainer *) tool_item,
198 (GtkWidget *) automation_toolbar->cut);
199
200 /* paste */
201 tool_item = gtk_tool_item_new();
202 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
203 (GtkWidget *) tool_item,
204 -1);
205
206 automation_toolbar->paste_tool = (GtkMenuToolButton *) g_object_new(GTK_TYPE_MENU_TOOL_BUTTON,
207 "label", i18n("Paste"),
208 "icon-name", "edit-paste",
209 NULL);
210
211 menu = (GtkMenu *) gtk_menu_new();
212
213 item = g_object_new(GTK_TYPE_CHECK_MENU_ITEM,
214 "label", "match line",
215 "active", TRUE,
216 NULL);
217 gtk_menu_shell_append((GtkMenuShell *) menu,
218 (GtkWidget *) item);
219
220 item = g_object_new(GTK_TYPE_CHECK_MENU_ITEM,
221 "label", "no duplicates",
222 "active", TRUE,
223 NULL);
224 gtk_menu_shell_append((GtkMenuShell *) menu,
225 (GtkWidget *) item);
226
227 gtk_menu_tool_button_set_menu(automation_toolbar->paste_tool,
228 (GtkWidget *) menu);
229 gtk_widget_show_all((GtkWidget *) menu);
230
231 gtk_container_add((GtkContainer *) tool_item,
232 (GtkWidget *) automation_toolbar->paste_tool);
233
234 /* menu tool */
235 tool_item = gtk_tool_item_new();
236 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
237 (GtkWidget *) tool_item,
238 -1);
239
240 automation_toolbar->menu_tool = (GtkMenuToolButton *) g_object_new(GTK_TYPE_MENU_TOOL_BUTTON,
241 "label", i18n("Tool"),
242 "icon-name", "system-run",
243 NULL);
244 gtk_container_add((GtkContainer *) tool_item,
245 (GtkWidget *) automation_toolbar->menu_tool);
246
247 /* menu tool - tool popup */
248 automation_toolbar->tool_popup = ags_automation_toolbar_tool_popup_new(automation_toolbar);
249 gtk_menu_tool_button_set_menu(automation_toolbar->menu_tool,
250 (GtkWidget *) automation_toolbar->tool_popup);
251
252 /* menu tool - dialogs */
253 automation_toolbar->select_acceleration = (GtkDialog *) ags_select_acceleration_dialog_new(NULL);
254 automation_toolbar->ramp_acceleration = (GtkDialog *) ags_ramp_acceleration_dialog_new(NULL);
255 automation_toolbar->position_automation_cursor = (GtkDialog *) ags_position_automation_cursor_dialog_new(NULL);
256
257 /* */
258 tool_item = gtk_tool_item_new();
259 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
260 (GtkWidget *) tool_item,
261 -1);
262
263 hbox = gtk_hbox_new(FALSE,
264 0);
265 gtk_container_add((GtkContainer *) tool_item,
266 (GtkWidget *) hbox);
267
268
269 label = (GtkLabel *) gtk_label_new(i18n("Zoom"));
270 gtk_box_pack_start(hbox,
271 (GtkWidget *) label,
272 FALSE, FALSE,
273 0);
274
275 automation_toolbar->zoom_history = 2;
276 automation_toolbar->zoom = ags_zoom_combo_box_new();
277 gtk_combo_box_set_active(GTK_COMBO_BOX(automation_toolbar->zoom),
278 2);
279 gtk_box_pack_start(hbox,
280 (GtkWidget *) automation_toolbar->zoom,
281 FALSE, FALSE,
282 0);
283
284 /* port */
285 tool_item = gtk_tool_item_new();
286 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
287 (GtkWidget *) tool_item,
288 -1);
289
290 hbox = gtk_hbox_new(FALSE,
291 0);
292 gtk_container_add((GtkContainer *) tool_item,
293 (GtkWidget *) hbox);
294
295 label = (GtkLabel *) gtk_label_new(i18n("Port"));
296 gtk_box_pack_start(hbox,
297 (GtkWidget *) label,
298 FALSE, FALSE,
299 0);
300
301 automation_toolbar->port = (GtkComboBox *) gtk_combo_box_new();
302
303 cell_renderer = gtk_cell_renderer_toggle_new();
304 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(automation_toolbar->port),
305 cell_renderer,
306 FALSE);
307 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(automation_toolbar->port), cell_renderer,
308 "active", 0,
309 NULL);
310 gtk_cell_renderer_toggle_set_activatable(GTK_CELL_RENDERER_TOGGLE(cell_renderer),
311 TRUE);
312
313 cell_renderer = gtk_cell_renderer_text_new();
314 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(automation_toolbar->port),
315 cell_renderer,
316 FALSE);
317 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(automation_toolbar->port), cell_renderer,
318 "text", 1,
319 NULL);
320
321 cell_renderer = gtk_cell_renderer_text_new();
322 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(automation_toolbar->port),
323 cell_renderer,
324 FALSE);
325 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(automation_toolbar->port), cell_renderer,
326 "text", 2,
327 NULL);
328
329 gtk_box_pack_start(hbox,
330 (GtkWidget *) automation_toolbar->port,
331 FALSE, FALSE,
332 0);
333
334 /* opacity */
335 tool_item = gtk_tool_item_new();
336 gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
337 (GtkWidget *) tool_item,
338 -1);
339
340 hbox = gtk_hbox_new(FALSE,
341 0);
342 gtk_container_add((GtkContainer *) tool_item,
343 (GtkWidget *) hbox);
344
345 label = (GtkLabel *) gtk_label_new(i18n("Opacity"));
346 gtk_box_pack_start(hbox,
347 (GtkWidget *) label,
348 FALSE, FALSE,
349 0);
350
351 automation_toolbar->opacity = (GtkSpinButton *) gtk_spin_button_new_with_range(0.0, 1.0, 0.001);
352 gtk_spin_button_set_value(automation_toolbar->opacity, 0.3);
353 gtk_box_pack_start(hbox,
354 (GtkWidget *) automation_toolbar->opacity,
355 FALSE, FALSE,
356 0);
357 }
358
359
360 void
ags_automation_toolbar_connect(AgsConnectable * connectable)361 ags_automation_toolbar_connect(AgsConnectable *connectable)
362 {
363 AgsWindow *window;
364 AgsAutomationWindow *automation_window;
365 AgsAutomationEditor *automation_editor;
366 AgsAutomationToolbar *automation_toolbar;
367
368 GList *list;
369
370 automation_toolbar = AGS_AUTOMATION_TOOLBAR(connectable);
371
372 if((AGS_AUTOMATION_TOOLBAR_CONNECTED & (automation_toolbar->flags)) != 0){
373 return;
374 }
375
376 automation_toolbar->flags |= AGS_AUTOMATION_TOOLBAR_CONNECTED;
377
378 automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
379 AGS_TYPE_AUTOMATION_EDITOR);
380
381 automation_window = (AgsAutomationWindow *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
382 AGS_TYPE_AUTOMATION_WINDOW);
383 window = (AgsWindow *) automation_window->parent_window;
384
385 g_object_set(automation_toolbar->select_acceleration,
386 "main-window", window,
387 NULL);
388 g_object_set(automation_toolbar->ramp_acceleration,
389 "main-window", window,
390 NULL);
391 g_object_set(automation_toolbar->position_automation_cursor,
392 "main-window", window,
393 NULL);
394
395 /* */
396 g_signal_connect_after(G_OBJECT(automation_editor), "machine-changed",
397 G_CALLBACK(ags_automation_toolbar_machine_changed_callback), automation_toolbar);
398
399 /* tool */
400 g_signal_connect_after((GObject *) automation_toolbar->position, "toggled",
401 G_CALLBACK(ags_automation_toolbar_position_callback), (gpointer) automation_toolbar);
402
403 g_signal_connect_after((GObject *) automation_toolbar->edit, "toggled",
404 G_CALLBACK(ags_automation_toolbar_edit_callback), (gpointer) automation_toolbar);
405
406 g_signal_connect_after((GObject *) automation_toolbar->clear, "toggled",
407 G_CALLBACK(ags_automation_toolbar_clear_callback), (gpointer) automation_toolbar);
408
409 g_signal_connect_after((GObject *) automation_toolbar->select, "toggled",
410 G_CALLBACK(ags_automation_toolbar_select_callback), (gpointer) automation_toolbar);
411
412 /* edit */
413 g_signal_connect((GObject *) automation_toolbar->copy, "clicked",
414 G_CALLBACK(ags_automation_toolbar_copy_or_cut_callback), (gpointer) automation_toolbar);
415
416 g_signal_connect((GObject *) automation_toolbar->cut, "clicked",
417 G_CALLBACK(ags_automation_toolbar_copy_or_cut_callback), (gpointer) automation_toolbar);
418
419 g_signal_connect((GObject *) automation_toolbar->paste_tool, "clicked",
420 G_CALLBACK(ags_automation_toolbar_paste_callback), (gpointer) automation_toolbar);
421
422 list = gtk_container_get_children((GtkContainer *) gtk_menu_tool_button_get_menu(automation_toolbar->paste_tool));
423
424 g_signal_connect_after(list->data, "activate",
425 G_CALLBACK(ags_automation_toolbar_match_line_callback), automation_toolbar);
426
427 g_signal_connect_after(list->next->data, "activate",
428 G_CALLBACK(ags_automation_toolbar_no_duplicates_callback), automation_toolbar);
429
430 g_list_free(list);
431
432 /* additional tools */
433 ags_connectable_connect(AGS_CONNECTABLE(automation_toolbar->select_acceleration));
434
435 ags_connectable_connect(AGS_CONNECTABLE(automation_toolbar->ramp_acceleration));
436
437 ags_connectable_connect(AGS_CONNECTABLE(automation_toolbar->position_automation_cursor));
438
439 /* zoom */
440 g_signal_connect_after((GObject *) automation_toolbar->zoom, "changed",
441 G_CALLBACK(ags_automation_toolbar_zoom_callback), (gpointer) automation_toolbar);
442
443 /* port */
444 g_signal_connect_after(automation_toolbar->port, "changed",
445 G_CALLBACK(ags_automation_toolbar_port_callback), automation_toolbar);
446
447 /* opacity */
448 g_signal_connect_after((GObject *) automation_toolbar->opacity, "value-changed",
449 G_CALLBACK(ags_automation_toolbar_opacity_callback), (gpointer) automation_toolbar);
450 }
451
452 void
ags_automation_toolbar_disconnect(AgsConnectable * connectable)453 ags_automation_toolbar_disconnect(AgsConnectable *connectable)
454 {
455 AgsAutomationToolbar *automation_toolbar;
456
457 GList *list;
458
459 automation_toolbar = AGS_AUTOMATION_TOOLBAR(connectable);
460
461 if((AGS_AUTOMATION_TOOLBAR_CONNECTED & (automation_toolbar->flags)) == 0){
462 return;
463 }
464
465 automation_toolbar->flags &= (~AGS_AUTOMATION_TOOLBAR_CONNECTED);
466
467 /* tool */
468 g_object_disconnect(G_OBJECT(automation_toolbar->position),
469 "any_signal::toggled",
470 G_CALLBACK(ags_automation_toolbar_position_callback),
471 automation_toolbar,
472 NULL);
473
474 g_object_disconnect(G_OBJECT(automation_toolbar->edit),
475 "any_signal::toggled",
476 G_CALLBACK(ags_automation_toolbar_edit_callback),
477 automation_toolbar,
478 NULL);
479
480 g_object_disconnect(G_OBJECT(automation_toolbar->clear),
481 "any_signal::toggled",
482 G_CALLBACK(ags_automation_toolbar_clear_callback),
483 automation_toolbar,
484 NULL);
485
486 g_object_disconnect(G_OBJECT(automation_toolbar->select),
487 "any_signal::toggled",
488 G_CALLBACK(ags_automation_toolbar_select_callback),
489 automation_toolbar,
490 NULL);
491
492 /* edit */
493 g_object_disconnect(G_OBJECT(automation_toolbar->copy),
494 "any_signal::clicked",
495 G_CALLBACK(ags_automation_toolbar_copy_or_cut_callback),
496 automation_toolbar,
497 NULL);
498
499 g_object_disconnect(G_OBJECT(automation_toolbar->cut),
500 "any_signal::clicked",
501 G_CALLBACK(ags_automation_toolbar_copy_or_cut_callback),
502 automation_toolbar,
503 NULL);
504
505 g_object_disconnect(G_OBJECT(automation_toolbar->paste_tool),
506 "any_signal::clicked",
507 G_CALLBACK(ags_automation_toolbar_paste_callback),
508 automation_toolbar,
509 NULL);
510
511 list = gtk_container_get_children((GtkContainer *) gtk_menu_tool_button_get_menu(automation_toolbar->paste_tool));
512
513 g_object_disconnect(G_OBJECT(list->data),
514 "any_signal::activate",
515 G_CALLBACK(ags_automation_toolbar_match_line_callback),
516 automation_toolbar,
517 NULL);
518
519 g_object_disconnect(G_OBJECT(list->next->data),
520 "any_signal::activate",
521 G_CALLBACK(ags_automation_toolbar_no_duplicates_callback),
522 automation_toolbar,
523 NULL);
524
525 g_list_free(list);
526
527 /* additional tools */
528 ags_connectable_disconnect(AGS_CONNECTABLE(automation_toolbar->select_acceleration));
529
530 ags_connectable_disconnect(AGS_CONNECTABLE(automation_toolbar->ramp_acceleration));
531
532 ags_connectable_disconnect(AGS_CONNECTABLE(automation_toolbar->position_automation_cursor));
533
534 /* zoom */
535 g_object_disconnect(G_OBJECT(automation_toolbar->zoom),
536 "any_signal::changed",
537 G_CALLBACK(ags_automation_toolbar_zoom_callback),
538 automation_toolbar,
539 NULL);
540
541 /* port */
542 g_object_disconnect(G_OBJECT(automation_toolbar->port),
543 "any_signal::changed",
544 G_CALLBACK(ags_automation_toolbar_port_callback),
545 automation_toolbar,
546 NULL);
547
548 /* opacity */
549 g_object_disconnect(G_OBJECT(automation_toolbar->opacity),
550 "any_signal::value-changed",
551 G_CALLBACK(ags_automation_toolbar_opacity_callback),
552 automation_toolbar,
553 NULL);
554 }
555
556 /**
557 * ags_automation_toolbar_load_port:
558 * @automation_toolbar: an #AgsAutomationToolbar
559 *
560 * Fill in port field with available ports.
561 *
562 * Since: 3.0.0
563 */
564 void
ags_automation_toolbar_load_port(AgsAutomationToolbar * automation_toolbar)565 ags_automation_toolbar_load_port(AgsAutomationToolbar *automation_toolbar)
566 {
567 AgsAutomationEditor *automation_editor;
568 AgsMachine *machine;
569
570 GtkListStore *list_store;
571 GtkTreeIter iter;
572
573 AgsChannel *start_channel;
574 AgsChannel *channel, *next_channel;
575
576 GList *start_port, *port;
577
578 gchar **collected_specifier;
579
580 guint length;
581
582 automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
583 AGS_TYPE_AUTOMATION_EDITOR);
584 machine = automation_editor->selected_machine;
585
586 if(machine == NULL){
587 gtk_combo_box_set_model(automation_toolbar->port,
588 NULL);
589 return;
590 }
591
592 /* */
593 list_store = gtk_list_store_new(3,
594 G_TYPE_BOOLEAN,
595 G_TYPE_STRING,
596 G_TYPE_STRING);
597 gtk_combo_box_set_model(automation_toolbar->port,
598 GTK_TREE_MODEL(list_store));
599
600 collected_specifier = (gchar **) malloc(sizeof(gchar*));
601
602 collected_specifier[0] = NULL;
603 length = 1;
604
605 /* audio */
606 port =
607 start_port = ags_audio_collect_all_audio_ports(machine->audio);
608
609 while(port != NULL){
610 AgsPluginPort *plugin_port;
611
612 gchar *specifier;
613
614 gboolean is_enabled;
615 gboolean contains_control_name;
616
617 g_object_get(port->data,
618 "specifier", &specifier,
619 "plugin-port", &plugin_port,
620 NULL);
621
622 if(specifier == NULL){
623 /* iterate */
624 port = port->next;
625
626 continue;
627 }
628
629 #ifdef HAVE_GLIB_2_44
630 contains_control_name = g_strv_contains(collected_specifier,
631 specifier);
632 #else
633 contains_control_name = ags_strv_contains(collected_specifier,
634 specifier);
635 #endif
636
637 if(plugin_port != NULL &&
638 !contains_control_name){
639 /* create list store entry */
640 is_enabled = (ags_machine_automation_port_find_channel_type_with_control_name(machine->enabled_automation_port,
641 G_TYPE_NONE,
642 specifier)) ? TRUE: FALSE;
643
644 gtk_list_store_append(list_store, &iter);
645 gtk_list_store_set(list_store, &iter,
646 0, is_enabled,
647 1, g_strdup("audio"),
648 2, g_strdup(specifier),
649 -1);
650
651 /* add to collected specifier */
652 collected_specifier = (gchar **) realloc(collected_specifier,
653 (length + 1) * sizeof(gchar *));
654 collected_specifier[length - 1] = g_strdup(specifier);
655 collected_specifier[length] = NULL;
656
657 length++;
658 }
659
660 /* iterate */
661 port = port->next;
662 }
663
664 g_list_free_full(start_port,
665 g_object_unref);
666
667 /* output */
668 g_object_get(machine->audio,
669 "output", &start_channel,
670 NULL);
671
672 channel = start_channel;
673 g_object_ref(channel);
674
675 next_channel = NULL;
676
677 while(channel != NULL){
678 /* output */
679 port =
680 start_port = ags_channel_collect_all_channel_ports(channel);
681
682 while(port != NULL){
683 AgsPluginPort *plugin_port;
684
685 gchar *specifier;
686
687 gboolean is_enabled;
688 gboolean contains_control_name;
689
690 g_object_get(port->data,
691 "specifier", &specifier,
692 "plugin-port", &plugin_port,
693 NULL);
694
695 contains_control_name = g_strv_contains(collected_specifier,
696 specifier);
697
698 if(plugin_port != NULL &&
699 !contains_control_name){
700 /* create list store entry */
701 is_enabled = (ags_machine_automation_port_find_channel_type_with_control_name(machine->enabled_automation_port,
702 AGS_TYPE_OUTPUT,
703 specifier)) ? TRUE: FALSE;
704
705 gtk_list_store_append(list_store, &iter);
706 gtk_list_store_set(list_store, &iter,
707 0, is_enabled,
708 1, g_strdup("output"),
709 2, g_strdup(specifier),
710 -1);
711
712 /* add to collected specifier */
713 collected_specifier = (gchar **) realloc(collected_specifier,
714 (length + 1) * sizeof(gchar *));
715 collected_specifier[length - 1] = g_strdup(specifier);
716 collected_specifier[length] = NULL;
717
718 length++;
719 }
720
721 /* iterate */
722 port = port->next;
723 }
724
725 g_list_free_full(start_port,
726 g_object_unref);
727
728 /* iterate */
729 next_channel = ags_channel_next(channel);
730
731 g_object_unref(channel);
732
733 channel = next_channel;
734 }
735
736 /* unref */
737 if(start_channel != NULL){
738 g_object_unref(start_channel);
739 }
740
741 if(next_channel != NULL){
742 g_object_unref(next_channel);
743 }
744
745 /* input */
746 g_object_get(machine->audio,
747 "input", &start_channel,
748 NULL);
749
750 channel = start_channel;
751 g_object_ref(channel);
752
753 next_channel = NULL;
754
755 while(channel != NULL){
756 /* input */
757 port =
758 start_port = ags_channel_collect_all_channel_ports(channel);
759
760 while(port != NULL){
761 AgsPluginPort *plugin_port;
762
763 gchar *specifier;
764
765 gboolean is_enabled;
766 gboolean contains_control_name;
767
768 g_object_get(port->data,
769 "specifier", &specifier,
770 "plugin-port", &plugin_port,
771 NULL);
772
773 #ifdef HAVE_GLIB_2_44
774 contains_control_name = g_strv_contains(collected_specifier,
775 specifier);
776 #else
777 contains_control_name = ags_strv_contains(collected_specifier,
778 specifier);
779 #endif
780
781 if(plugin_port != NULL &&
782 !contains_control_name){
783 /* create list store entry */
784 is_enabled = (ags_machine_automation_port_find_channel_type_with_control_name(machine->enabled_automation_port,
785 AGS_TYPE_INPUT,
786 specifier)) ? TRUE: FALSE;
787
788 gtk_list_store_append(list_store, &iter);
789 gtk_list_store_set(list_store, &iter,
790 0, is_enabled,
791 1, g_strdup("input"),
792 2, g_strdup(specifier),
793 -1);
794
795 /* add to collected specifier */
796 collected_specifier = (gchar **) realloc(collected_specifier,
797 (length + 1) * sizeof(gchar *));
798 collected_specifier[length - 1] = g_strdup(specifier);
799 collected_specifier[length] = NULL;
800
801 length++;
802 }
803
804 /* iterate */
805 port = port->next;
806 }
807
808 g_list_free_full(start_port,
809 g_object_unref);
810
811 /* iterate */
812 next_channel = ags_channel_next(channel);
813
814 g_object_unref(channel);
815
816 channel = next_channel;
817 }
818
819 /* unref */
820 if(start_channel != NULL){
821 g_object_unref(start_channel);
822 }
823
824 if(next_channel != NULL){
825 g_object_unref(next_channel);
826 }
827
828 g_strfreev(collected_specifier);
829
830 gtk_list_store_append(list_store, &iter);
831 gtk_list_store_set(list_store, &iter,
832 0, FALSE,
833 1, g_strdup(""),
834 2, g_strdup(""),
835 -1);
836 gtk_combo_box_set_active_iter(automation_toolbar->port,
837 &iter);
838 }
839
840 /**
841 * ags_automation_toolbar_apply_port:
842 * @automation_toolbar: an #AgsAutomationToolbar
843 * @channel_type: the #GType of channel
844 * @control_name: the specifier as string
845 *
846 * Applies all port to appropriate #AgsMachine.
847 *
848 * Since: 3.0.0
849 */
850 void
ags_automation_toolbar_apply_port(AgsAutomationToolbar * automation_toolbar,GType channel_type,gchar * control_name)851 ags_automation_toolbar_apply_port(AgsAutomationToolbar *automation_toolbar,
852 GType channel_type, gchar *control_name)
853 {
854 AgsAutomationEditor *automation_editor;
855 AgsMachine *machine;
856
857 GtkTreeModel *model;
858 GtkTreeIter iter;
859
860 AgsChannel *start_channel;
861 AgsChannel *channel, *next_channel;
862
863 AgsConfig *config;
864
865 GList *start_automation, *automation;
866 GList *start_port, *port;
867
868 gchar *str;
869
870 gdouble gui_scale_factor;
871 guint length;
872 gboolean contains_specifier;
873 gboolean is_active;
874
875 if(!g_ascii_strncasecmp(control_name,
876 "",
877 1)){
878 return;
879 }
880
881 automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
882 AGS_TYPE_AUTOMATION_EDITOR);
883 machine = automation_editor->selected_machine;
884
885 model = gtk_combo_box_get_model(automation_toolbar->port);
886
887 config = ags_config_get_instance();
888
889 /* scale factor */
890 gui_scale_factor = 1.0;
891
892 str = ags_config_get_value(config,
893 AGS_CONFIG_GENERIC,
894 "gui-scale");
895
896 if(str != NULL){
897 gui_scale_factor = g_ascii_strtod(str,
898 NULL);
899
900 g_free(str);
901 }
902
903 /* update port combo box */
904 start_port = NULL;
905
906 contains_specifier = FALSE;
907
908 if(gtk_combo_box_get_active_iter(automation_toolbar->port, &iter)){
909 GType scope;
910 gchar *str, *specifier;
911
912 GValue value = {0,};
913
914 gtk_tree_model_get(model,
915 &iter,
916 1, &str,
917 2, &specifier,
918 -1);
919
920 scope = G_TYPE_NONE;
921
922 if(!g_ascii_strcasecmp("audio",
923 str)){
924 scope = G_TYPE_NONE;
925
926 port = ags_audio_collect_all_audio_ports_by_specifier_and_context(machine->audio,
927 control_name,
928 TRUE);
929 start_port = port;
930
931 port = ags_audio_collect_all_audio_ports_by_specifier_and_context(machine->audio,
932 control_name,
933 FALSE);
934
935 if(start_port != NULL){
936 start_port = g_list_concat(start_port,
937 port);
938 }else{
939 start_port = port;
940 }
941 }else if(!g_ascii_strcasecmp("output",
942 str)){
943 scope = AGS_TYPE_OUTPUT;
944
945 g_object_get(machine->audio,
946 "output", &start_channel,
947 NULL);
948
949 channel = start_channel;
950 g_object_ref(channel);
951
952 next_channel = NULL;
953
954 start_port = NULL;
955
956 while(channel != NULL){
957 port = ags_channel_collect_all_channel_ports_by_specifier_and_context(channel,
958 control_name,
959 TRUE);
960 if(start_port != NULL){
961 start_port = g_list_concat(start_port,
962 port);
963 }else{
964 start_port = port;
965 }
966
967 port = ags_channel_collect_all_channel_ports_by_specifier_and_context(channel,
968 control_name,
969 FALSE);
970
971 if(start_port != NULL){
972 start_port = g_list_concat(start_port,
973 port);
974 }else{
975 start_port = port;
976 }
977
978 /* iterate */
979 next_channel = ags_channel_next(channel);
980
981 g_object_unref(channel);
982
983 channel = next_channel;
984 }
985
986 /* unref */
987 if(start_channel != NULL){
988 g_object_unref(start_channel);
989 }
990
991 if(next_channel != NULL){
992 g_object_unref(next_channel);
993 }
994 }else if(!g_ascii_strcasecmp("input",
995 str)){
996 scope = AGS_TYPE_INPUT;
997
998 g_object_get(machine->audio,
999 "input", &start_channel,
1000 NULL);
1001
1002 channel = start_channel;
1003 g_object_ref(channel);
1004
1005 next_channel = NULL;
1006
1007 start_port = NULL;
1008
1009 while(channel != NULL){
1010 port = ags_channel_collect_all_channel_ports_by_specifier_and_context(channel,
1011 control_name,
1012 TRUE);
1013 if(start_port != NULL){
1014 start_port = g_list_concat(start_port,
1015 port);
1016 }else{
1017 start_port = port;
1018 }
1019
1020 port = ags_channel_collect_all_channel_ports_by_specifier_and_context(channel,
1021 control_name,
1022 FALSE);
1023
1024 if(start_port != NULL){
1025 start_port = g_list_concat(start_port,
1026 port);
1027 }else{
1028 start_port = port;
1029 }
1030
1031 /* iterate */
1032 next_channel = ags_channel_next(channel);
1033
1034 g_object_unref(channel);
1035
1036 channel = next_channel;
1037 }
1038
1039 /* unref */
1040 if(start_channel != NULL){
1041 g_object_unref(start_channel);
1042 }
1043
1044 if(next_channel != NULL){
1045 g_object_unref(next_channel);
1046 }
1047 }
1048
1049 if(scope == channel_type &&
1050 !g_ascii_strcasecmp(specifier,
1051 control_name)){
1052 gtk_tree_model_get_value(model,
1053 &iter,
1054 0, &value);
1055
1056 if(g_value_get_boolean(&value)){
1057 g_value_set_boolean(&value, FALSE);
1058 }else{
1059 g_value_set_boolean(&value, TRUE);
1060
1061 contains_specifier = TRUE;
1062 }
1063
1064 gtk_list_store_set_value(GTK_LIST_STORE(model),
1065 &iter,
1066 0,
1067 &value);
1068 }
1069 }
1070
1071 /* add/remove enabled automation port */
1072 if(contains_specifier){
1073 machine->enabled_automation_port = g_list_prepend(machine->enabled_automation_port,
1074 ags_machine_automation_port_alloc(channel_type, control_name));
1075 }else{
1076 machine->enabled_automation_port = g_list_delete_link(machine->enabled_automation_port,
1077 ags_machine_automation_port_find_channel_type_with_control_name(machine->enabled_automation_port,
1078 channel_type, control_name));
1079 }
1080
1081 g_object_get(machine->audio,
1082 "automation", &start_automation,
1083 NULL);
1084
1085 /* apply */
1086 if(contains_specifier){
1087 AgsAutomationEdit *automation_edit;
1088 AgsScale *scale;
1089
1090 AgsPluginPort *plugin_port;
1091
1092 gchar *specifier;
1093
1094 gdouble upper, lower;
1095 gdouble default_value;
1096
1097 GValue *upper_value, *lower_value;
1098 GValue *value;
1099
1100 /* scale */
1101 scale = ags_scale_new();
1102 g_object_set(scale,
1103 "scale-width", (guint) (gui_scale_factor * AGS_SCALE_DEFAULT_SCALE_WIDTH),
1104 "scale-height", (guint) (gui_scale_factor * AGS_SCALE_DEFAULT_SCALE_HEIGHT),
1105 NULL);
1106
1107 /* get some fields */
1108 plugin_port = NULL;
1109
1110 if(start_port != NULL){
1111 g_object_get(start_port->data,
1112 "plugin-port", &plugin_port,
1113 NULL);
1114 }
1115
1116 if(plugin_port != NULL){
1117 g_object_get(plugin_port,
1118 "upper-value", &upper_value,
1119 "lower-value", &lower_value,
1120 "default-value", &value,
1121 NULL);
1122
1123 upper = g_value_get_float(upper_value);
1124 lower = g_value_get_float(lower_value);
1125
1126 default_value = g_value_get_float(value);
1127
1128 g_object_unref(plugin_port);
1129 }else{
1130 upper = 1.0;
1131 lower = 0.0;
1132
1133 default_value = 1.0;
1134 }
1135
1136 specifier = g_strdup(control_name);
1137
1138 /* apply scale */
1139 g_object_set(scale,
1140 "control-name", specifier,
1141 "upper", upper,
1142 "lower", lower,
1143 "default-value", default_value,
1144 NULL);
1145
1146 if(channel_type == G_TYPE_NONE){
1147 gtk_box_pack_start((GtkBox *) automation_editor->audio_scrolled_scale_box->scale_box,
1148 (GtkWidget *) scale,
1149 FALSE, FALSE,
1150 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1151 }else if(channel_type == AGS_TYPE_OUTPUT){
1152 gtk_box_pack_start((GtkBox *) automation_editor->output_scrolled_scale_box->scale_box,
1153 (GtkWidget *) scale,
1154 FALSE, FALSE,
1155 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1156 }else if(channel_type == AGS_TYPE_INPUT){
1157 gtk_box_pack_start((GtkBox *) automation_editor->input_scrolled_scale_box->scale_box,
1158 (GtkWidget *) scale,
1159 FALSE, FALSE,
1160 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1161 }
1162
1163 gtk_widget_show((GtkWidget *) scale);
1164
1165 /* automation edit */
1166 automation_edit = ags_automation_edit_new();
1167
1168 g_object_set(automation_edit,
1169 "channel-type", channel_type,
1170 "control-specifier", specifier,
1171 "control-name", control_name,
1172 "upper", upper,
1173 "lower", lower,
1174 "default-value", default_value,
1175 "upper", upper,
1176 "lower", lower,
1177 NULL);
1178
1179 if(plugin_port != NULL &&
1180 ags_plugin_port_test_flags(plugin_port, AGS_PLUGIN_PORT_LOGARITHMIC)){
1181 automation_edit->flags |= AGS_AUTOMATION_EDIT_LOGARITHMIC;
1182 }
1183
1184 if(channel_type == G_TYPE_NONE){
1185 gtk_box_pack_start((GtkBox *) automation_editor->audio_scrolled_automation_edit_box->automation_edit_box,
1186 (GtkWidget *) automation_edit,
1187 FALSE, FALSE,
1188 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1189 }else if(channel_type == AGS_TYPE_OUTPUT){
1190 gtk_box_pack_start((GtkBox *) automation_editor->output_scrolled_automation_edit_box->automation_edit_box,
1191 (GtkWidget *) automation_edit,
1192 FALSE, FALSE,
1193 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1194 }else if(channel_type == AGS_TYPE_INPUT){
1195 gtk_box_pack_start((GtkBox *) automation_editor->input_scrolled_automation_edit_box->automation_edit_box,
1196 (GtkWidget *) automation_edit,
1197 FALSE, FALSE,
1198 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1199 }
1200
1201 ags_connectable_connect(AGS_CONNECTABLE(automation_edit));
1202 gtk_widget_show((GtkWidget *) automation_edit);
1203
1204 if(channel_type == G_TYPE_NONE){
1205 g_signal_connect_after((GObject *) automation_edit->hscrollbar, "value-changed",
1206 G_CALLBACK(ags_automation_editor_audio_automation_edit_hscrollbar_value_changed), (gpointer) automation_editor);
1207 }else if(channel_type == AGS_TYPE_OUTPUT){
1208 g_signal_connect_after((GObject *) automation_edit->hscrollbar, "value-changed",
1209 G_CALLBACK(ags_automation_editor_output_automation_edit_hscrollbar_value_changed), (gpointer) automation_editor);
1210 }else if(channel_type == AGS_TYPE_INPUT){
1211 g_signal_connect_after((GObject *) automation_edit->hscrollbar, "value-changed",
1212 G_CALLBACK(ags_automation_editor_input_automation_edit_hscrollbar_value_changed), (gpointer) automation_editor);
1213 }
1214
1215 /* unset bypass */
1216 ags_audio_add_automation_port(machine->audio, control_name);
1217
1218 automation = start_automation;
1219
1220 while((automation = ags_automation_find_channel_type_with_control_name(automation,
1221 channel_type, control_name)) != NULL){
1222 ags_automation_unset_flags(automation->data,
1223 AGS_AUTOMATION_BYPASS);
1224
1225 automation = automation->next;
1226 }
1227 }else{
1228 GList *list_start, *list;
1229
1230 gint nth;
1231 gboolean success;
1232
1233 /* audio */
1234 nth = -1;
1235 success = FALSE;
1236
1237 list =
1238 list_start = NULL;
1239
1240 if(channel_type == G_TYPE_NONE){
1241 list =
1242 list_start = gtk_container_get_children((GtkContainer *) automation_editor->audio_scrolled_automation_edit_box->automation_edit_box);
1243 }else if(channel_type == AGS_TYPE_OUTPUT){
1244 list =
1245 list_start = gtk_container_get_children((GtkContainer *) automation_editor->output_scrolled_automation_edit_box->automation_edit_box);
1246 }else if(channel_type == AGS_TYPE_INPUT){
1247 list =
1248 list_start = gtk_container_get_children((GtkContainer *) automation_editor->input_scrolled_automation_edit_box->automation_edit_box);
1249 }
1250
1251
1252 while(list != NULL){
1253 nth++;
1254
1255 if(AGS_AUTOMATION_EDIT(list->data)->channel_type == channel_type &&
1256 !g_strcmp0(AGS_AUTOMATION_EDIT(list->data)->control_name,
1257 control_name)){
1258 gtk_widget_destroy(list->data);
1259
1260 success = TRUE;
1261
1262 break;
1263 }
1264
1265 list = list->next;
1266 }
1267
1268 g_list_free(list_start);
1269
1270 if(success){
1271 if(channel_type == G_TYPE_NONE){
1272 list_start = gtk_container_get_children((GtkContainer *) automation_editor->audio_scrolled_scale_box->scale_box);
1273 }else if(channel_type == AGS_TYPE_OUTPUT){
1274 list_start = gtk_container_get_children((GtkContainer *) automation_editor->output_scrolled_scale_box->scale_box);
1275 }else if(channel_type == AGS_TYPE_INPUT){
1276 list_start = gtk_container_get_children((GtkContainer *) automation_editor->input_scrolled_scale_box->scale_box);
1277 }
1278
1279 list = g_list_nth(list_start,
1280 nth);
1281
1282 gtk_widget_destroy(list->data);
1283
1284 g_list_free(list_start);
1285 }
1286
1287 /* set bypass */
1288 ags_audio_remove_automation_port(machine->audio, control_name);
1289
1290 automation = start_automation;
1291
1292 while((automation = ags_automation_find_channel_type_with_control_name(automation,
1293 channel_type, control_name)) != NULL){
1294 ags_automation_set_flags(automation->data,
1295 AGS_AUTOMATION_BYPASS);
1296
1297 automation = automation->next;
1298 }
1299 }
1300
1301 g_list_free_full(start_automation,
1302 g_object_unref);
1303
1304 g_list_free_full(start_port,
1305 g_object_unref);
1306 }
1307
1308 /**
1309 * ags_automation_toolbar_tool_popup_new:
1310 * @automation_toolbar: the #AgsAutomationToolbar
1311 *
1312 * Create a new #GtkMenu suitable for menu tool button.
1313 *
1314 * Returns: a new #GtkMenu
1315 *
1316 * Since: 3.0.0
1317 */
1318 GtkMenu*
ags_automation_toolbar_tool_popup_new(AgsAutomationToolbar * automation_toolbar)1319 ags_automation_toolbar_tool_popup_new(AgsAutomationToolbar *automation_toolbar)
1320 {
1321 GtkMenu *tool_popup;
1322 GtkMenuItem *item;
1323
1324 GList *list, *list_start;
1325
1326 tool_popup = (GtkMenu *) gtk_menu_new();
1327
1328 item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("select accelerations"));
1329 gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1330
1331 item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("ramp accelerations"));
1332 gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1333
1334 item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("position cursor"));
1335 gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1336
1337 gtk_menu_shell_append((GtkMenuShell*) tool_popup,
1338 (GtkWidget*) gtk_separator_menu_item_new());
1339
1340 item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("enable all lines"));
1341 gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1342
1343 item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("disable all lines"));
1344 gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1345
1346 /* connect */
1347 list_start =
1348 list = gtk_container_get_children((GtkContainer *) tool_popup);
1349
1350 g_signal_connect(G_OBJECT(list->data), "activate",
1351 G_CALLBACK(ags_automation_toolbar_tool_popup_select_acceleration_callback), (gpointer) automation_toolbar);
1352
1353 list = list->next;
1354 g_signal_connect(G_OBJECT(list->data), "activate",
1355 G_CALLBACK(ags_automation_toolbar_tool_popup_ramp_acceleration_callback), (gpointer) automation_toolbar);
1356
1357 list = list->next;
1358 g_signal_connect(G_OBJECT(list->data), "activate",
1359 G_CALLBACK(ags_automation_toolbar_tool_popup_position_cursor_callback), (gpointer) automation_toolbar);
1360
1361 list = list->next->next;
1362 g_signal_connect(G_OBJECT(list->data), "activate",
1363 G_CALLBACK(ags_automation_toolbar_tool_popup_enable_all_lines_callback), (gpointer) automation_toolbar);
1364
1365 list = list->next;
1366 g_signal_connect(G_OBJECT(list->data), "activate",
1367 G_CALLBACK(ags_automation_toolbar_tool_popup_disable_all_lines_callback), (gpointer) automation_toolbar);
1368
1369 g_list_free(list_start);
1370
1371 /* show */
1372 gtk_widget_show_all((GtkWidget *) tool_popup);
1373
1374 return(tool_popup);
1375 }
1376
1377 /**
1378 * ags_automation_toolbar_new:
1379 *
1380 * Create a new instance of #AgsAutomationToolbar.
1381 *
1382 * Returns: the new #AgsAutomationToolbar
1383 *
1384 * Since: 3.0.0
1385 */
1386 AgsAutomationToolbar*
ags_automation_toolbar_new()1387 ags_automation_toolbar_new()
1388 {
1389 AgsAutomationToolbar *automation_toolbar;
1390
1391 automation_toolbar = (AgsAutomationToolbar *) g_object_new(AGS_TYPE_AUTOMATION_TOOLBAR, NULL);
1392
1393 return(automation_toolbar);
1394 }
1395