From 1c90188ca8499260ac03630a9a42227b2389f6b3 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 16 Jun 2009 01:03:24 +0000 Subject: [PATCH] Cleaner implementation. git-svn-id: svn://localhost/ardour2/branches/3.0@5198 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor_summary.cc | 200 +++++++++++++++++++++------------- gtk2_ardour/editor_summary.h | 20 +++- 2 files changed, 137 insertions(+), 83 deletions(-) diff --git a/gtk2_ardour/editor_summary.cc b/gtk2_ardour/editor_summary.cc index 4a9a397fb9..d1f5821ce5 100644 --- a/gtk2_ardour/editor_summary.cc +++ b/gtk2_ardour/editor_summary.cc @@ -114,7 +114,7 @@ EditorSummary::on_expose_event (GdkEventExpose* event) pair x; pair y; - editor_view (&x, &y); + get_editor (&x, &y); cairo_t* cr = gdk_cairo_create (get_window()->gobj()); @@ -279,25 +279,35 @@ EditorSummary::on_size_allocate (Gtk::Allocation& alloc) void EditorSummary::centre_on_click (GdkEventButton* ev) { - nframes_t x = (ev->x / _x_scale) + _session->current_start_frame(); - nframes_t const xh = _editor->current_page_frames () / 2; - if (x > xh) { - x -= xh; - } else { - x = 0; + pair xr; + pair yr; + get_editor (&xr, &yr); + + double const w = xr.second - xr.first; + double const h = yr.second - yr.first; + + xr.first = ev->x - w / 2; + xr.second = ev->x + w / 2; + yr.first = ev->y - h / 2; + yr.second = ev->y + h / 2; + + if (xr.first < 0) { + xr.first = 0; + xr.second = w; + } else if (xr.second > _width) { + xr.second = _width; + xr.first = _width - w; } - - _editor->reset_x_origin (x); - - double y = ev->y / _y_scale; - double const yh = _editor->canvas_height () / 2; - if (y > yh) { - y -= yh; - } else { - y = 0; + + if (yr.first < 0) { + yr.first = 0; + yr.second = h; + } else if (yr.second > _height) { + yr.second = _height; + yr.first = _height - h; } - - _editor->reset_y_origin (y); + + set_editor (xr, yr); } /** Handle a button press. @@ -310,9 +320,14 @@ EditorSummary::on_button_press_event (GdkEventButton* ev) pair xr; pair yr; - editor_view (&xr, &yr); + get_editor (&xr, &yr); if (xr.first <= ev->x && ev->x <= xr.second && yr.first <= ev->y && ev->y <= yr.second) { + + _start_editor_x = xr; + _start_editor_y = yr; + _start_mouse_x = ev->x; + _start_mouse_y = ev->y; if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { @@ -321,21 +336,41 @@ EditorSummary::on_button_press_event (GdkEventButton* ev) double const x1 = xr.first + (xr.second - xr.first) * 0.33; double const x2 = xr.first + (xr.second - xr.first) * 0.67; + double const y1 = yr.first + (yr.second - yr.first) * 0.33; + double const y2 = yr.first + (yr.second - yr.first) * 0.67; if (ev->x < x1) { - _zoom_position = LEFT; + + if (ev->y < y1) { + _zoom_position = TOP_LEFT; + } else if (ev->y > y2) { + _zoom_position = BOTTOM_LEFT; + } else { + _zoom_position = LEFT; + } + } else if (ev->x > x2) { - _zoom_position = RIGHT; + + if (ev->y < y1) { + _zoom_position = TOP_RIGHT; + } else if (ev->y > y2) { + _zoom_position = BOTTOM_RIGHT; + } else { + _zoom_position = RIGHT; + } + } else { - _zoom_position = NONE; + + if (ev->y < y1) { + _zoom_position = TOP; + } else if (ev->y > y2) { + _zoom_position = BOTTOM; + } + } if (_zoom_position != NONE) { _zoom_dragging = true; - _mouse_x_start = ev->x; - _width_start = xr.second - xr.first; - _zoom_start = _editor->get_current_zoom (); - _frames_start = _editor->leftmost_position (); _editor->_dragging_playhead = true; } @@ -345,8 +380,6 @@ EditorSummary::on_button_press_event (GdkEventButton* ev) _move_dragging = true; _moved = false; - _x_offset = ev->x - xr.first; - _y_offset = ev->y - yr.first; _editor->_dragging_playhead = true; } @@ -361,60 +394,45 @@ EditorSummary::on_button_press_event (GdkEventButton* ev) } void -EditorSummary::editor_view (pair* x, pair* y) const +EditorSummary::get_editor (pair* x, pair* y) const { x->first = (_editor->leftmost_position () - _session->current_start_frame ()) * _x_scale; x->second = x->first + _editor->current_page_frames() * _x_scale; - y->first = _editor->get_trackview_group_vertical_offset () * _y_scale; + y->first = _editor->vertical_adjustment.get_value() * _y_scale; y->second = y->first + _editor->canvas_height () * _y_scale; } bool EditorSummary::on_motion_notify_event (GdkEventMotion* ev) { + pair xr = _start_editor_x; + pair yr = _start_editor_y; + if (_move_dragging) { _moved = true; - _editor->reset_x_origin (((ev->x - _x_offset) / _x_scale) + _session->current_start_frame ()); - _editor->reset_y_origin ((ev->y - _y_offset) / _y_scale); - return true; + + xr.first += ev->x - _start_mouse_x; + xr.second += ev->x - _start_mouse_x; + yr.first += ev->y - _start_mouse_y; + yr.second += ev->y - _start_mouse_y; + + set_editor (xr, yr); } else if (_zoom_dragging) { - double const dx = ev->x - _mouse_x_start; + double const dx = ev->x - _start_mouse_x; - nframes64_t rx = _frames_start; - double f = 1; - - switch (_zoom_position) { - case LEFT: - f = 1 - (dx / _width_start); - rx += (dx / _x_scale); - break; - case RIGHT: - f = 1 + (dx / _width_start); - break; - case NONE: - break; + if (_zoom_position == TOP_LEFT || _zoom_position == LEFT || _zoom_position == BOTTOM_LEFT) { + xr.first += dx; } - if (_editor->pending_visual_change.idle_handler_id < 0) { - - /* As a side-effect, the Editor's visual change idle handler processes - pending GTK events. Hence this motion notify handler can be called - in the middle of a visual change idle handler, and if this happens, - the queue_visual_change calls below modify the variables that the - idle handler is working with. This causes problems. Hence the - check above. It ensures that we won't modify the pending visual change - while a visual change idle handler is in progress. It's not perfect, - as it also means that we won't change these variables if an idle handler - is merely pending but not executing. But c'est la vie. - */ - - _editor->queue_visual_change (rx); - _editor->queue_visual_change (_zoom_start * f); + if (_zoom_position == TOP_RIGHT || _zoom_position == RIGHT || _zoom_position == BOTTOM_RIGHT) { + xr.second += dx; } + + set_editor (xr, yr); } return true; @@ -440,33 +458,61 @@ EditorSummary::on_scroll_event (GdkEventScroll* ev) pair xr; pair yr; - editor_view (&xr, &yr); + get_editor (&xr, &yr); + + double const amount = 8; if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - double x = xr.first; - if (ev->direction == GDK_SCROLL_UP) { - x += 16; + xr.first += amount; + xr.second += amount; } else { - x -= 16; + xr.first -= amount; + xr.second -= amount; } - - _editor->reset_x_origin (x / _x_scale); - + } else { - double y = yr.first; - if (ev->direction == GDK_SCROLL_DOWN) { - y += 16; + yr.first += amount; + yr.second += amount; } else { - y -= 16; + yr.first -= amount; + yr.second -= amount; } - - - _editor->reset_y_origin (y / _y_scale); } + set_editor (xr, yr); return true; } + +void +EditorSummary::set_editor (pair const & x, pair const & y) +{ + if (_editor->pending_visual_change.idle_handler_id < 0) { + + /* As a side-effect, the Editor's visual change idle handler processes + pending GTK events. Hence this motion notify handler can be called + in the middle of a visual change idle handler, and if this happens, + the queue_visual_change calls below modify the variables that the + idle handler is working with. This causes problems. Hence the + check above. It ensures that we won't modify the pending visual change + while a visual change idle handler is in progress. It's not perfect, + as it also means that we won't change these variables if an idle handler + is merely pending but not executing. But c'est la vie. + */ + + _editor->reset_x_origin (x.first / _x_scale); + _editor->reset_y_origin (y.first / _y_scale); + + double const nx = ( + ((x.second - x.first) / _x_scale) / + _editor->frame_to_unit (_editor->current_page_frames()) + ); + + if (nx != _editor->get_current_zoom ()) { + _editor->reset_zoom (nx); + } + } +} diff --git a/gtk2_ardour/editor_summary.h b/gtk2_ardour/editor_summary.h index 79c4174262..817940796f 100644 --- a/gtk2_ardour/editor_summary.h +++ b/gtk2_ardour/editor_summary.h @@ -54,7 +54,8 @@ private: void render (cairo_t *); GdkPixmap* get_pixmap (GdkDrawable *); void render_region (RegionView*, cairo_t*, nframes_t, double) const; - void editor_view (std::pair *, std::pair *) const; + void get_editor (std::pair *, std::pair *) const; + void set_editor (std::pair const &, std::pair const &); Editor* _editor; ///< our editor ARDOUR::Session* _session; ///< our session @@ -65,20 +66,27 @@ private: double _x_scale; ///< pixels per frame for the x axis of the pixmap double _y_scale; + std::pair _start_editor_x; + std::pair _start_editor_y; + double _start_mouse_x; + double _start_mouse_y; + bool _move_dragging; double _x_offset; double _y_offset; bool _moved; bool _zoom_dragging; - double _mouse_x_start; - double _width_start; - double _zoom_start; - nframes64_t _frames_start; enum ZoomPosition { - LEFT, + TOP_LEFT, + TOP, + TOP_RIGHT, RIGHT, + BOTTOM_RIGHT, + BOTTOM, + BOTTOM_LEFT, + LEFT, NONE };