MainWidget.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2019-2020, William McPherson <willmcpherson2@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include "MainWidget.h"
  8. #include "KeysWidget.h"
  9. #include "KnobsWidget.h"
  10. #include "PlayerWidget.h"
  11. #include "RollWidget.h"
  12. #include "SamplerWidget.h"
  13. #include "TrackManager.h"
  14. #include "WaveWidget.h"
  15. #include <LibGUI/Action.h>
  16. #include <LibGUI/BoxLayout.h>
  17. #include <LibGUI/Menu.h>
  18. #include <LibGUI/TabWidget.h>
  19. MainWidget::MainWidget(TrackManager& track_manager, AudioPlayerLoop& loop)
  20. : m_track_manager(track_manager)
  21. , m_audio_loop(loop)
  22. {
  23. set_layout<GUI::VerticalBoxLayout>();
  24. layout()->set_spacing(2);
  25. layout()->set_margins(2);
  26. set_fill_with_background_color(true);
  27. m_wave_widget = add<WaveWidget>(track_manager);
  28. m_wave_widget->set_fixed_height(100);
  29. m_tab_widget = add<GUI::TabWidget>();
  30. m_roll_widget = m_tab_widget->add_tab<RollWidget>("Piano Roll", track_manager);
  31. m_roll_widget->set_fixed_height(300);
  32. m_tab_widget->add_tab<SamplerWidget>("Sampler", track_manager);
  33. m_player_widget = add<PlayerWidget>(track_manager, loop);
  34. m_keys_and_knobs_container = add<GUI::Widget>();
  35. m_keys_and_knobs_container->set_layout<GUI::HorizontalBoxLayout>();
  36. m_keys_and_knobs_container->layout()->set_spacing(2);
  37. m_keys_and_knobs_container->set_fixed_height(100);
  38. m_keys_and_knobs_container->set_fill_with_background_color(true);
  39. m_keys_widget = m_keys_and_knobs_container->add<KeysWidget>(track_manager);
  40. m_knobs_widget = m_keys_and_knobs_container->add<KnobsWidget>(track_manager, *this);
  41. m_knobs_widget->set_fixed_width(350);
  42. m_roll_widget->set_keys_widget(m_keys_widget);
  43. }
  44. MainWidget::~MainWidget()
  45. {
  46. }
  47. void MainWidget::add_actions(GUI::Menu& menu)
  48. {
  49. menu.add_action(GUI::Action::create("&Add Track", { Mod_Ctrl, Key_T }, [&](auto&) {
  50. m_track_manager.add_track();
  51. }));
  52. menu.add_action(GUI::Action::create("&Next Track", { Mod_Ctrl, Key_N }, [&](auto&) {
  53. turn_off_pressed_keys();
  54. m_track_manager.next_track();
  55. turn_on_pressed_keys();
  56. m_knobs_widget->update_knobs();
  57. }));
  58. }
  59. // FIXME: There are some unnecessary calls to update() throughout this program,
  60. // which are an easy target for optimization.
  61. void MainWidget::custom_event(Core::CustomEvent&)
  62. {
  63. m_wave_widget->update();
  64. m_roll_widget->update();
  65. }
  66. void MainWidget::keydown_event(GUI::KeyEvent& event)
  67. {
  68. // This is to stop held-down keys from creating multiple events.
  69. if (m_keys_pressed[event.key()])
  70. return;
  71. else
  72. m_keys_pressed[event.key()] = true;
  73. note_key_action(event.key(), On);
  74. special_key_action(event.key());
  75. m_keys_widget->update();
  76. }
  77. void MainWidget::keyup_event(GUI::KeyEvent& event)
  78. {
  79. m_keys_pressed[event.key()] = false;
  80. note_key_action(event.key(), Off);
  81. m_keys_widget->update();
  82. }
  83. void MainWidget::note_key_action(int key_code, Switch switch_note)
  84. {
  85. int key = m_keys_widget->key_code_to_key(key_code);
  86. m_keys_widget->set_key(key, switch_note);
  87. }
  88. void MainWidget::special_key_action(int key_code)
  89. {
  90. switch (key_code) {
  91. case Key_Z:
  92. set_octave_and_ensure_note_change(Down);
  93. break;
  94. case Key_X:
  95. set_octave_and_ensure_note_change(Up);
  96. break;
  97. case Key_C:
  98. m_track_manager.current_track().set_wave(Up);
  99. m_knobs_widget->update_knobs();
  100. break;
  101. }
  102. }
  103. void MainWidget::turn_off_pressed_keys()
  104. {
  105. m_keys_widget->set_key(m_keys_widget->mouse_note(), Off);
  106. for (int i = 0; i < key_code_count; ++i) {
  107. if (m_keys_pressed[i])
  108. note_key_action(i, Off);
  109. }
  110. }
  111. void MainWidget::turn_on_pressed_keys()
  112. {
  113. m_keys_widget->set_key(m_keys_widget->mouse_note(), On);
  114. for (int i = 0; i < key_code_count; ++i) {
  115. if (m_keys_pressed[i])
  116. note_key_action(i, On);
  117. }
  118. }
  119. void MainWidget::set_octave_and_ensure_note_change(int octave)
  120. {
  121. turn_off_pressed_keys();
  122. m_track_manager.set_octave(octave);
  123. turn_on_pressed_keys();
  124. m_knobs_widget->update_knobs();
  125. m_keys_widget->update();
  126. }
  127. void MainWidget::set_octave_and_ensure_note_change(Direction direction)
  128. {
  129. turn_off_pressed_keys();
  130. m_track_manager.set_octave(direction);
  131. turn_on_pressed_keys();
  132. m_knobs_widget->update_knobs();
  133. m_keys_widget->update();
  134. }