persistent waveform shape setting.
[ardour.git] / gtk2_ardour / time_axis_view.cc
index 4408b88f8618d7680a811f7a0551d051b0b4a9f2..f67ca6a3cea5e70c0eda4861612a17912732b588 100644 (file)
 
 #include "pbd/error.h"
 #include "pbd/convert.h"
+#include "pbd/stacktrace.h"
 
 #include <gtkmm2ext/doi.h>
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/selector.h>
 
+#include "canvas/canvas.h"
 #include "canvas/rectangle.h"
+#include "canvas/debug.h"
 
 #include "ardour_ui.h"
 #include "ardour_dialog.h"
@@ -74,6 +77,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        , display_menu (0)
        , parent (rent)
        , selection_group (0)
+       , _ghost_group (0)
        , _hidden (false)
        , in_destructor (false)
        , _size_menu (0)
@@ -87,22 +91,23 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        , _resize_drag_start (-1)
        , _preresize_cursor (0)
        , _have_preresize_cursor (false)
-       , _ghost_group (0)
        , _ebox_release_can_act (true)
 {
        if (extra_height == 0) {
                compute_heights ();
        }
 
-       _canvas_background = new Group (ed.get_background_group (), ArdourCanvas::Duple (0.0, 0.0));
        _canvas_display = new Group (ed.get_trackview_group (), ArdourCanvas::Duple (0.0, 0.0));
+       CANVAS_DEBUG_NAME (_canvas_display, "main for TAV");
        _canvas_display->hide(); // reveal as needed
 
        selection_group = new Group (_canvas_display);
+       CANVAS_DEBUG_NAME (selection_group, "selection for TAV");
        selection_group->set_data (X_("timeselection"), (void *) 1);
        selection_group->hide();
 
        _ghost_group = new Group (_canvas_display);
+       CANVAS_DEBUG_NAME (_ghost_group, "ghost for TAV");
        _ghost_group->lower_to_bottom();
        _ghost_group->show();
 
@@ -131,12 +136,18 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        controls_table.set_no_show_all ();
 
        HSeparator* separator = manage (new HSeparator());
+       separator->set_name("TrackSeparator");
+       separator->set_size_request(-1, 1);
+       separator->show();
 
        controls_vbox.pack_start (controls_table, false, false);
        controls_vbox.show ();
 
+       controls_hbox.pack_start (controls_vbox, true, true);
+       controls_hbox.show ();
+
        //controls_ebox.set_name ("TimeAxisViewControlsBaseUnselected");
-       controls_ebox.add (controls_vbox);
+       controls_ebox.add (controls_hbox);
        controls_ebox.add_events (Gdk::BUTTON_PRESS_MASK|
                                  Gdk::BUTTON_RELEASE_MASK|
                                  Gdk::POINTER_MOTION_MASK|
@@ -153,10 +164,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        controls_ebox.signal_leave_notify_event().connect (sigc::mem_fun (*this, &TimeAxisView::controls_ebox_leave));
        controls_ebox.show ();
 
-       controls_hbox.pack_start (controls_ebox, true, true);
-       controls_hbox.show ();
-
-       time_axis_vbox.pack_start (controls_hbox, true, true);
+       time_axis_vbox.pack_start (controls_ebox, true, true, 0);
        time_axis_vbox.pack_end (*separator, false, false);
        time_axis_vbox.show();
 
@@ -174,7 +182,7 @@ TimeAxisView::~TimeAxisView()
        }
 
        for (list<SelectionRect*>::iterator i = free_selection_rects.begin(); i != free_selection_rects.end(); ++i) {
- delete (*i)->rect;
              delete (*i)->rect;
                delete (*i)->start_trim;
                delete (*i)->end_trim;
 
@@ -189,9 +197,6 @@ TimeAxisView::~TimeAxisView()
        delete selection_group;
        selection_group = 0;
 
-       delete _canvas_background;
-       _canvas_background = 0;
-
        delete _canvas_display;
        _canvas_display = 0;
 
@@ -209,7 +214,6 @@ TimeAxisView::hide ()
        }
 
        _canvas_display->hide ();
-       _canvas_background->hide ();
 
        if (control_parent) {
                control_parent->remove (time_axis_vbox);
@@ -255,15 +259,11 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
 
        if (_y_position != y) {
                _canvas_display->set_y_position (y);
-               _canvas_background->set_y_position (y);
                _y_position = y;
 
        }
 
-       _canvas_background->raise_to_top ();
        _canvas_display->raise_to_top ();
-
-       _canvas_background->show ();
        _canvas_display->show ();
 
        _hidden = false;
@@ -284,22 +284,12 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
        return _effective_height;
 }
 
-void
-TimeAxisView::clip_to_viewport ()
-{
-       if (marked_for_display()) {
-               _canvas_background->show ();
-               _canvas_display->show ();
-       }
-       return;
-}
-
 bool
 TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
 {
        switch (ev->direction) {
        case GDK_SCROLL_UP:
-               if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
+               if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
                        /* See Editor::_stepping_axis_view for notes on this hack */
                        Editor& e = dynamic_cast<Editor&> (_editor);
                        if (!e.stepping_axis_view ()) {
@@ -308,13 +298,13 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
                        e.stepping_axis_view()->step_height (false);
                        return true;
                } else if (Keyboard::no_modifiers_active (ev->state)) {
-                       _editor.scroll_tracks_up_line();
+                       _editor.scroll_up_one_track();
                        return true;
                }
                break;
 
        case GDK_SCROLL_DOWN:
-               if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
+               if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
                        /* See Editor::_stepping_axis_view for notes on this hack */
                        Editor& e = dynamic_cast<Editor&> (_editor);
                        if (!e.stepping_axis_view ()) {
@@ -323,7 +313,7 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
                        e.stepping_axis_view()->step_height (true);
                        return true;
                } else if (Keyboard::no_modifiers_active (ev->state)) {
-                       _editor.scroll_tracks_down_line();
+                       _editor.scroll_down_one_track();
                        return true;
                }
                break;
@@ -375,19 +365,16 @@ bool
 TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
 {
        if (_resize_drag_start >= 0) {
-               /* (ab)use the DragManager to do autoscrolling; adjust the event coordinates
-                  into the world coordinate space that DragManager::motion_handler is expecting,
-                  and then fake a DragManager motion event so that when maybe_autoscroll
-                  asks DragManager for the current pointer position it will get the correct
-                  answers.
+
+               /* (ab)use the DragManager to do autoscrolling - basically we
+                * are pretending that the drag is taking place over the canvas
+                * (which perhaps in the glorious future, when track headers
+                * and the canvas are unified, will actually be true.)
                */
-               int tx, ty;
-               controls_ebox.translate_coordinates (*control_parent, ev->x, ev->y, tx, ty);
-               ev->y = ty - _editor.get_trackview_group_vertical_offset();
-               _editor.drags()->motion_handler ((GdkEvent *) ev, false);
-               _editor.maybe_autoscroll (false, true, false, ev->y_root < _resize_drag_start);
 
-               /* now do the actual TAV resize */
+               _editor.maybe_autoscroll (false, true, true);
+
+               /* now schedule the actual TAV resize */
                 int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
                 _editor.add_to_idle_resize (this, delta);
                 _resize_drag_start = ev->y_root;
@@ -396,6 +383,7 @@ TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
                maybe_set_cursor (ev->y);
        }
 
+       gdk_event_request_motions(ev);
        return true;
 }
 
@@ -536,6 +524,8 @@ TimeAxisView::set_height (uint32_t h)
                /* resize the selection rect */
                show_selection (_editor.get_selection().time);
        }
+
+       _editor.override_visible_track_count ();
 }
 
 bool
@@ -794,14 +784,11 @@ TimeAxisView::build_display_menu ()
 }
 
 void
-TimeAxisView::set_frames_per_pixel (double fpp)
+TimeAxisView::set_samples_per_pixel (double fpp)
 {
        for (Children::iterator i = children.begin(); i != children.end(); ++i) {
-               (*i)->set_frames_per_pixel (fpp);
+               (*i)->set_samples_per_pixel (fpp);
        }
-
-       AnalysisFeatureList::const_iterator i;
-       list<ArdourCanvas::Line*>::iterator l;
 }
 
 void
@@ -856,8 +843,8 @@ TimeAxisView::show_selection (TimeSelection& ts)
 
                rect = get_selection_rect ((*i).id);
 
-               x1 = _editor.frame_to_unit (start);
-               x2 = _editor.frame_to_unit (start + cnt - 1);
+               x1 = _editor.sample_to_pixel (start);
+               x2 = _editor.sample_to_pixel (start + cnt - 1);
                y2 = current_height();
 
                rect->rect->set (ArdourCanvas::Rect (x1, 1, x2, y2));
@@ -962,14 +949,19 @@ TimeAxisView::get_selection_rect (uint32_t id)
                rect = new SelectionRect;
 
                rect->rect = new ArdourCanvas::Rectangle (selection_group);
-               rect->rect->set_outline_what (0);
-               rect->rect->set_fill_color (ARDOUR_UI::config()->canvasvar_SelectionRect.get());
+               CANVAS_DEBUG_NAME (rect->rect, "selection rect");
+               rect->rect->set_outline (false);
+               rect->rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SelectionRect());
 
                rect->start_trim = new ArdourCanvas::Rectangle (selection_group);
-               rect->start_trim->set_outline_what (0);
+               CANVAS_DEBUG_NAME (rect->rect, "selection rect start trim");
+               rect->start_trim->set_outline (false);
+               rect->start_trim->set_fill (false);
 
                rect->end_trim = new ArdourCanvas::Rectangle (selection_group);
-               rect->end_trim->set_outline_what (0);
+               CANVAS_DEBUG_NAME (rect->rect, "selection rect end trim");
+               rect->end_trim->set_outline (false);
+               rect->end_trim->set_fill (false);
 
                free_selection_rects.push_front (rect);
 
@@ -1135,26 +1127,26 @@ TimeAxisView::color_handler ()
 
        for (list<SelectionRect*>::iterator i = used_selection_rects.begin(); i != used_selection_rects.end(); ++i) {
 
-               (*i)->rect->set_fill_color (ARDOUR_UI::config()->canvasvar_SelectionRect.get());
-               (*i)->rect->set_outline_color (ARDOUR_UI::config()->canvasvar_Selection.get());
+               (*i)->rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SelectionRect());
+               (*i)->rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
 
-               (*i)->start_trim->set_fill_color (ARDOUR_UI::config()->canvasvar_Selection.get());
-               (*i)->start_trim->set_outline_color (ARDOUR_UI::config()->canvasvar_Selection.get());
+               (*i)->start_trim->set_fill_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+               (*i)->start_trim->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
                
-               (*i)->end_trim->set_fill_color (ARDOUR_UI::config()->canvasvar_Selection.get());
-               (*i)->end_trim->set_outline_color (ARDOUR_UI::config()->canvasvar_Selection.get());
+               (*i)->end_trim->set_fill_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+               (*i)->end_trim->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
        }
        
        for (list<SelectionRect*>::iterator i = free_selection_rects.begin(); i != free_selection_rects.end(); ++i) {
                
-               (*i)->rect->set_fill_color (ARDOUR_UI::config()->canvasvar_SelectionRect.get());
-               (*i)->rect->set_outline_color (ARDOUR_UI::config()->canvasvar_Selection.get());
+               (*i)->rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SelectionRect());
+               (*i)->rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
                
-               (*i)->start_trim->set_fill_color (ARDOUR_UI::config()->canvasvar_Selection.get());
-               (*i)->start_trim->set_outline_color (ARDOUR_UI::config()->canvasvar_Selection.get());
+               (*i)->start_trim->set_fill_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+               (*i)->start_trim->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
                
-               (*i)->end_trim->set_fill_color (ARDOUR_UI::config()->canvasvar_Selection.get());
-               (*i)->end_trim->set_outline_color (ARDOUR_UI::config()->canvasvar_Selection.get());
+               (*i)->end_trim->set_fill_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+               (*i)->end_trim->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
        }
 }
 
@@ -1166,7 +1158,7 @@ TimeAxisView::color_handler ()
  * and is in stacked or expanded * region display mode, otherwise 0.
  */
 std::pair<TimeAxisView*, double>
-TimeAxisView::covers_y_position (double y)
+TimeAxisView::covers_y_position (double y) const
 {
        if (hidden()) {
                return std::make_pair ((TimeAxisView *) 0, 0);
@@ -1201,7 +1193,7 @@ TimeAxisView::covers_y_position (double y)
                        break;
                }
 
-               return std::make_pair (this, l);
+               return std::make_pair (const_cast<TimeAxisView*>(this), l);
        }
 
        for (Children::const_iterator i = children.begin(); i != children.end(); ++i) {
@@ -1215,6 +1207,30 @@ TimeAxisView::covers_y_position (double y)
        return std::make_pair ((TimeAxisView *) 0, 0);
 }
 
+bool
+TimeAxisView::covered_by_y_range (double y0, double y1) const
+{
+       if (hidden()) {
+               return false;
+       }
+
+       /* if either the top or bottom of the axisview is in the vertical
+        * range, we cover it.
+        */
+       
+       if ((y0 < _y_position && y1 < _y_position) ||
+           (y0 >= _y_position + height && y1 >= _y_position + height)) {
+               return false;
+       }
+
+       for (Children::const_iterator i = children.begin(); i != children.end(); ++i) {
+               if ((*i)->covered_by_y_range (y0, y1)) {
+                       return true;
+               }
+       }
+
+       return true;
+}
 
 uint32_t
 TimeAxisView::preset_height (Height h)