fix up file renaming code a little bit
[ArdourMidi.git] / gtk2_ardour / automation_streamview.cc
blob146cdc7b8918077f672e772b115533b00ff84fdb
1 /*
2 Copyright (C) 2001-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include <cmath>
20 #include <cassert>
21 #include <utility>
23 #include <gtkmm.h>
25 #include <gtkmm2ext/gtk_ui.h>
27 #include "ardour/midi_playlist.h"
28 #include "ardour/midi_region.h"
29 #include "ardour/midi_source.h"
30 #include "ardour/midi_diskstream.h"
31 #include "ardour/midi_track.h"
32 #include "ardour/smf_source.h"
33 #include "ardour/region_factory.h"
35 #include "automation_streamview.h"
36 #include "region_view.h"
37 #include "automation_region_view.h"
38 #include "automation_time_axis.h"
39 #include "canvas-simplerect.h"
40 #include "region_selection.h"
41 #include "selection.h"
42 #include "public_editor.h"
43 #include "ardour_ui.h"
44 #include "rgb_macros.h"
45 #include "gui_thread.h"
46 #include "utils.h"
47 #include "simplerect.h"
48 #include "simpleline.h"
50 using namespace std;
51 using namespace ARDOUR;
52 using namespace PBD;
53 using namespace Editing;
55 AutomationStreamView::AutomationStreamView (AutomationTimeAxisView& tv)
56 : StreamView (*dynamic_cast<RouteTimeAxisView*>(tv.get_parent()),
57 new ArdourCanvas::Group(*tv.canvas_background()),
58 new ArdourCanvas::Group(*tv.canvas_display()))
59 , _controller(tv.controller())
60 , _automation_view(tv)
61 , _pending_automation_state (Off)
63 //canvas_rect->property_fill_color_rgba() = stream_base_color;
64 canvas_rect->property_outline_color_rgba() = RGBA_BLACK;
67 AutomationStreamView::~AutomationStreamView ()
72 RegionView*
73 AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region, bool wfd, bool /*recording*/)
75 if ( ! region) {
76 cerr << "No region" << endl;
77 return NULL;
80 if (wfd) {
81 boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
82 if (mr)
83 mr->midi_source()->load_model();
86 const boost::shared_ptr<AutomationControl> control = boost::dynamic_pointer_cast<AutomationControl> (
87 region->control (_controller->controllable()->parameter(), true)
90 boost::shared_ptr<AutomationList> list;
91 if (control) {
92 list = boost::dynamic_pointer_cast<AutomationList>(control->list());
93 assert(!control->list() || list);
96 AutomationRegionView *region_view;
97 std::list<RegionView *>::iterator i;
99 for (i = region_views.begin(); i != region_views.end(); ++i) {
100 if ((*i)->region() == region) {
102 /* great. we already have an AutomationRegionView for this Region. use it again. */
103 AutomationRegionView* arv = dynamic_cast<AutomationRegionView*>(*i);;
105 if (arv->line())
106 arv->line()->set_list (list);
107 (*i)->set_valid (true);
108 (*i)->enable_display(wfd);
109 display_region(arv);
111 return NULL;
115 region_view = new AutomationRegionView (_canvas_group, _automation_view, region,
116 _controller->controllable()->parameter(), list,
117 _samples_per_unit, region_color);
119 region_view->init (region_color, false);
120 region_views.push_front (region_view);
122 /* follow global waveform setting */
124 if (wfd) {
125 region_view->enable_display(true);
126 //region_view->midi_region()->midi_source(0)->load_model();
129 display_region(region_view);
131 /* catch regionview going away */
132 region->DropReferences.connect (*this, invalidator (*this), boost::bind (&AutomationStreamView::remove_region_view, this, boost::weak_ptr<Region>(region)), gui_context());
134 /* setup automation state for this region */
135 boost::shared_ptr<AutomationLine> line = region_view->line ();
136 if (line && line->the_list()) {
137 line->the_list()->set_automation_state (automation_state ());
140 RegionViewAdded (region_view);
142 return region_view;
145 void
146 AutomationStreamView::display_region(AutomationRegionView* region_view)
148 region_view->line().reset();
151 void
152 AutomationStreamView::set_automation_state (AutoState state)
154 /* XXX: not sure if this is right, but for now the automation state is basically held by
155 the regions' AutomationLists. Each region is always set to have the same AutoState.
158 if (region_views.empty()) {
159 _pending_automation_state = state;
160 } else {
161 for (std::list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
162 boost::shared_ptr<AutomationLine> line = dynamic_cast<AutomationRegionView*>(*i)->line();
163 if (line && line->the_list()) {
164 line->the_list()->set_automation_state (state);
170 void
171 AutomationStreamView::redisplay_track ()
173 list<RegionView *>::iterator i, tmp;
175 // Flag region views as invalid and disable drawing
176 for (i = region_views.begin(); i != region_views.end(); ++i) {
177 (*i)->set_valid (false);
178 (*i)->enable_display(false);
181 // Add and display region views, and flag them as valid
182 if (_trackview.is_track()) {
183 _trackview.track()->playlist()->foreach_region (
184 sigc::hide_return (sigc::mem_fun (*this, &StreamView::add_region_view))
188 // Stack regions by layer, and remove invalid regions
189 layer_regions();
193 void
194 AutomationStreamView::setup_rec_box ()
198 void
199 AutomationStreamView::color_handler ()
201 /*if (_trackview.is_midi_track()) {
202 canvas_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiTrackBase.get();
205 if (!_trackview.is_midi_track()) {
206 canvas_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiBusBase.get();;
210 AutoState
211 AutomationStreamView::automation_state () const
213 if (region_views.empty()) {
214 return _pending_automation_state;
217 boost::shared_ptr<AutomationLine> line = ((AutomationRegionView*) region_views.front())->line ();
218 if (!line || !line->the_list()) {
219 return Off;
222 return line->the_list()->automation_state ();
225 bool
226 AutomationStreamView::has_automation () const
228 list<RegionView*>::const_iterator i = region_views.begin ();
229 while (i != region_views.end()) {
230 AutomationRegionView* rv = static_cast<AutomationRegionView*> (*i);
231 if (rv->line() && rv->line()->npoints() > 0) {
232 return true;
234 ++i;
237 return false;
240 /** Our parent AutomationTimeAxisView calls this when the user requests a particular
241 * InterpolationStyle; tell the AutomationLists in our regions.
243 void
244 AutomationStreamView::set_interpolation (AutomationList::InterpolationStyle s)
246 for (list<RegionView*>::const_iterator i = region_views.begin(); i != region_views.end(); ++i) {
247 AutomationRegionView* arv = dynamic_cast<AutomationRegionView*> (*i);
248 assert (arv);
249 arv->line()->the_list()->set_interpolation (s);
253 AutomationList::InterpolationStyle
254 AutomationStreamView::interpolation () const
256 if (region_views.empty()) {
257 return AutomationList::Linear;
260 AutomationRegionView* v = dynamic_cast<AutomationRegionView*> (region_views.front());
261 assert (v);
263 return v->line()->the_list()->interpolation ();