1 /*
2 * Copyright (C) 2019-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 "zrythm-config.h"
21
22 #include <math.h>
23
24 #include "audio/audio_region.h"
25 #include "audio/automation_region.h"
26 #include "audio/automation_track.h"
27 #include "audio/automation_tracklist.h"
28 #include "audio/channel.h"
29 #include "audio/clip.h"
30 #include "audio/modulator_track.h"
31 #include "audio/pool.h"
32 #include "audio/router.h"
33 #include "audio/stretcher.h"
34 #include "audio/track.h"
35 #include "gui/backend/event.h"
36 #include "gui/backend/event_manager.h"
37 #include "gui/backend/clip_editor.h"
38 #include "gui/backend/piano_roll.h"
39 #include "gui/widgets/audio_arranger.h"
40 #include "gui/widgets/audio_editor_space.h"
41 #include "gui/widgets/automation_arranger.h"
42 #include "gui/widgets/automation_editor_space.h"
43 #include "gui/widgets/bot_bar.h"
44 #include "gui/widgets/bot_dock_edge.h"
45 #include "gui/widgets/center_dock.h"
46 #include "gui/widgets/clip_editor.h"
47 #include "gui/widgets/clip_editor_inner.h"
48 #include "gui/widgets/channel.h"
49 #include "gui/widgets/channel_sends_expander.h"
50 #include "gui/widgets/chord_arranger.h"
51 #include "gui/widgets/chord_editor_space.h"
52 #include "gui/widgets/chord_key.h"
53 #include "gui/widgets/chord_pad.h"
54 #include "gui/widgets/color_area.h"
55 #include "gui/widgets/editor_ruler.h"
56 #include "gui/widgets/editor_selection_info.h"
57 #include "gui/widgets/editor_toolbar.h"
58 #include "gui/widgets/event_viewer.h"
59 #include "gui/widgets/foldable_notebook.h"
60 #include "gui/widgets/header.h"
61 #include "gui/widgets/home_toolbar.h"
62 #include "gui/widgets/inspector_track.h"
63 #include "gui/widgets/left_dock_edge.h"
64 #include "gui/widgets/main_notebook.h"
65 #include "gui/widgets/main_window.h"
66 #include "gui/widgets/midi_arranger.h"
67 #include "gui/widgets/midi_modifier_arranger.h"
68 #include "gui/widgets/modulator.h"
69 #include "gui/widgets/modulator_view.h"
70 #include "gui/widgets/monitor_section.h"
71 #include "gui/widgets/midi_editor_space.h"
72 #include "gui/widgets/mixer.h"
73 #include "gui/widgets/piano_roll_keys.h"
74 #include "gui/widgets/plugin_browser.h"
75 #include "gui/widgets/plugin_strip_expander.h"
76 #include "gui/widgets/right_dock_edge.h"
77 #include "gui/widgets/route_target_selector.h"
78 #include "gui/widgets/ruler_marker.h"
79 #include "gui/widgets/snap_box.h"
80 #include "gui/widgets/timeline_arranger.h"
81 #include "gui/widgets/timeline_bot_box.h"
82 #include "gui/widgets/timeline_minimap.h"
83 #include "gui/widgets/timeline_panel.h"
84 #include "gui/widgets/timeline_ruler.h"
85 #include "gui/widgets/timeline_toolbar.h"
86 #include "gui/widgets/timeline_selection_info.h"
87 #include "gui/widgets/toolbox.h"
88 #include "gui/widgets/top_bar.h"
89 #include "gui/widgets/track.h"
90 #include "gui/widgets/track_properties_expander.h"
91 #include "gui/widgets/track_visibility_tree.h"
92 #include "gui/widgets/tracklist.h"
93 #include "gui/widgets/tracklist_header.h"
94 #include "gui/widgets/transport_controls.h"
95 #include "gui/widgets/visibility.h"
96 #include "plugins/plugin_gtk.h"
97 #include "project.h"
98 #include "settings/settings.h"
99 #include "utils/arrays.h"
100 #include "utils/flags.h"
101 #include "utils/gtk.h"
102 #include "utils/log.h"
103 #include "utils/mpmc_queue.h"
104 #include "utils/object_pool.h"
105 #include "utils/objects.h"
106 #include "utils/stack.h"
107 #include "utils/string.h"
108 #include "zrythm.h"
109 #include "zrythm_app.h"
110
111 #include <glib/gi18n.h>
112
113 static void
on_project_selection_type_changed(void)114 on_project_selection_type_changed (void)
115 {
116 const char * class = "selected-element";
117 const char * selectable_class =
118 "selectable-element";
119
120 z_gtk_widget_remove_style_class (
121 GTK_WIDGET (MW_TRACKLIST), class);
122 z_gtk_widget_remove_style_class (
123 GTK_WIDGET (
124 MW_TIMELINE_PANEL->timelines_plus_ruler),
125 class);
126 z_gtk_widget_add_style_class (
127 GTK_WIDGET (
128 MW_TIMELINE_PANEL->timelines_plus_ruler),
129 selectable_class);
130 z_gtk_widget_remove_style_class (
131 GTK_WIDGET (MW_TIMELINE_PANEL->tracklist_top),
132 class);
133 z_gtk_widget_add_style_class (
134 GTK_WIDGET (MW_TIMELINE_PANEL->tracklist_top),
135 selectable_class);
136 z_gtk_widget_remove_style_class (
137 GTK_WIDGET (MW_CLIP_EDITOR_INNER), class);
138 z_gtk_widget_add_style_class (
139 GTK_WIDGET (MW_CLIP_EDITOR_INNER),
140 selectable_class);
141 z_gtk_widget_remove_style_class (
142 GTK_WIDGET (MW_MIXER), class);
143 z_gtk_widget_add_style_class (
144 GTK_WIDGET (MW_MIXER), selectable_class);
145
146 switch (PROJECT->last_selection)
147 {
148 case SELECTION_TYPE_TRACKLIST:
149 z_gtk_widget_add_style_class (
150 GTK_WIDGET (
151 MW_TIMELINE_PANEL->tracklist_top),
152 class);
153 z_gtk_widget_remove_style_class (
154 GTK_WIDGET (
155 MW_TIMELINE_PANEL->tracklist_top),
156 selectable_class);
157 z_gtk_widget_add_style_class (
158 GTK_WIDGET (MW_MIXER), class);
159 z_gtk_widget_remove_style_class (
160 GTK_WIDGET (MW_MIXER),
161 selectable_class);
162 break;
163 case SELECTION_TYPE_TIMELINE:
164 z_gtk_widget_add_style_class (
165 GTK_WIDGET (
166 MW_TIMELINE_PANEL->timelines_plus_ruler),
167 class);
168 z_gtk_widget_remove_style_class (
169 GTK_WIDGET (
170 MW_TIMELINE_PANEL->timelines_plus_ruler),
171 selectable_class);
172 break;
173 case SELECTION_TYPE_INSERT:
174 case SELECTION_TYPE_MIDI_FX:
175 case SELECTION_TYPE_INSTRUMENT:
176 case SELECTION_TYPE_MODULATOR:
177 break;
178 case SELECTION_TYPE_EDITOR:
179 z_gtk_widget_add_style_class (
180 GTK_WIDGET (MW_CLIP_EDITOR_INNER), class);
181 z_gtk_widget_remove_style_class (
182 GTK_WIDGET (MW_CLIP_EDITOR_INNER),
183 selectable_class);
184 break;
185 }
186 }
187
188 static void
redraw_arranger_for_selections(ArrangerSelections * sel)189 redraw_arranger_for_selections (
190 ArrangerSelections * sel)
191 {
192 switch (sel->type)
193 {
194 case ARRANGER_SELECTIONS_TYPE_TIMELINE:
195 arranger_widget_redraw_whole (MW_TIMELINE);
196 arranger_widget_redraw_whole (
197 MW_PINNED_TIMELINE);
198 break;
199 case ARRANGER_SELECTIONS_TYPE_AUTOMATION:
200 arranger_widget_redraw_whole (
201 MW_AUTOMATION_ARRANGER);
202 break;
203 case ARRANGER_SELECTIONS_TYPE_MIDI:
204 arranger_widget_redraw_whole (
205 MW_MIDI_ARRANGER);
206 arranger_widget_redraw_whole (
207 MW_MIDI_MODIFIER_ARRANGER);
208 break;
209 case ARRANGER_SELECTIONS_TYPE_CHORD:
210 arranger_widget_redraw_whole (
211 MW_CHORD_ARRANGER);
212 break;
213 default:
214 break;
215 }
216 }
217
218 static void
redraw_all_arranger_bgs()219 redraw_all_arranger_bgs ()
220 {
221 arranger_widget_redraw_whole (MW_TIMELINE);
222 arranger_widget_redraw_whole (MW_PINNED_TIMELINE);
223 arranger_widget_redraw_whole (MW_MIDI_ARRANGER);
224 arranger_widget_redraw_whole (
225 MW_MIDI_MODIFIER_ARRANGER);
226 arranger_widget_redraw_whole (
227 MW_AUTOMATION_ARRANGER);
228 arranger_widget_redraw_whole (MW_CHORD_ARRANGER);
229 arranger_widget_redraw_whole (MW_AUDIO_ARRANGER);
230 }
231
232 static void
redraw_regions_for_midi_selections(MidiArrangerSelections * sel)233 redraw_regions_for_midi_selections (
234 MidiArrangerSelections * sel)
235 {
236 for (int i = 0; i < sel->num_midi_notes;
237 i++)
238 {
239 MidiNote * mn = sel->midi_notes[i];
240 ZRegion * region =
241 midi_note_get_region (mn);
242 arranger_object_queue_redraw (
243 (ArrangerObject *) region);
244 }
245 }
246
247 static void
redraw_velocities_for_midi_selections(MidiArrangerSelections * sel)248 redraw_velocities_for_midi_selections (
249 MidiArrangerSelections * sel)
250 {
251 for (int i = 0; i < sel->num_midi_notes;
252 i++)
253 {
254 MidiNote * mn = sel->midi_notes[i];
255 arranger_object_queue_redraw (
256 (ArrangerObject *) mn->vel);
257 }
258 }
259
260 static void
on_arranger_selections_in_transit(ArrangerSelections * sel)261 on_arranger_selections_in_transit (
262 ArrangerSelections * sel)
263 {
264 g_return_if_fail (sel);
265
266 arranger_selections_redraw (sel);
267
268 event_viewer_widget_refresh_for_selections (sel);
269
270 switch (sel->type)
271 {
272 case ARRANGER_SELECTIONS_TYPE_TIMELINE:
273 if (TL_SELECTIONS->num_regions > 0)
274 {
275 ZRegion * r = TL_SELECTIONS->regions[0];
276 switch (r->id.type)
277 {
278 case REGION_TYPE_MIDI:
279 arranger_widget_redraw_whole (
280 MW_MIDI_ARRANGER);
281 arranger_widget_redraw_whole (
282 MW_MIDI_MODIFIER_ARRANGER);
283 break;
284 case REGION_TYPE_AUTOMATION:
285 arranger_widget_redraw_whole (
286 MW_AUTOMATION_ARRANGER);
287 break;
288 case REGION_TYPE_CHORD:
289 arranger_widget_redraw_whole (
290 MW_CHORD_ARRANGER);
291 break;
292 case REGION_TYPE_AUDIO:
293 arranger_widget_redraw_whole (
294 MW_AUDIO_ARRANGER);
295 break;
296 }
297 ruler_widget_redraw_whole (EDITOR_RULER);
298 }
299 break;
300 case ARRANGER_SELECTIONS_TYPE_AUTOMATION:
301 clip_editor_redraw_region (CLIP_EDITOR);
302 break;
303 case ARRANGER_SELECTIONS_TYPE_MIDI:
304 redraw_regions_for_midi_selections (
305 (MidiArrangerSelections *) sel);
306 redraw_velocities_for_midi_selections (
307 (MidiArrangerSelections *) sel);
308 break;
309 default:
310 break;
311 }
312 }
313
314 /**
315 * @param manually Whether the position was changed
316 * by the user.
317 */
318 static void
on_playhead_changed(bool manually)319 on_playhead_changed (
320 bool manually)
321 {
322 if (MAIN_WINDOW)
323 {
324 if (MW_DIGITAL_TRANSPORT)
325 {
326 gtk_widget_queue_draw (
327 GTK_WIDGET (MW_DIGITAL_TRANSPORT));
328 }
329 if (MW_RULER)
330 {
331 if (manually)
332 ruler_widget_redraw_whole (MW_RULER);
333 else
334 ruler_widget_redraw_playhead (MW_RULER);
335 }
336 if (EDITOR_RULER)
337 {
338 if (manually)
339 ruler_widget_redraw_whole (
340 EDITOR_RULER);
341 else
342 ruler_widget_redraw_playhead (
343 EDITOR_RULER);
344 }
345 if (MW_MIDI_EDITOR_SPACE)
346 {
347 if (MW_MIDI_ARRANGER)
348 {
349 if (manually)
350 arranger_widget_redraw_whole (
351 MW_MIDI_ARRANGER);
352 else
353 arranger_widget_redraw_playhead (
354 MW_MIDI_ARRANGER);
355 }
356 if (MW_MIDI_MODIFIER_ARRANGER)
357 {
358 if (manually)
359 arranger_widget_redraw_whole (
360 MW_MIDI_MODIFIER_ARRANGER);
361 else
362 arranger_widget_redraw_playhead (
363 MW_MIDI_MODIFIER_ARRANGER);
364 }
365 piano_roll_keys_widget_refresh (
366 MW_PIANO_ROLL_KEYS);
367 }
368 if (MW_TIMELINE)
369 {
370 if (manually)
371 arranger_widget_redraw_whole (
372 MW_TIMELINE);
373 else
374 arranger_widget_redraw_playhead (
375 MW_TIMELINE);
376 }
377 if (MW_PINNED_TIMELINE)
378 {
379 if (manually)
380 arranger_widget_redraw_whole (
381 MW_PINNED_TIMELINE);
382 else
383 arranger_widget_redraw_playhead (
384 MW_PINNED_TIMELINE);
385 }
386 if (MW_AUTOMATION_ARRANGER)
387 {
388 if (manually)
389 arranger_widget_redraw_whole (
390 MW_AUTOMATION_ARRANGER);
391 else
392 arranger_widget_redraw_playhead (
393 MW_AUTOMATION_ARRANGER);
394 }
395 if (MW_AUDIO_ARRANGER)
396 {
397 if (manually)
398 arranger_widget_redraw_whole (
399 MW_AUDIO_ARRANGER);
400 else
401 arranger_widget_redraw_playhead (
402 MW_AUDIO_ARRANGER);
403 }
404 if (MW_CHORD_ARRANGER)
405 {
406 if (manually)
407 arranger_widget_redraw_whole (
408 MW_CHORD_ARRANGER);
409 else
410 arranger_widget_redraw_playhead (
411 MW_CHORD_ARRANGER);
412 }
413 }
414 }
415
416 static void
on_channel_output_changed(Channel * ch)417 on_channel_output_changed (
418 Channel * ch)
419 {
420 if (ch->widget)
421 {
422 route_target_selector_widget_refresh (
423 ch->widget->output, ch);
424 }
425 }
426
427 static void
on_track_state_changed(Track * track)428 on_track_state_changed (Track * track)
429 {
430 if (track->widget)
431 {
432 /*track_widget_block_all_signal_handlers (*/
433 /*track->widget);*/
434 track_widget_force_redraw (track->widget);
435 /*track_widget_unblock_all_signal_handlers (*/
436 /*track->widget);*/
437 }
438
439 Channel * chan = track_get_channel (track);
440 if (chan && chan->widget)
441 {
442 channel_widget_refresh (chan->widget);
443 }
444
445 if (TRACKLIST_SELECTIONS->tracks[0] == track)
446 {
447 inspector_track_widget_show_tracks (
448 MW_TRACK_INSPECTOR, TRACKLIST_SELECTIONS,
449 true);
450 }
451 }
452
453 static void
on_range_selection_changed()454 on_range_selection_changed ()
455 {
456 redraw_all_arranger_bgs ();
457 /*gtk_widget_set_visible (*/
458 /*GTK_WIDGET (MW_RULER->range),*/
459 /*PROJECT->has_range);*/
460 gtk_widget_queue_allocate (
461 GTK_WIDGET (MW_RULER));
462 ruler_widget_redraw_whole (
463 (RulerWidget *) MW_RULER);
464 ruler_widget_redraw_whole (
465 (RulerWidget *) EDITOR_RULER);
466 }
467
468 static void
on_automation_track_added(AutomationTrack * at)469 on_automation_track_added (
470 AutomationTrack * at)
471 {
472 /*AutomationTracklist * atl =*/
473 /*track_get_automation_tracklist (at->track);*/
474 /*if (atl && atl->widget)*/
475 /*automation_tracklist_widget_refresh (*/
476 /*atl->widget);*/
477
478 Track * track =
479 automation_track_get_track (at);
480 g_return_if_fail (track);
481 if (Z_IS_TRACK_WIDGET (track->widget))
482 {
483 TrackWidget * tw =
484 (TrackWidget *) track->widget;
485 track_widget_update_size (tw);
486 }
487
488 arranger_widget_redraw_whole (
489 MW_TIMELINE);
490 arranger_widget_redraw_whole (
491 MW_PINNED_TIMELINE);
492
493 visibility_widget_refresh (MW_VISIBILITY);
494 }
495
496 static void
on_track_added(Track * track)497 on_track_added (Track * track)
498 {
499 if (!MAIN_WINDOW || !MW_CENTER_DOCK)
500 return;
501
502 if (MW_MIXER)
503 mixer_widget_hard_refresh (MW_MIXER);
504 if (MW_TRACKLIST)
505 tracklist_widget_hard_refresh (MW_TRACKLIST);
506
507 /* needs to be called later because tracks need
508 * time to get allocated */
509 EVENTS_PUSH (ET_REFRESH_ARRANGER, NULL);
510 }
511
512 static void
on_automation_value_changed(Port * port)513 on_automation_value_changed (
514 Port * port)
515 {
516 PortIdentifier * id = &port->id;
517
518 if (id->flags2 & PORT_FLAG2_CHANNEL_SEND_AMOUNT)
519 {
520 Track * tr = port_get_track (port, true);
521 if (track_is_selected (tr))
522 {
523 gtk_widget_queue_draw (
524 GTK_WIDGET (
525 MW_TRACK_INSPECTOR->sends->
526 slots[id->port_index]));
527 }
528 }
529 }
530
531 static void
on_plugin_added(Plugin * plugin)532 on_plugin_added (Plugin * plugin)
533 {
534 Track * track =
535 plugin_get_track (plugin);
536 /*AutomationTracklist * automation_tracklist =*/
537 /*track_get_automation_tracklist (track);*/
538 if (track && track->widget)
539 track_widget_force_redraw (track->widget);
540 }
541
542 static void
on_plugin_crashed(Plugin * plugin)543 on_plugin_crashed (Plugin * plugin)
544 {
545 char * str =
546 g_strdup_printf (
547 _("Plugin '%s' has crashed and has been "
548 "disabled."),
549 plugin->setting->descr->name);
550 ui_show_error_message (MAIN_WINDOW, str);
551 g_free (str);
552 }
553
554 static void
on_plugin_state_changed(Plugin * pl)555 on_plugin_state_changed (Plugin * pl)
556 {
557 Track * track = plugin_get_track (pl);
558 if (track && track->channel &&
559 track->channel->widget)
560 {
561 /* redraw slot */
562 switch (pl->id.slot_type)
563 {
564 case PLUGIN_SLOT_MIDI_FX:
565 plugin_strip_expander_widget_redraw_slot (
566 MW_TRACK_INSPECTOR->midi_fx,
567 pl->id.slot);
568 break;
569 case PLUGIN_SLOT_INSERT:
570 plugin_strip_expander_widget_redraw_slot (
571 MW_TRACK_INSPECTOR->inserts,
572 pl->id.slot);
573 plugin_strip_expander_widget_redraw_slot (
574 track->channel->widget->inserts,
575 pl->id.slot);
576 break;
577 default:
578 break;
579 }
580 }
581 }
582
583 static void
on_modulator_added(Plugin * modulator)584 on_modulator_added (Plugin * modulator)
585 {
586 on_plugin_added (modulator);
587
588 Track * track = plugin_get_track (modulator);
589 modulator_view_widget_refresh (
590 MW_MODULATOR_VIEW, track);
591 }
592
593 static void
on_plugins_removed(Track * tr)594 on_plugins_removed (Track * tr)
595 {
596 /* redraw slots */
597 if (tr && tr->channel)
598 {
599 plugin_strip_expander_widget_set_state_flags (
600 tr->channel->widget->inserts, -1,
601 GTK_STATE_FLAG_SELECTED, false);
602 }
603
604 /* change inspector page */
605 left_dock_edge_widget_refresh (
606 MW_LEFT_DOCK_EDGE);
607
608 /* refresh modulator view */
609 modulator_view_widget_refresh (
610 MW_MODULATOR_VIEW, P_MODULATOR_TRACK);
611 }
612
613 static void
refresh_for_selections_type(ArrangerSelectionsType type)614 refresh_for_selections_type (
615 ArrangerSelectionsType type)
616 {
617 switch (type)
618 {
619 case ARRANGER_SELECTIONS_TYPE_TIMELINE:
620 event_viewer_widget_refresh (
621 MW_TIMELINE_EVENT_VIEWER);
622 break;
623 case ARRANGER_SELECTIONS_TYPE_MIDI:
624 clip_editor_redraw_region (CLIP_EDITOR);
625 event_viewer_widget_refresh (
626 MW_EDITOR_EVENT_VIEWER);
627 break;
628 case ARRANGER_SELECTIONS_TYPE_CHORD:
629 clip_editor_redraw_region (CLIP_EDITOR);
630 event_viewer_widget_refresh (
631 MW_EDITOR_EVENT_VIEWER);
632 break;
633 case ARRANGER_SELECTIONS_TYPE_AUTOMATION:
634 clip_editor_redraw_region (CLIP_EDITOR);
635 event_viewer_widget_refresh (
636 MW_EDITOR_EVENT_VIEWER);
637 break;
638 default:
639 g_return_if_reached ();
640 }
641 }
642
643 static void
on_arranger_selections_changed(ArrangerSelections * sel)644 on_arranger_selections_changed (
645 ArrangerSelections * sel)
646 {
647 int size = 0;
648 ArrangerObject ** objs =
649 arranger_selections_get_all_objects (
650 sel, &size);
651 bool redraw_editor_ruler = false;
652 bool redraw_midi_modifier = false;
653 for (int i = 0; i < size; i++)
654 {
655 ArrangerObject * obj = objs[i];
656 g_return_if_fail (IS_ARRANGER_OBJECT (obj));
657
658 if (obj->type == ARRANGER_OBJECT_TYPE_REGION)
659 redraw_editor_ruler = true;
660
661 arranger_object_queue_redraw (obj);
662
663 if (obj->type ==
664 ARRANGER_OBJECT_TYPE_MIDI_NOTE)
665 {
666 redraw_midi_modifier = true;
667
668 /* FIXME doesn't work for some reason */
669 #if 0
670 MidiNote * mn = (MidiNote *) obj;
671 arranger_object_queue_redraw (
672 (ArrangerObject *) mn->vel);
673 #endif
674 }
675 }
676
677 if (redraw_editor_ruler)
678 {
679 ruler_widget_redraw_whole (EDITOR_RULER);
680 }
681 if (redraw_midi_modifier)
682 {
683 arranger_widget_redraw_whole (
684 MW_MIDI_MODIFIER_ARRANGER);
685 }
686
687 refresh_for_selections_type (sel->type);
688 left_dock_edge_widget_refresh (
689 MW_LEFT_DOCK_EDGE);
690
691 timeline_toolbar_widget_refresh (
692 MW_TIMELINE_TOOLBAR);
693 }
694
695 static void
arranger_selections_change_redraw_everything(ArrangerSelections * sel)696 arranger_selections_change_redraw_everything (
697 ArrangerSelections * sel)
698 {
699 switch (sel->type)
700 {
701 case ARRANGER_SELECTIONS_TYPE_TIMELINE:
702 arranger_widget_redraw_whole (
703 MW_TIMELINE);
704 arranger_widget_redraw_whole (
705 MW_PINNED_TIMELINE);
706 event_viewer_widget_refresh (
707 MW_TIMELINE_EVENT_VIEWER);
708 arranger_widget_redraw_whole (
709 MW_MIDI_ARRANGER);
710 arranger_widget_redraw_whole (
711 MW_MIDI_MODIFIER_ARRANGER);
712 arranger_widget_redraw_whole (
713 MW_CHORD_ARRANGER);
714 arranger_widget_redraw_whole (
715 MW_AUTOMATION_ARRANGER);
716 ruler_widget_redraw_whole (
717 EDITOR_RULER);
718 break;
719 case ARRANGER_SELECTIONS_TYPE_MIDI:
720 clip_editor_redraw_region (CLIP_EDITOR);
721 arranger_widget_redraw_whole (
722 MW_MIDI_ARRANGER);
723 arranger_widget_redraw_whole (
724 MW_MIDI_MODIFIER_ARRANGER);
725 {
726 MidiArrangerSelections * ma_sel =
727 (MidiArrangerSelections *) sel;
728 redraw_regions_for_midi_selections (
729 ma_sel);
730 }
731 event_viewer_widget_refresh (
732 MW_EDITOR_EVENT_VIEWER);
733 break;
734 case ARRANGER_SELECTIONS_TYPE_CHORD:
735 clip_editor_redraw_region (CLIP_EDITOR);
736 arranger_widget_redraw_whole (
737 MW_CHORD_ARRANGER);
738 event_viewer_widget_refresh (
739 MW_EDITOR_EVENT_VIEWER);
740 break;
741 case ARRANGER_SELECTIONS_TYPE_AUTOMATION:
742 clip_editor_redraw_region (CLIP_EDITOR);
743 arranger_widget_redraw_whole (
744 MW_AUTOMATION_ARRANGER);
745 event_viewer_widget_refresh (
746 MW_EDITOR_EVENT_VIEWER);
747 break;
748 case ARRANGER_SELECTIONS_TYPE_AUDIO:
749 clip_editor_redraw_region (CLIP_EDITOR);
750 arranger_widget_redraw_whole (
751 MW_AUDIO_ARRANGER);
752 event_viewer_widget_refresh (
753 MW_EDITOR_EVENT_VIEWER);
754 break;
755 default:
756 g_return_if_reached ();
757 }
758 }
759
760 static void
on_arranger_selections_created(ArrangerSelections * sel)761 on_arranger_selections_created (
762 ArrangerSelections * sel)
763 {
764 arranger_selections_change_redraw_everything (
765 sel);
766 }
767
768 static void
on_arranger_selections_moved(ArrangerSelections * sel)769 on_arranger_selections_moved (
770 ArrangerSelections * sel)
771 {
772 arranger_selections_change_redraw_everything (
773 sel);
774 }
775
776 static void
on_arranger_selections_removed(ArrangerSelections * sel)777 on_arranger_selections_removed (
778 ArrangerSelections * sel)
779 {
780 MW_TIMELINE->hovered_object = NULL;
781 MW_MIDI_ARRANGER->hovered_object = NULL;
782 MW_MIDI_MODIFIER_ARRANGER->hovered_object = NULL;
783 MW_AUTOMATION_ARRANGER->hovered_object = NULL;
784 MW_AUDIO_ARRANGER->hovered_object = NULL;
785 MW_CHORD_ARRANGER->hovered_object = NULL;
786
787 arranger_selections_change_redraw_everything (
788 sel);
789
790 #if 0
791 switch (type)
792 {
793 case ARRANGER_SELECTIONS_TYPE_TIMELINE:
794 arranger_widget_redraw_whole (
795 MW_TIMELINE);
796 arranger_widget_redraw_whole (
797 MW_PINNED_TIMELINE);
798 event_viewer_widget_refresh (
799 MW_TIMELINE_EVENT_VIEWER);
800 break;
801 case ARRANGER_SELECTIONS_TYPE_MIDI:
802 clip_editor_redraw_region (CLIP_EDITOR);
803 arranger_widget_redraw_whole (
804 MW_MIDI_ARRANGER);
805 arranger_widget_redraw_whole (
806 MW_MIDI_MODIFIER_ARRANGER);
807 event_viewer_widget_refresh (
808 MW_EDITOR_EVENT_VIEWER);
809 break;
810 case ARRANGER_SELECTIONS_TYPE_CHORD:
811 clip_editor_redraw_region (CLIP_EDITOR);
812 arranger_widget_redraw_whole (
813 MW_CHORD_ARRANGER);
814 event_viewer_widget_refresh (
815 MW_EDITOR_EVENT_VIEWER);
816 break;
817 case ARRANGER_SELECTIONS_TYPE_AUTOMATION:
818 clip_editor_redraw_region (CLIP_EDITOR);
819 arranger_widget_redraw_whole (
820 MW_AUTOMATION_ARRANGER);
821 event_viewer_widget_refresh (
822 MW_EDITOR_EVENT_VIEWER);
823 break;
824 default:
825 g_return_if_reached ();
826 }
827 #endif
828 timeline_toolbar_widget_refresh (
829 MW_TIMELINE_TOOLBAR);
830 }
831
832 static void
on_mixer_selections_changed()833 on_mixer_selections_changed ()
834 {
835 for (int i = 0; i < TRACKLIST->num_tracks; i++)
836 {
837 Track * track = TRACKLIST->tracks[i];
838 if (!track_type_has_channel (track->type))
839 continue;
840
841 Channel * ch = track->channel;
842 if (ch->widget)
843 {
844 plugin_strip_expander_widget_refresh (
845 ch->widget->inserts);
846 }
847 }
848 left_dock_edge_widget_refresh (
849 MW_LEFT_DOCK_EDGE);
850 }
851
852 static void
on_track_color_changed(Track * track)853 on_track_color_changed (Track * track)
854 {
855 if (track_type_has_channel (track->type))
856 {
857 channel_widget_refresh (
858 track->channel->widget);
859 }
860 track_widget_force_redraw (track->widget);
861 left_dock_edge_widget_refresh (
862 MW_LEFT_DOCK_EDGE);
863 }
864
865 static void
on_track_name_changed(Track * track)866 on_track_name_changed (Track * track)
867 {
868 /* refresh all because tracks routed to/from are
869 * also affected */
870 mixer_widget_soft_refresh (MW_MIXER);
871 track_widget_force_redraw (track->widget);
872 left_dock_edge_widget_refresh (
873 MW_LEFT_DOCK_EDGE);
874 visibility_widget_refresh (MW_VISIBILITY);
875 }
876
877 static void
on_arranger_object_changed(ArrangerObject * obj)878 on_arranger_object_changed (
879 ArrangerObject * obj)
880 {
881 g_return_if_fail (IS_ARRANGER_OBJECT (obj));
882
883 /* parent region, if any */
884 ArrangerObject * parent_r_obj =
885 (ArrangerObject *)
886 arranger_object_get_region (obj);
887
888 bool is_timeline = !parent_r_obj;
889 if (is_timeline)
890 event_viewer_widget_refresh (
891 MW_TIMELINE_EVENT_VIEWER);
892 else
893 event_viewer_widget_refresh (
894 MW_EDITOR_EVENT_VIEWER);
895
896 switch (obj->type)
897 {
898 case ARRANGER_OBJECT_TYPE_AUTOMATION_POINT:
899 {
900 /*ArrangerObject * prev_ap_obj =*/
901 /*(ArrangerObject *)*/
902 /*automation_region_get_prev_ap (*/
903 /*((AutomationPoint *) obj)->region,*/
904 /*(AutomationPoint *) obj);*/
905
906 /* redraw this ap and also the previous one
907 * if any */
908 for (int i = 0; i < 2; i++)
909 {
910 /*ArrangerObject * _obj = NULL;*/
911 /*if (i == 0)*/
912 /*_obj = obj;*/
913 /*else if (prev_ap_obj)*/
914 /*_obj = prev_ap_obj;*/
915 /*else*/
916 /*break;*/
917
918 /*if (_obj &&*/
919 /*Z_IS_ARRANGER_OBJECT_WIDGET (*/
920 /*_obj->widget))*/
921 /*{*/
922 /*arranger_object_widget_force_redraw (*/
923 /*(ArrangerObjectWidget *)*/
924 /*_obj->widget);*/
925 /*}*/
926 }
927 }
928 break;
929 case ARRANGER_OBJECT_TYPE_MIDI_NOTE:
930 {
931 /*MidiNote * mn =*/
932 /*(MidiNote *)*/
933 /*arranger_object_get_main (obj);*/
934 /*ArrangerObject * vel_obj =*/
935 /*(ArrangerObject *) mn->vel;*/
936 /*if (vel_obj->widget)*/
937 /*{*/
938 /*arranger_object_set_widget_visibility_and_state (*/
939 /*vel_obj, 1);*/
940 /*}*/
941 arranger_object_queue_redraw (
942 (ArrangerObject *) parent_r_obj);
943 }
944 break;
945 case ARRANGER_OBJECT_TYPE_REGION:
946 /* redraw editor ruler if region
947 * positions were changed */
948 ruler_widget_redraw_whole (
949 EDITOR_RULER);
950 timeline_toolbar_widget_refresh (
951 MW_TIMELINE_TOOLBAR);
952 break;
953 case ARRANGER_OBJECT_TYPE_MARKER:
954 {
955 /*MarkerWidget * mw =*/
956 /*(MarkerWidget *) obj->widget;*/
957 /*if (Z_IS_MARKER_WIDGET (mw))*/
958 /*{*/
959 /*marker_widget_recreate_pango_layouts (*/
960 /*mw);*/
961 /*}*/
962 }
963 break;
964 default:
965 break;
966 }
967
968 /* redraw parent region */
969 if (parent_r_obj)
970 {
971 /*ArrangerObjectWidget * obj_w =*/
972 /*(ArrangerObjectWidget *)*/
973 /*parent_r_obj->widget;*/
974 /*if (obj_w)*/
975 /*arranger_object_widget_force_redraw (*/
976 /*obj_w);*/
977 }
978
979 /* redraw this */
980 /*ArrangerObjectWidget * obj_w =*/
981 /*(ArrangerObjectWidget *) obj->widget;*/
982 /*if (obj_w)*/
983 /*arranger_object_widget_force_redraw (obj_w);*/
984
985 /* refresh arranger */
986 arranger_object_queue_redraw (obj);
987 /*ArrangerWidget * arranger =*/
988 /*arranger_object_get_arranger (obj);*/
989 /*arranger_widget_redraw_whole (arranger);*/
990 }
991
992 static void
on_arranger_object_created(ArrangerObject * obj)993 on_arranger_object_created (
994 ArrangerObject * obj)
995 {
996 /* refresh arranger */
997 /*ArrangerWidget * arranger =*/
998 /*arranger_object_get_arranger (obj);*/
999 /*arranger_widget_redraw_whole (arranger);*/
1000 arranger_object_queue_redraw (obj);
1001
1002 if (obj->type == ARRANGER_OBJECT_TYPE_MIDI_NOTE)
1003 {
1004 arranger_widget_redraw_whole (
1005 (ArrangerWidget *)
1006 MW_MIDI_MODIFIER_ARRANGER);
1007 }
1008 }
1009
1010 static void
on_arranger_object_removed(ArrangerObjectType type)1011 on_arranger_object_removed (
1012 ArrangerObjectType type)
1013 {
1014 switch (type)
1015 {
1016 case ARRANGER_OBJECT_TYPE_MIDI_NOTE:
1017 case ARRANGER_OBJECT_TYPE_VELOCITY:
1018 arranger_widget_redraw_whole (
1019 MW_MIDI_ARRANGER);
1020 arranger_widget_redraw_whole (
1021 MW_MIDI_MODIFIER_ARRANGER);
1022 break;
1023 case ARRANGER_OBJECT_TYPE_REGION:
1024 case ARRANGER_OBJECT_TYPE_SCALE_OBJECT:
1025 case ARRANGER_OBJECT_TYPE_MARKER:
1026 arranger_widget_redraw_whole (
1027 MW_TIMELINE);
1028 arranger_widget_redraw_whole (
1029 MW_PINNED_TIMELINE);
1030 break;
1031 case ARRANGER_OBJECT_TYPE_CHORD_OBJECT:
1032 arranger_widget_redraw_whole (
1033 MW_CHORD_ARRANGER);
1034 break;
1035 case ARRANGER_OBJECT_TYPE_AUTOMATION_POINT:
1036 arranger_widget_redraw_whole (
1037 MW_AUTOMATION_ARRANGER);
1038 break;
1039 default:
1040 g_return_if_reached ();
1041 }
1042 }
1043
1044 static void
on_track_changed(Track * track)1045 on_track_changed (
1046 Track * track)
1047 {
1048 g_return_if_fail (IS_TRACK_AND_NONNULL (track));
1049 if (GTK_IS_WIDGET (track->widget))
1050 {
1051 gtk_widget_set_visible (
1052 GTK_WIDGET (track->widget),
1053 track->visible);
1054 track_widget_force_redraw (track->widget);
1055 }
1056 }
1057
1058 static void
on_plugin_window_visibility_changed(Plugin * pl)1059 on_plugin_window_visibility_changed (
1060 Plugin * pl)
1061 {
1062 g_message ("start");
1063 if (!IS_PLUGIN (pl) || pl->deleting)
1064 {
1065 return;
1066 }
1067
1068 Track * track = plugin_get_track (pl);
1069 if (track && track->type == TRACK_TYPE_INSTRUMENT
1070 && track->widget
1071 && Z_IS_TRACK_WIDGET (track->widget))
1072 track_widget_force_redraw (track->widget);
1073
1074 if (track && track->channel
1075 && track->channel->widget
1076 &&
1077 Z_IS_CHANNEL_WIDGET (track->channel->widget))
1078 {
1079 /* redraw slot */
1080 switch (pl->id.slot_type)
1081 {
1082 case PLUGIN_SLOT_MIDI_FX:
1083 plugin_strip_expander_widget_redraw_slot (
1084 MW_TRACK_INSPECTOR->midi_fx,
1085 pl->id.slot);
1086 break;
1087 case PLUGIN_SLOT_INSERT:
1088 plugin_strip_expander_widget_redraw_slot (
1089 MW_TRACK_INSPECTOR->inserts,
1090 pl->id.slot);
1091 plugin_strip_expander_widget_redraw_slot (
1092 track->channel->widget->inserts,
1093 pl->id.slot);
1094 break;
1095 case PLUGIN_SLOT_INSTRUMENT:
1096 track_properties_expander_widget_refresh (
1097 MW_TRACK_INSPECTOR->track_info, track);
1098 break;
1099 default:
1100 break;
1101 }
1102 }
1103
1104 if (pl->modulator_widget)
1105 {
1106 modulator_widget_refresh (
1107 pl->modulator_widget);
1108 }
1109 g_message ("done");
1110 }
1111
1112 static void
on_plugin_visibility_changed(Plugin * pl)1113 on_plugin_visibility_changed (Plugin * pl)
1114 {
1115 g_debug (
1116 "start - visible: %d", pl->visible);
1117 if (pl->visible)
1118 {
1119 plugin_open_ui (pl);
1120 }
1121 else if (!pl->visible)
1122 {
1123 plugin_close_ui (pl);
1124 }
1125
1126 on_plugin_window_visibility_changed (pl);
1127 g_debug ("done");
1128 }
1129
1130 /*static int*/
1131 /*update_adj ()*/
1132 /*{*/
1133 /*GtkAdjustment * adj =*/
1134 /*gtk_scrolled_window_get_hadjustment (*/
1135 /*MW_CENTER_DOCK->timeline_scroll);*/
1136 /*gtk_adjustment_set_value (*/
1137 /*adj,*/
1138 /*gtk_adjustment_get_value (adj) + gtk_adjustment_get_step_increment (adj));*/
1139 /*gtk_scrolled_window_set_hadjustment(*/
1140 /*MW_CENTER_DOCK->timeline_scroll,*/
1141 /*adj);*/
1142
1143 /*return FALSE;*/
1144 /*}*/
1145
1146 static inline void
clean_duplicates_and_copy(EventManager * self,GPtrArray * events_arr)1147 clean_duplicates_and_copy (
1148 EventManager * self,
1149 GPtrArray * events_arr)
1150 {
1151 MPMCQueue * q = self->mqueue;
1152 ZEvent * event;
1153
1154 g_ptr_array_remove_range (
1155 events_arr, 0, events_arr->len);
1156
1157 /* only add events once to new array while
1158 * popping */
1159 while (event_queue_dequeue_event (
1160 q, &event))
1161 {
1162 bool already_exists = false;
1163
1164 for (guint i = 0; i < events_arr->len; i++)
1165 {
1166 ZEvent * cur_event =
1167 (ZEvent *)
1168 g_ptr_array_index (events_arr, i);
1169 if (event->type == cur_event->type &&
1170 event->arg == cur_event->arg)
1171 already_exists = true;
1172 }
1173
1174 if (already_exists)
1175 {
1176 object_pool_return (
1177 self->obj_pool, event);
1178 }
1179 else
1180 {
1181 g_ptr_array_add (events_arr, event);
1182 }
1183 }
1184 }
1185
1186 static int
soft_recalc_graph_when_paused(void * data)1187 soft_recalc_graph_when_paused (
1188 void * data)
1189 {
1190 EventManager * self = (EventManager *) data;
1191 if (TRANSPORT->play_state == PLAYSTATE_PAUSED)
1192 {
1193 router_recalc_graph (ROUTER, F_SOFT);
1194 self->pending_soft_recalc = false;
1195 return G_SOURCE_REMOVE;
1196 }
1197 return G_SOURCE_CONTINUE;
1198 }
1199
1200 /**
1201 * Processes the given event.
1202 *
1203 * The caller is responsible for putting the event
1204 * back in the object pool if needed.
1205 */
1206 void
event_manager_process_event(EventManager * self,ZEvent * ev)1207 event_manager_process_event (
1208 EventManager * self,
1209 ZEvent * ev)
1210 {
1211 switch (ev->type)
1212 {
1213 case ET_PLUGIN_LATENCY_CHANGED:
1214 if (!self->pending_soft_recalc)
1215 {
1216 self->pending_soft_recalc = true;
1217 g_idle_add (
1218 soft_recalc_graph_when_paused,
1219 self);
1220 }
1221 break;
1222 case ET_TRACKS_REMOVED:
1223 if (MW_MIXER)
1224 mixer_widget_hard_refresh (MW_MIXER);
1225 if (MW_TRACKLIST)
1226 tracklist_widget_hard_refresh (
1227 MW_TRACKLIST);
1228 visibility_widget_refresh (
1229 MW_VISIBILITY);
1230 tracklist_header_widget_refresh_track_count (
1231 MW_TRACKLIST_HEADER);
1232 left_dock_edge_widget_refresh (
1233 MW_LEFT_DOCK_EDGE);
1234 break;
1235 case ET_CHANNEL_REMOVED:
1236 mixer_widget_hard_refresh (
1237 MW_MIXER);
1238 break;
1239 case ET_ARRANGER_OBJECT_CREATED:
1240 on_arranger_object_created (
1241 (ArrangerObject *) ev->arg);
1242 break;
1243 case ET_ARRANGER_OBJECT_CHANGED:
1244 on_arranger_object_changed (
1245 (ArrangerObject *) ev->arg);
1246 break;
1247 case ET_ARRANGER_OBJECT_REMOVED:
1248 on_arranger_object_removed (
1249 (ArrangerObjectType) ev->arg);
1250 break;
1251 case ET_ARRANGER_SELECTIONS_CHANGED:
1252 on_arranger_selections_changed (
1253 ARRANGER_SELECTIONS (ev->arg));
1254 break;
1255 case ET_ARRANGER_SELECTIONS_CREATED:
1256 on_arranger_selections_created (
1257 ARRANGER_SELECTIONS (ev->arg));
1258 break;
1259 case ET_ARRANGER_SELECTIONS_REMOVED:
1260 on_arranger_selections_removed (
1261 ARRANGER_SELECTIONS (ev->arg));
1262 break;
1263 case ET_ARRANGER_SELECTIONS_MOVED:
1264 on_arranger_selections_moved (
1265 ARRANGER_SELECTIONS (ev->arg));
1266 break;
1267 case ET_ARRANGER_SELECTIONS_QUANTIZED:
1268 redraw_arranger_for_selections (
1269 ARRANGER_SELECTIONS (ev->arg));
1270 break;
1271 case ET_ARRANGER_SELECTIONS_ACTION_FINISHED:
1272 redraw_all_arranger_bgs ();
1273 ruler_widget_redraw_whole (
1274 (RulerWidget *) MW_RULER);
1275 ruler_widget_redraw_whole (
1276 (RulerWidget *) EDITOR_RULER);
1277 break;
1278 case ET_TRACKLIST_SELECTIONS_CHANGED:
1279 /* only refresh the inspector if the
1280 * tracklist selection changed by
1281 * clicking on a track */
1282 if (PROJECT->last_selection ==
1283 SELECTION_TYPE_TRACKLIST ||
1284 PROJECT->last_selection ==
1285 SELECTION_TYPE_INSERT ||
1286 PROJECT->last_selection ==
1287 SELECTION_TYPE_MIDI_FX)
1288 {
1289 left_dock_edge_widget_refresh (
1290 MW_LEFT_DOCK_EDGE);
1291 }
1292 mixer_widget_soft_refresh (MW_MIXER);
1293 /* TODO implement soft refresh */
1294 tracklist_widget_hard_refresh (
1295 MW_TRACKLIST);
1296 break;
1297 case ET_RULER_SIZE_CHANGED:
1298 {
1299 RulerWidget * ruler =
1300 Z_RULER_WIDGET (ev->arg);
1301 gtk_widget_queue_allocate (
1302 GTK_WIDGET (ruler));
1303 ruler_widget_redraw_whole (ruler);
1304 if (ev->arg == MW_RULER)
1305 {
1306 arranger_widget_redraw_whole (
1307 Z_ARRANGER_WIDGET (
1308 MW_TIMELINE));
1309 arranger_widget_redraw_whole (
1310 Z_ARRANGER_WIDGET (
1311 MW_PINNED_TIMELINE));
1312 }
1313 else if (ev->arg == EDITOR_RULER)
1314 {
1315 if (gtk_widget_get_visible (
1316 GTK_WIDGET (MW_MIDI_ARRANGER)))
1317 {
1318 arranger_widget_redraw_whole (
1319 Z_ARRANGER_WIDGET (
1320 MW_MIDI_ARRANGER));
1321 arranger_widget_redraw_whole (
1322 Z_ARRANGER_WIDGET (
1323 MW_MIDI_MODIFIER_ARRANGER));
1324 }
1325 if (gtk_widget_get_visible (
1326 GTK_WIDGET (MW_AUDIO_ARRANGER)))
1327 {
1328 arranger_widget_redraw_whole (
1329 Z_ARRANGER_WIDGET (
1330 MW_AUDIO_ARRANGER));
1331 }
1332 }
1333 }
1334 break;
1335 case ET_CLIP_MARKER_POS_CHANGED:
1336 ruler_widget_redraw_whole (
1337 EDITOR_RULER);
1338 clip_editor_redraw_region (CLIP_EDITOR);
1339 break;
1340 case ET_TIMELINE_LOOP_MARKER_POS_CHANGED:
1341 case ET_TIMELINE_PUNCH_MARKER_POS_CHANGED:
1342 ruler_widget_redraw_whole (
1343 (RulerWidget *) MW_RULER);
1344 ruler_widget_redraw_whole (
1345 (RulerWidget *) EDITOR_RULER);
1346 redraw_all_arranger_bgs ();
1347 break;
1348 case ET_TIMELINE_SONG_MARKER_POS_CHANGED:
1349 gtk_widget_queue_allocate (
1350 GTK_WIDGET (MW_RULER));
1351 ruler_widget_redraw_whole (
1352 (RulerWidget *) MW_RULER);
1353 break;
1354 case ET_PLUGIN_VISIBILITY_CHANGED:
1355 on_plugin_visibility_changed (
1356 (Plugin *) ev->arg);
1357 break;
1358 case ET_PLUGIN_WINDOW_VISIBILITY_CHANGED:
1359 on_plugin_window_visibility_changed (
1360 (Plugin *) ev->arg);
1361 break;
1362 case ET_PLUGIN_STATE_CHANGED:
1363 {
1364 Plugin * pl = (Plugin *) ev->arg;
1365 if (IS_PLUGIN (pl))
1366 {
1367 on_plugin_state_changed (pl);
1368 g_atomic_int_set (
1369 &pl->state_changed_event_sent, 0);
1370 }
1371 }
1372 break;
1373 case ET_TRANSPORT_TOTAL_BARS_CHANGED:
1374 snap_grid_update_snap_points_default (
1375 SNAP_GRID_TIMELINE);
1376
1377 ruler_widget_refresh (
1378 (RulerWidget *) MW_RULER);
1379 ruler_widget_refresh (
1380 (RulerWidget *) EDITOR_RULER);
1381 timeline_minimap_widget_refresh (
1382 MW_TIMELINE_MINIMAP);
1383 break;
1384 case ET_AUTOMATION_VALUE_CHANGED:
1385 on_automation_value_changed (
1386 (Port *) ev->arg);
1387 break;
1388 case ET_RANGE_SELECTION_CHANGED:
1389 on_range_selection_changed ();
1390 timeline_toolbar_widget_refresh (
1391 MW_TIMELINE_TOOLBAR);
1392 break;
1393 case ET_TOOL_CHANGED:
1394 toolbox_widget_refresh (MW_TOOLBOX);
1395 arranger_widget_refresh_cursor (
1396 Z_ARRANGER_WIDGET (MW_TIMELINE));
1397 if (MW_MIDI_ARRANGER &&
1398 gtk_widget_get_realized (
1399 GTK_WIDGET (MW_MIDI_ARRANGER)))
1400 arranger_widget_refresh_cursor (
1401 Z_ARRANGER_WIDGET (MW_MIDI_ARRANGER));
1402 if (MW_MIDI_MODIFIER_ARRANGER &&
1403 gtk_widget_get_realized (
1404 GTK_WIDGET (MW_MIDI_MODIFIER_ARRANGER)))
1405 arranger_widget_refresh_cursor (
1406 Z_ARRANGER_WIDGET (
1407 MW_MIDI_MODIFIER_ARRANGER));
1408 break;
1409 case ET_TIME_SIGNATURE_CHANGED:
1410 ruler_widget_refresh (
1411 Z_RULER_WIDGET (MW_RULER));
1412 ruler_widget_refresh (
1413 Z_RULER_WIDGET (EDITOR_RULER));
1414 gtk_widget_queue_draw (
1415 GTK_WIDGET (MW_DIGITAL_TIME_SIG));
1416 break;
1417 case ET_PLAYHEAD_POS_CHANGED:
1418 on_playhead_changed (false);
1419 break;
1420 case ET_PLAYHEAD_POS_CHANGED_MANUALLY:
1421 on_playhead_changed (true);
1422 break;
1423 case ET_CLIP_EDITOR_REGION_CHANGED:
1424 /*on_clip_editor_region_changed ();*/
1425 clip_editor_widget_on_region_changed (
1426 MW_CLIP_EDITOR);
1427 PIANO_ROLL->num_current_notes = 0;
1428 piano_roll_keys_widget_redraw_full (
1429 MW_PIANO_ROLL_KEYS);
1430 break;
1431 case ET_TRACK_AUTOMATION_VISIBILITY_CHANGED:
1432 tracklist_widget_update_track_visibility (
1433 MW_TRACKLIST);
1434 break;
1435 case ET_TRACK_LANES_VISIBILITY_CHANGED:
1436 tracklist_widget_update_track_visibility (
1437 MW_TRACKLIST);
1438 /*arranger_widget_update_visibility (*/
1439 /*(ArrangerWidget *) MW_TIMELINE);*/
1440 /*arranger_widget_update_visibility (*/
1441 /*(ArrangerWidget *) MW_PINNED_TIMELINE);*/
1442 break;
1443 case ET_TRACK_ADDED:
1444 on_track_added ((Track *) ev->arg);
1445 tracklist_header_widget_refresh_track_count (
1446 MW_TRACKLIST_HEADER);
1447 break;
1448 case ET_TRACK_CHANGED:
1449 on_track_changed ((Track *) ev->arg);
1450 break;
1451 case ET_TRACKS_ADDED:
1452 if (MW_MIXER)
1453 mixer_widget_hard_refresh (MW_MIXER);
1454 if (MW_TRACKLIST)
1455 tracklist_widget_hard_refresh (
1456 MW_TRACKLIST);
1457 visibility_widget_refresh (
1458 MW_VISIBILITY);
1459 tracklist_header_widget_refresh_track_count (
1460 MW_TRACKLIST_HEADER);
1461 break;
1462 case ET_TRACK_COLOR_CHANGED:
1463 on_track_color_changed ((Track *) ev->arg);
1464 break;
1465 case ET_TRACK_NAME_CHANGED:
1466 on_track_name_changed ((Track *) ev->arg);
1467 break;
1468 case ET_REFRESH_ARRANGER:
1469 /* remove the children of the pinned
1470 * timeline first because one of them
1471 * will be added to the unpinned
1472 * tracklist when unpinning */
1473 arranger_widget_redraw_whole (
1474 MW_PINNED_TIMELINE);
1475
1476 if (MW_TIMELINE)
1477 arranger_widget_redraw_whole (
1478 MW_TIMELINE);
1479 break;
1480 case ET_RULER_VIEWPORT_CHANGED:
1481 timeline_minimap_widget_refresh (
1482 MW_TIMELINE_MINIMAP);
1483 ruler_widget_refresh (
1484 Z_RULER_WIDGET (ev->arg));
1485 break;
1486 case ET_TRACK_STATE_CHANGED:
1487 /*on_track_state_changed (*/
1488 /*(Track *) ev->arg);*/
1489 for (int j = 0; j < TRACKLIST->num_tracks;
1490 j++)
1491 {
1492 on_track_state_changed (
1493 TRACKLIST->tracks[j]);
1494 }
1495 monitor_section_widget_refresh (
1496 MW_MONITOR_SECTION);
1497 break;
1498 case ET_TRACK_VISIBILITY_CHANGED:
1499 tracklist_widget_update_track_visibility (
1500 MW_TRACKLIST);
1501 arranger_widget_redraw_whole (
1502 MW_TIMELINE);
1503 arranger_widget_redraw_whole (
1504 MW_PINNED_TIMELINE);
1505 track_visibility_tree_widget_refresh (
1506 MW_TRACK_VISIBILITY_TREE);
1507 tracklist_header_widget_refresh_track_count (
1508 MW_TRACKLIST_HEADER);
1509 mixer_widget_hard_refresh (MW_MIXER);
1510 break;
1511 case ET_UNDO_REDO_ACTION_DONE:
1512 home_toolbar_widget_refresh_undo_redo_buttons (
1513 MW_HOME_TOOLBAR);
1514 break;
1515 case ET_PIANO_ROLL_HIGHLIGHTING_CHANGED:
1516 if (MW_MIDI_EDITOR_SPACE)
1517 piano_roll_keys_widget_refresh (
1518 MW_PIANO_ROLL_KEYS);
1519 break;
1520 case ET_PIANO_ROLL_KEY_ON_OFF:
1521 piano_roll_keys_widget_redraw_full (
1522 MW_PIANO_ROLL_KEYS);
1523 break;
1524 case ET_RULER_STATE_CHANGED:
1525 ruler_widget_refresh (
1526 (RulerWidget *) MW_RULER);
1527 break;
1528 case ET_AUTOMATION_TRACK_ADDED:
1529 case ET_AUTOMATION_TRACK_REMOVED:
1530 case ET_AUTOMATION_TRACK_CHANGED:
1531 on_automation_track_added (
1532 (AutomationTrack *) ev->arg);
1533 break;
1534 case ET_PLUGINS_ADDED:
1535 on_plugins_removed ((Track *)ev->arg);
1536 break;
1537 case ET_PLUGIN_ADDED:
1538 on_plugin_added (
1539 (Plugin *) ev->arg);
1540 break;
1541 case ET_PLUGIN_CRASHED:
1542 on_plugin_crashed (
1543 (Plugin *) ev->arg);
1544 break;
1545 case ET_PLUGINS_REMOVED:
1546 on_plugins_removed ((Track *)ev->arg);
1547 break;
1548 case ET_MIXER_SELECTIONS_CHANGED:
1549 on_mixer_selections_changed ();
1550 break;
1551 case ET_CHANNEL_OUTPUT_CHANGED:
1552 on_channel_output_changed (
1553 (Channel *)ev->arg);
1554 break;
1555 case ET_TRACKS_MOVED:
1556 if (MW_MIXER)
1557 mixer_widget_hard_refresh (MW_MIXER);
1558
1559 /* remove the children of the pinned
1560 * tracklist first because one of them
1561 * will be added to the unpinned
1562 * tracklist when unpinning */
1563 /*z_gtk_container_remove_all_children (*/
1564 /*GTK_CONTAINER (MW_PINNED_TRACKLIST));*/
1565
1566 if (MW_TRACKLIST)
1567 tracklist_widget_hard_refresh (
1568 MW_TRACKLIST);
1569 /*if (MW_PINNED_TRACKLIST)*/
1570 /*pinned_tracklist_widget_hard_refresh (*/
1571 /*MW_PINNED_TRACKLIST);*/
1572
1573 visibility_widget_refresh (
1574 MW_VISIBILITY);
1575
1576 /* needs to be called later because tracks
1577 * need time to get allocated */
1578 EVENTS_PUSH (ET_REFRESH_ARRANGER, NULL);
1579 break;
1580 case ET_CHANNEL_SLOTS_CHANGED:
1581 {
1582 Channel * ch = (Channel *) ev->arg;
1583 ChannelWidget * cw =
1584 ch ? ch->widget : NULL;
1585 if (cw)
1586 {
1587 channel_widget_update_midi_fx_and_inserts (
1588 cw);
1589 }
1590 }
1591 break;
1592 case ET_DRUM_MODE_CHANGED:
1593 midi_editor_space_widget_refresh (
1594 MW_MIDI_EDITOR_SPACE);
1595 arranger_widget_redraw_whole (
1596 MW_MIDI_ARRANGER);
1597 break;
1598 case ET_MODULATOR_ADDED:
1599 on_modulator_added ((Plugin *)ev->arg);
1600 break;
1601 case ET_PINNED_TRACKLIST_SIZE_CHANGED:
1602 /*gtk_widget_set_size_request (*/
1603 /*GTK_WIDGET (*/
1604 /*MW_CENTER_DOCK->*/
1605 /*pinned_timeline_scroll),*/
1606 /*-1,*/
1607 /*gtk_widget_get_allocated_height (*/
1608 /*GTK_WIDGET (MW_PINNED_TRACKLIST)));*/
1609 break;
1610 case ET_TRACK_LANE_ADDED:
1611 case ET_TRACK_LANE_REMOVED:
1612 tracklist_widget_update_track_visibility (
1613 MW_TRACKLIST);
1614 /*arranger_widget_update_visibility (*/
1615 /*(ArrangerWidget *) MW_TIMELINE);*/
1616 break;
1617 case ET_LOOP_TOGGLED:
1618 redraw_all_arranger_bgs ();
1619 ruler_widget_redraw_whole (
1620 (RulerWidget *) EDITOR_RULER);
1621 ruler_widget_redraw_whole (
1622 (RulerWidget *) MW_RULER);
1623 transport_controls_widget_refresh (
1624 MW_TRANSPORT_CONTROLS);
1625 break;
1626 case ET_ARRANGER_SELECTIONS_IN_TRANSIT:
1627 on_arranger_selections_in_transit (
1628 (ArrangerSelections *) ev->arg);
1629 break;
1630 case ET_CHORD_KEY_CHANGED:
1631 for (int j = 0;
1632 j < CHORD_EDITOR->num_chords; j++)
1633 {
1634 if (CHORD_EDITOR->chords[j] ==
1635 (ChordDescriptor *) ev->arg)
1636 {
1637 chord_key_widget_refresh (
1638 MW_CHORD_EDITOR_SPACE->
1639 chord_keys[j]);
1640 }
1641 }
1642 chord_pad_widget_refresh (MW_CHORD_PAD);
1643 break;
1644 case ET_JACK_TRANSPORT_TYPE_CHANGED:
1645 g_message ("doing");
1646 top_bar_widget_refresh (
1647 TOP_BAR);
1648 break;
1649 case ET_SELECTING_IN_ARRANGER:
1650 {
1651 ArrangerWidget * arranger =
1652 Z_ARRANGER_WIDGET (ev->arg);
1653 ArrangerSelections * sel =
1654 arranger_widget_get_selections (arranger);
1655 arranger_selections_redraw (sel);
1656 event_viewer_widget_refresh_for_arranger (
1657 arranger);
1658 timeline_toolbar_widget_refresh (
1659 MW_TIMELINE_TOOLBAR);
1660 }
1661 break;
1662 case ET_TRACKS_RESIZED:
1663 g_warn_if_fail (ev->arg);
1664 arranger_widget_redraw_whole (
1665 MW_TIMELINE);
1666 arranger_widget_redraw_whole (
1667 MW_PINNED_TIMELINE);
1668 break;
1669 case ET_CLIP_EDITOR_FIRST_TIME_REGION_SELECTED:
1670 gtk_widget_set_visible (
1671 GTK_WIDGET (MW_EDITOR_EVENT_VIEWER),
1672 g_settings_get_boolean (
1673 S_UI, "editor-event-viewer-visible"));
1674 break;
1675 case ET_PIANO_ROLL_MIDI_MODIFIER_CHANGED:
1676 arranger_widget_redraw_whole (
1677 (ArrangerWidget *)
1678 MW_MIDI_MODIFIER_ARRANGER);
1679 break;
1680 case ET_BPM_CHANGED:
1681 ruler_widget_refresh (MW_RULER);
1682 ruler_widget_refresh (EDITOR_RULER);
1683 gtk_widget_queue_draw (
1684 GTK_WIDGET (MW_DIGITAL_BPM));
1685
1686 /* these are only used in the UI so
1687 * no need to update them during DSP */
1688 snap_grid_update_snap_points_default (
1689 SNAP_GRID_TIMELINE);
1690 snap_grid_update_snap_points_default (
1691 SNAP_GRID_EDITOR);
1692 quantize_options_update_quantize_points (
1693 QUANTIZE_OPTIONS_TIMELINE);
1694 quantize_options_update_quantize_points (
1695 QUANTIZE_OPTIONS_EDITOR);
1696 redraw_all_arranger_bgs ();
1697 break;
1698 case ET_CHANNEL_FADER_VAL_CHANGED:
1699 channel_widget_redraw_fader (
1700 ((Channel *)ev->arg)->widget);
1701 #if 0
1702 inspector_track_widget_show_tracks (
1703 MW_TRACK_INSPECTOR, TRACKLIST_SELECTIONS);
1704 #endif
1705 break;
1706 case ET_PIANO_ROLL_KEY_HEIGHT_CHANGED:
1707 midi_editor_space_widget_refresh (
1708 MW_MIDI_EDITOR_SPACE);
1709 break;
1710 case ET_MAIN_WINDOW_LOADED:
1711 /* show all visible plugins */
1712 for (int j = 0; j < TRACKLIST->num_tracks;
1713 j++)
1714 {
1715 Channel * ch =
1716 TRACKLIST->tracks[j]->channel;
1717 if (!ch)
1718 continue;
1719
1720 for (int k = 0;
1721 k < STRIP_SIZE * 2 + 1; k++)
1722 {
1723 Plugin * pl = NULL;
1724 if (k < STRIP_SIZE)
1725 pl = ch->midi_fx[k];
1726 else if (k == STRIP_SIZE)
1727 pl = ch->instrument;
1728 else
1729 pl =
1730 ch->inserts[
1731 k - (STRIP_SIZE + 1)];
1732
1733 if (!pl)
1734 continue;
1735 if (pl->visible)
1736 plugin_open_ui (pl);
1737 }
1738 }
1739 /* refresh modulator view */
1740 if (MW_MODULATOR_VIEW)
1741 {
1742 modulator_view_widget_refresh (
1743 MW_MODULATOR_VIEW,
1744 P_MODULATOR_TRACK);
1745 }
1746
1747 /* show clip editor if clip selected */
1748 if (MW_CLIP_EDITOR &&
1749 CLIP_EDITOR->has_region)
1750 {
1751 clip_editor_widget_on_region_changed (
1752 MW_CLIP_EDITOR);
1753 }
1754
1755 /* refresh inspector */
1756 left_dock_edge_widget_refresh (
1757 MW_LEFT_DOCK_EDGE);
1758 on_project_selection_type_changed ();
1759 main_notebook_widget_refresh (
1760 MW_MAIN_NOTEBOOK);
1761
1762 #ifdef CHECK_UPDATES
1763 zrythm_app_check_for_updates (zrythm_app);
1764 #endif /* CHECK_UPDATES */
1765 break;
1766 case ET_SPLASH_CLOSED:
1767 break;
1768 case ET_PROJECT_SAVED:
1769 header_widget_set_subtitle (
1770 MW_HEADER,
1771 ((Project *) ev->arg)->title);
1772 break;
1773 case ET_PROJECT_LOADED:
1774 header_widget_set_subtitle (
1775 MW_HEADER,
1776 ((Project *) ev->arg)->title);
1777 home_toolbar_widget_refresh_undo_redo_buttons (
1778 MW_HOME_TOOLBAR);
1779 ruler_widget_set_zoom_level (
1780 MW_RULER,
1781 ruler_widget_get_zoom_level (
1782 MW_RULER));
1783 ruler_widget_set_zoom_level (
1784 EDITOR_RULER,
1785 ruler_widget_get_zoom_level (
1786 EDITOR_RULER));
1787 break;
1788 case ET_AUTOMATION_TRACKLIST_AT_REMOVED:
1789 /* TODO */
1790 break;
1791 case ET_TRIAL_LIMIT_REACHED:
1792 {
1793 char msg[500];
1794 sprintf (
1795 msg,
1796 _("Trial limit has been reached. "
1797 "%s will now go silent"),
1798 PROGRAM_NAME);
1799 ui_show_message_full (
1800 GTK_WINDOW (MAIN_WINDOW),
1801 GTK_MESSAGE_INFO, "%s", msg);
1802 }
1803 break;
1804 case ET_CHANNEL_SEND_CHANGED:
1805 {
1806 ChannelSend * send =
1807 (ChannelSend *) ev->arg;
1808 ChannelSendWidget * widget =
1809 channel_send_find_widget (send);
1810 if (widget)
1811 {
1812 gtk_widget_queue_draw (
1813 GTK_WIDGET (widget));
1814 }
1815 Track * tr =
1816 channel_send_get_track (send);
1817 ChannelWidget * ch_w =
1818 tr->channel->widget;
1819 if (ch_w)
1820 {
1821 gtk_widget_queue_draw (
1822 GTK_WIDGET (
1823 ch_w->sends->slots[
1824 send->slot]));
1825 }
1826 }
1827 break;
1828 case ET_RULER_DISPLAY_TYPE_CHANGED:
1829 redraw_all_arranger_bgs ();
1830 if (EDITOR_RULER)
1831 {
1832 ruler_widget_redraw_whole (
1833 EDITOR_RULER);
1834 }
1835 if (MW_RULER)
1836 {
1837 ruler_widget_redraw_whole (MW_RULER);
1838 }
1839 break;
1840 case ET_ARRANGER_HIGHLIGHT_CHANGED:
1841 {
1842 ArrangerWidget * arranger =
1843 Z_ARRANGER_WIDGET (ev->arg);
1844 arranger_widget_redraw_whole (
1845 arranger);
1846 }
1847 break;
1848 case ET_ENGINE_ACTIVATE_CHANGED:
1849 case ET_ENGINE_BUFFER_SIZE_CHANGED:
1850 case ET_ENGINE_SAMPLE_RATE_CHANGED:
1851 if (!gtk_widget_in_destruction (
1852 GTK_WIDGET (MAIN_WINDOW)))
1853 {
1854 bot_bar_widget_refresh (MW_BOT_BAR);
1855 ruler_widget_redraw_whole (EDITOR_RULER);
1856 ruler_widget_redraw_whole (MW_RULER);
1857 inspector_track_widget_show_tracks (
1858 MW_TRACK_INSPECTOR,
1859 TRACKLIST_SELECTIONS, false);
1860 }
1861 break;
1862 case ET_MIDI_BINDINGS_CHANGED:
1863 main_notebook_widget_refresh (
1864 MW_MAIN_NOTEBOOK);
1865 break;
1866 case ET_PORT_CONNECTION_CHANGED:
1867 main_notebook_widget_refresh (
1868 MW_MAIN_NOTEBOOK);
1869 break;
1870 case ET_EDITOR_FUNCTION_APPLIED:
1871 editor_toolbar_widget_refresh (
1872 MW_EDITOR_TOOLBAR);
1873 break;
1874 case ET_ARRANGER_SELECTIONS_CHANGED_REDRAW_EVERYTHING:
1875 arranger_selections_change_redraw_everything (
1876 ARRANGER_SELECTIONS (ev->arg));
1877 break;
1878 case ET_AUTOMATION_VALUE_VISIBILITY_CHANGED:
1879 arranger_widget_redraw_whole (
1880 MW_AUTOMATION_ARRANGER);
1881 break;
1882 case ET_PROJECT_SELECTION_TYPE_CHANGED:
1883 on_project_selection_type_changed ();
1884 break;
1885 case ET_AUDIO_SELECTIONS_RANGE_CHANGED:
1886 arranger_widget_redraw_whole (
1887 MW_AUDIO_ARRANGER);
1888 break;
1889 case ET_PLUGIN_COLLETIONS_CHANGED:
1890 plugin_browser_widget_refresh_collections (
1891 MW_PLUGIN_BROWSER);
1892 break;
1893 case ET_SNAP_GRID_OPTIONS_CHANGED:
1894 {
1895 SnapGrid * sg = (SnapGrid *) ev->arg;
1896 if (sg == SNAP_GRID_TIMELINE)
1897 {
1898 snap_box_widget_refresh (
1899 MW_TIMELINE_TOOLBAR->snap_box);
1900 }
1901 else if (sg == SNAP_GRID_EDITOR)
1902 {
1903 snap_box_widget_refresh (
1904 MW_EDITOR_TOOLBAR->snap_box);
1905 }
1906 }
1907 break;
1908 case ET_TRANSPORT_RECORDING_ON_OFF_CHANGED:
1909 gtk_toggle_button_set_active (
1910 MW_TRANSPORT_CONTROLS->trans_record_btn,
1911 TRANSPORT->recording);
1912 break;
1913 case ET_TRACK_FREEZE_CHANGED:
1914 arranger_selections_change_redraw_everything (
1915 (ArrangerSelections *) TL_SELECTIONS);
1916 break;
1917 case ET_LOG_WARNING_STATE_CHANGED:
1918 header_widget_refresh (MW_HEADER);
1919 break;
1920 case ET_PLAYHEAD_SCROLL_MODE_CHANGED:
1921 break;
1922 case ET_TRACK_FADER_BUTTON_CHANGED:
1923 on_track_state_changed (
1924 (Track *) ev->arg);
1925 break;
1926 case ET_PLUGIN_PRESET_SAVED:
1927 case ET_PLUGIN_PRESET_LOADED:
1928 {
1929 Plugin * pl = (Plugin *) ev->arg;
1930 if (pl->window)
1931 {
1932 plugin_gtk_set_window_title (
1933 pl, pl->window);
1934 }
1935 }
1936 break;
1937 case ET_TRACK_FOLD_CHANGED:
1938 on_track_added ((Track *) ev->arg);
1939 break;
1940 case ET_MIXER_CHANNEL_INSERTS_EXPANDED_CHANGED:
1941 case ET_MIXER_CHANNEL_MIDI_FX_EXPANDED_CHANGED:
1942 case ET_MIXER_CHANNEL_SENDS_EXPANDED_CHANGED:
1943 mixer_widget_soft_refresh (MW_MIXER);
1944 break;
1945 case ET_REGION_ACTIVATED:
1946 bot_dock_edge_widget_show_clip_editor (
1947 MW_BOT_DOCK_EDGE, true);
1948 break;
1949 case ET_VELOCITIES_RAMPED:
1950 arranger_widget_redraw_whole (
1951 MW_MIDI_MODIFIER_ARRANGER);
1952 break;
1953 case ET_AUDIO_REGION_FADE_IN_CHANGED:
1954 audio_arranger_widget_redraw_fade (
1955 MW_AUDIO_ARRANGER, true);
1956 break;
1957 case ET_AUDIO_REGION_FADE_OUT_CHANGED:
1958 audio_arranger_widget_redraw_fade (
1959 MW_AUDIO_ARRANGER, false);
1960 break;
1961 case ET_AUDIO_REGION_GAIN_CHANGED:
1962 audio_arranger_widget_redraw_gain (
1963 MW_AUDIO_ARRANGER);
1964 break;
1965 default:
1966 g_warning (
1967 "event %d not implemented yet",
1968 ev->type);
1969 break;
1970 }
1971 }
1972
1973 /**
1974 * GSourceFunc to be added using idle add.
1975 *
1976 * This will loop indefinintely.
1977 */
1978 static int
process_events(void * data)1979 process_events (void * data)
1980 {
1981 EventManager * self = (EventManager *) data;
1982
1983 ZEvent * ev;
1984 clean_duplicates_and_copy (
1985 self, self->events_arr);
1986
1987 /*g_message ("starting processing");*/
1988 for (guint i = 0; i < self->events_arr->len; i++)
1989 {
1990 if (i > 30)
1991 {
1992 g_message (
1993 "more than 30 UI events processed "
1994 "(%d)!", i);
1995 }
1996
1997 ev =
1998 (ZEvent *)
1999 g_ptr_array_index (self->events_arr, i);
2000
2001 if (!ZRYTHM_HAVE_UI)
2002 {
2003 g_message (
2004 "%s: (%d) No UI, skipping",
2005 __func__, i);
2006 goto return_to_pool;
2007 }
2008
2009 /*g_message ("event type %d", ev->type);*/
2010
2011 event_manager_process_event (self, ev);
2012
2013 return_to_pool:
2014 object_pool_return (
2015 self->obj_pool, ev);
2016 }
2017 /*g_message ("processed %d events", i);*/
2018
2019 if (self->events_arr->len > 6)
2020 g_message ("More than 6 events processed. "
2021 "Optimization needed.");
2022
2023 /*g_usleep (8000);*/
2024 /*project_validate (PROJECT);*/
2025
2026 return G_SOURCE_CONTINUE;
2027 }
2028
2029 /**
2030 * Starts accepting events.
2031 */
2032 void
event_manager_start_events(EventManager * self)2033 event_manager_start_events (
2034 EventManager * self)
2035 {
2036 g_message ("%s: starting...", __func__);
2037
2038 if (self->process_source_id)
2039 {
2040 g_message (
2041 "%s: already processing events", __func__);
2042 return;
2043 }
2044
2045 g_message (
2046 "%s: starting processing events...", __func__);
2047
2048 self->process_source_id =
2049 g_timeout_add (12, process_events, self);
2050
2051 g_message ("%s: done...", __func__);
2052 }
2053
2054 /**
2055 * Creates the event queue and starts the event loop.
2056 *
2057 * Must be called from a GTK thread.
2058 */
2059 EventManager *
event_manager_new(void)2060 event_manager_new (void)
2061 {
2062 EventManager * self = object_new (EventManager);
2063
2064 self->obj_pool =
2065 object_pool_new (
2066 (ObjectCreatorFunc) event_new,
2067 (ObjectFreeFunc) event_free,
2068 EVENT_MANAGER_MAX_EVENTS);
2069 self->mqueue = mpmc_queue_new ();
2070 mpmc_queue_reserve (
2071 self->mqueue,
2072 (size_t)
2073 EVENT_MANAGER_MAX_EVENTS * sizeof (ZEvent *));
2074
2075 self->events_arr =
2076 g_ptr_array_sized_new (200);
2077
2078 return self;
2079 }
2080
2081 /**
2082 * Stops events from getting fired.
2083 */
2084 void
event_manager_stop_events(EventManager * self)2085 event_manager_stop_events (
2086 EventManager * self)
2087 {
2088 if (self->process_source_id)
2089 {
2090 /* remove the source func */
2091 g_source_remove_and_zero (
2092 self->process_source_id);
2093 }
2094
2095 /* process any remaining events - clear the
2096 * queue. */
2097 process_events (self);
2098 }
2099
2100 /**
2101 * Processes the events now.
2102 *
2103 * Must only be called from the GTK thread.
2104 */
2105 void
event_manager_process_now(EventManager * self)2106 event_manager_process_now (
2107 EventManager * self)
2108 {
2109 g_return_if_fail (self);
2110
2111 g_message ("processing events now...");
2112
2113 /* process events now */
2114 process_events (self);
2115
2116 g_message ("done");
2117 }
2118
2119 /**
2120 * Removes events where the arg matches the
2121 * given object.
2122 *
2123 * FIXME doesn't work - infinite loop.
2124 */
2125 void
event_manager_remove_events_for_obj(EventManager * self,void * obj)2126 event_manager_remove_events_for_obj (
2127 EventManager * self,
2128 void * obj)
2129 {
2130 MPMCQueue * q = self->mqueue;
2131 ZEvent * event;
2132 while (event_queue_dequeue_event (q, &event))
2133 {
2134 if (event->arg == obj)
2135 {
2136 object_pool_return (
2137 self->obj_pool, event);
2138 }
2139 else
2140 {
2141 event_queue_push_back_event (q, event);
2142 }
2143 }
2144 }
2145
2146 void
event_manager_free(EventManager * self)2147 event_manager_free (
2148 EventManager * self)
2149 {
2150 g_message ("%s: Freeing...", __func__);
2151
2152 event_manager_stop_events (self);
2153
2154 object_free_w_func_and_null (
2155 object_pool_free, self->obj_pool);
2156 object_free_w_func_and_null (
2157 mpmc_queue_free, self->mqueue);
2158 object_free_w_func_and_null (
2159 g_ptr_array_unref, self->events_arr);
2160
2161 object_zero_and_free (self);
2162
2163 g_message ("%s: done", __func__);
2164 }
2165