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.
20 #include <pbd/error.h>
21 #include <pbd/stacktrace.h>
23 #include <ardour/types.h>
24 #include <ardour/ardour.h>
26 #include <gtkmm2ext/utils.h>
28 #include "public_editor.h"
29 #include "time_axis_view_item.h"
30 #include "time_axis_view.h"
31 #include "simplerect.h"
33 #include "canvas_impl.h"
34 #include "rgb_macros.h"
35 #include "ardour_ui.h"
40 using namespace Editing;
43 using namespace ARDOUR;
45 //------------------------------------------------------------------------------
46 /** Initialize const static memeber data */
48 Pango::FontDescription* TimeAxisViewItem::NAME_FONT = 0;
49 bool TimeAxisViewItem::have_name_font = false;
50 const double TimeAxisViewItem::NAME_X_OFFSET = 15.0;
51 const double TimeAxisViewItem::GRAB_HANDLE_LENGTH = 6 ;
53 double TimeAxisViewItem::NAME_Y_OFFSET;
54 double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
55 double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
58 //---------------------------------------------------------------------------------------//
59 // Constructor / Desctructor
62 * Constructs a new TimeAxisViewItem.
64 * @param it_name the unique name/Id of this item
65 * @param parant the parent canvas group
66 * @param tv the TimeAxisView we are going to be added to
67 * @param spu samples per unit
69 * @param start the start point of this item
70 * @param duration the duration of this item
72 TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color,
73 nframes_t start, nframes_t duration, bool recording,
75 : trackview (tv), _recregion(recording)
77 if (!have_name_font) {
79 /* first constructed item sets up font info */
81 NAME_FONT = get_font_for_style (N_("TimeAxisViewItemName"));
87 Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
91 layout->set_font_description (*NAME_FONT);
92 Gtkmm2ext::get_ink_pixel_size (layout, width, height);
94 NAME_Y_OFFSET = height + 5;
95 NAME_HIGHLIGHT_SIZE = height + 6;
96 NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 2;
98 have_name_font = true;
101 group = new ArdourCanvas::Group (parent);
103 init (it_name, spu, base_color, start, duration, vis);
107 TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
108 : trackview (other.trackview)
114 UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
115 c.set_rgb_p (r/255.0, g/255.0, b/255.0);
117 /* share the other's parent, but still create a new group */
119 Gnome::Canvas::Group* parent = other.group->property_parent();
121 group = new ArdourCanvas::Group (*parent);
123 init (other.item_name, other.samples_per_unit, c, other.frame_position, other.item_duration, other.visibility);
128 TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_color, nframes_t start, nframes_t duration, Visibility vis)
130 item_name = it_name ;
131 name_text_width = ::pixel_width (it_name, *NAME_FONT);
132 last_name_text_width = 0;
133 samples_per_unit = spu ;
134 should_show_selection = true;
135 frame_position = start ;
136 item_duration = duration ;
137 name_connected = false;
138 // why? fill_opacity = 60;
139 position_locked = false ;
140 max_item_duration = ARDOUR::max_frames;
141 min_item_duration = 0 ;
142 show_vestigial = true;
147 warning << "Time Axis Item Duration == 0" << endl ;
150 vestigial_frame = new ArdourCanvas::SimpleRect (*group);
151 vestigial_frame->property_x1() = (double) 0.0;
152 vestigial_frame->property_y1() = (double) 1.0;
153 vestigial_frame->property_x2() = (double) 2.0;
154 vestigial_frame->property_y2() = (double) trackview.current_height();
155 vestigial_frame->property_outline_what() = 0xF;
156 vestigial_frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
157 vestigial_frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
158 vestigial_frame->hide ();
160 if (visibility & ShowFrame) {
161 frame = new ArdourCanvas::SimpleRect (*group);
162 frame->property_x1() = (double) 0.0;
163 frame->property_y1() = (double) 1.0;
164 frame->property_x2() = (double) trackview.editor().frame_to_pixel(duration);
165 frame->property_y2() = (double) trackview.current_height();
166 frame->property_outline_pixels() = 1;
167 frame->property_outline_what() = 0xF;
168 frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
170 /* by default draw all 4 edges */
172 uint32_t outline_what = 0x1|0x2|0x4|0x8;
174 if (visibility & HideFrameLeft) {
175 outline_what &= ~(0x1);
178 if (visibility & HideFrameRight) {
179 outline_what &= ~(0x2);
182 if (visibility & HideFrameTB) {
183 outline_what &= ~(0x4 | 0x8);
186 frame->property_outline_what() = outline_what;
192 if (visibility & ShowNameHighlight) {
193 name_highlight = new ArdourCanvas::SimpleRect (*group);
194 if (visibility & FullWidthNameHighlight) {
195 name_highlight->property_x1() = (double) 0.0;
196 name_highlight->property_x2() = (double) (trackview.editor().frame_to_pixel(item_duration));
198 name_highlight->property_x1() = (double) 1.0;
199 name_highlight->property_x2() = (double) (trackview.editor().frame_to_pixel(item_duration)) - 1;
201 name_highlight->property_y1() = (double) (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE);
202 name_highlight->property_y2() = (double) (trackview.current_height() - 1);
204 name_highlight->set_data ("timeaxisviewitem", this);
210 if (visibility & ShowNameText) {
211 name_text = new ArdourCanvas::Text (*group);
212 name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET;
213 /* trackview.current_height() is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
214 then NAME_Y_OFFSET to position the text in the vertical center of the highlight
216 name_text->property_y() = (double) trackview.current_height() - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
217 name_text->property_font_desc() = *NAME_FONT;
218 name_text->property_anchor() = Gtk::ANCHOR_NW;
220 name_text->set_data ("timeaxisviewitem", this);
226 /* create our grab handles used for trimming/duration etc */
228 if (visibility & ShowHandles) {
229 frame_handle_start = new ArdourCanvas::SimpleRect (*group);
230 frame_handle_start->property_x1() = (double) 0.0;
231 frame_handle_start->property_x2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH;
232 frame_handle_start->property_y1() = (double) 1.0;
233 frame_handle_start->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH+1;
234 frame_handle_start->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
236 frame_handle_end = new ArdourCanvas::SimpleRect (*group);
237 frame_handle_end->property_x1() = (double) (trackview.editor().frame_to_pixel(get_duration())) - (TimeAxisViewItem::GRAB_HANDLE_LENGTH);
238 frame_handle_end->property_x2() = (double) trackview.editor().frame_to_pixel(get_duration());
239 frame_handle_end->property_y1() = (double) 1;
240 frame_handle_end->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH + 1;
241 frame_handle_end->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
244 frame_handle_start = 0;
245 frame_handle_end = 0;
248 set_color (base_color) ;
250 set_duration (item_duration, this) ;
251 set_position (start, this) ;
257 TimeAxisViewItem::~TimeAxisViewItem()
263 //---------------------------------------------------------------------------------------//
264 // Position and duration Accessors/Mutators
267 * Set the position of this item upon the timeline to the specified value
269 * @param pos the new position
270 * @param src the identity of the object that initiated the change
271 * @return true if the position change was a success, false otherwise
274 TimeAxisViewItem::set_position(nframes_t pos, void* src, double* delta)
276 if (position_locked) {
280 frame_position = pos;
282 /* This sucks. The GnomeCanvas version I am using
283 doesn't correctly implement gnome_canvas_group_set_arg(),
284 so that simply setting the "x" arg of the group
285 fails to move the group. Instead, we have to
286 use gnome_canvas_item_move(), which does the right
287 thing. I see that in GNOME CVS, the current (Sept 2001)
288 version of GNOME Canvas rectifies this issue cleanly.
291 double old_unit_pos ;
292 double new_unit_pos = pos / samples_per_unit ;
294 old_unit_pos = group->property_x();
296 if (new_unit_pos != old_unit_pos) {
297 group->move (new_unit_pos - old_unit_pos, 0.0);
301 (*delta) = new_unit_pos - old_unit_pos;
304 PositionChanged (frame_position, src) ; /* EMIT_SIGNAL */
310 * Return the position of this item upon the timeline
312 * @return the position of this item
315 TimeAxisViewItem::get_position() const
317 return frame_position;
321 * Sets the duration of this item
323 * @param dur the new duration of this item
324 * @param src the identity of the object that initiated the change
325 * @return true if the duration change was succesful, false otherwise
328 TimeAxisViewItem::set_duration (nframes_t dur, void* src)
330 if ((dur > max_item_duration) || (dur < min_item_duration)) {
331 warning << string_compose (_("new duration %1 frames is out of bounds for %2"), get_item_name(), dur)
342 reset_width_dependent_items (trackview.editor().frame_to_pixel (dur));
344 DurationChanged (dur, src) ; /* EMIT_SIGNAL */
349 * Returns the duration of this item
353 TimeAxisViewItem::get_duration() const
355 return (item_duration);
359 * Sets the maximum duration that this item make have.
361 * @param dur the new maximum duration
362 * @param src the identity of the object that initiated the change
365 TimeAxisViewItem::set_max_duration(nframes_t dur, void* src)
367 max_item_duration = dur ;
368 MaxDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */
372 * Returns the maxmimum duration that this item may be set to
374 * @return the maximum duration that this item may be set to
377 TimeAxisViewItem::get_max_duration() const
379 return (max_item_duration) ;
383 * Sets the minimu duration that this item may be set to
385 * @param the minimum duration that this item may be set to
386 * @param src the identity of the object that initiated the change
389 TimeAxisViewItem::set_min_duration(nframes_t dur, void* src)
391 min_item_duration = dur ;
392 MinDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */
396 * Returns the minimum duration that this item mey be set to
398 * @return the nimum duration that this item mey be set to
401 TimeAxisViewItem::get_min_duration() const
403 return(min_item_duration) ;
407 * Sets whether the position of this Item is locked to its current position
408 * Locked items cannot be moved until the item is unlocked again.
410 * @param yn set to true to lock this item to its current position
411 * @param src the identity of the object that initiated the change
414 TimeAxisViewItem::set_position_locked(bool yn, void* src)
416 position_locked = yn ;
417 set_trim_handle_colors() ;
418 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
422 * Returns whether this item is locked to its current position
424 * @return true if this item is locked to its current posotion
428 TimeAxisViewItem::get_position_locked() const
430 return (position_locked);
434 * Sets whether the Maximum Duration constraint is active and should be enforced
436 * @param active set true to enforce the max duration constraint
437 * @param src the identity of the object that initiated the change
440 TimeAxisViewItem::set_max_duration_active(bool active, void* src)
442 max_duration_active = active ;
446 * Returns whether the Maximum Duration constraint is active and should be enforced
448 * @return true if the maximum duration constraint is active, false otherwise
451 TimeAxisViewItem::get_max_duration_active() const
453 return(max_duration_active) ;
457 * Sets whether the Minimum Duration constraint is active and should be enforced
459 * @param active set true to enforce the min duration constraint
460 * @param src the identity of the object that initiated the change
463 TimeAxisViewItem::set_min_duration_active(bool active, void* src)
465 min_duration_active = active ;
469 * Returns whether the Maximum Duration constraint is active and should be enforced
471 * @return true if the maximum duration constraint is active, false otherwise
474 TimeAxisViewItem::get_min_duration_active() const
476 return(min_duration_active) ;
479 //---------------------------------------------------------------------------------------//
480 // Name/Id Accessors/Mutators
483 * Set the name/Id of this item.
485 * @param new_name the new name of this item
486 * @param src the identity of the object that initiated the change
489 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
491 if (new_name != item_name) {
492 std::string temp_name = item_name ;
493 item_name = new_name ;
494 name_text_width = ::pixel_width (new_name, *NAME_FONT);
495 NameChanged (item_name, temp_name, src) ; /* EMIT_SIGNAL */
500 * Returns the name/id of this item
502 * @return the name/id of this item
505 TimeAxisViewItem::get_item_name() const
510 //---------------------------------------------------------------------------------------//
514 * Set to true to indicate that this item is currently selected
516 * @param yn true if this item is currently selected
517 * @param src the identity of the object that initiated the change
520 TimeAxisViewItem::set_selected(bool yn)
522 if (_selected != yn) {
523 Selectable::set_selected (yn);
529 TimeAxisViewItem::set_should_show_selection (bool yn)
531 if (should_show_selection != yn) {
532 should_show_selection = yn;
537 //---------------------------------------------------------------------------------------//
538 // Parent Componenet Methods
541 * Returns the TimeAxisView that this item is upon
543 * @return the timeAxisView that this item is placed upon
546 TimeAxisViewItem::get_time_axis_view()
550 //---------------------------------------------------------------------------------------//
554 * Sets the displayed item text
555 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item
557 * @param new_name the new name text to display
560 TimeAxisViewItem::set_name_text(const ustring& new_name)
563 name_text->property_text() = new_name;
564 name_text_width = pixel_width (new_name, *NAME_FONT);
565 name_text_size_cache.clear ();
570 * Set the height of this item
572 * @param h the new height
575 TimeAxisViewItem::set_height (double height)
577 if (name_highlight) {
578 if (height < NAME_HIGHLIGHT_THRESH) {
579 name_highlight->hide();
584 name_highlight->show();
590 if (height > NAME_HIGHLIGHT_SIZE) {
591 name_highlight->property_y1() = (double) height+1 - NAME_HIGHLIGHT_SIZE;
592 name_highlight->property_y2() = (double) height;
595 /* it gets hidden now anyway */
596 name_highlight->property_y1() = (double) 1.0;
597 name_highlight->property_y2() = (double) height;
602 name_text->property_y() = height+1 - NAME_Y_OFFSET;
603 if (height < NAME_HIGHLIGHT_THRESH) {
604 name_text->property_fill_color_rgba() = fill_color;
607 name_text->property_fill_color_rgba() = label_color;
612 frame->property_y2() = height+1;
615 vestigial_frame->property_y2() = height+1;
622 TimeAxisViewItem::set_color(Gdk::Color& base_color)
624 compute_colors (base_color);
632 TimeAxisViewItem::get_canvas_frame()
641 TimeAxisViewItem::get_canvas_group()
650 TimeAxisViewItem::get_name_highlight()
652 return (name_highlight) ;
659 TimeAxisViewItem::get_name_text()
665 * Calculates some contrasting color for displaying various parts of this item, based upon the base color
667 * @param color the base color of the item
670 TimeAxisViewItem::compute_colors(Gdk::Color& base_color)
672 unsigned char radius ;
675 unsigned char r,g,b ;
677 /* FILL: this is simple */
678 r = base_color.get_red()/256 ;
679 g = base_color.get_green()/256 ;
680 b = base_color.get_blue()/256 ;
681 fill_color = RGBA_TO_UINT(r,g,b,160) ;
684 if the overall saturation is strong, make the minor colors light.
685 if its weak, make them dark.
687 we do this by moving an equal distance to the other side of the
688 central circle in the color wheel from where we started.
691 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f)) ;
692 minor_shift = 125 - radius ;
694 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
696 r = base_color.get_red()/256;
697 g = base_color.get_green()/256;
698 b = base_color.get_blue()/256;
704 /* red sector => green */
709 /* green sector => blue */
717 /* blue sector => red */
722 /* green sector => blue */
731 label_color = RGBA_TO_UINT(r,g,b,255);
732 r = (base_color.get_red()/256) + 127 ;
733 g = (base_color.get_green()/256) + 127 ;
734 b = (base_color.get_blue()/256) + 127 ;
736 label_color = RGBA_TO_UINT(r,g,b,255);
738 /* XXX can we do better than this ? */
739 /* We're trying ;) */
742 //frame_color_r = 192;
743 //frame_color_g = 192;
744 //frame_color_b = 194;
746 //selected_frame_color_r = 182;
747 //selected_frame_color_g = 145;
748 //selected_frame_color_b = 168;
750 //handle_color_r = 25 ;
751 //handle_color_g = 0 ;
752 //handle_color_b = 255 ;
753 //lock_handle_color_r = 235 ;
754 //lock_handle_color_g = 16;
755 //lock_handle_color_b = 16;
759 * Convenience method to set the various canvas item colors
762 TimeAxisViewItem::set_colors()
766 double height = NAME_HIGHLIGHT_THRESH;
769 height = frame->property_y2();
772 if (height < NAME_HIGHLIGHT_THRESH) {
773 name_text->property_fill_color_rgba() = fill_color;
776 name_text->property_fill_color_rgba() = label_color;
780 if (name_highlight) {
781 name_highlight->property_fill_color_rgba() = fill_color;
782 name_highlight->property_outline_color_rgba() = fill_color;
784 set_trim_handle_colors() ;
788 * Sets the frame color depending on whether this item is selected
791 TimeAxisViewItem::set_frame_color()
796 if (_selected && should_show_selection) {
797 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a);
798 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
801 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_RecordingRect.get(), &r, &g, &b, &a);
802 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
804 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
805 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
812 * Sets the colors of the start and end trim handle depending on object state
816 TimeAxisViewItem::set_trim_handle_colors()
818 if (frame_handle_start) {
819 if (position_locked) {
820 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get();
821 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get();
823 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get();
824 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get();
830 TimeAxisViewItem::get_samples_per_unit()
832 return(samples_per_unit) ;
836 TimeAxisViewItem::set_samples_per_unit (double spu)
838 samples_per_unit = spu ;
839 set_position (this->get_position(), this);
840 reset_width_dependent_items ((double)get_duration() / samples_per_unit);
844 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
846 if (pixel_width < GRAB_HANDLE_LENGTH * 2) {
848 if (frame_handle_start) {
849 frame_handle_start->hide();
850 frame_handle_end->hide();
853 } if (pixel_width < 2.0) {
855 if (show_vestigial) {
856 vestigial_frame->show();
859 if (name_highlight) {
860 name_highlight->hide();
870 if (frame_handle_start) {
871 frame_handle_start->hide();
872 frame_handle_end->hide();
876 vestigial_frame->hide();
878 if (name_highlight) {
880 double height = name_highlight->property_y2 ();
882 if (height < NAME_HIGHLIGHT_THRESH) {
883 name_highlight->hide();
888 name_highlight->show();
889 if (name_text && !get_item_name().empty()) {
891 reset_name_width (pixel_width);
895 if (visibility & FullWidthNameHighlight) {
896 name_highlight->property_x2() = pixel_width;
898 name_highlight->property_x2() = pixel_width - 1.0;
905 frame->property_x2() = pixel_width;
908 if (frame_handle_start) {
909 if (pixel_width < (2*TimeAxisViewItem::GRAB_HANDLE_LENGTH)) {
910 frame_handle_start->hide();
911 frame_handle_end->hide();
913 frame_handle_start->show();
914 frame_handle_end->property_x1() = pixel_width - (TimeAxisViewItem::GRAB_HANDLE_LENGTH);
915 frame_handle_end->show();
916 frame_handle_end->property_x2() = pixel_width;
922 TimeAxisViewItem::reset_name_width (double pixel_width)
924 if (name_text == 0) {
928 int limit = (int) floor (pixel_width - NAME_X_OFFSET);
929 bool shrinking = (last_name_text_width > pixel_width);
932 ustring::size_type n;
934 if ((last_name_text_width && // we did this once
935 shrinking && // we're getting smaller
936 (name_text_width <= limit) && // fits the new size
937 (name_text_width <= last_name_text_width - NAME_X_OFFSET))) { // fit into the old size too
938 last_name_text_width = pixel_width;
942 /* now check the cache of existing truncations */
945 Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout ("");
947 for (n = item_name.length(); n > 0; --n) {
949 map<ustring::size_type,int>::iterator i;
951 if ((i = name_text_size_cache.find (n)) != name_text_size_cache.end()) {
953 /* we know the length of this substring already */
955 if ((actual_width = (*i).second) < limit) {
957 /* it fits, use it */
959 ustr = item_name.substr (0, n);
965 /* we don't know the length of this substring already, so compute
966 it and put it into the cache.
969 layout->set_text (item_name.substr (0, n));
972 Gtkmm2ext::get_ink_pixel_size (layout, width, height);
974 name_text_size_cache[n] = width;
976 if ((actual_width = width) < limit) {
977 ustr = item_name.substr (0, n);
984 name_text->property_text() = "";
985 last_name_text_width = pixel_width;
989 /* don't use name for event handling if it leaves no room
990 for trimming to work.
993 if (pixel_width - actual_width < (NAME_X_OFFSET * 2.0)) {
994 if (name_connected) {
995 name_connected = false;
998 if (!name_connected) {
999 name_connected = true;
1003 name_text->property_text() = ustr;
1004 name_text_width = actual_width;
1006 last_name_text_width = pixel_width;
1011 //---------------------------------------------------------------------------------------//
1012 // Handle time axis removal
1015 * Handles the Removal of this time axis item
1016 * This _needs_ to be called to alert others of the removal properly, ie where the source
1017 * of the removal came from.
1019 * XXX Although im not too happy about this method of doing things, I cant think of a cleaner method
1020 * just now to capture the source of the removal
1022 * @param src the identity of the object that initiated the change
1025 TimeAxisViewItem::remove_this_item(void* src)
1028 defer to idle loop, otherwise we'll delete this object
1029 while we're still inside this function ...
1031 Glib::signal_idle().connect(bind (sigc::ptr_fun (&TimeAxisViewItem::idle_remove_this_item), this, src));
1035 * Callback used to remove this time axis item during the gtk idle loop
1036 * This is used to avoid deleting the obejct while inside the remove_this_item
1039 * @param item the TimeAxisViewItem to remove
1040 * @param src the identity of the object that initiated the change
1043 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1045 item->ItemRemoved (item->get_item_name(), src) ; /* EMIT_SIGNAL */
1052 TimeAxisViewItem::set_y (double y)
1054 double const old = group->property_y ();
1056 group->move (0, y - old);