1 /* 2 * Copyright (C) 2005-2017 Paul Davis <paul@linuxaudiosystems.com> 3 * Copyright (C) 2005 Karsten Wiese <fzuuzf@googlemail.com> 4 * Copyright (C) 2005 Nick Mainsbridge <mainsbridge@gmail.com> 5 * Copyright (C) 2005 Taybin Rutkin <taybin@taybin.com> 6 * Copyright (C) 2006 Hans Fugal <hans@fugal.net> 7 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net> 8 * Copyright (C) 2007-2015 David Robillard <d@drobilla.net> 9 * Copyright (C) 2014-2017 Robin Gareus <robin@gareus.org> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License along 22 * with this program; if not, write to the Free Software Foundation, Inc., 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 */ 25 26 #ifndef __ardour_automation_line_h__ 27 #define __ardour_automation_line_h__ 28 29 #include <vector> 30 #include <list> 31 #include <string> 32 #include <sys/types.h> 33 34 #include <sigc++/signal.h> 35 36 #include "evoral/TimeConverter.h" 37 38 #include "pbd/undo.h" 39 #include "pbd/statefuldestructible.h" 40 #include "pbd/memento_command.h" 41 42 #include "ardour/automation_list.h" 43 #include "ardour/parameter_descriptor.h" 44 #include "ardour/types.h" 45 46 #include "canvas/types.h" 47 #include "canvas/container.h" 48 #include "canvas/poly_line.h" 49 50 class AutomationLine; 51 class ControlPoint; 52 class PointSelection; 53 class TimeAxisView; 54 class AutomationTimeAxisView; 55 class Selectable; 56 class Selection; 57 class PublicEditor; 58 59 60 /** A GUI representation of an ARDOUR::AutomationList */ 61 class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible 62 { 63 public: 64 enum VisibleAspects { 65 Line = 0x1, 66 ControlPoints = 0x2, 67 SelectedControlPoints = 0x4 68 }; 69 70 AutomationLine (const std::string& name, 71 TimeAxisView& tv, 72 ArdourCanvas::Item& parent, 73 boost::shared_ptr<ARDOUR::AutomationList> al, 74 const ARDOUR::ParameterDescriptor& desc, 75 Evoral::TimeConverter<double, ARDOUR::samplepos_t>* converter = 0); 76 77 virtual ~AutomationLine (); 78 79 void queue_reset (); 80 void reset (); 81 void clear (); set_fill(bool f)82 void set_fill (bool f) { _fill = f; } // owner needs to call set_height 83 84 void set_selected_points (PointSelection const &); 85 void get_selectables (ARDOUR::samplepos_t, ARDOUR::samplepos_t, double, double, std::list<Selectable*>&); 86 void get_inverted_selectables (Selection&, std::list<Selectable*>& results); 87 88 virtual void remove_point (ControlPoint&); 89 bool control_points_adjacent (double xval, uint32_t& before, uint32_t& after); 90 91 /* dragging API */ 92 virtual void start_drag_single (ControlPoint*, double, float); 93 virtual void start_drag_line (uint32_t, uint32_t, float); 94 virtual void start_drag_multiple (std::list<ControlPoint*>, float, XMLNode *); 95 virtual std::pair<float, float> drag_motion (double, float, bool, bool with_push, uint32_t& final_index); 96 virtual void end_drag (bool with_push, uint32_t final_index); 97 98 ControlPoint* nth (uint32_t); 99 ControlPoint const * nth (uint32_t) const; npoints()100 uint32_t npoints() const { return control_points.size(); } 101 name()102 std::string name() const { return _name; } visible()103 bool visible() const { return _visible != VisibleAspects(0); } height()104 guint32 height() const { return _height; } 105 106 void set_line_color (uint32_t); get_line_color()107 uint32_t get_line_color() const { return _line_color; } 108 109 void set_visibility (VisibleAspects); 110 void add_visibility (VisibleAspects); 111 void remove_visibility (VisibleAspects); 112 113 void hide (); 114 void set_height (guint32); 115 116 bool get_uses_gain_mapping () const; 117 118 TimeAxisView& trackview; 119 canvas_group()120 ArdourCanvas::Container& canvas_group() const { return *group; } parent_group()121 ArdourCanvas::Item& parent_group() const { return _parent_group; } grab_item()122 ArdourCanvas::Item& grab_item() const { return *line; } 123 124 virtual std::string get_verbose_cursor_string (double) const; 125 std::string get_verbose_cursor_relative_string (double, double) const; 126 std::string fraction_to_string (double) const; 127 std::string delta_to_string (double) const; 128 double string_to_fraction (std::string const &) const; 129 void view_to_model_coord (double& x, double& y) const; 130 void view_to_model_coord_y (double &) const; 131 void model_to_view_coord (double& x, double& y) const; 132 void model_to_view_coord_y (double &) const; 133 134 double compute_delta (double from, double to) const; 135 void apply_delta (double& val, double delta) const; 136 137 void set_list(boost::shared_ptr<ARDOUR::AutomationList> list); the_list()138 boost::shared_ptr<ARDOUR::AutomationList> the_list() const { return alist; } 139 140 void track_entered(); 141 void track_exited(); 142 143 bool is_last_point (ControlPoint &); 144 bool is_first_point (ControlPoint &); 145 146 XMLNode& get_state (void); 147 int set_state (const XMLNode&, int version); 148 void set_colors(); 149 150 void modify_point_y (ControlPoint&, double); 151 152 virtual MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder (); 153 time_converter()154 const Evoral::TimeConverter<double, ARDOUR::samplepos_t>& time_converter () const { 155 return *_time_converter; 156 } 157 158 std::pair<ARDOUR::samplepos_t, ARDOUR::samplepos_t> get_point_x_range () const; 159 160 void set_maximum_time (ARDOUR::samplecnt_t); maximum_time()161 ARDOUR::samplecnt_t maximum_time () const { 162 return _maximum_time; 163 } 164 165 void set_offset (ARDOUR::samplecnt_t); offset()166 ARDOUR::samplecnt_t offset () { return _offset; } 167 void set_width (ARDOUR::samplecnt_t); 168 169 samplepos_t session_position (ARDOUR::AutomationList::const_iterator) const; 170 171 protected: 172 173 std::string _name; 174 guint32 _height; 175 uint32_t _line_color; 176 177 boost::shared_ptr<ARDOUR::AutomationList> alist; 178 Evoral::TimeConverter<double, ARDOUR::samplepos_t>* _time_converter; 179 /** true if _time_converter belongs to us (ie we should delete it on destruction) */ 180 bool _our_time_converter; 181 182 VisibleAspects _visible; 183 184 bool terminal_points_can_slide; 185 bool update_pending; 186 bool have_timeout; 187 bool no_draw; 188 bool _is_boolean; 189 /** true if we did a push at any point during the current drag */ 190 bool did_push; 191 192 ArdourCanvas::Item& _parent_group; 193 ArdourCanvas::Container* group; 194 ArdourCanvas::PolyLine* line; /* line */ 195 ArdourCanvas::Points line_points; /* coordinates for canvas line */ 196 std::vector<ControlPoint*> control_points; /* visible control points */ 197 198 class ContiguousControlPoints : public std::list<ControlPoint*> { 199 public: 200 ContiguousControlPoints (AutomationLine& al); 201 double clamp_dx (double dx); 202 void move (double dx, double dvalue); 203 void compute_x_bounds (PublicEditor& e); 204 private: 205 AutomationLine& line; 206 double before_x; 207 double after_x; 208 }; 209 210 friend class ContiguousControlPoints; 211 212 typedef boost::shared_ptr<ContiguousControlPoints> CCP; 213 std::vector<CCP> contiguous_points; 214 215 bool sync_model_with_view_point (ControlPoint&); 216 bool sync_model_with_view_points (std::list<ControlPoint*>); 217 void start_drag_common (double, float); 218 219 void reset_callback (const Evoral::ControlList&); 220 void list_changed (); 221 222 virtual bool event_handler (GdkEvent*); 223 224 private: 225 std::list<ControlPoint*> _drag_points; ///< points we are dragging 226 std::list<ControlPoint*> _push_points; ///< additional points we are dragging if "push" is enabled 227 bool _drag_had_movement; ///< true if the drag has seen movement, otherwise false 228 double _drag_x; ///< last x position of the drag, in units 229 double _drag_distance; ///< total x movement of the drag, in canvas units 230 double _last_drag_fraction; ///< last y position of the drag, as a fraction 231 /** offset from the start of the automation list to the start of the line, so that 232 * a +ve offset means that the 0 on the line is at _offset in the list 233 */ 234 ARDOUR::samplecnt_t _offset; 235 236 bool is_stepped() const; 237 void update_visibility (); 238 void reset_line_coords (ControlPoint&); 239 void add_visible_control_point (uint32_t, uint32_t, double, double, ARDOUR::AutomationList::iterator, uint32_t); 240 double control_point_box_size (); 241 void connect_to_list (); 242 void interpolation_changed (ARDOUR::AutomationList::InterpolationStyle); 243 244 PBD::ScopedConnectionList _list_connections; 245 246 /** maximum time that a point on this line can be at, relative to the position of its region or start of its track */ 247 ARDOUR::samplecnt_t _maximum_time; 248 249 bool _fill; 250 251 const ARDOUR::ParameterDescriptor _desc; 252 253 friend class AudioRegionGainLine; 254 }; 255 256 #endif /* __ardour_automation_line_h__ */ 257 258