diff --git a/glui/sminsteditwindow.cc b/glui/sminsteditwindow.cc index 9050caf5..a40a074b 100644 --- a/glui/sminsteditwindow.cc +++ b/glui/sminsteditwindow.cc @@ -207,13 +207,14 @@ InstEditWindow::InstEditWindow (EventLoop& event_loop, Instrument *edit_instrume grid.add_widget (sample_scroll_view, 1, 8, 91, 46); sample_widget = new SampleWidget (sample_scroll_view); + connect (sample_widget->signal_drag_scroll, this, &InstEditWindow::on_drag_scroll); grid.add_widget (sample_widget, 1, 1, 100, 42); sample_scroll_view->set_scroll_widget (sample_widget, true, false, /* center_zoom */ true); /*----- hzoom -----*/ grid.add_widget (new Label (this, "HZoom"), 1, 54, 6, 3); - Slider *hzoom_slider = new Slider (this, 0.0); + hzoom_slider = new Slider (this, 0.0); grid.add_widget (hzoom_slider, 7, 54, 28, 3); connect (hzoom_slider->signal_value_changed, this, &InstEditWindow::on_update_hzoom); @@ -623,6 +624,15 @@ InstEditWindow::on_remove_sample_clicked() instrument->remove_sample(); } +void +InstEditWindow::on_drag_scroll (double cx, double dx, double dy) +{ + hzoom_slider->set_value (std::clamp (hzoom_slider->value() - dy * 0.003, 0, 1)); + double factor = pow (2, hzoom_slider->value() * 10); + sample_scroll_view->change_widget_x_and_width (cx, dx, 89 * factor * 8); + hzoom_label->set_text (string_printf ("%.1f %%", factor * 100)); +} + void InstEditWindow::on_update_hzoom (float value) { diff --git a/glui/sminsteditwindow.hh b/glui/sminsteditwindow.hh index 5df8e27a..67d87b6e 100644 --- a/glui/sminsteditwindow.hh +++ b/glui/sminsteditwindow.hh @@ -27,6 +27,7 @@ class CheckBox; class Button; class Timer; class ComboBox; +class Slider; class SampleWidget; class SynthInterface; @@ -73,10 +74,11 @@ class InstEditWindow : public Window Sample::Loop text_to_loop (const std::string& text); std::string loop_to_text (const Sample::Loop loop); - ComboBox *sample_combobox; - ScrollView *sample_scroll_view; - Label *hzoom_label; - Label *vzoom_label; + ComboBox *sample_combobox; + ScrollView *sample_scroll_view; + Label *hzoom_label = nullptr; + Label *vzoom_label = nullptr; + Slider *hzoom_slider = nullptr; PlayMode play_mode = PlayMode::SPECTMORPH; ComboBox *play_mode_combobox; ComboBox *loop_combobox; @@ -114,6 +116,7 @@ public: void on_remove_sample_clicked(); void on_update_hzoom (float value); void on_update_vzoom (float value); + void on_drag_scroll (double cx, double dx, double dy); void on_show_hide_params(); void on_show_hide_note(); void on_import_clicked(); diff --git a/glui/smsamplewidget.hh b/glui/smsamplewidget.hh index f8382f68..aaa79e51 100644 --- a/glui/smsamplewidget.hh +++ b/glui/smsamplewidget.hh @@ -56,6 +56,9 @@ private: Sample *m_sample = nullptr; MarkerType selected_marker = MARKER_NONE; bool mouse_down = false; + double mouse_click_x = 0; + double mouse_click_y = 0; + double mouse_click_pos = 0; DisplayTuning m_display_tuning; std::map marker_rect; @@ -298,7 +301,15 @@ public: if (mouse_down) { if (selected_marker == MARKER_NONE) - return; + { + double dx = event.x + abs_x() - mouse_click_x; + double dy = event.y - mouse_click_y; + mouse_click_x = event.x + abs_x(); + mouse_click_y = event.y; + + signal_drag_scroll (mouse_click_pos, dx, dy); + return; + } const double sample_len_ms = m_sample->wav_data().samples().size() / m_sample->wav_data().mix_freq() * 1000.0; const double x_ms = sm_bound (0, event.x / width() * sample_len_ms, sample_len_ms); @@ -332,7 +343,12 @@ public: mouse_press (const MouseEvent& event) override { if (event.button == LEFT_BUTTON) - mouse_down = true; + { + mouse_down = true; + mouse_click_x = event.x + abs_x(); + mouse_click_y = event.y; + mouse_click_pos = event.x / width(); + } } void mouse_release (const MouseEvent& event) override @@ -413,6 +429,7 @@ public: { update(); } + Signal signal_drag_scroll; }; } diff --git a/glui/smscrollview.hh b/glui/smscrollview.hh index e3d430cf..efa0c14e 100644 --- a/glui/smscrollview.hh +++ b/glui/smscrollview.hh @@ -144,6 +144,19 @@ public: // reposition widget on screen if necessary on_scroll_bar_changed (0); } + void + change_widget_x_and_width (double cx, double dx, double width) + { + double old_width = scroll_widget->width(); + scroll_widget->set_width (width); + double x = scroll_widget->x() + dx - (width - old_width) * cx; + double new_page_size = view_width / (scroll_widget->width() + 16); + h_scroll_bar->set_page_size (new_page_size); + double new_pos = (8 - x) / (scroll_widget->width() + 16); + new_pos = std::clamp (new_pos, 0.0, 1 - new_page_size); + h_scroll_bar->set_pos (new_pos); + on_scroll_bar_changed (0); + } }; }