2 Copyright (C) 2007 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "pbd/memento_command.h"
21 #include "ardour/automation_control.h"
22 #include "ardour/event_type_map.h"
23 #include "ardour/session.h"
24 #include "ardour/source.h"
25 #include "ardour/midi_automation_list_binder.h"
26 #include "ardour/midi_region.h"
28 #include "automation_region_view.h"
29 #include "gui_thread.h"
30 #include "public_editor.h"
31 #include "midi_automation_line.h"
35 AutomationRegionView::AutomationRegionView(ArdourCanvas::Group
* parent
,
36 AutomationTimeAxisView
& time_axis
,
37 boost::shared_ptr
<ARDOUR::Region
> region
,
38 const Evoral::Parameter
& param
,
39 boost::shared_ptr
<ARDOUR::AutomationList
> list
,
41 Gdk::Color
const & basic_color
)
42 : RegionView(parent
, time_axis
, region
, spu
, basic_color
)
46 assert(list
->parameter() == param
);
50 group
->signal_event().connect (sigc::mem_fun (this, &AutomationRegionView::canvas_event
), false);
51 group
->raise_to_top();
55 AutomationRegionView::init (Gdk::Color
const & basic_color
, bool /*wfd*/)
57 _enable_display
= false;
59 RegionView::init(basic_color
, false);
61 compute_colors (basic_color
);
63 reset_width_dependent_items ((double) _region
->length() / samples_per_unit
);
65 set_height (trackview
.current_height());
67 _region
->PropertyChanged
.connect (*this, invalidator (*this), ui_bind (&RegionView::region_changed
, this, _1
), gui_context());
71 _enable_display
= true;
75 AutomationRegionView::create_line (boost::shared_ptr
<ARDOUR::AutomationList
> list
)
77 _line
= boost::shared_ptr
<AutomationLine
> (new MidiAutomationLine(
78 ARDOUR::EventTypeMap::instance().to_symbol(list
->parameter()),
79 trackview
, *get_canvas_group(), list
,
80 boost::dynamic_pointer_cast
<ARDOUR::MidiRegion
> (_region
),
84 _line
->set_height ((uint32_t)rint(trackview
.current_height() - NAME_HIGHLIGHT_SIZE
));
86 _line
->show_all_control_points();
90 AutomationRegionView::canvas_event(GdkEvent
* ev
)
92 if (ev
->type
== GDK_BUTTON_RELEASE
) {
94 double x
= ev
->button
.x
;
95 double y
= ev
->button
.y
;
97 /* convert to item coordinates in the time axis view */
98 automation_view()->canvas_display()->w2i (x
, y
);
102 y
= min (y
, _height
- NAME_HIGHLIGHT_SIZE
);
104 add_automation_event (ev
, trackview
.editor().pixel_to_frame (x
) - _region
->position(), y
);
110 /** @param when Position in frames, where 0 is the start of the region.
111 * @param y y position, relative to our TimeAxisView.
114 AutomationRegionView::add_automation_event (GdkEvent
*, nframes_t when
, double y
)
117 boost::shared_ptr
<Evoral::Control
> c
= _region
->control(_parameter
, true);
118 boost::shared_ptr
<ARDOUR::AutomationControl
> ac
119 = boost::dynamic_pointer_cast
<ARDOUR::AutomationControl
>(c
);
121 create_line(ac
->alist());
125 AutomationTimeAxisView
* const view
= automation_view ();
127 /* compute vertical fractional position */
129 const double h
= trackview
.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE
- 2;
134 double when_d
= when
;
135 _line
->view_to_model_coord (when_d
, y
);
137 view
->session()->begin_reversible_command (_("add automation event"));
138 XMLNode
& before
= _line
->the_list()->get_state();
140 _line
->the_list()->add (when_d
, y
);
142 XMLNode
& after
= _line
->the_list()->get_state();
145 boost::shared_ptr
<ARDOUR::MidiRegion
> mr
= boost::dynamic_pointer_cast
<ARDOUR::MidiRegion
> (_region
);
148 view
->session()->commit_reversible_command (
149 new MementoCommand
<ARDOUR::AutomationList
> (new ARDOUR::MidiAutomationListBinder (mr
->midi_source(), _parameter
), &before
, &after
)
153 view
->session()->set_dirty ();
157 AutomationRegionView::set_height (double h
)
159 RegionView::set_height(h
);
162 _line
->set_height ((uint32_t)rint(h
- NAME_HIGHLIGHT_SIZE
));
167 AutomationRegionView::set_position (nframes64_t pos
, void* src
, double* ignored
)
169 return RegionView::set_position(pos
, src
, ignored
);
174 AutomationRegionView::reset_width_dependent_items (double pixel_width
)
176 RegionView::reset_width_dependent_items(pixel_width
);
184 AutomationRegionView::region_resized (const PBD::PropertyChange
& what_changed
)
186 RegionView::region_resized(what_changed
);
194 AutomationRegionView::entered (bool)
197 _line
->track_entered();
202 AutomationRegionView::exited()
205 _line
->track_exited();