2 Copyright (C) 2003 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.
23 #include <gtkmm2ext/gtk_ui.h>
25 #include "imageframe_time_axis_group.h"
26 #include "imageframe_time_axis_view.h"
27 #include "imageframe_view.h"
28 #include "imageframe_time_axis.h"
29 #include "canvas-simplerect.h"
30 #include "region_selection.h"
31 #include "public_editor.h"
32 #include "gui_thread.h"
36 using namespace ARDOUR
;
38 //---------------------------------------------------------------------------------------//
39 // Constructor / Desctructor
42 * Constructs a new ImageFrameTimeAxisGroup.
44 * @param iftav the parent ImageFrameTimeAxis of this view helper
45 * @param group_id the unique name/id of this group
47 ImageFrameTimeAxisGroup::ImageFrameTimeAxisGroup(ImageFrameTimeAxisView
& iftav
, const string
& group_id
)
48 : _view_helper(iftav
), _group_id(group_id
)
50 selected_imageframe_item
= 0 ;
56 * Responsible for destroying any Items that may have been added to this group
59 ImageFrameTimeAxisGroup::~ImageFrameTimeAxisGroup()
61 // Destroy all the ImageFramViews that we have
62 for(ImageFrameViewList::iterator iter
= imageframe_views
.begin(); iter
!= imageframe_views
.end(); ++iter
)
64 ImageFrameView
* ifv
= *iter
;
66 ImageFrameViewList::iterator next
= iter
;
69 imageframe_views
.erase(iter
) ;
77 GoingAway() ; /* EMIT_SIGNAL */
81 //---------------------------------------------------------------------------------------//
82 // Name/Id Accessors/Mutators
85 * Set the name/Id of this group.
87 * @param new_name the new name of this group
88 * @param src the identity of the object that initiated the change
91 ImageFrameTimeAxisGroup::set_group_name(const string
& new_name
, void* src
)
93 if(_group_id
!= new_name
)
95 std::string temp_name
= _group_id
;
96 _group_id
= new_name
;
97 NameChanged(_group_id
, temp_name
, src
) ; /* EMIT_SIGNAL */
102 * Returns the id of this group
103 * The group id must be unique upon a time axis
105 * @return the id of this group
108 ImageFrameTimeAxisGroup::get_group_name() const
114 //---------------------------------------------------------------------------------------//
118 * Sets the height of the time axis view and the item upon it
120 * @param height the new height
123 ImageFrameTimeAxisGroup::set_item_heights(gdouble h
)
125 /* limit the values to something sane-ish */
126 if (h
< 10.0 || h
> 1000.0)
131 // set the heights of all the imaeg frame views within the group
132 for(ImageFrameViewList::const_iterator citer
= imageframe_views
.begin(); citer
!= imageframe_views
.end(); ++citer
)
134 (*citer
)->set_height(h
) ;
141 * Sets the current samples per unit.
142 * this method tells each item upon the time axis of the change
144 * @param spu the new samples per canvas unit value
147 ImageFrameTimeAxisGroup::set_item_samples_per_units(gdouble spp
)
154 for(ImageFrameViewList::const_iterator citer
= imageframe_views
.begin(); citer
!= imageframe_views
.end(); ++citer
)
156 (*citer
)->set_samples_per_unit(spp
) ;
163 * Sets the color of the items contained uopn this view helper
165 * @param color the new base color
168 ImageFrameTimeAxisGroup::apply_item_color(Gdk::Color
& color
)
170 region_color
= color
;
171 for(ImageFrameViewList::const_iterator citer
= imageframe_views
.begin(); citer
!= imageframe_views
.end(); citer
++)
173 (*citer
)->set_color (region_color
) ;
179 //---------------------------------------------------------------------------------------//
180 // child ImageFrameView methods
183 * Adds an ImageFrameView to the list of items upon this time axis view helper
184 * the new ImageFrameView is returned
186 * @param item_id the unique id of the new item
187 * @param image_id the id/name of the image data we are usin
188 * @param start the position the new item should be placed upon the time line
189 * @param duration the duration the new item should be placed upon the timeline
190 * @param rgb_data the rgb data of the image
191 * @param width the original image width of the rgb_data (not the size to display)
192 * @param height the irigianl height of the rgb_data
193 * @param num_channels the number of channles within the rgb_data
194 * @param src the identity of the object that initiated the change
197 ImageFrameTimeAxisGroup::add_imageframe_item(const string
& frame_id
, nframes_t start
, nframes_t duration
, unsigned char* rgb_data
, uint32_t width
, uint32_t height
, uint32_t num_channels
, void* src
)
199 ImageFrameView
* ifv
= 0 ;
201 //check that there is not already an imageframe with that id
202 if(get_named_imageframe_item(frame_id
) == 0)
204 ifv
= new ImageFrameView(frame_id
,
205 _view_helper
.canvas_item()->property_parent(),
206 &(_view_helper
.trackview()),
208 _view_helper
.trackview().editor
.get_current_zoom(),
217 imageframe_views
.push_front(ifv
) ;
219 ifv
->GoingAway
.connect(bind(mem_fun(*this,&ImageFrameTimeAxisGroup::remove_imageframe_item
), (void*)this)) ;
221 ImageFrameAdded(ifv
, src
) ; /* EMIT_SIGNAL */
229 * Returns the named ImageFrameView or 0 if the named view does not exist on this view helper
231 * @param item_id the unique id of the item to search for
232 * @return the named ImageFrameView, or 0 if it is not held upon this view
235 ImageFrameTimeAxisGroup::get_named_imageframe_item(const string
& frame_id
)
237 ImageFrameView
* ifv
= 0 ;
239 for (ImageFrameViewList::const_iterator i
= imageframe_views
.begin(); i
!= imageframe_views
.end(); ++i
)
241 if (((ImageFrameView
*)*i
)->get_item_name() == frame_id
)
243 ifv
= ((ImageFrameView
*)*i
) ;
251 * Removes the currently selected ImageFrameView
253 * @param src the identity of the object that initiated the change
254 * @todo need to remoev this, the selected item within group is no longer
255 * used in favour of a time axis selected item
256 * @see add_imageframe_view
259 ImageFrameTimeAxisGroup::remove_selected_imageframe_item(void* src
)
261 std::string frame_id
;
263 if(selected_imageframe_item
)
265 ImageFrameViewList::iterator i
;
267 if((i
= find(imageframe_views
.begin(), imageframe_views
.end(), selected_imageframe_item
)) != imageframe_views
.end())
269 imageframe_views
.erase(i
) ;
270 frame_id
= selected_imageframe_item
->get_item_name() ;
272 // note that we delete the item here
273 delete(selected_imageframe_item
) ;
274 selected_imageframe_item
= 0 ;
276 std::string track_id
= _view_helper
.trackview().name() ;
277 ImageFrameRemoved(track_id
, _group_id
, frame_id
, src
) ; /* EMIT_SIGNAL */
282 //cerr << "No Selected ImageFrame" << endl ;
288 * Removes and returns the named ImageFrameView from the list of ImageFrameViews held by this view helper
290 * @param item_id the ImageFrameView unique id to remove
291 * @param src the identity of the object that initiated the change
292 * @see add_imageframe_view
295 ImageFrameTimeAxisGroup::remove_named_imageframe_item(const string
& frame_id
, void* src
)
297 ImageFrameView
* removed
= 0 ;
299 for(ImageFrameViewList::iterator iter
= imageframe_views
.begin(); iter
!= imageframe_views
.end(); ++iter
)
301 ImageFrameView
* tempItem
= *iter
;
302 if(tempItem
->get_item_name() == frame_id
)
305 imageframe_views
.erase(iter
) ;
307 if (removed
== selected_imageframe_item
)
309 selected_imageframe_item
= 0 ;
312 std::string track_id
= _view_helper
.trackview().name() ;
313 ImageFrameRemoved(track_id
, _group_id
, frame_id
, src
) ; /* EMIT_SIGNAL */
315 // break from the for loop
325 * Removes ifv from the list of ImageFrameViews upon this TimeAxis.
326 * if ifv is not upon this TimeAxis, this method takes no action
328 * @param ifv the ImageFrameView to remove
331 ImageFrameTimeAxisGroup::remove_imageframe_item(ImageFrameView
* ifv
, void* src
)
333 ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameTimeAxisGroup::remove_imageframe_item
), ifv
, src
));
335 ImageFrameViewList::iterator i
;
336 if((i
= find (imageframe_views
.begin(), imageframe_views
.end(), ifv
)) != imageframe_views
.end())
338 imageframe_views
.erase(i
) ;
340 std::string frame_id
= ifv
->get_item_name() ;
341 std::string track_id
= _view_helper
.trackview().name() ;
342 ImageFrameRemoved(track_id
, _group_id
, frame_id
, src
) ; /* EMIT_SIGNAL */
346 //---------------------------------------------------------------------------------------//
347 // Selected group methods
350 * Sets the currently selected item upon this time axis
352 * @param ifv the item to set selected
355 //ImageFrameTimeAxisGroup::set_selected_imageframe_item(ImageFrameView* ifv)
357 // if(selected_imageframe_item)
359 // selected_imageframe_item->set_selected(false, this) ;
362 // selected_imageframe_item = ifv ;
364 // if(!ifv->get_selected())
366 // selected_imageframe_item->set_selected(true, this) ;
372 * Sets the currently selected item upon this time axis to the named item
374 * @param item_id the name/id of the item to set selected
377 //ImageFrameTimeAxisGroup::set_selected_imageframe_item(std::string frame_id)
379 // selected_imageframe_item = get_named_imageframe_item(frame_id) ;
384 * Returns the currently selected item upon this time axis
386 * @return the currently selected item pon this time axis
389 // ImageFrameTimeAxisGroup::get_selected_imageframe_item()
391 // return(selected_imageframe_item) ;
397 * Returns whether this grou pis currently selected
399 * @returns true if this group is currently selected
402 ImageFrameTimeAxisGroup::get_selected() const
404 return(is_selected
) ;
409 * Sets he selected state of this group
411 * @param yn set true if this group is selected, false otherwise
414 ImageFrameTimeAxisGroup::set_selected(bool yn
)
421 //---------------------------------------------------------------------------------------//
422 // Handle time axis removal
425 * Handles the Removal of this VisualTimeAxis
426 * This _needs_ to be called to alert others of the removal properly, ie where the source
427 * of the removal came from.
429 * XXX Although im not too happy about this method of doing things, I cant think of a cleaner method
430 * just now to capture the source of the removal
432 * @param src the identity of the object that initiated the change
435 ImageFrameTimeAxisGroup::remove_this_group(void* src
)
438 defer to idle loop, otherwise we'll delete this object
439 while we're still inside this function ...
441 Glib::signal_idle().connect(bind(ptr_fun(&ImageFrameTimeAxisGroup::idle_remove_this_group
), this, src
));
445 * Callback used to remove this group during the gtk idle loop
446 * This is used to avoid deleting the obejct while inside the remove_this_group
449 * @param group the ImageFrameTimeAxisGroup to remove
450 * @param src the identity of the object that initiated the change
453 ImageFrameTimeAxisGroup::idle_remove_this_group(ImageFrameTimeAxisGroup
* group
, void* src
)
457 group
->GroupRemoved(group
->get_group_name(), src
) ; /* EMIT_SIGNAL */