update drobilla's fascistic dir-locals.el to force emacs users into whitespace submis...
[ardour.git] / gtk2_ardour / marker_time_axis_view.cc
1 /*
2     Copyright (C) 2003 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #include <algorithm>
21
22 #include <gtkmm.h>
23 #include <gtkmm2ext/gtk_ui.h>
24
25 #include "marker_time_axis_view.h"
26 #include "marker_time_axis.h"
27 #include "marker_view.h"
28 #include "imageframe_view.h"
29 #include "imageframe_time_axis.h"
30 #include "canvas-simplerect.h"
31 #include "public_editor.h"
32 #include "rgb_macros.h"
33 #include "gui_thread.h"
34 #include "ardour_ui.h"
35
36 #include "i18n.h"
37
38 using namespace ARDOUR ;
39 using namespace Editing;
40
41 //---------------------------------------------------------------------------------------//
42 // Constructor / Desctructor
43
44 /**
45  * Construct a new MarkerTimeAxisView helper time axis helper
46  *
47  * @param mta the TimeAxsiView that this objbect is the helper for
48  */
49 MarkerTimeAxisView::MarkerTimeAxisView(MarkerTimeAxis& tv)
50         : _trackview (tv)
51 {
52         region_color = _trackview.color();
53         stream_base_color = ARDOUR_UI::config()->canvasvar_MarkerTrack.get();
54
55         canvas_group = new ArdourCanvas::Group (*_trackview.canvas_display);
56
57         canvas_rect =  new ArdourCanvas::SimpleRect (*canvas_group);
58         canvas_rect->property_x1() = 0.0;
59         canvas_rect->property_y1() = 0.0;
60         canvas_rect->property_x2() = max_framepos;
61         canvas_rect->property_y2() = (double)20;
62         canvas_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_MarkerTrack.get();
63         canvas_rect->property_fill_color_rgba() = stream_base_color;
64
65         canvas_rect->signal_event().connect (sigc::bind (sigc::mem_fun (_trackview.editor, &PublicEditor::canvas_marker_time_axis_view_event), canvas_rect, &_trackview));
66
67         _samples_per_unit = _trackview.editor.get_current_zoom() ;
68
69         _trackview.editor.ZoomChanged.connect (sigc::mem_fun(*this, &MarkerTimeAxisView::reset_samples_per_unit));
70         MarkerView::CatchDeletion.connect (*this, ui_bind (&MarkerTimeAxisView::remove_marker_view, this, _1), gui_context());
71 }
72
73 /**
74  * Destructor
75  * Reposinsibly for destroying all marker items that may have been added to this time axis view
76  *
77  */
78 MarkerTimeAxisView::~MarkerTimeAxisView()
79 {
80         // destroy everything upon this view
81         for(MarkerViewList::iterator iter = marker_view_list.begin(); iter != marker_view_list.end(); ++iter)
82         {
83                 MarkerView* mv = (*iter) ;
84
85                 MarkerViewList::iterator next = iter ;
86                 next++ ;
87                 marker_view_list.erase(iter) ;
88
89                 delete mv ;
90                 mv = 0 ;
91
92                 iter = next ;
93         }
94
95         delete canvas_rect;
96         canvas_rect = 0 ;
97
98         delete canvas_group;
99         canvas_group = 0 ;
100 }
101
102
103 //---------------------------------------------------------------------------------------//
104 // ui methods & data
105
106 /**
107  * Sets the height of the time axis view and the item upon it
108  *
109  * @param height the new height
110  */
111 int
112 MarkerTimeAxisView::set_height(gdouble h)
113 {
114         if (h < 10.0 || h > 1000.0) {
115                 return -1;
116         }
117
118         canvas_rect->property_y2() = h;
119
120         for (MarkerViewList::iterator i = marker_view_list.begin(); i != marker_view_list.end(); ++i) {
121                 (*i)->set_y_position_and_height(0, h);
122         }
123
124         return 0;
125 }
126
127 /**
128  * Sets the position of this view helper on the canvas
129  *
130  * @param x the x position upon the canvas
131  * @param y the y position upon the canvas
132  */
133 int
134 MarkerTimeAxisView::set_position(gdouble x, gdouble y)
135 {
136         canvas_group->property_x() = x;
137         canvas_group->property_y() = y;
138         return 0;
139 }
140
141 /**
142  * Sets the current samples per unit.
143  * this method tells each item upon the time axis of the change
144  *
145  * @param spu the new samples per canvas unit value
146  */
147 int
148 MarkerTimeAxisView::set_samples_per_unit(gdouble spp)
149 {
150         if(spp < 1.0) {
151                 return -1 ;
152         }
153
154         _samples_per_unit = spp ;
155
156         for(MarkerViewList::iterator i = marker_view_list.begin(); i != marker_view_list.end(); ++i)
157         {
158                 (*i)->set_samples_per_unit(spp) ;
159         }
160         return(0) ;
161 }
162
163 /**
164  * Sets the color of the items contained upon this view helper
165  *
166  * @param color the new base color
167  */
168 void
169 MarkerTimeAxisView::apply_color(Gdk::Color& color)
170 {
171         region_color = color;
172
173         for (MarkerViewList::iterator i = marker_view_list.begin(); i != marker_view_list.end(); i++)
174         {
175                 (*i)->set_color (region_color) ;
176         }
177 }
178
179
180 //---------------------------------------------------------------------------------------//
181 // Child MarkerView Accessors/Mutators
182
183 /**
184  * Adds a marker view to the list of items upon this time axis view helper
185  * the new MarkerView is returned
186  *
187  * @param ifv the ImageFrameView that the new item is marking up
188  * @param mark_text the text to be displayed uopn the new marker item
189  * @param mark_id the unique id of the new item
190  * @param start the position the new item should be placed upon the time line
191  * @param duration the duration the new item should be placed upon the timeline
192  * @param src the identity of the object that initiated the change
193  */
194 MarkerView*
195 MarkerTimeAxisView::add_marker_view(ImageFrameView* ifv, std::string mark_type, std::string mark_id, framepos_t start, framecnt_t dur, void* src)
196 {
197         if(ifv->has_marker_view_item(mark_id))
198         {
199                 return(0) ;
200         }
201
202         MarkerView* mv = new MarkerView(canvas_group,
203                  &_trackview,
204                  ifv,
205                  _trackview.editor.get_current_zoom(),
206                  region_color,
207                  mark_type,
208                  mark_id,
209                  start,
210                  dur) ;
211
212         ifv->add_marker_view_item(mv, src) ;
213         marker_view_list.push_front(mv) ;
214
215         MarkerViewAdded(mv,src) ; /* EMIT_SIGNAL */
216
217         return(mv) ;
218 }
219
220 /**
221  * Returns the named MarkerView or 0 if the named marker does not exist
222  *
223  * @param item_id the unique id of the item to search for
224  * @return the named MarkerView, or 0 if it is not held upon this view
225  */
226 MarkerView*
227 MarkerTimeAxisView::get_named_marker_view(std::string item_id)
228 {
229         MarkerView* mv =  0 ;
230
231         for(MarkerViewList::iterator i = marker_view_list.begin(); i != marker_view_list.end(); ++i)
232         {
233                 if(((MarkerView*)*i)->get_item_name() == item_id)
234                 {
235                         mv = ((MarkerView*)*i) ;
236                         break ;
237                 }
238         }
239         return(mv) ;
240 }
241
242 /**
243  * Removes the currently selected MarverView
244  * Note that this method actually destroys the MarkerView too.
245  * We assume that since we own the object, we are allowed to do this
246  *
247  * @param src the identity of the object that initiated the change
248  * @see add_marker_view
249  */
250 void
251 MarkerTimeAxisView::remove_selected_marker_view(void* src)
252 {
253         std::string removed ;
254
255         if (selected_time_axis_item)
256         {
257                 MarkerViewList::iterator i ;
258                 if((i = find (marker_view_list.begin(), marker_view_list.end(), selected_time_axis_item)) != marker_view_list.end())
259                 {
260                         marker_view_list.erase(i) ;
261
262                          MarkerViewRemoved(selected_time_axis_item->get_item_name(),src) ; /* EMIT_SIGNAL */
263
264                         delete(selected_time_axis_item) ;
265                         selected_time_axis_item = 0 ;
266                 }
267         }
268         else
269         {
270                 //No selected marker view
271         }
272 }
273
274 /**
275  * Removes and returns the named MarkerView from the list of MarkerView held by this view helper
276  *
277  * @param item_id the MarkerView unique id to remove
278  * @param src the identity of the object that initiated the change
279  * @see add_marker_view
280  */
281 MarkerView*
282 MarkerTimeAxisView::remove_named_marker_view(std::string item_id, void* src)
283 {
284         MarkerView* mv = 0 ;
285
286         MarkerViewList::iterator i = marker_view_list.begin() ;
287
288         for(MarkerViewList::iterator iter = marker_view_list.begin(); iter != marker_view_list.end(); ++iter)
289         {
290                 if(((MarkerView*)*i)->get_item_name() == item_id)
291                 {
292                         mv = ((MarkerView*)*i) ;
293                         marker_view_list.erase(i) ;
294
295                          MarkerViewRemoved(mv->get_item_name(), src) ; /* EMIT_SIGNAL */
296
297                         // break from the for loop
298                         break;
299                 }
300                 i++ ;
301         }
302
303         return(mv) ;
304 }
305
306 /**
307  * Removes mv from the list of MarkerView upon this TimeAxis
308  *
309  * @param mv the MarkerView to remove
310  * @param src the identity of the object that initiated the change
311  */
312 void
313 MarkerTimeAxisView::remove_marker_view (MarkerView* mv)
314 {
315         ENSURE_GUI_THREAD (*this, &MarkerTimeAxisView::remove_marker_view, mv, src)
316
317         MarkerViewList::iterator i;
318
319         if((i = find (marker_view_list.begin(), marker_view_list.end(), mv)) != marker_view_list.end()) {
320                 marker_view_list.erase(i) ;
321
322                 // Assume this remove happened locally, else use remove_named_marker_time_axis
323                 // let listeners know that the named MarkerTimeAxis has been removed
324                  MarkerViewRemoved(mv->get_item_name(), src) ; /* EMIT_SIGNAL */
325         }
326 }
327
328 /**
329  * Sets the duration of the selected MarkerView to the specified number of seconds
330  *
331  * @param sec the duration to set the MArkerView to, in seconds
332  */
333 void
334 MarkerTimeAxisView::set_marker_duration_sec(double sec)
335 {
336   if(get_selected_time_axis_item() != 0)
337   {
338           get_selected_time_axis_item()->set_duration((sec * _trackview.editor.session()->frame_rate()), this);
339   }
340 }
341
342
343 //---------------------------------------------------------------------------------------//
344 // Selected item methods
345
346 /**
347  * Sets the currently selected item upon this time axis
348  *
349  * @param mv the item to set selected
350  */
351 void
352 MarkerTimeAxisView::set_selected_time_axis_item(MarkerView* mv)
353 {
354         selected_time_axis_item = mv ;
355 }
356
357 /**
358  * Clears any selected item upon this time axis
359  *
360  */
361 void
362 MarkerTimeAxisView::clear_selected_time_axis_item()
363 {
364         selected_time_axis_item = 0 ;
365 }
366
367 /**
368  * Returnsthe currently selected item upon this time axis
369  *
370  * @return the currently selected item pon this time axis
371  */
372 MarkerView*
373 MarkerTimeAxisView::get_selected_time_axis_item()
374 {
375         return(selected_time_axis_item) ;
376 }
377
378
379
380
381 /**
382  * convenience method to re-get the samples per unit and tell items upon this view
383  *
384  */
385 void
386 MarkerTimeAxisView::reset_samples_per_unit ()
387 {
388         set_samples_per_unit(_trackview.editor.get_current_zoom()) ;
389 }