1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html 2 3 #include "smsamplewinview.hh" 4 #include "smnavigator.hh" 5 #include "smutils.hh" 6 7 #include <QVBoxLayout> 8 9 #define LOOP_NONE_TEXT "No loop" 10 #define LOOP_FRAME_FORWARD_TEXT "Frame loop forward" 11 #define LOOP_FRAME_PING_PONG_TEXT "Frame loop ping-pong" 12 #define LOOP_TIME_FORWARD_TEXT "Time loop forward" 13 #define LOOP_TIME_PING_PONG_TEXT "Time loop ping-pong" 14 15 using namespace SpectMorph; 16 17 using std::string; 18 19 SampleWinView::SampleWinView (Navigator *navigator) 20 { 21 this->navigator = navigator; 22 23 zoom_controller = new ZoomController (this, 1, 5000, 10, 5000); 24 connect (zoom_controller, SIGNAL (zoom_changed()), this, SLOT (on_zoom_changed())); 25 26 m_sample_view = new SampleView(); 27 time_label = new QLabel(); 28 connect (m_sample_view, SIGNAL (mouse_time_changed (int)), this, SLOT (on_mouse_time_changed (int))); 29 on_mouse_time_changed (0); 30 31 edit_loop_start = new QPushButton ("Edit Loop Start"); 32 edit_loop_end = new QPushButton ("Edit Loop End"); 33 34 connect (edit_loop_start, SIGNAL (clicked()), this, SLOT (on_edit_marker_changed())); 35 connect (edit_loop_end, SIGNAL (clicked()), this, SLOT (on_edit_marker_changed())); 36 37 edit_loop_start->setCheckable (true); 38 edit_loop_end->setCheckable (true); 39 40 loop_type_combo = new QComboBox(); 41 loop_type_combo->addItem (LOOP_NONE_TEXT); 42 loop_type_combo->addItem (LOOP_FRAME_FORWARD_TEXT); 43 loop_type_combo->addItem (LOOP_FRAME_PING_PONG_TEXT); 44 loop_type_combo->addItem (LOOP_TIME_FORWARD_TEXT); 45 loop_type_combo->addItem (LOOP_TIME_PING_PONG_TEXT); 46 47 connect (loop_type_combo, SIGNAL (currentIndexChanged (int)), this, SLOT (on_loop_type_changed())); 48 49 show_tuning_button = new QPushButton ("Show Tuning"); 50 connect (show_tuning_button, SIGNAL (clicked()), this, SLOT (on_show_tuning_changed())); 51 show_tuning_button->setCheckable (true); 52 53 scroll_area = new QScrollArea(); 54 scroll_area->setWidgetResizable (true); 55 scroll_area->setWidget (m_sample_view); 56 57 zoom_controller->set_hscrollbar (scroll_area->horizontalScrollBar()); 58 QGridLayout *grid = new QGridLayout(); 59 grid->addWidget (scroll_area, 0, 0, 1, 3); 60 for (int i = 0; i < 3; i++) 61 { 62 grid->addWidget (zoom_controller->hwidget (i), 1, i); 63 grid->addWidget (zoom_controller->vwidget (i), 2, i); 64 } 65 QHBoxLayout *button_hbox = new QHBoxLayout(); 66 button_hbox->addWidget (time_label); 67 button_hbox->addWidget (edit_loop_start); 68 button_hbox->addWidget (edit_loop_end); 69 button_hbox->addWidget (loop_type_combo); 70 button_hbox->addWidget (show_tuning_button); 71 72 grid->addLayout (button_hbox, 3, 0, 1, 3); 73 74 setLayout (grid); 75 } 76 77 void 78 SampleWinView::load (const WavData *wav_data, Audio *audio) 79 { 80 m_sample_view->load (wav_data, audio); 81 if (audio) 82 { 83 if (audio->loop_type == Audio::LOOP_NONE) 84 loop_type_combo->setCurrentText (LOOP_NONE_TEXT); 85 else if (audio->loop_type == Audio::LOOP_FRAME_FORWARD) 86 loop_type_combo->setCurrentText (LOOP_FRAME_FORWARD_TEXT); 87 else if (audio->loop_type == Audio::LOOP_FRAME_PING_PONG) 88 loop_type_combo->setCurrentText (LOOP_FRAME_PING_PONG_TEXT); 89 else if (audio->loop_type == Audio::LOOP_TIME_FORWARD) 90 loop_type_combo->setCurrentText (LOOP_TIME_FORWARD_TEXT); 91 else if (audio->loop_type == Audio::LOOP_TIME_PING_PONG) 92 loop_type_combo->setCurrentText (LOOP_TIME_PING_PONG_TEXT); 93 else 94 { 95 g_assert_not_reached(); 96 } 97 } 98 } 99 100 void 101 SampleWinView::on_zoom_changed() 102 { 103 m_sample_view->set_zoom (zoom_controller->get_hzoom(), zoom_controller->get_vzoom()); 104 } 105 106 void 107 SampleWinView::on_mouse_time_changed (int time) 108 { 109 int ms = time % 1000; 110 time /= 1000; 111 int s = time % 60; 112 time /= 60; 113 int m = time; 114 time_label->setText (string_locale_printf ("Time: %02d:%02d:%03d ms", m, s, ms).c_str()); 115 } 116 117 void 118 SampleWinView::on_edit_marker_changed() 119 { 120 SampleView::EditMarkerType marker_type; 121 122 QPushButton *btn = qobject_cast<QPushButton *> (sender()); 123 if (btn == edit_loop_start) 124 marker_type = SampleView::MARKER_LOOP_START; 125 else if (btn == edit_loop_end) 126 marker_type = SampleView::MARKER_LOOP_END; 127 else 128 g_assert_not_reached(); 129 130 if (m_sample_view->edit_marker_type() == marker_type) // we're selected already -> turn it off 131 marker_type = SampleView::MARKER_NONE; 132 133 m_sample_view->set_edit_marker_type (marker_type); 134 135 edit_loop_start->setChecked (marker_type == SampleView::MARKER_LOOP_START); 136 edit_loop_end->setChecked (marker_type == SampleView::MARKER_LOOP_END); 137 } 138 139 void 140 SampleWinView::on_show_tuning_changed() 141 { 142 m_sample_view->set_show_tuning (show_tuning_button->isChecked()); 143 } 144 145 void 146 SampleWinView::on_loop_type_changed() 147 { 148 Audio *audio = navigator->get_audio(); 149 if (audio) 150 { 151 string text = loop_type_combo->currentText().toLatin1().data(); 152 Audio::LoopType new_loop_type; 153 154 if (text == LOOP_NONE_TEXT) 155 new_loop_type = Audio::LOOP_NONE; 156 else if (text == LOOP_FRAME_FORWARD_TEXT) 157 new_loop_type = Audio::LOOP_FRAME_FORWARD; 158 else if (text == LOOP_FRAME_PING_PONG_TEXT) 159 new_loop_type = Audio::LOOP_FRAME_PING_PONG; 160 else if (text == LOOP_TIME_FORWARD_TEXT) 161 new_loop_type = Audio::LOOP_TIME_FORWARD; 162 else if (text == LOOP_TIME_PING_PONG_TEXT) 163 new_loop_type = Audio::LOOP_TIME_PING_PONG; 164 else 165 { 166 g_assert_not_reached(); 167 } 168 169 if (new_loop_type != audio->loop_type) 170 { 171 Q_EMIT audio_edit(); 172 audio->loop_type = new_loop_type; 173 } 174 } 175 } 176 177 SampleView * 178 SampleWinView::sample_view() 179 { 180 return m_sample_view; 181 } 182