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 PBD::Signal1
<void,ImageFrameTimeAxisGroup
*> ImageFrameTimeAxisGroup::CatchDeletion
;
40 //---------------------------------------------------------------------------------------//
41 // Constructor / Desctructor
44 * Constructs a new ImageFrameTimeAxisGroup.
46 * @param iftav the parent ImageFrameTimeAxis of this view helper
47 * @param group_id the unique name/id of this group
49 ImageFrameTimeAxisGroup::ImageFrameTimeAxisGroup(ImageFrameTimeAxisView
& iftav
, const string
& group_id
)
50 : _view_helper(iftav
), _group_id(group_id
)
52 selected_imageframe_item
= 0;
55 ImageFrameView::CatchDeletion
.connect (*this, ui_bind (&ImageFrameTimeAxisGroup::remove_imageframe_item
, this, _1
), gui_context());
60 * Responsible for destroying any Items that may have been added to this group
63 ImageFrameTimeAxisGroup::~ImageFrameTimeAxisGroup()
65 // Destroy all the ImageFramViews that we have
66 for(ImageFrameViewList::iterator iter
= imageframe_views
.begin(); iter
!= imageframe_views
.end(); ++iter
)
68 ImageFrameView
* ifv
= *iter
;
70 ImageFrameViewList::iterator next
= iter
;
73 imageframe_views
.erase(iter
);
81 CatchDeletion
; /* EMIT_SIGNAL */
85 //---------------------------------------------------------------------------------------//
86 // Name/Id Accessors/Mutators
89 * Set the name/Id of this group.
91 * @param new_name the new name of this group
92 * @param src the identity of the object that initiated the change
95 ImageFrameTimeAxisGroup::set_group_name(const string
& new_name
, void* src
)
97 if(_group_id
!= new_name
)
99 std::string temp_name
= _group_id
;
100 _group_id
= new_name
;
101 NameChanged(_group_id
, temp_name
, src
); /* EMIT_SIGNAL */
106 * Returns the id of this group
107 * The group id must be unique upon a time axis
109 * @return the id of this group
112 ImageFrameTimeAxisGroup::get_group_name() const
118 //---------------------------------------------------------------------------------------//
122 * Sets the height of the time axis view and the item upon it
124 * @param height the new height
127 ImageFrameTimeAxisGroup::set_item_heights(gdouble h
)
129 /* limit the values to something sane-ish */
130 if (h
< 10.0 || h
> 1000.0)
135 // set the heights of all the imaeg frame views within the group
136 for(ImageFrameViewList::const_iterator citer
= imageframe_views
.begin(); citer
!= imageframe_views
.end(); ++citer
)
138 (*citer
)->set_height(h
);
145 * Sets the current samples per unit.
146 * this method tells each item upon the time axis of the change
148 * @param spu the new samples per canvas unit value
151 ImageFrameTimeAxisGroup::set_item_samples_per_units(gdouble spp
)
158 for(ImageFrameViewList::const_iterator citer
= imageframe_views
.begin(); citer
!= imageframe_views
.end(); ++citer
)
160 (*citer
)->set_samples_per_unit(spp
);
167 * Sets the color of the items contained uopn this view helper
169 * @param color the new base color
172 ImageFrameTimeAxisGroup::apply_item_color(Gdk::Color
& color
)
174 region_color
= color
;
175 for(ImageFrameViewList::const_iterator citer
= imageframe_views
.begin(); citer
!= imageframe_views
.end(); citer
++)
177 (*citer
)->set_color (region_color
);
183 //---------------------------------------------------------------------------------------//
184 // child ImageFrameView methods
187 * Adds an ImageFrameView to the list of items upon this time axis view helper
188 * the new ImageFrameView is returned
190 * @param item_id the unique id of the new item
191 * @param image_id the id/name of the image data we are usin
192 * @param start the position the new item should be placed upon the time line
193 * @param duration the duration the new item should be placed upon the timeline
194 * @param rgb_data the rgb data of the image
195 * @param width the original image width of the rgb_data (not the size to display)
196 * @param height the irigianl height of the rgb_data
197 * @param num_channels the number of channles within the rgb_data
198 * @param src the identity of the object that initiated the change
201 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
)
203 ImageFrameView
* ifv
= 0;
205 //check that there is not already an imageframe with that id
206 if(get_named_imageframe_item(frame_id
) == 0)
208 ifv
= new ImageFrameView(frame_id
,
209 _view_helper
.canvas_item()->property_parent(),
210 &(_view_helper
.trackview()),
212 _view_helper
.trackview().editor
.get_current_zoom(),
221 imageframe_views
.push_front(ifv
);
222 ImageFrameAdded(ifv
, src
); /* EMIT_SIGNAL */
230 * Returns the named ImageFrameView or 0 if the named view does not exist on this view helper
232 * @param item_id the unique id of the item to search for
233 * @return the named ImageFrameView, or 0 if it is not held upon this view
236 ImageFrameTimeAxisGroup::get_named_imageframe_item(const string
& frame_id
)
238 ImageFrameView
* ifv
= 0;
240 for (ImageFrameViewList::const_iterator i
= imageframe_views
.begin(); i
!= imageframe_views
.end(); ++i
)
242 if (((ImageFrameView
*)*i
)->get_item_name() == frame_id
)
244 ifv
= ((ImageFrameView
*)*i
);
252 * Removes the currently selected ImageFrameView
254 * @param src the identity of the object that initiated the change
255 * @todo need to remoev this, the selected item within group is no longer
256 * used in favour of a time axis selected item
257 * @see add_imageframe_view
260 ImageFrameTimeAxisGroup::remove_selected_imageframe_item(void* src
)
262 std::string frame_id
;
264 if(selected_imageframe_item
)
266 ImageFrameViewList::iterator i
;
268 if((i
= find(imageframe_views
.begin(), imageframe_views
.end(), selected_imageframe_item
)) != imageframe_views
.end())
270 imageframe_views
.erase(i
);
271 frame_id
= selected_imageframe_item
->get_item_name();
273 // note that we delete the item here
274 delete(selected_imageframe_item
);
275 selected_imageframe_item
= 0;
277 std::string track_id
= _view_helper
.trackview().name();
278 ImageFrameRemoved(track_id
, _group_id
, frame_id
, src
); /* EMIT_SIGNAL */
283 //cerr << "No Selected ImageFrame" << endl;
289 * Removes and returns the named ImageFrameView from the list of ImageFrameViews held by this view helper
291 * @param item_id the ImageFrameView unique id to remove
292 * @param src the identity of the object that initiated the change
293 * @see add_imageframe_view
296 ImageFrameTimeAxisGroup::remove_named_imageframe_item(const string
& frame_id
, void* src
)
298 ImageFrameView
* removed
= 0;
300 for(ImageFrameViewList::iterator iter
= imageframe_views
.begin(); iter
!= imageframe_views
.end(); ++iter
)
302 ImageFrameView
* tempItem
= *iter
;
303 if(tempItem
->get_item_name() == frame_id
)
306 imageframe_views
.erase(iter
);
308 if (removed
== selected_imageframe_item
)
310 selected_imageframe_item
= 0;
313 std::string track_id
= _view_helper
.trackview().name();
314 ImageFrameRemoved(track_id
, _group_id
, frame_id
, src
); /* EMIT_SIGNAL */
316 // break from the for loop
326 * Removes ifv from the list of ImageFrameViews upon this TimeAxis.
327 * if ifv is not upon this TimeAxis, this method takes no action
329 * @param ifv the ImageFrameView to remove
332 ImageFrameTimeAxisGroup::remove_imageframe_item (ImageFrameView
* ifv
)
334 ENSURE_GUI_THREAD (*this, &ImageFrameTimeAxisGroup::remove_imageframe_item
, ifv
, src
)
336 ImageFrameViewList::iterator i
;
338 if((i
= find (imageframe_views
.begin(), imageframe_views
.end(), ifv
)) != imageframe_views
.end()) {
339 imageframe_views
.erase(i
);
341 std::string frame_id
= ifv
->get_item_name();
342 std::string track_id
= _view_helper
.trackview().name();
343 ImageFrameRemoved(track_id
, _group_id
, frame_id
, src
); /* EMIT_SIGNAL */
347 //---------------------------------------------------------------------------------------//
348 // Selected group methods
351 * Sets the currently selected item upon this time axis
353 * @param ifv the item to set selected
356 //ImageFrameTimeAxisGroup::set_selected_imageframe_item(ImageFrameView* ifv)
358 // if(selected_imageframe_item)
360 // selected_imageframe_item->set_selected(false, this);
363 // selected_imageframe_item = ifv;
365 // if(!ifv->get_selected())
367 // selected_imageframe_item->set_selected(true, this);
373 * Sets the currently selected item upon this time axis to the named item
375 * @param item_id the name/id of the item to set selected
378 //ImageFrameTimeAxisGroup::set_selected_imageframe_item(std::string frame_id)
380 // selected_imageframe_item = get_named_imageframe_item(frame_id);
385 * Returns the currently selected item upon this time axis
387 * @return the currently selected item pon this time axis
390 // ImageFrameTimeAxisGroup::get_selected_imageframe_item()
392 // return(selected_imageframe_item);
398 * Returns whether this grou pis currently selected
400 * @returns true if this group is currently selected
403 ImageFrameTimeAxisGroup::get_selected() const
410 * Sets he selected state of this group
412 * @param yn set true if this group is selected, false otherwise
415 ImageFrameTimeAxisGroup::set_selected(bool yn
)
422 //---------------------------------------------------------------------------------------//
423 // Handle time axis removal
426 * Handles the Removal of this VisualTimeAxis
427 * This _needs_ to be called to alert others of the removal properly, ie where the source
428 * of the removal came from.
430 * XXX Although im not too happy about this method of doing things, I cant think of a cleaner method
431 * just now to capture the source of the removal
433 * @param src the identity of the object that initiated the change
436 ImageFrameTimeAxisGroup::remove_this_group(void* src
)
439 defer to idle loop, otherwise we'll delete this object
440 while we're still inside this function ...
442 Glib::signal_idle().connect(sigc::bind(ptr_fun(&ImageFrameTimeAxisGroup::idle_remove_this_group
), this, src
));
446 * Callback used to remove this group during the gtk idle loop
447 * This is used to avoid deleting the obejct while inside the remove_this_group
450 * @param group the ImageFrameTimeAxisGroup to remove
451 * @param src the identity of the object that initiated the change
454 ImageFrameTimeAxisGroup::idle_remove_this_group(ImageFrameTimeAxisGroup
* group
, void* src
)
458 group
->GroupRemoved(group
->get_group_name(), src
); /* EMIT_SIGNAL */