fix crash when closing session w/action hooks
[ardour.git] / gtk2_ardour / mini_timeline.cc
index 2a1e3233fddaeaffcd7e88be5b62f54c9ffb7aed..653c3c40b04af4e91e708270ddb49324f53171b4 100644 (file)
 #include "main_clock.h"
 #include "mini_timeline.h"
 #include "timers.h"
+#include "tooltips.h"
 #include "ui_config.h"
 
 #include "pbd/i18n.h"
 
+#define PADDING 3
 #define BBT_BAR_CHAR "|"
 
 using namespace ARDOUR;
@@ -68,6 +70,11 @@ MiniTimeline::MiniTimeline ()
        Location::start_changed.connect (marker_connection, invalidator (*this), boost::bind (&MiniTimeline::update_minitimeline, this), gui_context ());
        Location::flags_changed.connect (marker_connection, invalidator (*this), boost::bind (&MiniTimeline::update_minitimeline, this), gui_context ());
 
+       ARDOUR_UI_UTILS::set_tooltip (*this,
+                       string_compose (_("<b>Navigation Timeline</b>. Use left-click to locate to time position or marker; scroll-wheel to jump, hold %1 for fine gained and %2 + %3 for extra-fine grained control. Right-click to set display range. The display unit is defined by the primary clock."),
+                               Gtkmm2ext::Keyboard::primary_modifier_name(),
+                               Gtkmm2ext::Keyboard::primary_modifier_name (),
+                               Gtkmm2ext::Keyboard::secondary_modifier_name ()));
 }
 
 MiniTimeline::~MiniTimeline ()
@@ -189,7 +196,7 @@ MiniTimeline::set_span (framecnt_t ts)
 void
 MiniTimeline::super_rapid_update ()
 {
-       if (!_session || !_session->engine().running()) {
+       if (!_session || !_session->engine().running() || !is_mapped ()) {
                return;
        }
        framepos_t const frame = PublicEditor::instance().playhead_cursor_sample ();
@@ -206,6 +213,11 @@ MiniTimeline::super_rapid_update ()
                change = true;
        }
 
+       if (_clock_mode == AudioClock::BBT) {
+               // TODO check if tempo-map changed
+               change = true;
+       }
+
        if (change) {
                _last_update_frame = frame;
                update_minitimeline ();
@@ -326,7 +338,7 @@ MiniTimeline::draw_mark (cairo_t* cr, int x0, int x1, const std::string& label,
         *        (3,MH)
         */
 
-       int y = 3;
+       const int y = PADDING;
        int w2 = (h - 1) / 4;
        double h0 = h * .4;
        double h1 = h - h0;
@@ -336,7 +348,7 @@ MiniTimeline::draw_mark (cairo_t* cr, int x0, int x1, const std::string& label,
        _layout->get_pixel_size (lw, lh);
        int rw = std::min (x1, x0 + w2 + lw + 2);
 
-       if (_pointer_y >= 0 && _pointer_y < h && _pointer_x >= x0 && _pointer_x <= rw) {
+       if (_pointer_y >= 0 && _pointer_y <= y + h && _pointer_x >= x0 && _pointer_x <= rw) {
                prelight = true;
        }
 
@@ -407,7 +419,7 @@ MiniTimeline::render (cairo_t* cr, cairo_rectangle_t*)
        ArdourCanvas::set_source_rgba(cr, base);
        cairo_fill (cr);
 
-       Gtkmm2ext::rounded_rectangle (cr, 3, 3, get_width()-6, get_height()-6, 4);
+       Gtkmm2ext::rounded_rectangle (cr, PADDING, PADDING, get_width() - PADDING - PADDING, get_height() - PADDING - PADDING, 4);
        cairo_clip (cr);
 
        if (_session == 0) {
@@ -432,7 +444,7 @@ MiniTimeline::render (cairo_t* cr, cairo_rectangle_t*)
                _layout->get_pixel_size (lw, lh);
 
                int x0 = xpos - lw / 2.0;
-               int y0 = get_height() - 3 - _time_height;
+               int y0 = get_height() - PADDING - _time_height;
 
                draw_dots (cr, dot_left, x0, y0 + _time_height * .5, text);
 
@@ -441,7 +453,7 @@ MiniTimeline::render (cairo_t* cr, cairo_rectangle_t*)
                pango_cairo_show_layout (cr, _layout->gobj());
                dot_left = x0 + lw;
        }
-       draw_dots (cr, dot_left, get_width(), get_height() - 3 - _time_height * .5, text);
+       draw_dots (cr, dot_left, get_width(), get_height() - PADDING - _time_height * .5, text);
 
        /* locations */
        framepos_t lmin = std::max ((framepos_t)0, (p - _time_span_samples));
@@ -575,11 +587,12 @@ bool
 MiniTimeline::on_button_release_event (GdkEventButton *ev)
 {
        if (!_session) { return true; }
+       if (_session->actively_recording ()) { return true; }
        if (ev->y < 0 || ev->y > get_height () || ev->x < 0 || ev->x > get_width ()) {
                return true;
        }
 
-       if (ev->y <= _marker_height) {
+       if (ev->y <= PADDING + _marker_height) {
                for (JumpList::const_iterator i = _jumplist.begin (); i != _jumplist.end(); ++i) {
                        if (i->left < ev->x && ev->x < i->right) {
                                _session->request_locate (i->to, _session->transport_rolling ());
@@ -600,6 +613,7 @@ bool
 MiniTimeline::on_motion_notify_event (GdkEventMotion *ev)
 {
        if (!_session) { return true; }
+       if (_session->actively_recording ()) { return true; }
 
        _pointer_x = ev->x;
        _pointer_y = ev->y;
@@ -607,7 +621,7 @@ MiniTimeline::on_motion_notify_event (GdkEventMotion *ev)
        bool need_expose = false;
 
        for (JumpList::const_iterator i = _jumplist.begin (); i != _jumplist.end(); ++i) {
-               if (i->left < ev->x && ev->x < i->right && ev->y <= _marker_height) {
+               if (i->left < ev->x && ev->x < i->right && ev->y <= PADDING + _marker_height) {
                        if (!(*i).prelight) {
                                need_expose = true;
                                break;
@@ -644,6 +658,7 @@ bool
 MiniTimeline::on_scroll_event (GdkEventScroll *ev)
 {
        if (!_session) { return true; }
+       if (_session->actively_recording ()) { return true; }
        const framecnt_t time_span = _session->config.get_minitimeline_span ();
        framepos_t when = _session->audible_frame ();
 
@@ -659,9 +674,11 @@ MiniTimeline::on_scroll_event (GdkEventScroll *ev)
 
        switch (ev->direction) {
                case GDK_SCROLL_UP:
+               case GDK_SCROLL_RIGHT:
                        when += scale * _session->nominal_frame_rate ();
                        break;
                case GDK_SCROLL_DOWN:
+               case GDK_SCROLL_LEFT:
                        when -= scale * _session->nominal_frame_rate ();
                        break;
                default: