Show discrete/toggled automation as stepped line.
authorDavid Robillard <d@drobilla.net>
Sat, 29 Nov 2014 00:17:39 +0000 (19:17 -0500)
committerDavid Robillard <d@drobilla.net>
Sat, 29 Nov 2014 02:15:28 +0000 (21:15 -0500)
gtk2_ardour/automation_line.cc
gtk2_ardour/automation_line.h
libs/canvas/canvas/poly_line.h
libs/canvas/poly_line.cc

index 7b84e686f0f2d1892312d47a7c8b84c407eea127..4d39ff9b874d623f20be310e8efd5e26053502d9 100644 (file)
@@ -142,6 +142,13 @@ AutomationLine::event_handler (GdkEvent* event)
        return PublicEditor::instance().canvas_line_event (event, line, this);
 }
 
+bool
+AutomationLine::is_stepped() const
+{
+       return (_desc.toggled ||
+               (alist && alist->interpolation() == AutomationList::Discrete));
+}
+
 void
 AutomationLine::update_visibility ()
 {
@@ -150,7 +157,7 @@ AutomationLine::update_visibility ()
                   when automation points have been removed (the line will still follow the shape of the
                   old points).
                */
-               if (alist->interpolation() != AutomationList::Discrete && control_points.size() >= 2) {
+               if (control_points.size() >= 2) {
                        line->show();
                } else {
                        line->hide ();
@@ -200,11 +207,6 @@ AutomationLine::hide ()
 double
 AutomationLine::control_point_box_size ()
 {
-       if (alist->interpolation() == AutomationList::Discrete) {
-               return max((_height*4.0) / (double)(alist->parameter().max() - alist->parameter().min()),
-                          4.0);
-       }
-
        if (_height > TimeAxisView::preset_height (HeightLarger)) {
                return 8.0;
        } else if (_height > (guint32) TimeAxisView::preset_height (HeightNormal)) {
@@ -287,7 +289,7 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
        reset_line_coords (cp);
 
        if (line_points.size() > 1) {
-               line->set (line_points);
+               line->set_steps (line_points, is_stepped());
        }
 
        alist->freeze ();
@@ -716,7 +718,7 @@ AutomationLine::drag_motion (double const x, float fraction, bool ignore_x, bool
                 */
 
                if (line_points.size() > 1) {
-                       line->set (line_points);
+                       line->set_steps (line_points, is_stepped());
                }
        }
        
@@ -1029,7 +1031,7 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
                        line_points[n].y = control_points[n]->get_y();
                }
 
-               line->set (line_points);
+               line->set_steps (line_points, is_stepped());
 
                update_visibility ();
        }
@@ -1132,17 +1134,13 @@ AutomationLine::remove_visibility (VisibleAspects va)
 void
 AutomationLine::track_entered()
 {
-       if (alist->interpolation() != AutomationList::Discrete) {
-               add_visibility (ControlPoints);
-       }
+       add_visibility (ControlPoints);
 }
 
 void
 AutomationLine::track_exited()
 {
-       if (alist->interpolation() != AutomationList::Discrete) {
-               remove_visibility (ControlPoints);
-       }
+       remove_visibility (ControlPoints);
 }
 
 XMLNode &
@@ -1182,7 +1180,7 @@ AutomationLine::view_to_model_coord_y (double& y) const
                y = 2.0 * y - 1.0;
        } else {
                y = y * (double)(alist->get_max_y() - alist->get_min_y()) + alist->get_min_y();
-               if (ARDOUR::parameter_is_midi((ARDOUR::AutomationType)alist->parameter().type())) {
+               if (_desc.toggled || _desc.integer_step) {
                        y = round(y);
                }
        }
@@ -1211,11 +1209,8 @@ AutomationLine::model_to_view_coord (double& x, double& y) const
 void
 AutomationLine::interpolation_changed (AutomationList::InterpolationStyle style)
 {
-       if (style == AutomationList::Discrete) {
-               set_visibility (ControlPoints);
-               line->hide();
-       } else {
-               set_visibility (Line);
+       if (line_points.size() > 1) {
+               line->set_steps(line_points, is_stepped());
        }
 }
 
index a18f93d9ae164ff742b095e836d528aada0f1afa..cf940df5be5f55e50721e734f1eb9a7618aface6 100644 (file)
@@ -224,6 +224,7 @@ private:
         */
        ARDOUR::framecnt_t _offset;
 
+       bool is_stepped() const;
        void update_visibility ();
        void reset_line_coords (ControlPoint&);
        void add_visible_control_point (uint32_t, uint32_t, double, double, ARDOUR::AutomationList::iterator, uint32_t);
index 16db9a69e2c2bcf299f49c9a323f20e3cd7879dc..04b05f5df1f33b2b7fede5a787e2bb29bf5874db 100644 (file)
@@ -33,6 +33,8 @@ class LIBCANVAS_API PolyLine : public PolyItem
        PolyLine (Item*);
        
        void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const;
+
+       virtual void set_steps (Points const &, bool stepped);
        
         bool covers (Duple const &) const;
        /**
index 60bca6bccf87011de9afbc28f6a12d679d49184f..3150907db6f17aec5fec9f16e362444bac54ff99 100644 (file)
@@ -47,6 +47,30 @@ PolyLine::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
        }
 }
 
+void
+PolyLine::set_steps (Points const & points, bool stepped)
+{
+       if (!stepped) {
+               PolyItem::set(points);
+               return;
+       }
+
+       Points copy;
+       for (Points::const_iterator p = points.begin(); p != points.end();) {
+               Points::const_iterator next = p;
+               ++next;
+
+               copy.push_back(*p);
+               if (next != points.end() && next->x != p->x) {
+                       copy.push_back(Duple(next->x, p->y));
+               }
+
+               p = next;
+       }
+
+       PolyItem::set(copy);
+}
+
 bool
 PolyLine::covers (Duple const & point) const
 {