*/
#include "ardour/session.h"
+
#include "time_axis_view.h"
#include "streamview.h"
#include "editor_summary.h"
_old_follow_playhead (false)
{
Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context());
+ Route::RemoteControlIDChange.connect (route_ctrl_id_connection, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context());
_editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), boost::bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
- add_events (Gdk::POINTER_MOTION_MASK);
+ add_events (Gdk::POINTER_MOTION_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK);
+ set_flags (get_flags() | Gtk::CAN_FOCUS);
}
/** Connect to a session.
}
}
-/** Handle an expose event.
- * @param event Event from GTK.
- */
-bool
-EditorSummary::on_expose_event (GdkEventExpose* event)
-{
- CairoWidget::on_expose_event (event);
-
- if (_session == 0) {
- return false;
- }
-
- cairo_t* cr = gdk_cairo_create (get_window()->gobj());
-
- /* Render the view rectangle. If there is an editor visual pending, don't update
- the view rectangle now --- wait until the expose event that we'll get after
- the visual change. This prevents a flicker.
- */
-
- if (_editor->pending_visual_change.idle_handler_id < 0) {
- get_editor (&_view_rectangle_x, &_view_rectangle_y);
- }
-
- cairo_move_to (cr, _view_rectangle_x.first, _view_rectangle_y.first);
- cairo_line_to (cr, _view_rectangle_x.second, _view_rectangle_y.first);
- cairo_line_to (cr, _view_rectangle_x.second, _view_rectangle_y.second);
- cairo_line_to (cr, _view_rectangle_x.first, _view_rectangle_y.second);
- cairo_line_to (cr, _view_rectangle_x.first, _view_rectangle_y.first);
- cairo_set_source_rgba (cr, 1, 1, 1, 0.25);
- cairo_fill_preserve (cr);
- cairo_set_line_width (cr, 1);
- cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
- cairo_stroke (cr);
-
- /* Playhead */
-
- cairo_set_line_width (cr, 1);
- /* XXX: colour should be set from configuration file */
- cairo_set_source_rgba (cr, 1, 0, 0, 1);
-
- double const p = playhead_frame_to_position (_editor->playhead_cursor->current_frame);
- cairo_move_to (cr, p, 0);
- cairo_line_to (cr, p, get_height());
- cairo_stroke (cr);
- _last_playhead = p;
-
- cairo_destroy (cr);
-
- return true;
-}
-
/** Render the required regions to a cairo context.
* @param cr Context.
*/
cairo_set_line_width (cr, 1);
cairo_set_source_rgb (cr, 1, 1, 0);
- double const p = (_session->current_start_frame() - _start) * _x_scale;
+ const double p = (_session->current_start_frame() - _start) * _x_scale;
cairo_move_to (cr, p, 0);
cairo_line_to (cr, p, get_height());
cairo_stroke (cr);
cairo_move_to (cr, q, 0);
cairo_line_to (cr, q, get_height());
cairo_stroke (cr);
+
+ /* Render the view rectangle. If there is an editor visual pending, don't update
+ the view rectangle now --- wait until the expose event that we'll get after
+ the visual change. This prevents a flicker.
+ */
+
+ if (_editor->pending_visual_change.idle_handler_id < 0) {
+ get_editor (&_view_rectangle_x, &_view_rectangle_y);
+ }
+
+ cairo_move_to (cr, _view_rectangle_x.first, _view_rectangle_y.first);
+ cairo_line_to (cr, _view_rectangle_x.second, _view_rectangle_y.first);
+ cairo_line_to (cr, _view_rectangle_x.second, _view_rectangle_y.second);
+ cairo_line_to (cr, _view_rectangle_x.first, _view_rectangle_y.second);
+ cairo_line_to (cr, _view_rectangle_x.first, _view_rectangle_y.first);
+ cairo_set_source_rgba (cr, 1, 1, 1, 0.25);
+ cairo_fill_preserve (cr);
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
+ cairo_stroke (cr);
+
+ /* Playhead */
+
+ cairo_set_line_width (cr, 1);
+ /* XXX: colour should be set from configuration file */
+ cairo_set_source_rgba (cr, 1, 0, 0, 1);
+
+ const double ph= playhead_frame_to_position (_editor->playhead_cursor->current_frame);
+ cairo_move_to (cr, ph, 0);
+ cairo_line_to (cr, ph, get_height());
+ cairo_stroke (cr);
+ _last_playhead = ph;
+
}
/** Render a region for the summary.
set_editor (ex, ey);
}
+bool
+EditorSummary::on_enter_notify_event (GdkEventCrossing*)
+{
+ grab_focus ();
+ Keyboard::magic_widget_grab_focus ();
+ return false;
+}
+
+bool
+EditorSummary::on_leave_notify_event (GdkEventCrossing*)
+{
+ /* there are no inferior/child windows, so any leave event means that
+ we're gone.
+ */
+ Keyboard::magic_widget_drop_focus ();
+ return false;
+}
+
+bool
+EditorSummary::on_key_press_event (GdkEventKey* key)
+{
+ gint x, y;
+ GtkAccelKey set_playhead_accel;
+ if (gtk_accel_map_lookup_entry ("<Actions>/Editor/set-playhead", &set_playhead_accel)) {
+ if (key->keyval == set_playhead_accel.accel_key && (int) key->state == set_playhead_accel.accel_mods) {
+ if (_session) {
+ get_pointer (x, y);
+ _session->request_locate (_start + (framepos_t) x / _x_scale, _session->transport_rolling());
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool
+EditorSummary::on_key_release_event (GdkEventKey* key)
+{
+
+ GtkAccelKey set_playhead_accel;
+ if (gtk_accel_map_lookup_entry ("<Actions>/Editor/set-playhead", &set_playhead_accel)) {
+ if (key->keyval == set_playhead_accel.accel_key && (int) key->state == set_playhead_accel.accel_mods) {
+ return true;
+ }
+ }
+ return false;
+}
+
/** Handle a button press.
* @param ev GTK event.
*/
bool
EditorSummary::on_button_press_event (GdkEventButton* ev)
{
+ _old_follow_playhead = _editor->follow_playhead ();
+
if (ev->button == 1) {
pair<double, double> xr;
_zoom_position = get_position (ev->x, ev->y);
_zoom_dragging = true;
_editor->_dragging_playhead = true;
- _old_follow_playhead = _editor->follow_playhead ();
_editor->set_follow_playhead (false);
if (suspending_editor_updates ()) {
_move_dragging = true;
_moved = false;
_editor->_dragging_playhead = true;
- _old_follow_playhead = _editor->follow_playhead ();
_editor->set_follow_playhead (false);
}
}
}
set_editor (x, y);
- set_cursor (_start_position);
+ // set_cursor (_start_position);
} else if (_zoom_dragging) {
double x = xr.first;
double y = yr.first;
- double amount = 8;
-
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) {
- amount = 64;
- } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
- amount = 1;
- }
-
- if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
-
- /* secondary-wheel == left-right scrolling */
-
- if (ev->direction == GDK_SCROLL_UP) {
- x -= amount;
- } else if (ev->direction == GDK_SCROLL_DOWN) {
- x += amount;
- }
-
- } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
-
- /* primary-wheel == zoom */
-
- if (ev->direction == GDK_SCROLL_UP) {
- _editor->temporal_zoom_step (false);
- } else {
- _editor->temporal_zoom_step (true);
- }
-
- } else {
-
- if (ev->direction == GDK_SCROLL_DOWN) {
- y += amount;
- } else if (ev->direction == GDK_SCROLL_UP) {
- y -= amount;
- } else if (ev->direction == GDK_SCROLL_LEFT) {
- x -= amount;
- } else if (ev->direction == GDK_SCROLL_RIGHT) {
- x += amount;
- }
+ switch (ev->direction) {
+ case GDK_SCROLL_UP:
+ if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollHorizontalModifier)) {
+ x -= 64;
+ } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomHorizontalModifier)) {
+ _editor->temporal_zoom_step (false);
+ } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
+ yr.first += 4;
+ yr.second -= 4;
+ set_editor (xr, yr);
+ return true;
+ } else {
+ y -= 8;
+ }
+ break;
+ case GDK_SCROLL_DOWN:
+ if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollHorizontalModifier)) {
+ x += 64;
+ } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomHorizontalModifier)) {
+ _editor->temporal_zoom_step (true);
+ } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
+ yr.first -= 4;
+ yr.second += 4;
+ set_editor (xr, yr);
+ return true;
+ } else {
+ y += 8;
+ }
+ break;
+ case GDK_SCROLL_LEFT:
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) {
+ x -= 64;
+ } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
+ x -= 1;
+ } else {
+ x -= 8;
+ }
+ break;
+ case GDK_SCROLL_RIGHT:
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) {
+ x += 64;
+ } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
+ x += 1;
+ } else {
+ x += 8;
+ }
+ break;
+ default:
+ break;
}
set_editor (x, y);
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.
*/
-
+
return;
}
int const o = int (_last_playhead);
int const n = int (playhead_frame_to_position (p));
if (_session && o != n) {
- int a = min (o, n);
+ int a = max(2, min (o, n));
int b = max (o, n);
- set_overlays_dirty (a - 1, 0, b + 1, get_height ());
+ set_overlays_dirty (a - 2, 0, b + 2, get_height ());
}
}
{
return (t - _start) * _x_scale;
}
+
+framepos_t
+EditorSummary::position_to_playhead_frame_to_position (double pos) const
+{
+ return _start + (pos * _x_scale);
+}